Under heavy device-mapper ioctl load (e.g. LUN-number recycling combined
with ALUA transitions), dm_flush_map__() could leave a multipath map
suspended indefinitely after a failed DM_DEVICE_REMOVE. A suspended map
wedges any later task that touches it in uninterruptible D state, and
because sync() walks every block device, this can hang I/O node-wide
until reboot. The storage itself is healthy; the defect is entirely in
user space.

Patch 1 is the actual fix. Query errors on the failed-remove path were
misclassified as external removal: anything that was not DM_IS_MPATH_YES
was treated as "removed externally" and returned DM_FLUSH_OK without
resuming. But dm_is_mpath() also returns DM_IS_MPATH_ERR (-1) when the
status query itself fails transiently under ioctl pressure, so a
still-suspended map was abandoned. Only DM_IS_MPATH_NO now counts as
external removal; a query error is logged and falls through to the
resume path.

Patch 2 checks the DM_DEVICE_RESUME return value on the failed-remove
path and logs at condlog(1) if it fails, so a leaked suspend is at least
visible in the logs instead of being silent.

Only libmultipath/devmapper.c changes. There is no change to the success
path or to behavior outside the failed-remove branch.

Changes since v1:
 - Dropped the v1 "retry the resume" patch. As discussed on the list,
   the fault injector never exercised a resume failure, and on this
   no-table-swap resume the realistic failures (-EINVAL "not suspended",
   -ENXIO "gone") already mean the map is not left suspended, so an
   immediate identical retry (with or without a short delay) buys
   little.
 - Replaced it with a patch that simply logs at condlog(1) if the resume
   ioctl fails, so a leaked suspend is visible in the logs.
 - Patch 1 is unchanged from v1 and carries Benjamin Marzinski's
   Reviewed-by.

v1: 
https://lore.kernel.org/dm-devel/[email protected]/

Suresh Thelkar (2):
  libmultipath: dm_flush_map__: do not treat query error as external
    removal
  libmultipath: dm_flush_map__: log if the resume fails after a failed
    remove

 libmultipath/devmapper.c | 33 ++++++++++++++++++++++++---------
 1 file changed, 24 insertions(+), 9 deletions(-)


base-commit: d53932bdbee02f440518ea384e63d7c4d3f66685
-- 
2.43.0


Reply via email to