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
