Merge branch 'master' of git://git.kernel.org/pub/scm/linux/storage/multipath-tools/
authorHannes Reinecke <hare@suse.de>
Mon, 26 May 2008 13:12:14 +0000 (15:12 +0200)
committerHannes Reinecke <hare@suse.de>
Mon, 26 May 2008 13:12:14 +0000 (15:12 +0200)
17 files changed:
.gitignore [new file with mode: 0644]
libmultipath/checkers.c
libmultipath/checkers.h
libmultipath/config.c
libmultipath/config.h
libmultipath/configure.c
libmultipath/configure.h
libmultipath/dict.c
libmultipath/hwtable.c
libmultipath/print.c
libmultipath/print.h
libmultipath/prio.c
libmultipath/prio.h
libmultipath/propsel.c
multipath/main.c
multipathd/cli_handlers.c
multipathd/main.c

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..5ef5aec
--- /dev/null
@@ -0,0 +1,9 @@
+*.o
+.dotest
+*~
+*.so
+*.a
+*.gz
+kpartx
+multipath
+multipathd
index 3aa1f9d..5889ad7 100644 (file)
@@ -47,10 +47,7 @@ struct checker * checker_lookup (char * name)
                if (!strncmp(name, c->name, CHECKER_NAME_LEN))
                        return c;
        }
-       c = add_checker(name);
-       if (c)
-               return c;
-       return checker_default();
+       return add_checker(name);
 }
 
 struct checker * add_checker (char * name)
@@ -172,13 +169,14 @@ char * checker_message (struct checker * c)
        return c->message;
 }
 
-struct checker * checker_default (void)
+void checker_get (struct checker * dst, char * name)
 {
-       return checker_lookup(DEFAULT_CHECKER);
-}
+       struct checker * src = checker_lookup(name);
 
