[dm-devel] [PATCH 51/78] Rework uev_add_path()
Hannes Reinecke
hare at suse.de
Mon Mar 16 12:36:38 UTC 2015
Rework uev_add_path() to handle failed and blacklisted
paths properly.
Signed-off-by: Hannes Reinecke <hare at suse.de>
---
libmultipath/discovery.c | 34 +++++++++++++++++++++++
libmultipath/discovery.h | 2 ++
libmultipath/structs_vec.c | 3 +++
multipathd/main.c | 67 +++++++++++++++++++++++++++++-----------------
4 files changed, 82 insertions(+), 24 deletions(-)
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
index 6ba14ac..b1db00f 100644
--- a/libmultipath/discovery.c
+++ b/libmultipath/discovery.c
@@ -31,6 +31,40 @@
#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)
{
diff --git a/libmultipath/discovery.h b/libmultipath/discovery.h
index 7e5680e..da7652c 100644
--- a/libmultipath/discovery.h
+++ b/libmultipath/discovery.h
@@ -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);
diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c
index 6d2d45e..d9a731a 100644
--- a/libmultipath/structs_vec.c
+++ b/libmultipath/structs_vec.c
@@ -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;
diff --git a/multipathd/main.c b/multipathd/main.c
index 0608f06..394bec4 100644
--- a/multipathd/main.c
+++ b/multipathd/main.c
@@ -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;
}
/*
--
1.8.4.5
More information about the dm-devel
mailing list