If dm_suspend_and_flush_map() disables queueing on a device, and then
fails both to flush the device and restore queueing, the device will
still have queue_if_no_path set in mpp->features, but not in reality.
Fix this.

Signed-off-by: Benjamin Marzinski <[email protected]>
---
 libmultipath/devmapper.c          | 4 ++--
 libmultipath/devmapper.h          | 1 +
 libmultipath/libmultipath.version | 3 ++-
 multipathd/main.c                 | 2 ++
 4 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c
index e970e71b..373d2e6c 100644
--- a/libmultipath/devmapper.c
+++ b/libmultipath/devmapper.c
@@ -1136,8 +1136,8 @@ int _dm_flush_map (const char * mapname, int need_sync, 
int deferred_remove,
                        sleep(1);
        } while (retries-- > 0);
 
-       if (queue_if_no_path == 1)
-               _dm_queue_if_no_path(mapname, 1);
+       if (queue_if_no_path == 1 && _dm_queue_if_no_path(mapname, 1) != 0)
+               return DM_FLUSH_FAIL_CANT_RESTORE;
 
        return DM_FLUSH_FAIL;
 }
diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h
index fa9c6114..a7d66604 100644
--- a/libmultipath/devmapper.h
+++ b/libmultipath/devmapper.h
@@ -52,6 +52,7 @@ int dm_is_mpath(const char *);
 enum {
        DM_FLUSH_OK = 0,
        DM_FLUSH_FAIL,
+       DM_FLUSH_FAIL_CANT_RESTORE,
        DM_FLUSH_DEFERRED,
        DM_FLUSH_BUSY,
 };
diff --git a/libmultipath/libmultipath.version 
b/libmultipath/libmultipath.version
index 8ab7c802..df2c0fff 100644
--- a/libmultipath/libmultipath.version
+++ b/libmultipath/libmultipath.version
@@ -43,7 +43,7 @@ LIBMPATHCOMMON_1.0.0 {
        put_multipath_config;
 };
 
-LIBMULTIPATH_22.0.0 {
+LIBMULTIPATH_23.0.0 {
 global:
        /* symbols referenced by multipath and multipathd */
        add_foreign;
@@ -151,6 +151,7 @@ global:
        _print_multipath_topology;
        reinstate_paths;
        remember_wwid;
+       remove_feature;
        remove_map;
        remove_map_by_alias;
        remove_map_callback;
diff --git a/multipathd/main.c b/multipathd/main.c
index ed543caa..13cb404d 100644
--- a/multipathd/main.c
+++ b/multipathd/main.c
@@ -790,6 +790,8 @@ flush_map(struct multipath * mpp, struct vectors * vecs)
 {
        int r = dm_suspend_and_flush_map(mpp->alias, 0);
        if (r != DM_FLUSH_OK) {
+               if (DM_FLUSH_FAIL_CANT_RESTORE)
+                       remove_feature(&mpp->features, "queue_if_no_path");
                condlog(0, "%s: can't flush", mpp->alias);
                return r;
        }
-- 
2.43.0


Reply via email to