Rework uev_add_path()
authorHannes Reinecke <hare@suse.de>
Mon, 9 Mar 2015 11:06:35 +0000 (07:06 -0400)
committerChristophe Varoqui <christophe.varoqui@opensvc.com>
Sun, 29 Mar 2015 16:10:33 +0000 (18:10 +0200)
Rework uev_add_path() to handle failed and blacklisted
paths properly.

Signed-off-by: Hannes Reinecke <hare@suse.de>
libmultipath/discovery.c
libmultipath/discovery.h
libmultipath/structs_vec.c
multipathd/main.c

index 6ba14ac..b1db00f 100644 (file)
 #include "prio.h"
 #include "defaults.h"
 
+int
+alloc_path_with_pathinfo (vector hwtable, struct udev_device *udevice,
+                         int flag, struct path **pp_ptr)
+{
+       int err = PATHINFO_FAILED;
+       struct path * pp;
+       const char * devname;
+
+       if (pp_ptr)
+               *pp_ptr = NULL;
+
+       devname = udev_device_get_sysname(udevice);
+       if (!devname)
+               return PATHINFO_FAILED;
+
+       pp = alloc_path();
+
+       if (!pp)
+               return PATHINFO_FAILED;
+
+       if (safe_sprintf(pp->dev, "%s", devname)) {
+               condlog(0, "pp->dev too small");
+       } else {
+               pp->udev = udev_device_ref(udevice);
+               err = pathinfo(pp, hwtable, flag | DI_BLACKLIST);
+       }
+
+       if (err)
+               free_path(pp);
+       else if (pp_ptr)
+               *pp_ptr = pp;
+       return err;
+}
+
 int
 store_pathinfo (vector pathvec, vector hwtable, struct udev_device *udevice,
                int flag, struct path **pp_ptr)
index 7e5680e..da7652c 100644 (file)
@@ -36,6 +36,8 @@ int do_tur (char *);
 int path_offline (struct path *);
 int get_state (struct path * pp, int daemon);
 int pathinfo (struct path *, vector hwtable, int mask);
+int alloc_path_with_pathinfo (vector hwtable, struct udev_device *udevice,
+                             int flag, struct path **pp_ptr);
 int store_pathinfo (vector pathvec, vector hwtable,
                    struct udev_device *udevice, int flag,
                    struct path **pp_ptr);
index 6d2d45e..d9a731a 100644 (file)
@@ -459,6 +459,9 @@ add_map_with_path (struct vectors * vecs,
 {
        struct multipath * mpp;
 
+       if (!strlen(pp->wwid))
+               return NULL;
+
        if (!(mpp = alloc_multipath()))
                return NULL;
 
index 0608f06..394bec4 100644 (file)
@@ -401,7 +401,7 @@ static int
 uev_add_path (struct uevent *uev, struct vectors * vecs)
 {
        struct path *pp;
-       int ret, i;
+       int ret = 0, i;
 
        condlog(2, "%s: add path (uevent)", uev->kernel);
        if (strstr(uev->kernel, "..") != NULL) {
@@ -414,44 +414,63 @@ uev_add_path (struct uevent *uev, struct vectors * vecs)
 
        pp = find_path_by_dev(vecs->pathvec, uev->kernel);
        if (pp) {
+               int r;
+
                condlog(0, "%s: spurious uevent, path already in pathvec",
                        uev->kernel);
-               if (pp->mpp)
-                       return 0;
-               if (!strlen(pp->wwid)) {
+               if (!pp->mpp && !strlen(pp->wwid)) {
+                       condlog(3, "%s: reinitialize path", uev->kernel);
                        udev_device_unref(pp->udev);
                        pp->udev = udev_device_ref(uev->udev);
-                       ret = pathinfo(pp, conf->hwtable,
-                                      DI_ALL | DI_BLACKLIST);
-                       if (ret == 2) {
+                       r = pathinfo(pp, conf->hwtable,
+                                    DI_ALL | DI_BLACKLIST);
+                       if (r == PATHINFO_OK)
+                               ret = ev_add_path(pp, vecs);
+                       else if (r == PATHINFO_SKIPPED) {
+                               condlog(3, "%s: remove blacklisted path",
+                                       uev->kernel);
                                i = find_slot(vecs->pathvec, (void *)pp);
                                if (i != -1)
                                        vector_del_slot(vecs->pathvec, i);
                                free_path(pp);
-                               return 0;
-                       } else if (ret == 1) {
+                       } else {
                                condlog(0, "%s: failed to reinitialize path",
                                        uev->kernel);
-                               return 1;
+                               ret = 1;
                        }
                }
-       } else {
-               /*
-                * get path vital state
-                */
-               ret = store_pathinfo(vecs->pathvec, conf->hwtable,
-                                    uev->udev, DI_ALL, &pp);
-               if (!pp) {
-                       if (ret == 2)
-                               return 0;
-                       condlog(0, "%s: failed to store path info",
-                               uev->kernel);
-                       return 1;
-               }
+               return ret;
+       }
+
+       /*
+        * get path vital state
+        */
+       ret = alloc_path_with_pathinfo(conf->hwtable, uev->udev,
+                                      DI_ALL, &pp);
+       if (!pp) {
+               if (ret == PATHINFO_SKIPPED)
+                       return 0;
+               condlog(3, "%s: failed to get path info", uev->kernel);
+               return 1;
+       }
+       if (!strlen(pp->wwid)) {
+               condlog(3, "%s: Failed to get path wwid", uev->kernel);
+               free_path(pp);
+               return 1;
+       }
+       ret = store_path(vecs->pathvec, pp);
+       if (!ret) {
                pp->checkint = conf->checkint;
+               ret = ev_add_path(pp, vecs);
+       } else {
+               condlog(0, "%s: failed to store path info, "
+                       "dropping event",
+                       uev->kernel);
+               free_path(pp);
+               ret = 1;
        }
 
-       return ev_add_path(pp, vecs);
+       return ret;
 }
 
 /*