[dm-devel] [PATCH 05/11] libmultipath: proactively remove path
Hannes Reinecke
hare at suse.de
Fri Dec 13 12:14:08 UTC 2013
When path_offline() detects a removed path we really do not need
to wait for any uevent to arrive, but can remove the path
straightaway.
Signed-off-by: Hannes Reinecke <hare at suse.de>
---
libmultipath/checkers.c | 1 +
libmultipath/checkers.h | 5 +++++
libmultipath/discovery.c | 15 ++++++++++++---
libmultipath/sysfs.c | 2 +-
multipathd/main.c | 5 +++++
5 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/libmultipath/checkers.c b/libmultipath/checkers.c
index 47f5c68..4a4cd7c 100644
--- a/libmultipath/checkers.c
+++ b/libmultipath/checkers.c
@@ -18,6 +18,7 @@ char *checker_state_names[] = {
"ghost",
"pending",
"timeout",
+ "removed",
};
static LIST_HEAD(checkers);
diff --git a/libmultipath/checkers.h b/libmultipath/checkers.h
index 1b6c22d..e62b52f 100644
--- a/libmultipath/checkers.h
+++ b/libmultipath/checkers.h
@@ -50,6 +50,10 @@
* PATH_TIMEOUT:
* - Use: Only tur checker
* - Description: Command timed out
+ *
+ * PATH REMOVED:
+ * - Use: All checkers
+ * - Description: Device has been removed from the system
*/
enum path_check_state {
PATH_WILD,
@@ -60,6 +64,7 @@ enum path_check_state {
PATH_GHOST,
PATH_PENDING,
PATH_TIMEOUT,
+ PATH_REMOVED,
PATH_MAX_STATE
};
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
index d519c02..ccd3b62 100644
--- a/libmultipath/discovery.c
+++ b/libmultipath/discovery.c
@@ -839,6 +839,7 @@ path_offline (struct path * pp)
{
struct udev_device * parent;
char buff[SCSI_STATE_SIZE];
+ int err;
if (pp->bus != SYSFS_BUS_SCSI)
return PATH_UP;
@@ -853,12 +854,18 @@ path_offline (struct path * pp)
if (!parent) {
condlog(1, "%s: failed to get sysfs information", pp->dev);
- return PATH_DOWN;
+ return PATH_REMOVED;
}
memset(buff, 0x0, SCSI_STATE_SIZE);
- if (sysfs_attr_get_value(parent, "state", buff, SCSI_STATE_SIZE) <= 0)
- return PATH_DOWN;
+ err = sysfs_attr_get_value(parent, "state", buff, SCSI_STATE_SIZE);
+ if (err <= 0) {
+ if (err == -ENXIO)
+ return PATH_REMOVED;
+ else
+ return PATH_DOWN;
+ }
+
condlog(3, "%s: path state = %s", pp->dev, buff);
@@ -1084,6 +1091,8 @@ pathinfo (struct path *pp, vector hwtable, int mask)
}
path_state = path_offline(pp);
+ if (path_state == PATH_REMOVED)
+ goto blank;
/*
* fetch info not available through sysfs
diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c
index 8ba27d4..e5834f9 100644
--- a/libmultipath/sysfs.c
+++ b/libmultipath/sysfs.c
@@ -59,7 +59,7 @@ ssize_t sysfs_attr_get_value(struct udev_device *dev, const char *attr_name,
condlog(4, "open '%s'", devpath);
if (stat(devpath, &statbuf) != 0) {
condlog(4, "stat '%s' failed: %s", devpath, strerror(errno));
- return -errno;
+ return -ENXIO;
}
/* skip directories */
diff --git a/multipathd/main.c b/multipathd/main.c
index 2633da9..96564f8 100644
--- a/multipathd/main.c
+++ b/multipathd/main.c
@@ -1122,6 +1122,11 @@ check_path (struct vectors * vecs, struct path * pp)
pp->tick = conf->checkint;
newstate = path_offline(pp);
+ if (newstate == PATH_REMOVED) {
+ condlog(2, "%s: remove path (checker)", pp->dev);
+ ev_remove_path(pp, vecs);
+ return;
+ }
if (newstate == PATH_UP)
newstate = get_state(pp, 1);
else
--
1.8.1.4
More information about the dm-devel
mailing list