-void checker_get (struct checker * dst, struct checker * src)
-{
+       if (!src) {
+               dst->check = NULL;
+               return;
+       }
        dst->fd = src->fd;
        dst->sync = src->sync;
        strncpy(dst->name, src->name, CHECKER_NAME_LEN);
index 4ff475d..a65aaf9 100644 (file)
@@ -117,12 +117,10 @@ void checker_set_async (struct checker *);
 void checker_set_fd (struct checker *, int);
 void checker_enable (struct checker *);
 void checker_disable (struct checker *);
-struct checker * checker_lookup (char *);
 int checker_check (struct checker *);
 int checker_selected (struct checker *);
 char * checker_name (struct checker *);
 char * checker_message (struct checker *);
-struct checker * checker_default (void);
-void checker_get (struct checker *, struct checker *);
+void checker_get (struct checker *, char *);
 
 #endif /* _CHECKERS_H */
index 4548ad1..a109cd9 100644 (file)
 #include "defaults.h"
 #include "prio.h"
 
-static struct hwentry *
-find_hwe_strmatch (vector hwtable, char * vendor, char * product, char * revision)
+static int
+hwe_strmatch (struct hwentry *hwe1, struct hwentry *hwe2)
 {
-       int i;
-       struct hwentry *hwe, *ret = NULL;
+       if (hwe1->vendor && hwe2->vendor && strcmp(hwe1->vendor, hwe2->vendor))
+               return 1;
 
-       vector_foreach_slot (hwtable, hwe, i) {
-               if (hwe->vendor && vendor && strcmp(hwe->vendor, vendor))
-                       continue;
+       if (hwe1->product && hwe2->product && strcmp(hwe1->product, hwe2->product))
+               return 1;
 
-               if (hwe->product && product && strcmp(hwe->product, product))
-                       continue;
+       if (hwe1->revision && hwe2->revision && strcmp(hwe1->revision, hwe2->revision))
+               return 1;
 
-               if (hwe->revision && revision && strcmp(hwe->revision, revision))
-                       continue;
+       return 0;
+}
+
+static struct hwentry *
+find_hwe_strmatch (vector hwtable, struct hwentry *hwe)
+{
+       int i;
+       struct hwentry *tmp, *ret = NULL;
 
-               ret = hwe;
+       vector_foreach_slot (hwtable, tmp, i) {
+               if (hwe_strmatch(tmp, hwe))
+                       continue;
+               ret = tmp;
                break;
        }
        return ret;
@@ -239,12 +247,47 @@ set_param_str(char * str)
        return dst;
 }
 
+#define merge_str(s) \
+       if (hwe2->s) { \
+               if (hwe1->s) \
+                       free(hwe1->s); \
+               if (!(hwe1->s = set_param_str(hwe2->s))) \
+                       return 1; \
+       }
+
+#define merge_num(s) \
+       if (hwe2->s) \
+               hwe1->s = hwe2->s
+
+
+static int
+merge_hwe (struct hwentry * hwe1, struct hwentry * hwe2)
+{
+       merge_str(vendor);
+       merge_str(product);
+       merge_str(revision);
+       merge_str(getuid);
+       merge_str(features);
+       merge_str(hwhandler);
+       merge_str(selector);
+       merge_str(checker_name);
+       merge_str(prio_name);
+       merge_str(bl_product);
+       merge_num(pgpolicy);
+       merge_num(pgfailback);
+       merge_num(rr_weight);
+       merge_num(no_path_retry);
+       merge_num(minio);
+
+       return 0;
+}
+
 int
 store_hwe (vector hwtable, struct hwentry * dhwe)
 {
        struct hwentry * hwe;
 
-       if (find_hwe_strmatch(hwtable, dhwe->vendor, dhwe->product, dhwe->revision))
+       if (find_hwe_strmatch(hwtable, dhwe))
                return 0;
        
        if (!(hwe = alloc_hwe()))
@@ -270,14 +313,18 @@ store_hwe (vector hwtable, struct hwentry * dhwe)
 
        if (dhwe->selector && !(hwe->selector = set_param_str(dhwe->selector)))
                goto out;
+
+       if (dhwe->checker_name && !(hwe->checker_name = set_param_str(dhwe->checker_name)))
+               goto out;
+                               
+       if (dhwe->prio_name && !(hwe->prio_name = set_param_str(dhwe->prio_name)))
+               goto out;
                                
        hwe->pgpolicy = dhwe->pgpolicy;
        hwe->pgfailback = dhwe->pgfailback;
        hwe->rr_weight = dhwe->rr_weight;
        hwe->no_path_retry = dhwe->no_path_retry;
        hwe->minio = dhwe->minio;
-       hwe->checker = dhwe->checker;
-       hwe->prio = dhwe->prio;
 
        if (dhwe->bl_product && !(hwe->bl_product = set_param_str(dhwe->bl_product)))
                goto out;
@@ -292,6 +339,27 @@ out:
        return 1;
 }
 
+static int
+factorize_hwtable (vector hw)
+{
+       struct hwentry *hwe1, *hwe2;
+       int i, j;
+
+       vector_foreach_slot(hw, hwe1, i) {
+               j = i+1;
+               vector_foreach_slot_after(hw, hwe2, j) {
+                       if (hwe_strmatch(hwe1, hwe2))
+                               continue;
+                       /* dup */
+                       merge_hwe(hwe1, hwe2);
+                       free_hwe(hwe2);
+                       vector_del_slot(hw, j);
+                       j--;
+               }
+       }
+       return 0;
+}
+
 struct config *
 alloc_config (void)
 {
@@ -358,6 +426,19 @@ load_config (char * file)
        conf->minio = 1000;
        conf->max_fds = 0;
        conf->bindings_file = DEFAULT_BINDINGS_FILE;
+       conf->multipath_dir = set_default(DEFAULT_MULTIPATHDIR);
+
+       /*
+        * preload default hwtable
+        */
+       if (conf->hwtable == NULL) {
+               conf->hwtable = vector_alloc();
+
+               if (!conf->hwtable)
+                       goto out;
+       }
+       if (setup_default_hwtable(conf->hwtable))
+               goto out;
 
        /*
         * read the config file
@@ -371,20 +452,14 @@ load_config (char * file)
        }
 
        /*
-        * fill the voids left in the config file
+        * remove duplica in hwtable. config file takes precedence
+        * over build-in hwtable
         */
-       if (conf->multipath_dir == NULL)
-               conf->multipath_dir = set_default(DEFAULT_MULTIPATHDIR);
-
-       if (conf->hwtable == NULL) {
-               conf->hwtable = vector_alloc();
-
-               if (!conf->hwtable)
-                       goto out;
-       }
-       if (setup_default_hwtable(conf->hwtable))
-               goto out;
+       factorize_hwtable(conf->hwtable);
 
+       /*
+        * fill the voids left in the config file
+        */
        if (conf->blist_devnode == NULL) {
                conf->blist_devnode = vector_alloc();
 
@@ -452,11 +527,11 @@ load_config (char * file)
            !conf->hwhandler)
                goto out;
 
-       if (!conf->prio)
-               conf->prio = prio_default();
+       if (!conf->prio_name)
+               conf->prio_name = set_default(DEFAULT_PRIO);
 
-       if (!conf->checker)
-               conf->checker = checker_lookup(DEFAULT_CHECKER);
+       if (!conf->checker_name)
+               conf->checker_name = set_default(DEFAULT_CHECKER);
 
        return 0;
 out:
index 8a97799..fb917f4 100644 (file)
@@ -28,8 +28,6 @@ struct hwentry {
        int no_path_retry;
        int minio;
        int pg_timeout;
-       struct prio * prio;
-       struct checker * checker;
        char * bl_product;
 };
 
@@ -54,8 +52,6 @@ struct config {
        int pgpolicy_flag;
        int with_sysfs;
        int pgpolicy;
-       struct prio * prio;
-       struct checker * checker;
        enum devtypes dev_type;
        int minio;
        int checkint;
@@ -67,6 +63,7 @@ struct config {
        int user_friendly_names;
        int pg_timeout;
        int max_fds;
+       int force_reload;
 
        char * dev;
        char * sysfs_dir;
@@ -77,6 +74,8 @@ struct config {
        char * features;
        char * hwhandler;
        char * bindings_file;
+       char * prio_name;
+       char * checker_name;
 
        vector keywords;
        vector mptable;
index d9fa397..ad76832 100644 (file)
@@ -130,7 +130,7 @@ pgcmp (struct multipath * mpp, struct multipath * cmpp)
 }
 
 static void
-select_action (struct multipath * mpp, vector curmp)
+select_action (struct multipath * mpp, vector curmp, int force_reload)
 {
        struct multipath * cmpp;
 
@@ -169,6 +169,12 @@ select_action (struct multipath * mpp, vector curmp)
                        mpp->alias);
                return;
        }
+       if (force_reload) {
+               mpp->action = ACT_RELOAD;
+               condlog(3, "%s: set ACT_RELOAD (forced by user)",
+                       mpp->alias);
+               return;
+       }
        if (cmpp->size != mpp->size) {
                mpp->action = ACT_RELOAD;
                condlog(3, "%s: set ACT_RELOAD (size change)",
@@ -410,7 +416,7 @@ deadmap (struct multipath * mpp)
 }
 
 extern int
-coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid)
+coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, int force_reload)
 {
        int r = 1;
        int k, i;
@@ -423,6 +429,11 @@ coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid)
 
        memset(empty_buff, 0, WWID_SIZE);
 
+       if (force_reload) {
+               vector_foreach_slot (pathvec, pp1, k) {
+                       pp1->mpp = NULL;
+               }
+       }
        vector_foreach_slot (pathvec, pp1, k) {
                /* skip this path for some reason */
 
@@ -446,7 +457,8 @@ coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid)
                /*
                 * at this point, we know we really got a new mp
                 */
-               if ((mpp = add_map_with_path(vecs, pp1, 0)) == NULL)
+               mpp = add_map_with_path(vecs, pp1, 0);
+               if (!mpp)
                        return 1;
 
                if (pp1->priority == PRIO_UNDEF)
@@ -487,7 +499,7 @@ coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid)
                }
 
                if (mpp->action == ACT_UNDEF)
-                       select_action(mpp, curmp);
+                       select_action(mpp, curmp, force_reload);
 
                r = domap(mpp);
 
index 1cbbe82..75d5057 100644 (file)
@@ -24,6 +24,6 @@ enum actions {
 int setup_map (struct multipath * mpp);
 int domap (struct multipath * mpp);
 int reinstate_paths (struct multipath *mpp);
-int coalesce_paths (struct vectors *vecs, vector curmp, char * refwwid);
+int coalesce_paths (struct vectors *vecs, vector curmp, char * refwwid, int force_reload);
 char * get_refwwid (char * dev, enum devtypes dev_type, vector pathvec);
 
index b6f7845..f5bca30 100644 (file)
@@ -95,14 +95,11 @@ def_getuid_callout_handler(vector strvec)
 static int
 def_prio_handler(vector strvec)
 {
-       char * buff;
+       conf->prio_name = set_value(strvec);
 
-       buff = set_value(strvec);
-       if (!buff)
+       if (!conf->prio_name)
                return 1;
 
-       conf->prio = prio_lookup(buff);
-       FREE(buff);
        return 0;
 }
 
@@ -120,16 +117,11 @@ def_features_handler(vector strvec)
 static int
 def_path_checker_handler(vector strvec)
 {
-       char * buff;
-
-       buff = set_value(strvec);
+       conf->checker_name = set_value(strvec);
 
-       if (!buff)
+       if (!conf->checker_name)
                return 1;
        
-       conf->checker = checker_lookup(buff);
-       FREE(buff);
-
        return 0;
 }
 
@@ -426,7 +418,8 @@ ble_except_product_handler(vector strvec)
 static int
 devices_handler(vector strvec)
 {
-       conf->hwtable = vector_alloc();
+       if (!conf->hwtable)
+               conf->hwtable = vector_alloc();
 
        if (!conf->hwtable)
                return 1;
@@ -549,20 +542,16 @@ hw_selector_handler(vector strvec)
 static int
 hw_path_checker_handler(vector strvec)
 {
-       char * buff;
        struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
 
        if (!hwe)
                return 1;
 
-       buff = set_value(strvec);
+       hwe->checker_name = set_value(strvec);
 
-       if (!buff)
+       if (!hwe->checker_name)
                return 1;
        
-       hwe->checker = checker_lookup(buff);
-       FREE(buff);
-
        return 0;
 }
 
@@ -602,17 +591,15 @@ static int
 hw_prio_handler(vector strvec)
 {
        struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
-       char * buff;
-       
+
        if (!hwe)
                return 1;
 
-       buff = set_value(strvec);
-       if (!buff)
+       hwe->prio_name = set_value(strvec);
+
+       if (!hwe->prio_name)
                return 1;
-       
-       hwe->prio = prio_lookup(buff);
-       FREE(buff);
+
        return 0;
 }
 
@@ -1100,7 +1087,7 @@ snprint_hw_vendor (char * buff, int len, void * data)
        if (!hwe->vendor)
                return 0;
 
-       return snprintf(buff, len, "%s", hwe->vendor);
+       return snprintf(buff, len, "\"%s\"", hwe->vendor);
 }
 
 static int
@@ -1111,7 +1098,7 @@ snprint_hw_product (char * buff, int len, void * data)
        if (!hwe->product)
                return 0;
 
-       return snprintf(buff, len, "%s", hwe->product);
+       return snprintf(buff, len, "\"%s\"", hwe->product);
 }
 
 static int
@@ -1122,7 +1109,7 @@ snprint_hw_bl_product (char * buff, int len, void * data)
        if (!hwe->bl_product)
                return 0;
 
-       return snprintf(buff, len, "%s", hwe->bl_product);
+       return snprintf(buff, len, "\"%s\"", hwe->bl_product);
 }
 
 static int
