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 primary 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 makes the resume on the failed-remove path robust: it checks the
DM_DEVICE_RESUME result, retries once if it fails, and logs at condlog(1)
if the map is still not resumed. The retry handles the inactive-table
case (dm fails the table swap and leaves the map suspended with the
invalid table dropped; a second resume reactivates it with the old
table) - the same scenario dm_addmap_reload() already guards against.

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

Changes since v2:
 - Patch 2: restored the single resume retry (dropped in v2) and added a
   comment explaining why, as requested on the list. Per Ben Marzinski's
   explanation, a resume can fail the table swap on a map with an
   inactive table and leave it suspended; a second resume recovers it
   (as dm_addmap_reload() does). Martin Wilck agreed the retry is
   worthwhile and asked for the explanatory comment. Kept the v2
   condlog(1) so a still-unresumed map stays visible.
 - Patch 1 unchanged; carries Benjamin Marzinski's Reviewed-by.

Changes since v1:
 - v2 had replaced the retry with a log-only change; v3 restores the
   retry together with the explanatory comment.

v1: 
https://lore.kernel.org/dm-devel/[email protected]/
v2: 
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__: retry the resume after a failed remove

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


base-commit: d53932bdbee02f440518ea384e63d7c4d3f66685
-- 
2.43.0


Reply via email to