After a failed DM_DEVICE_REMOVE the map was suspended earlier in
dm_flush_map__(), and the recovery path issued a single fire-and-forget
DM_DEVICE_RESUME whose result was ignored. If that resume ioctl failed
(possible under an ioctl storm) the map stayed suspended, which wedges
any later task in uninterruptible D state and, because sync() walks
every block device, hangs I/O node-wide until reboot.

Since the map is known to have been suspended at the start of the loop,
the DM_DEVICE_RESUME return value is authoritative. Simply retry the
resume once if the ioctl fails, so a transient failure does not leave
the map suspended. The remove is still retried by the enclosing loop
when retries are requested.

Signed-off-by: Suresh Thelkar <[email protected]>
---
 libmultipath/devmapper.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c
index a5570a85..bea7e804 100644
--- a/libmultipath/devmapper.c
+++ b/libmultipath/devmapper.c
@@ -1062,10 +1062,12 @@ int dm_flush_map__ (const char *mapname, int flags, int 
retries)
                        else
                                condlog(2, "failed to remove multipath map %s",
                                        mapname);
-                       if ((flags & DMFL_SUSPEND) && queue_if_no_path != -1) {
-                               dm_simplecmd_noflush(DM_DEVICE_RESUME,
-                                                    mapname, udev_flags);
-                       }
+                       /* The map was suspended above; resume it so a failed
+                        * remove does not leave it suspended. Retry once if the
+                        * resume ioctl itself fails. */
+                       if ((flags & DMFL_SUSPEND) && queue_if_no_path != -1 &&
+                           !dm_simplecmd_noflush(DM_DEVICE_RESUME, mapname, 
udev_flags))
+                               dm_simplecmd_noflush(DM_DEVICE_RESUME, mapname, 
udev_flags);
                }
                if (retries)
                        sleep(1);
-- 
2.43.0


Reply via email to