@@ -1136,7 +1123,7 @@ snprint_hw_getuid_callout (char * buff, int len, void * data)
            !strcmp(hwe->getuid, conf->getuid))
                return 0;
 
-       return snprintf(buff, len, "%s", hwe->getuid);
+       return snprintf(buff, len, "\"%s\"", hwe->getuid);
 }
 
 static int
@@ -1144,12 +1131,12 @@ snprint_hw_prio (char * buff, int len, void * data)
 {
        struct hwentry * hwe = (struct hwentry *)data;
 
-       if (!hwe->prio)
+       if (!hwe->prio_name)
                return 0;
-       if (hwe->prio == conf->prio)
+       if (!strcmp(hwe->prio_name, conf->prio_name))
                return 0;
        
-       return snprintf(buff, len, "%s", prio_name(hwe->prio));
+       return snprintf(buff, len, "%s", hwe->prio_name);
 }
 
 static int
@@ -1163,7 +1150,7 @@ snprint_hw_features (char * buff, int len, void * data)
            !strcmp(hwe->features, conf->features))
                return 0;
 
-       return snprintf(buff, len, "%s", hwe->features);
+       return snprintf(buff, len, "\"%s\"", hwe->features);
 }
 
 static int
@@ -1177,7 +1164,7 @@ snprint_hw_hardware_handler (char * buff, int len, void * data)
            !strcmp(hwe->hwhandler, conf->hwhandler))
                return 0;
 
