Repository navigation
fix(lvol): confirm crypto bdev absence instead of raising on -ENODEV - #1486
Hamdy-khader wants to merge 2 commits into
Conversation
A retried delete pass that reached the crypto branch of _remove_bdev_stack after the crypto bdev (or its key) was already removed on a prior pass hit an unhandled RPCRemoteError(-ENODEV) from lvol_crypto_delete/lvol_crypto_key_delete. The exception escaped _remove_bdev_stack entirely, skipping the all_removed=False path and the caller's RuntimeError, so the delete retried forever instead of converging (SFAM-2826). Mirror the bdev_lvol/bdev_lvol_clone handling: probe with bdev_get before deleting, and treat -ENODEV from either RPC as confirmation the resource is already gone. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
There was a problem hiding this comment.
With some of the other RPC functions I moved the error check into the helper, adding an idempotent check, e.g.:
def some_rpc_deleter(self, name, *, idempotent=False):
try:
self._request("delete_resource", name=name)
except RPCRemoteError as e:
if idempotent and e.code == -errno.ENODEV:
return
raise
With that the code at the caller-site needs to do fewer distinctions, in this case the whole block could just be:
rpc_client.lvol_crypto_delete(name, idempotent=True)
rpc_client.lvol_crypto_key_delete(f"key_{name}", idempotent=True)
bdev["status"] = "deleted"
Just checked: bdev_crypto_delete yields -ENODEV on missing entity, lvol_crypto_key_delete gets RPCErrorCode.invalid_params with a message "No key object found".
mxsrc's review on #1486 pointed out the error-check-in-the-caller shape duplicates work other RPC wrappers already centralize: push the "-ENODEV means already gone" distinction into lvol_crypto_delete and lvol_crypto_key_delete themselves via an idempotent= kwarg, so _remove_bdev_stack's crypto branch no longer needs to special-case each call's result. accel_crypto_key_destroy does not answer -ENODEV for a missing key like bdev_crypto_delete does -- checked live against SPDK, it rejects that as invalid_params with message "No key object found" -- so lvol_crypto_key_delete's idempotent path matches on that message, not just the error code, to avoid swallowing an unrelated invalid_params failure. Adds direct RPCClient-level tests for both methods' idempotent behavior in tests/unit/rpc/test_client.py, and updates the _remove_bdev_stack crypto tests to match: the bdev delete and key delete are now independent idempotent calls rather than one gating the other, so an absorbed -ENODEV on the bdev delete no longer skips the key delete. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Good call — pushed up 46211b2 addressing this. Moved the idempotent-absorption into try:
rpc_client.lvol_crypto_delete(name, idempotent=True)
rpc_client.lvol_crypto_key_delete(f'key_{name}', idempotent=True)
ret = True
except RPCRemoteError:
ret = NoneOne adjustment from your snippet: since the two calls are independently idempotent now rather than one gating the other, the key delete runs even when the bdev delete hit the absorbed Also confirmed and encoded your finding as a comment + test: Added direct |
Summary
_remove_bdev_stack'scryptobranch had no handling for the bdev (or its key) already being removed on a prior teardown pass.lvol_crypto_delete/lvol_crypto_key_deleteraiseRPCRemoteErroron SPDK's-ENODEVanswer; left uncaught, that exception escaped_remove_bdev_stackentirely — skipping theall_removed=Falsepath and the caller'sRuntimeError— solvol_monitorretried the same failing delete indefinitely (92 attempts / 57 minutes in the reported run).bdev_lvol/bdev_lvol_clonehandling: probe withbdev_getbefore attempting the delete, and treat-ENODEVfrom either the bdev delete or the key delete as confirmation the resource is already gone, marking the stack entrydeletedinstead of raising.Systemic causes (not fixed here, left for follow-up)
lvol_controller.py:2156) is commented out, so every retry re-attempts RPCs against entries already stampeddeleted— a narrower, probe-confirmed version of that skip (as suggested in the ticket) would help all branches, not just crypto.RPCRemoteError, treat-ENODEVas confirmed absence" idiom that 4 of 6 branches in this function already need by hand — a future new branch could reintroduce this bug class.tests/unit/test_lvol_teardown_confirmation.pydespite every sibling branch being covered — that gap is why this shipped unnoticed.Test plan
tox run -e lint,typeson the changed files — cleantox run -e unit -- tests/unit/test_lvol_teardown_confirmation.py— newTestRemoveBdevStackCryptosuite (6 tests) covers: genuine failure stays unconfirmed, normal successful delete, absent-bdev probe skip,-ENODEVfrom the bdev delete,-ENODEVfrom the key delete, andsync=Truestill bypassing the crypto branchtox run -e unit(full suite) — 4700 passed; the one pre-existing failure (test_metrics_are_served, missingprocess_open_fdson macOS/no-/proc) reproduces identically onmainand is unrelated to this change🤖 Generated with Claude Code