Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 44 additions & 14 deletions simplyblock_core/controllers/lvol_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -930,14 +930,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":
Expand Down Expand Up @@ -1043,12 +1035,50 @@ 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."""
try:
_remove_bdev_stack(lvol.bdev_stack[::-1], rpc_client)
lvol.status = LVol.STATUS_IN_DELETION
lvol.write_to_db(DBController().kv_store)
except Exception:
logger.exception("rollback of bdev stack failed for %s", lvol.get_id())
db_controller = DBController()
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)

all_nodes = [host_node]
for sid in secondary_ids:
try:
all_nodes.append(db_controller.get_storage_node_by_id(sid))
except KeyError:
Comment thread
github-code-quality[bot] marked this conversation as resolved.
Fixed
logger.debug(
"Skipping missing secondary/tertiary node '%s' during rollback for lvol '%s'",
sid,
lvol.get_id(),
)

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


Expand Down
2 changes: 1 addition & 1 deletion simplyblock_core/env_var
Original file line number Diff line number Diff line change
@@ -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
6 changes: 4 additions & 2 deletions simplyblock_core/storage_node_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -6988,8 +6988,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
Expand Down
Loading