-       return snprintf(buff, len, "%s", hwe->hwhandler);
+       return snprintf(buff, len, "\"%s\"", hwe->hwhandler);
 }
 
 static int
@@ -1312,14 +1299,12 @@ snprint_hw_path_checker (char * buff, int len, void * data)
 {
        struct hwentry * hwe = (struct hwentry *)data;
 
-       if (!hwe->checker)
+       if (!hwe->checker_name)
                return 0;
-       if (!checker_selected(hwe->checker))
-               return 0;
-       if (hwe->checker == conf->checker)
+       if (!strcmp(hwe->checker_name, conf->checker_name))
                return 0;
        
-       return snprintf(buff, len, "%s", checker_name(hwe->checker));
+       return snprintf(buff, len, "%s", hwe->checker_name);
 }
 
 static int
@@ -1339,7 +1324,7 @@ snprint_def_udev_dir (char * buff, int len, void * data)
            !strcmp(conf->udev_dir, DEFAULT_UDEVDIR))
                return 0;
 
-       return snprintf(buff, len, "%s", conf->udev_dir);
+       return snprintf(buff, len, "\"%s\"", conf->udev_dir);
 }
 
 static int
@@ -1351,7 +1336,7 @@ snprint_def_multipath_dir (char * buff, int len, void * data)
            !strcmp(conf->multipath_dir, DEFAULT_MULTIPATHDIR))
                return 0;
 
-       return snprintf(buff, len, "%s", conf->multipath_dir);
+       return snprintf(buff, len, "\"%s\"", conf->multipath_dir);
 }
 
 static int
@@ -1390,16 +1375,20 @@ snprint_def_getuid_callout (char * buff, int len, void * data)
            !strcmp(conf->getuid, DEFAULT_GETUID))
                return 0;
 
-       return snprintf(buff, len, "%s", conf->getuid);
+       return snprintf(buff, len, "\"%s\"", conf->getuid);
 }
 
 static int
 snprint_def_prio (char * buff, int len, void * data)
 {
-       if (!conf->prio)
+       if (!conf->prio_name)
                return 0;
 
-       return snprintf(buff, len, "%s", prio_name(conf->prio));
+       if (strlen(conf->prio_name) == strlen(DEFAULT_PRIO) &&
+           !strcmp(conf->prio_name, DEFAULT_PRIO))
+               return 0;
+       
+       return snprintf(buff, len, "%s", conf->prio_name);
 }
 
 static int
@@ -1411,18 +1400,19 @@ snprint_def_features (char * buff, int len, void * data)
            !strcmp(conf->features, DEFAULT_FEATURES))
                return 0;
 
-       return snprintf(buff, len, "%s", conf->features);
+       return snprintf(buff, len, "\"%s\"", conf->features);
 }
 
 static int
 snprint_def_path_checker (char * buff, int len, void * data)
 {
-       if (!conf->checker)
+       if (!conf->checker_name)
                return 0;
-       if (conf->checker == checker_default())
+       if (strlen(conf->checker_name) == strlen(DEFAULT_CHECKER) &&
+           !strcmp(conf->checker_name, DEFAULT_CHECKER))
                return 0;
        
-       return snprintf(buff, len, "%s", checker_name(conf->checker));
+       return snprintf(buff, len, "%s", conf->checker_name);
 }
 
 static int
@@ -1534,7 +1524,7 @@ snprint_ble_simple (char * buff, int len, void * data)
 {
        struct blentry * ble = (struct blentry *)data;
 
-       return snprintf(buff, len, "%s", ble->str);
+       return snprintf(buff, len, "\"%s\"", ble->str);
 }
 
 static int
@@ -1542,7 +1532,7 @@ snprint_bled_vendor (char * buff, int len, void * data)
 {
        struct blentry_device * bled = (struct blentry_device *)data;
 
-       return snprintf(buff, len, "%s", bled->vendor);
+       return snprintf(buff, len, "\"%s\"", bled->vendor);
 }
        
 static int
@@ -1550,7 +1540,7 @@ snprint_bled_product (char * buff, int len, void * data)
 {
        struct blentry_device * bled = (struct blentry_device *)data;
 
-       return snprintf(buff, len, "%s", bled->product);
+       return snprintf(buff, len, "\"%s\"", bled->product);
 }
        
 #define __deprecated
index 5ed7090..2afed20 100644 (file)
@@ -732,8 +732,6 @@ setup_default_hwtable (vector hw)
        struct hwentry * hwe = default_hw;
 
        while (hwe->vendor) {
-               hwe->checker = checker_lookup(hwe->checker_name);
-               hwe->prio = prio_lookup(hwe->prio_name);
                r += store_hwe(hw, hwe);
                hwe++;
        }
index 175c883..9c509d5 100644 (file)
@@ -93,6 +93,17 @@ snprint_sysfs (char * buff, size_t len, struct multipath * mpp)
                return snprintf(buff, len, "n/a");
 }
 
