From 783d173c4292b6aa40f513dad613e8e5323ad4da Mon Sep 17 00:00:00 2001 From: hamdykhader Date: Tue, 4 Aug 2026 00:23:31 +0300 Subject: [PATCH 1/6] Check RPC process status rather than RPC responsiveness for node checking phase before adding LVols --- simplyblock_core/storage_node_ops.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/simplyblock_core/storage_node_ops.py b/simplyblock_core/storage_node_ops.py index a9dc05ddbd..8629be54dc 100644 --- a/simplyblock_core/storage_node_ops.py +++ b/simplyblock_core/storage_node_ops.py @@ -6872,8 +6872,10 @@ def check_non_leader_for_operation(node_id, lvs_name, operation_type="create", StorageNode.RESTART_PHASE_POST_UNBLOCK): return "queue" - # 3. Fabric is connected — check RPC responsiveness - if _is_node_rpc_responsive(node, lvs_name): + # 3. Fabric is connected — check the SPDK process + nodeapi = SNodeClient(node) + is_up, _ = nodeapi.spdk_process_is_up(node.rpc_port, node.cluster_id) + if is_up: return "proceed" # 4. RPC failing but fabric connected From 3946fe3733043ebfe0811818c8c690797eb12de5 Mon Sep 17 00:00:00 2001 From: hamdykhader Date: Tue, 4 Aug 2026 00:43:21 +0300 Subject: [PATCH 2/6] feat(lvol): implement cleanup and update logic for LVols and storage nodes --- simplyblock_core/controllers/lvol_controller.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/simplyblock_core/controllers/lvol_controller.py b/simplyblock_core/controllers/lvol_controller.py index 5db9b88409..742dcc12d8 100644 --- a/simplyblock_core/controllers/lvol_controller.py +++ b/simplyblock_core/controllers/lvol_controller.py @@ -903,14 +903,6 @@ def _create_bdev_stack(lvol, snode, is_primary=True): type = bdev['type'] name = bdev['name'] params = bdev['params'] - # Idempotency probe per stack bdev. A by-name bdev_get_bdevs resolves - # names, aliases and uuids server-side and returns [] / an -ENODEV - # error (→ None) when absent — equivalent to the previous full-dump - # membership test, but O(1) instead of serializing every bdev on the - # node into the response (the dump grows with lvol count and was the - # single largest cost of mass creates). - if rpc_client.get_bdevs(name): - continue ret = None if type == "bmap_init": From 0bff3df18a883de6b0b66aa1c4a54fa18f152164 Mon Sep 17 00:00:00 2001 From: hamdykhader Date: Tue, 4 Aug 2026 20:43:15 +0300 Subject: [PATCH 3/6] fix(lvol): enhance deletion process by checking existing bdevs on primary node --- simplyblock_core/controllers/lvol_controller.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/simplyblock_core/controllers/lvol_controller.py b/simplyblock_core/controllers/lvol_controller.py index 742dcc12d8..a0e6e46153 100644 --- a/simplyblock_core/controllers/lvol_controller.py +++ b/simplyblock_core/controllers/lvol_controller.py @@ -1008,9 +1008,24 @@ def _fail_after_bdev(lvol, rpc_client, msg): the SPDK clone-blob in place, which then blocks the parent snapshot delete with "vbdev_lvol_destroy: ... has N clones". Logs but does not raise on rollback failure so the caller still sees the original error.""" + db_controller = DBController() try: - _remove_bdev_stack(lvol.bdev_stack[::-1], rpc_client) + primary_node = db_controller.get_storage_node_by_id(lvol.node_id) + primary_rpc_client = primary_node.rpc_client(timeout=5) + existing_on_primary = primary_rpc_client.get_bdevs(f"{lvol.lvs_name}/{lvol.lvol_bdev}") + if not existing_on_primary: + for sn_id in lvol.nodes: + if sn_id != lvol.node_id: + rpc_client = db_controller.get_storage_node_by_id(sn_id).rpc_client() + existing_on_secondary = rpc_client.get_bdevs(f"{lvol.lvs_name}/{lvol.lvol_bdev}") + if existing_on_secondary: + # register on primary + rpc_client.bdev_lvol_register( + existing_on_secondary[0], lvol.lvs_name, lvol.lvol_uuid, lvol.blobid, lvol.lvol_priority_class) + break + lvol.status = LVol.STATUS_IN_DELETION + lvol.deletion_status = "" lvol.write_to_db(DBController().kv_store) except Exception: logger.exception("rollback of bdev stack failed for %s", lvol.get_id()) From ff79557d8afdecb10aff188748ab365d4dd927ff Mon Sep 17 00:00:00 2001 From: hamdykhader Date: Thu, 6 Aug 2026 00:57:55 +0300 Subject: [PATCH 4/6] update env_var --- simplyblock_core/env_var | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simplyblock_core/env_var b/simplyblock_core/env_var index 5abdecd440..e1b73b6b3a 100644 --- a/simplyblock_core/env_var +++ b/simplyblock_core/env_var @@ -1,5 +1,5 @@ SIMPLY_BLOCK_COMMAND_NAME=sbcli-dev SIMPLY_BLOCK_VERSION=19.2.34 -SIMPLY_BLOCK_DOCKER_IMAGE=public.ecr.aws/simply-block/simplyblock:main +SIMPLY_BLOCK_DOCKER_IMAGE=public.ecr.aws/simply-block/simplyblock:main-sfam-2793 SIMPLY_BLOCK_SPDK_ULTRA_IMAGE=public.ecr.aws/simply-block/ultra:main-latest From 590d8420a3bcb9b6074102a5fdc07ba782518714 Mon Sep 17 00:00:00 2001 From: hamdykhader Date: Thu, 6 Aug 2026 15:25:26 +0300 Subject: [PATCH 5/6] Refactor lvol deletion logic to improve error handling and streamline node registration --- .../controllers/lvol_controller.py | 57 ++++++++++++------- 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/simplyblock_core/controllers/lvol_controller.py b/simplyblock_core/controllers/lvol_controller.py index dd46bbdd66..c762b4e871 100644 --- a/simplyblock_core/controllers/lvol_controller.py +++ b/simplyblock_core/controllers/lvol_controller.py @@ -1036,26 +1036,45 @@ def _fail_after_bdev(lvol, rpc_client, msg): with "vbdev_lvol_destroy: ... has N clones". Logs but does not raise on rollback failure so the caller still sees the original error.""" db_controller = DBController() - try: - primary_node = db_controller.get_storage_node_by_id(lvol.node_id) - primary_rpc_client = primary_node.rpc_client(timeout=5) - existing_on_primary = primary_rpc_client.get_bdevs(f"{lvol.lvs_name}/{lvol.lvol_bdev}") - if not existing_on_primary: - for sn_id in lvol.nodes: - if sn_id != lvol.node_id: - rpc_client = db_controller.get_storage_node_by_id(sn_id).rpc_client() - existing_on_secondary = rpc_client.get_bdevs(f"{lvol.lvs_name}/{lvol.lvol_bdev}") - if existing_on_secondary: - # register on primary - rpc_client.bdev_lvol_register( - existing_on_secondary[0], lvol.lvs_name, lvol.lvol_uuid, lvol.blobid, lvol.lvol_priority_class) - break + host_node = db_controller.get_storage_node_by_id(lvol.node_id) + secondary_ids = [host_node.secondary_node_id] + if host_node.tertiary_node_id: + secondary_ids.append(host_node.tertiary_node_id) - lvol.status = LVol.STATUS_IN_DELETION - lvol.deletion_status = "" - lvol.write_to_db(DBController().kv_store) - except Exception: - logger.exception("rollback of bdev stack failed for %s", lvol.get_id()) + all_nodes = [host_node] + for sid in secondary_ids: + try: + all_nodes.append(db_controller.get_storage_node_by_id(sid)) + except KeyError: + pass + + if lvol.blobid: + try: + from simplyblock_core.storage_node_ops import find_leader_with_failover + primary_node, non_leaders = find_leader_with_failover(all_nodes, lvol.lvs_name) + if primary_node is None: + msg = "No leader available, marking it for deletion and let lvol monitor handle deletion" + else: + existing_on_primary = primary_node.rpc_client().get_bdevs(f"{lvol.lvs_name}/{lvol.lvol_bdev}") + if not existing_on_primary: + for sn_id in lvol.nodes: + if sn_id != lvol.node_id: + rpc_client = db_controller.get_storage_node_by_id(sn_id).rpc_client() + existing_on_secondary = rpc_client.get_bdevs(f"{lvol.lvs_name}/{lvol.lvol_bdev}") + if existing_on_secondary: + # register on primary + rpc_client.bdev_lvol_register( + existing_on_secondary[0], lvol.lvs_name, lvol.lvol_uuid, lvol.blobid, lvol.lvol_priority_class) + + lvol.status = LVol.STATUS_IN_DELETION + lvol.deletion_status = "" + lvol.write_to_db(DBController().kv_store) + except Exception: + logger.exception("rollback of bdev stack failed for %s", lvol.get_id()) + else: + for node in all_nodes: + _remove_lvol_subsys_from_node(lvol, node.rpc_client()) + lvol.remove_from_db(db_controller.kv_store) return False, msg From e8b2f07b1e4943523ae99986d1211a000ecd7aa9 Mon Sep 17 00:00:00 2001 From: "Hamdy H. Khader" Date: Thu, 6 Aug 2026 17:57:08 +0300 Subject: [PATCH 6/6] Potential fix for pull request finding 'Empty except' Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com> --- simplyblock_core/controllers/lvol_controller.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/simplyblock_core/controllers/lvol_controller.py b/simplyblock_core/controllers/lvol_controller.py index c762b4e871..41d2ca5a2c 100644 --- a/simplyblock_core/controllers/lvol_controller.py +++ b/simplyblock_core/controllers/lvol_controller.py @@ -1046,7 +1046,11 @@ def _fail_after_bdev(lvol, rpc_client, msg): try: all_nodes.append(db_controller.get_storage_node_by_id(sid)) except KeyError: - pass + logger.debug( + "Skipping missing secondary/tertiary node '%s' during rollback for lvol '%s'", + sid, + lvol.get_id(), + ) if lvol.blobid: try: