Don't display the state of the newly added map during addition in the daemon
[platform/upstream/multipath-tools.git] / multipath / main.c
index 07c046b..dacae1f 100644 (file)
@@ -25,9 +25,9 @@
 #include <stdio.h>
 #include <unistd.h>
 #include <ctype.h>
-#include <sysfs/libsysfs.h>
 
 #include <checkers.h>
+#include <prio.h>
 #include <vector.h>
 #include <memory.h>
 #include <libdevmapper.h>
@@ -37,6 +37,7 @@
 #include <structs.h>
 #include <structs_vec.h>
 #include <dmparser.h>
+#include <sysfs.h>
 #include <config.h>
 #include <blacklist.h>
 #include <discovery.h>
@@ -48,6 +49,8 @@
 #include <pgpolicies.h>
 #include <version.h>
 
+int logsink;
+
 static int
 filter_pathvec (vector pathvec, char * refwwid)
 {
@@ -72,33 +75,39 @@ static void
 usage (char * progname)
 {
        fprintf (stderr, VERSION_STRING);
-       fprintf (stderr, "Usage: %s\t[-v level] [-d] [-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-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);
@@ -127,13 +136,16 @@ update_paths (struct multipath * mpp)
                                        pp->state = PATH_DOWN;
                                        continue;
                                }
+                               pp->mpp = mpp;
                                pathinfo(pp, conf->hwtable, DI_ALL);
                                continue;
                        }
-                       if (pp->state == PATH_UNCHECKED)
+                       pp->mpp = mpp;
+                       if (pp->state == PATH_UNCHECKED ||
+                           pp->state == PATH_WILD)
                                pathinfo(pp, conf->hwtable, DI_CHECKER);
 
-                       if (!pp->priority)
+                       if (pp->priority == PRIO_UNDEF)
                                pathinfo(pp, conf->hwtable, DI_PRIO);
                }
        }
@@ -146,7 +158,7 @@ get_dm_mpvec (vector curmp, vector pathvec, char * refwwid)
        int i;
        struct multipath * mpp;
 
-       if (dm_get_maps(curmp, DEFAULT_TARGET))
+       if (dm_get_maps(curmp))
                return 1;
 
        vector_foreach_slot (curmp, mpp, i) {
@@ -221,7 +233,7 @@ configure (void)
        vecs.mpvec = curmp;
 
        /*
-        * if we have a blacklisted device parameter, exit early
+        * dev is "/dev/" . "sysfs block dev"
         */
        if (conf->dev) {
                if (!strncmp(conf->dev, "/dev/", 5) &&
@@ -231,8 +243,12 @@ configure (void)
                        dev = conf->dev;
        }
        
-       if (dev && blacklist(conf->blist_devnode, dev))
-               goto out;
+       /*
+        * if we have a blacklisted device parameter, exit early
+        */
+       if (dev && 
+           (filter_devnode(conf->blist_devnode, conf->elist_devnode, dev) > 0))
+                       goto out;
        
        /*
         * scope limiting must be translated into a wwid
@@ -246,8 +262,8 @@ configure (void)
                        goto out;
                }
                condlog(3, "scope limited to %s", refwwid);
-
-               if (blacklist(conf->blist_wwid, refwwid))
+               if (filter_wwid(conf->blist_wwid, conf->elist_wwid,
+                               refwwid) > 0)
                        goto out;
        }
 
@@ -273,20 +289,22 @@ configure (void)
        if (conf->verbosity > 2)
                print_all_paths(pathvec, 1);
 
-       get_path_layout(pathvec);
+       get_path_layout(pathvec, 0);
 
        if (get_dm_mpvec(curmp, pathvec, refwwid))
                goto out;
 
        filter_pathvec(pathvec, refwwid);
 
-       if (conf->list)
+       if (conf->list) {
+               r = 0;
                goto out;
+       }
 
        /*
         * core logic entry point
         */
-       r = coalesce_paths(&vecs, NULL, NULL);
+       r = coalesce_paths(&vecs, NULL, NULL, conf->force_reload);
 
 out:
        if (refwwid)
@@ -311,17 +329,25 @@ main (int argc, char *argv[])
                exit(1);
        }
 
-       if (dm_prereq(DEFAULT_TARGET, 1, 0, 3))
+       if (dm_prereq())
                exit(1);
 
-       if (sysfs_get_mnt_path(sysfs_path, FILE_NAME_SIZE)) {
-               condlog(0, "multipath tools need sysfs mounted");
-               exit(1);
-       }
        if (load_config(DEFAULT_CONFIGFILE))
                exit(1);
 
-       while ((arg = getopt(argc, argv, ":qdl::Ffi:M:v:p:b:")) != EOF ) {
+       if (init_checkers()) {
+               condlog(0, "failed to initialize checkers");
+               exit(1);
+       }
+       if (init_prio()) {
+               condlog(0, "failed to initialize prioritizers");
+               exit(1);
+       }
+       if (sysfs_init(conf->sysfs_dir, FILE_NAME_SIZE)) {
+               condlog(0, "multipath tools need sysfs mounted");
+               exit(1);
+       }
+       while ((arg = getopt(argc, argv, ":dhl::FfM:v:p:b:r")) != EOF ) {
                switch(arg) {
                case 1: printf("optarg : %s\n",optarg);
                        break;
@@ -364,6 +390,11 @@ main (int argc, char *argv[])
                                usage(argv[0]);
                        }                
                        break;
+               case 'r':
+                       conf->force_reload = 1;
+                       break;
+               case 'h':
+                       usage(argv[0]);
                case ':':
                        fprintf(stderr, "Missing option arguement\n");
                        usage(argv[0]);        
@@ -390,26 +421,40 @@ main (int argc, char *argv[])
                        conf->dev_type = DEV_DEVMAP;
 
        }
+       conf->daemon = 0;
+       dm_init();
 
        if (conf->remove == FLUSH_ONE) {
                if (conf->dev_type == DEV_DEVMAP)
-                       dm_flush_map(conf->dev, DEFAULT_TARGET);
+                       r = dm_flush_map(conf->dev);
                else
                        condlog(0, "must provide a map name to remove");
 
                goto out;
        }
        else if (conf->remove == FLUSH_ALL) {
-               dm_flush_maps(DEFAULT_TARGET);
+               r = dm_flush_maps();
                goto out;
        }
        while ((r = configure()) < 0)
                condlog(3, "restart multipath configuration process");
        
 out:
-       free_config(conf);
+
+       sysfs_cleanup();
        dm_lib_release();
        dm_lib_exit();
+
+       cleanup_prio();
+       cleanup_checkers();
+       /*
+        * Freeing config must be done after dm_lib_exit(), because
+        * the logging function (dm_write_log()), which is called there,
+        * references the config.
+        */
+       free_config(conf);
+       conf = NULL;
+
 #ifdef _DEBUG_
        dbg_free_final(NULL);
 #endif