+static int
+snprint_ro (char * buff, size_t len, struct multipath * mpp)
+{
+       if (!mpp->dmi)
+               return snprintf(buff, len, "n/a");
+       if (mpp->dmi->read_only)
+               return snprintf(buff, len, "ro");
+       else
+               return snprintf(buff, len, "rw");
+}
+
 static int
 snprint_progress (char * buff, size_t len, int cur, int total)
 {
@@ -388,6 +399,7 @@ struct multipath_data mpd[] = {
        {'F', "failback",      0, snprint_failback},
        {'Q', "queueing",      0, snprint_queueing},
        {'N', "paths",         0, snprint_nb_paths},
+       {'r', "write_prot",    0, snprint_ro},
        {'t', "dm-st",         0, snprint_dm_map_state},
        {'S', "size",          0, snprint_multipath_size},
        {'f', "features",      0, snprint_features},
@@ -423,14 +435,17 @@ struct pathgroup_data pgd[] = {
 };
 
 void
-get_path_layout (vector pathvec)
+get_path_layout (vector pathvec, int header)
 {
        int i, j;
        char buff[MAX_FIELD_LEN];
        struct path * pp;
 
        for (j = 0; pd[j].header; j++) {
-               pd[j].width = strlen(pd[j].header);
+               if (header)
+                       pd[j].width = strlen(pd[j].header);
+               else
+                       pd[j].width = 0;
 
                vector_foreach_slot (pathvec, pp, i) {
                        pd[j].snprint(buff, MAX_FIELD_LEN, pp);
@@ -440,14 +455,17 @@ get_path_layout (vector pathvec)
 }
 
 void
-get_multipath_layout (vector mpvec)
+get_multipath_layout (vector mpvec, int header)
 {
        int i, j;
        char buff[MAX_FIELD_LEN];
        struct multipath * mpp;
 
        for (j = 0; mpd[j].header; j++) {
-               mpd[j].width = strlen(mpd[j].header);
+               if (header)
+                       mpd[j].width = strlen(mpd[j].header);
+               else
+                       mpd[j].width = 0;
 
                vector_foreach_slot (mpvec, mpp, i) {
                        mpd[j].snprint(buff, MAX_FIELD_LEN, mpp);
@@ -709,7 +727,7 @@ snprint_multipath_topology (char * buff, int len, struct multipath * mpp,
        if (fwd > len)
                return len;
        fwd += snprint_multipath(buff + fwd, len - fwd,
-                                "[size=%S][features=%f][hwhandler=%h]", mpp);
+                                "[size=%S][features=%f][hwhandler=%h][%r]", mpp);
        if (fwd > len)
                return len;
 
@@ -1243,7 +1261,7 @@ print_all_paths_custo (vector pathvec, int banner, char *fmt)
        if (banner)
                fprintf(stdout, "===== paths list =====\n");
 
-       get_path_layout(pathvec);
+       get_path_layout(pathvec, 1);
        snprint_path_header(line, MAX_LINE_LEN, fmt);
        fprintf(stdout, "%s", line);
 
index 1182031..5c7023c 100644 (file)
@@ -1,7 +1,7 @@
 #define PRINT_PATH_LONG      "%w %i %d %D %p %t%T %s"
 #define PRINT_PATH_INDENT    " \\_ %i %d %D %t%T"
 #define PRINT_PATH_CHECKER   "%i %d %D %p %t%T %C"
-#define PRINT_MAP_STATUS     "%n %F %Q %N %t"
+#define PRINT_MAP_STATUS     "%n %F %Q %N %t %r"
 #define PRINT_MAP_STATS      "%n %0 %1 %2 %3 %4"
 #define PRINT_MAP_NAMES      "%n %d %w"
 #define PRINT_PG_INDENT      "\\_ %s [prio=%p]%t"
@@ -32,8 +32,8 @@ struct pathgroup_data {
        int (*snprint)(char * buff, size_t len, struct pathgroup * pgp);
 };
 
-void get_path_layout (vector pathvec);
-void get_multipath_layout (vector mpvec);
+void get_path_layout (vector pathvec, int header);
+void get_multipath_layout (vector mpvec, int header);
 int snprint_path_header (char *, int, char *);
 int snprint_multipath_header (char *, int, char *);
 int snprint_path (char *, int, char *, struct path *);
index 54393f2..c9d2873 100644 (file)
@@ -46,10 +46,7 @@ struct prio * prio_lookup (char * name)
                if (!strncmp(name, p->name, PRIO_NAME_LEN))
                        return p;
        }
-       p = add_prio(name);
-       if (p)
-               return p;
-       return prio_default();
+       return add_prio(name);
 }
 
 struct prio * add_prio (char * name)
@@ -94,8 +91,3 @@ char * prio_name (struct prio * p)
 {
        return p->name;
 }
-
-struct prio * prio_default (void)
-{
-       return prio_lookup(DEFAULT_PRIO);
-}
index 6bf6d4b..491e6fc 100644 (file)
@@ -46,6 +46,5 @@ struct prio * add_prio (char *);
 struct prio * prio_lookup (char *);
 int prio_getprio (struct prio *, struct path *);
 char * prio_name (struct prio *);
-struct prio * prio_default (void);
 
 #endif /* _PRIO_H */
index 0c7fb99..bd85cb9 100644 (file)
@@ -217,19 +217,19 @@ select_checker(struct path *pp)
 {
        struct checker * c = &pp->checker;
 
-       if (pp->hwe && pp->hwe->checker) {
-               checker_get(c, pp->hwe->checker);
+       if (pp->hwe && pp->hwe->checker_name) {
+               checker_get(c, pp->hwe->checker_name);
                condlog(3, "%s: path checker = %s (controller setting)",
                        pp->dev, checker_name(c));
                return 0;
        }
-       if (conf->checker) {
-               checker_get(c, conf->checker);
+       if (conf->checker_name) {
+               checker_get(c, conf->checker_name);
                condlog(3, "%s: path checker = %s (config file default)",
                        pp->dev, checker_name(c));
                return 0;
        }
-       checker_get(c, checker_default());
+       checker_get(c, DEFAULT_CHECKER);
        condlog(3, "%s: path checker = %s (internal default)",
                pp->dev, checker_name(c));
        return 0;
@@ -259,21 +259,21 @@ select_getuid (struct path * pp)
 extern int
 select_prio (struct path * pp)
 {
-       if (pp->hwe && pp->hwe->prio) {
-               pp->prio = pp->hwe->prio;
+       if (pp->hwe && pp->hwe->prio_name) {
+               pp->prio = prio_lookup(pp->hwe->prio_name);
                condlog(3, "%s: prio = %s (controller setting)",
-                       pp->dev, prio_name(pp->prio));
+                       pp->dev, pp->hwe->prio_name);
                return 0;
        }
-       if (conf->prio) {
-               pp->prio = conf->prio;
+       if (conf->prio_name) {
+               pp->prio = prio_lookup(conf->prio_name);
                condlog(3, "%s: prio = %s (config file default)",
-                       pp->dev, prio_name(pp->prio));
+                       pp->dev, conf->prio_name);
                return 0;
        }
-       pp->prio = prio_default();
+       pp->prio = prio_lookup(DEFAULT_PRIO);
        condlog(3, "%s: prio = %s (internal default)",
-               pp->dev, prio_name(pp->prio));
+               pp->dev, DEFAULT_PRIO);
        return 0;
 }
 
index f1ac256..b7334ec 100644 (file)
@@ -75,34 +75,39 @@ static void
 usage (char * progname)
 {
        fprintf (stderr, VERSION_STRING);
-       fprintf (stderr, "Usage: %s\t[-v level] [-d] [-h|-l|-ll|-f|-F]\n",
-               progname);
+       fprintf (stderr, "Usage:\n");
+       fprintf (stderr, "  %s [-d] [-r] [-v lvl] [-p pol] [-b fil] [dev]\n", progname);
+       fprintf (stderr, "  %s -l|-ll|-f [-v lvl] [-b fil] [dev]\n", progname);
+       fprintf (stderr, "  %s -F [-v lvl]\n", progname);
+       fprintf (stderr, "  %s -h\n", progname);
        fprintf (stderr,
-               "\t\t\t[-p failover|multibus|group_by_serial|group_by_prio]\n" \
-               "\t\t\t[device]\n" \
-               "\n" \
-               "\t-v level\tverbosity level\n" \
-               "\t   0\t\t\tno output\n" \
-               "\t   1\t\t\tprint created devmap names only\n" \
-               "\t   2\t\t\tdefault verbosity\n" \
-               "\t   3\t\t\tprint debug information\n" \
-               "\t-h\t\tprint this usage text\n" \
-               "\t-b file\t\tbindings file location\n" \
-               "\t-d\t\tdry run, do not create or update devmaps\n" \
-               "\t-l\t\tshow multipath topology (sysfs and DM info)\n" \
-               "\t-ll\t\tshow multipath topology (maximum info)\n" \
-               "\t-f\t\tflush a multipath device map\n" \
-               "\t-F\t\tflush all multipath device maps\n" \
-               "\t-p policy\tforce all maps to specified policy :\n" \
-               "\t   failover\t\t1 path per priority group\n" \
-               "\t   multibus\t\tall paths in 1 priority group\n" \
-               "\t   group_by_serial\t1 priority group per serial\n" \
-               "\t   group_by_prio\t1 priority group per priority lvl\n" \
-               "\t   group_by_node_name\t1 priority group per target node\n" \
-               "\n" \
-               "\tdevice\t\tlimit scope to the device's multipath\n" \
-               "\t\t\t(udev-style $DEVNAME reference, eg /dev/sdb\n" \
-               "\t\t\tor major:minor or a device map name)\n" \
+               "\n"
+               "Where:\n"
+               "  -h      print this usage text\n" \
+               "  -l      show multipath topology (sysfs and DM info)\n" \
+               "  -ll     show multipath topology (maximum info)\n" \
+               "  -f      flush a multipath device map\n" \
+               "  -F      flush all multipath device maps\n" \
+               "  -d      dry run, do not create or update devmaps\n" \
+               "  -r      force devmap reload\n" \
+               "  -p      policy failover|multibus|group_by_serial|group_by_prio\n" \
+               "  -b fil  bindings file location\n" \
+               "  -p pol  force all maps to specified path grouping policy :\n" \
+               "          . failover            one path per priority group\n" \
+               "          . multibus            all paths in one priority group\n" \
+               "          . group_by_serial     one priority group per serial\n" \
+               "          . group_by_prio       one priority group per priority lvl\n" \
+               "          . group_by_node_name  one priority group per target node\n" \
+               "  -v lvl  verbosity level\n" \
+               "          . 0 no output\n" \
+               "          . 1 print created devmap names only\n" \
+               "          . 2 default verbosity\n" \
+               "          . 3 print debug information\n" \
+               "  dev     action limited to:\n" \
+               "          . multipath named 'dev' (ex: mpath0) or\n" \
+               "          . multipath whose wwid is 'dev' (ex: 60051..)\n" \
+               "          . multipath including the path named 'dev' (ex: /dev/sda)\n" \
+               "          . multipath including the path with maj:min 'dev' (ex: 8:0)\n" \
                );
 
        exit(1);
@@ -283,7 +288,7 @@ configure (void)
        if (conf->verbosity > 2)
                print_all_paths(pathvec, 1);
 
-       get_path_layout(pathvec);
+       get_path_layout(pathvec, 1);
 
        if (get_dm_mpvec(curmp, pathvec, refwwid))
                goto out;
@@ -298,7 +303,7 @@ configure (void)
        /*
         * core logic entry point
         */
-       r = coalesce_paths(&vecs, NULL, NULL);
+       r = coalesce_paths(&vecs, NULL, NULL, conf->force_reload);
 
 out:
        if (refwwid)
@@ -341,7 +346,7 @@ main (int argc, char *argv[])
                condlog(0, "multipath tools need sysfs mounted");
                exit(1);
        }
-       while ((arg = getopt(argc, argv, ":dhl::FfM:v:p:b:")) != EOF ) {
+       while ((arg = getopt(argc, argv, ":dhl::FfM:v:p:b:r")) != EOF ) {
                switch(arg) {
                case 1: printf("optarg : %s\n",optarg);
                        break;
@@ -384,6 +389,9 @@ main (int argc, char *argv[])
                                usage(argv[0]);
                        }                
                        break;
+               case 'r':
+                       conf->force_reload = 1;
+                       break;
                case 'h':
                        usage(argv[0]);
                case ':':
index f71dca0..540a330 100644 (file)
@@ -28,7 +28,7 @@ show_paths (char ** r, int * len, struct vectors * vecs, char * style)
        unsigned int maxlen = INITIAL_REPLY_LEN;
        int again = 1;
 
-       get_path_layout(vecs->pathvec);
+       get_path_layout(vecs->pathvec, 1);
        reply = MALLOC(maxlen);
 
        while (again) {
@@ -94,7 +94,7 @@ show_maps_topology (char ** r, int * len, struct vectors * vecs)
        unsigned int maxlen = INITIAL_REPLY_LEN;
        int again = 1;
  
-       get_path_layout(vecs->pathvec);
+       get_path_layout(vecs->pathvec, 0);
        reply = MALLOC(maxlen);
 
        while (again) {
@@ -191,7 +191,7 @@ cli_list_map_topology (void * v, char ** reply, int * len, void * data)
        struct vectors * vecs = (struct vectors *)data;
        char * param = get_keyparam(v, MAP);
        
-       get_path_layout(vecs->pathvec);
+       get_path_layout(vecs->pathvec, 0);
        mpp = find_mp_by_str(vecs->mpvec, param);
 
        if (!mpp)
@@ -222,7 +222,7 @@ show_maps (char ** r, int *len, struct vectors * vecs, char * style)
        unsigned int maxlen = INITIAL_REPLY_LEN;
        int again = 1;
 
-       get_multipath_layout(vecs->mpvec);
+       get_multipath_layout(vecs->mpvec, 1);
        reply = MALLOC(maxlen);
 
        while (again) {
index ac9cd36..8c752d2 100644 (file)
@@ -266,7 +266,7 @@ ev_add_map (struct sysfs_device * dev, struct vectors * vecs)
        refwwid = get_refwwid(dev->kernel, DEV_DEVMAP, vecs->pathvec);
 
        if (refwwid) {
-               r = coalesce_paths(vecs, NULL, refwwid);
+               r = coalesce_paths(vecs, NULL, refwwid, 0);
                dm_lib_release();
        }
 
@@ -1080,7 +1080,7 @@ configure (struct vectors * vecs, int start_waiters)
        /*
         * create new set of maps & push changed ones into dm
         */
-       if (coalesce_paths(vecs, mpvec, NULL))
+       if (coalesce_paths(vecs, mpvec, NULL, 0))
                return 1;
 
        /*