If removing a multipath device fails because the device is in use,
return DM_FLUSH_BUSY from remove_functions, which causes cli_del_map()
to return -EBUSY, which will now print extra information in
default_reply().

Reviewed-by: Martin Wilck <[email protected]>
Signed-off-by: Benjamin Marzinski <[email protected]>
---
 libmultipath/devmapper.c  | 14 +++++++-------
 libmultipath/devmapper.h  |  1 +
 multipathd/cli_handlers.c |  9 ++++++++-
 multipathd/uxlsnr.c       |  3 +++
 4 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c
index 73bb6fe7..6bbe784d 100644
--- a/libmultipath/devmapper.c
+++ b/libmultipath/devmapper.c
@@ -1083,7 +1083,7 @@ int _dm_flush_map (const char * mapname, int need_sync, 
int deferred_remove,
        /* If you aren't doing a deferred remove, make sure that no
         * devices are in use */
        if (!do_deferred(deferred_remove) && partmap_in_use(mapname, NULL))
-                       return DM_FLUSH_FAIL;
+                       return DM_FLUSH_BUSY;
 
        if (need_suspend &&
            dm_get_map(mapname, &mapsize, &params) == DMP_OK &&
@@ -1097,12 +1097,12 @@ int _dm_flush_map (const char * mapname, int need_sync, 
int deferred_remove,
        free(params);
        params = NULL;
 
-       if (dm_remove_partmaps(mapname, need_sync, deferred_remove))
-               return DM_FLUSH_FAIL;
+       if ((r = dm_remove_partmaps(mapname, need_sync, deferred_remove)))
+               return r;
 
        if (!do_deferred(deferred_remove) && dm_get_opencount(mapname)) {
                condlog(2, "%s: map in use", mapname);
-               return DM_FLUSH_FAIL;
+               return DM_FLUSH_BUSY;
        }
 
        do {
@@ -1506,7 +1506,7 @@ do_foreach_partmaps (const char * mapname,
                    (p = strstr(params, dev_t)) &&
                    !isdigit(*(p + strlen(dev_t)))
                   ) {
-                       if (partmap_func(names->name, data) != 0)
+                       if ((r = partmap_func(names->name, data)) != 0)
                                goto out;
                }
 
@@ -1538,12 +1538,12 @@ remove_partmap(const char *name, void *data)
                if (!do_deferred(rd->deferred_remove) &&
                    dm_get_opencount(name)) {
                        condlog(2, "%s: map in use", name);
-                       return 1;
+                       return DM_FLUSH_BUSY;
                }
        }
        condlog(4, "partition map %s removed", name);
        dm_device_remove(name, rd->need_sync, rd->deferred_remove);
-       return 0;
+       return DM_FLUSH_OK;
 }
 
 static int
diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h
index 3fc8473b..fa9c6114 100644
--- a/libmultipath/devmapper.h
+++ b/libmultipath/devmapper.h
@@ -53,6 +53,7 @@ enum {
        DM_FLUSH_OK = 0,
        DM_FLUSH_FAIL,
        DM_FLUSH_DEFERRED,
+       DM_FLUSH_BUSY,
 };
 
 int _dm_flush_map (const char *, int, int, int, int);
diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c
index 9a0cd065..b49bc73a 100644
--- a/multipathd/cli_handlers.c
+++ b/multipathd/cli_handlers.c
@@ -31,6 +31,7 @@
 #include "foreign.h"
 #include "strbuf.h"
 #include "cli_handlers.h"
+#include "devmapper.h"
 
 static int
 show_paths (struct strbuf *reply, struct vectors *vecs, char *style, int 
pretty)
@@ -743,6 +744,7 @@ cli_del_map (void * v, struct strbuf *reply, void * data)
        struct vectors * vecs = (struct vectors *)data;
        char * param = get_keyparam(v, KEY_MAP);
        struct multipath *mpp;
+       int r;
 
        param = convert_dev(param, 0);
        condlog(2, "%s: remove map (operator)", param);
@@ -752,7 +754,12 @@ cli_del_map (void * v, struct strbuf *reply, void * data)
        if (!mpp)
                return 1;
 
-       return flush_map(mpp, vecs);
+       r = flush_map(mpp, vecs);
+       if (r == DM_FLUSH_OK)
+               return 0;
+       else if (r == DM_FLUSH_BUSY)
+               return -EBUSY;
+       return 1;
 }
 
 static int
diff --git a/multipathd/uxlsnr.c b/multipathd/uxlsnr.c
index 4df01666..707ed396 100644
--- a/multipathd/uxlsnr.c
+++ b/multipathd/uxlsnr.c
@@ -411,6 +411,9 @@ void default_reply(struct client *c, int r)
        case -ETIMEDOUT:
                append_strbuf_str(&c->reply, "timeout\n");
                break;
+       case -EBUSY:
+               append_strbuf_str(&c->reply, "map or partition in use\n");
+               break;
        }
 }
 
-- 
2.43.0


Reply via email to