Add 'none' checker
authorHannes Reinecke <hare@suse.de>
Fri, 15 Sep 2017 06:30:29 +0000 (08:30 +0200)
committerChristophe Varoqui <christophe.varoqui@opensvc.com>
Wed, 20 Sep 2017 13:32:34 +0000 (15:32 +0200)
For NVMe we don't have a good way of checking the path state, so
add a new checker 'none' which doesn't do any checking, but rely
on the internal sysfs state for path checking.

Signed-off-by: Hannes Reinecke <hare@suse.com>
libmultipath/checkers.c
libmultipath/checkers.h
libmultipath/discovery.c
libmultipath/discovery.h
multipath/multipath.conf.5
multipathd/main.c

index c32f727..cd6d6a3 100644 (file)
@@ -19,6 +19,7 @@ char *checker_state_names[] = {
        "timeout",
        "removed",
        "delayed",
+       "none",
 };
 
 static LIST_HEAD(checkers);
@@ -102,6 +103,8 @@ struct checker * add_checker (char *multipath_dir, char * name)
        if (!c)
                return NULL;
        snprintf(c->name, CHECKER_NAME_LEN, "%s", name);
+       if (!strncmp(c->name, NONE, 4))
+               goto done;
        snprintf(libname, LIB_CHECKER_NAMELEN, "%s/libcheck%s.so",
                 multipath_dir, name);
        if (stat(libname,&stbuf) < 0) {
@@ -145,7 +148,7 @@ struct checker * add_checker (char *multipath_dir, char * name)
                condlog(0, "A dynamic linking error occurred: (%s)", errstr);
        if (!c->repair)
                goto out;
-
+done:
        c->fd = -1;
        c->sync = 1;
        list_add(&c->node, &checkers);
@@ -195,14 +198,16 @@ int checker_init (struct checker * c, void ** mpctxt_addr)
        if (!c)
                return 1;
        c->mpcontext = mpctxt_addr;
-       return c->init(c);
+       if (c->init)
+               return c->init(c);
+       return 0;
 }
 
 void checker_put (struct checker * dst)
 {
        struct checker * src;
 
-       if (!dst || !dst->check)
+       if (!dst || !strlen(dst->name))
                return;
        src = checker_lookup(dst->name);
        if (dst->free)
@@ -221,11 +226,11 @@ void checker_repair (struct checker * c)
                MSG(c, "checker disabled");
                return;
        }
-
-       c->repair(c);
+       if (c->repair)
+               c->repair(c);
 }
 
-int checker_check (struct checker * c)
+int checker_check (struct checker * c, int path_state)
 {
        int r;
 
@@ -237,6 +242,9 @@ int checker_check (struct checker * c)
                MSG(c, "checker disabled");
                return PATH_UNCHECKED;
        }
+       if (!strncmp(c->name, NONE, 4))
+               return path_state;
+
        if (c->fd < 0) {
                MSG(c, "no usable fd");
                return PATH_WILD;
@@ -250,6 +258,8 @@ int checker_selected (struct checker * c)
 {
        if (!c)
                return 0;
+       if (!strncmp(c->name, NONE, 4))
+               return 1;
        return (c->check) ? 1 : 0;
 }
 
index 1d225de..713399f 100644 (file)
@@ -85,6 +85,7 @@ enum path_check_state {
 #define EMC_CLARIION "emc_clariion"
 #define READSECTOR0  "readsector0"
 #define CCISS_TUR    "cciss_tur"
+#define NONE         "none"
 #define RBD          "rbd"
 
 #define ASYNC_TIMEOUT_SEC      30
@@ -135,7 +136,7 @@ void checker_set_fd (struct checker *, int);
 void checker_enable (struct checker *);
 void checker_disable (struct checker *);
 void checker_repair (struct checker *);
-int checker_check (struct checker *);
+int checker_check (struct checker *, int);
 int checker_selected (struct checker *);
 char * checker_name (struct checker *);
 char * checker_message (struct checker *);
index a880f4b..225fd4d 100644 (file)
@@ -1550,7 +1550,7 @@ cciss_ioctl_pathinfo (struct path * pp, int mask)
 }
 
 int
-get_state (struct path * pp, struct config *conf, int daemon)
+get_state (struct path * pp, struct config *conf, int daemon, int oldstate)
 {
        struct checker * c = &pp->checker;
        int state;
@@ -1588,8 +1588,9 @@ get_state (struct path * pp, struct config *conf, int daemon)
        if (!conf->checker_timeout &&
            sysfs_get_timeout(pp, &(c->timeout)) <= 0)
                c->timeout = DEF_TIMEOUT;
-       state = checker_check(c);
-       condlog(3, "%s: state = %s", pp->dev, checker_state_name(state));
+       state = checker_check(c, oldstate);
+       condlog(3, "%s: %s state = %s", pp->dev,
+               checker_name(c), checker_state_name(state));
        if (state != PATH_UP && state != PATH_GHOST &&
            strlen(checker_message(c)))
                condlog(3, "%s: checker msg is \"%s\"",
@@ -1960,7 +1961,8 @@ int pathinfo(struct path *pp, struct config *conf, int mask)
 
        if (mask & DI_CHECKER) {
                if (path_state == PATH_UP) {
-                       pp->chkrstate = pp->state = get_state(pp, conf, 0);
+                       pp->chkrstate = pp->state = get_state(pp, conf, 0,
+                                                             path_state);
                        if (pp->state == PATH_UNCHECKED ||
                            pp->state == PATH_WILD)
                                goto blank;
index 51c23d6..6a54b78 100644 (file)
@@ -34,7 +34,7 @@ int path_discovery (vector pathvec, int flag);
 
 int do_tur (char *);
 int path_offline (struct path *);
-int get_state (struct path * pp, struct config * conf, int daemon);
+int get_state (struct path * pp, struct config * conf, int daemon, int state);
 int get_vpd_sgio (int fd, int pg, char * str, int maxlen);
 int pathinfo (struct path * pp, struct config * conf, int mask);
 int alloc_path_with_pathinfo (struct config *conf, struct udev_device *udevice,
index 57a771c..5b6dde7 100644 (file)
@@ -462,6 +462,9 @@ Please use \fItur\fR instead.
 (Hardware-dependent)
 Check the path state for HP/COMPAQ Smart Array(CCISS) controllers.
 .TP
+.I none
+Do not check the device, fallback to use the values retrieved from sysfs
+.TP
 .I rbd
 Check if the path is in the Ceph blacklist and remap the path if it is.
 .TP
index f766d64..8049da2 100644 (file)
@@ -1642,7 +1642,7 @@ check_path (struct vectors * vecs, struct path * pp, int ticks)
 
        if (newstate == PATH_UP) {
                conf = get_multipath_config();
-               newstate = get_state(pp, conf, 1);
+               newstate = get_state(pp, conf, 1, newstate);
                put_multipath_config(conf);
        } else
                checker_clear_message(&pp->checker);