#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>
#include <structs.h>
#include <structs_vec.h>
#include <dmparser.h>
+#include <sysfs.h>
#include <config.h>
#include <blacklist.h>
#include <discovery.h>
#include <pgpolicies.h>
#include <version.h>
+int logsink;
+
static int
filter_pathvec (vector pathvec, char * refwwid)
{
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);
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);
}
}
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) {
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) &&
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
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;
}
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)
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;
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]);
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