Skip to content

Commit 50bca11

Browse files
committed
fix(cinder-understack): refactor init error cases to start cleanly
If any error occurred during startup the driver would just enter a failure loop because there would already be another instance for a prior SVM and things could never recover. This refactors the error paths to clean up and ensure things can startup successfully.
1 parent 77f0ef9 commit 50bca11

File tree

2 files changed

+19
-10
lines changed

2 files changed

+19
-10
lines changed

python/cinder-understack/cinder_understack/dynamic_netapp_driver.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -233,10 +233,9 @@ def do_setup(self, ctxt):
233233
svm_lib.do_setup(ctxt)
234234
self._libraries[svm_name] = svm_lib
235235

236-
def _remove_svm_lib(self, svm_name: str, svm_lib: NetAppMinimalLibrary):
236+
def _remove_svm_lib(self, svm_lib: NetAppMinimalLibrary):
237237
"""Remove resources for a given SVM library."""
238238
# TODO: Need to free up resources here.
239-
LOG.info("Removing resources for SVM library %s", svm_name)
240239
for task in svm_lib.loopingcalls.tasks:
241240
task.looping_call.stop()
242241
svm_lib.loopingcalls.tasks = []
@@ -257,17 +256,16 @@ def _actual_refresh_svm_libraries(self, ctxt):
257256
stale_svms = existing_libs - current_svms
258257
for svm_name in stale_svms:
259258
LOG.info("Removing stale NVMe library for SVM: %s", svm_name)
260-
# TODO : stop looping calls, free resources.
261-
svm_lib = self._libraries.get(svm_name)
262-
self._remove_svm_lib(svm_name, svm_lib)
259+
svm_lib = self._libraries[svm_name]
260+
self._remove_svm_lib(svm_lib)
263261
del self._libraries[svm_name]
264262

265263
# Add new SVM libraries
266264
new_svms = current_svms - existing_libs
267265
for svm_name in new_svms:
268266
LOG.info("Creating NVMe library for new SVM: %s", svm_name)
267+
lib = self._create_svm_lib(svm_name)
269268
try:
270-
lib = self._create_svm_lib(svm_name)
271269
# Call do_setup to initialize the library
272270
lib.do_setup(ctxt)
273271
lib.check_for_setup_error()
@@ -278,13 +276,21 @@ def _actual_refresh_svm_libraries(self, ctxt):
278276
"Failed to create library for SVM %s",
279277
svm_name,
280278
)
279+
self._remove_svm_lib(lib)
281280
LOG.info("Final libraries loaded: %s", list(self._libraries.keys()))
282281

283282
def check_for_setup_error(self):
284283
"""Check for setup errors."""
285-
for svm_name, svm_lib in self._libraries.items():
284+
svm_to_init = set(self._libraries.keys())
285+
for svm_name in svm_to_init:
286286
LOG.info("Checking NVMe library for errors for SVM %s", svm_name)
287-
svm_lib.check_for_setup_error()
287+
svm_lib = self._libraries[svm_name]
288+
try:
289+
svm_lib.check_for_setup_error()
290+
except Exception:
291+
LOG.exception("Failed to initialize SVM %s, skipping", svm_name)
292+
self._remove_svm_lib(svm_lib)
293+
del self._libraries[svm_name]
288294

289295
# looping call to refresh SVM libraries
290296
if not self._looping_call:

python/cinder-understack/cinder_understack/tests/test_dynamic_netapp_driver.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,8 +201,11 @@ def test_refresh_svm_libraries_handles_lib_creation_failure(
201201
self, mock_get_svms, mock_create_svm_lib
202202
):
203203
"""Ensure that failure in lib creation is caught and logged, not raised."""
204-
mock_get_svms.return_value = ["os-new-failing-svm"]
205-
mock_create_svm_lib.side_effect = Exception("Simulated failure")
204+
test_svm_name = "os-new-failing_svm"
205+
mock_get_svms.return_value = [test_svm_name]
206+
mock_svm_lib = _create_mock_svm_lib(test_svm_name)
207+
mock_svm_lib.check_for_setup_error.side_effect = Exception("Simulated failure")
208+
mock_create_svm_lib.return_value = mock_svm_lib
206209

207210
self.driver._libraries = {}
208211

0 commit comments

Comments
 (0)