summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2010-02-03 14:22:22 +0100
committerChristophe Varoqui <christophe.varoqui@free.fr>2010-02-03 15:29:57 +0100
commit88c75172cf56e78d87b56fe48627b2e1da4eff48 (patch)
treec13cffa8a070dcb6a6f97c21d5fa74fe61886cf9
parent53bf3a2b0086b1b7c2f3a62335569042f916f4ec (diff)
downloadmultipath-tools-88c75172cf56e78d87b56fe48627b2e1da4eff48.tar.gz
multipath-tools-88c75172cf56e78d87b56fe48627b2e1da4eff48.tar.bz2
multipath-tools-88c75172cf56e78d87b56fe48627b2e1da4eff48.zip
Update path_offline() to return device status
A SCSI device can have for more states than just 'offline' and 'running'. In fact, any device _not_ in state 'running' is unaccessible to I/O, so running a path checker on these devices will cause the checker to be delayed and hence stall the entire daemon. This patch updates the path_offline() function to return the actual device state. Path checkers will only be run if the state is PATH_UP. A 'blocked' device state will be translated into PATH_PENDING, causing the checkerloop to skip this device and recheck as soon as possible. Signed-off-by: Hannes Reinecke <hare@suse.de>
-rw-r--r--libmultipath/discovery.c23
-rw-r--r--multipathd/main.c5
2 files changed, 17 insertions, 11 deletions
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
index 98d1618..6b99d07 100644
--- a/libmultipath/discovery.c
+++ b/libmultipath/discovery.c
@@ -587,7 +587,7 @@ path_offline (struct path * pp)
pp->sysdev = sysfs_device_from_path(pp);
if (!pp->sysdev) {
condlog(1, "%s: failed to get sysfs information", pp->dev);
- return 1;
+ return PATH_WILD;
}
parent = sysfs_device_get_parent(pp->sysdev);
@@ -597,20 +597,25 @@ path_offline (struct path * pp)
parent = sysfs_device_get_parent(parent);
if (!parent) {
condlog(1, "%s: failed to get parent", pp->dev);
- return 1;
+ return PATH_WILD;
}
if (sysfs_get_state(parent, buff, SCSI_STATE_SIZE))
- return 1;
+ return PATH_WILD;
condlog(3, "%s: state = %s", pp->dev, buff);
if (!strncmp(buff, "offline", 7)) {
pp->offline = 1;
- return 1;
+ return PATH_DOWN;
}
pp->offline = 0;
- return 0;
+ if (!strncmp(buff, "blocked", 7))
+ return PATH_PENDING;
+ else if (!strncmp(buff, "running", 7))
+ return PATH_UP;
+
+ return PATH_DOWN;
}
extern int
@@ -703,6 +708,7 @@ static int
get_state (struct path * pp)
{
struct checker * c = &pp->checker;
+ int sysfs_state;
condlog(3, "%s: get_state", pp->dev);
@@ -718,9 +724,10 @@ get_state (struct path * pp)
return 1;
}
}
- if (path_offline(pp)) {
- condlog(3, "%s: path offline", pp->dev);
- pp->state = PATH_DOWN;
+ sysfs_state = path_offline(pp);
+ if (sysfs_state != PATH_UP) {
+ condlog(3, "%s: path inaccessible", pp->dev);
+ pp->state = sysfs_state;
return 0;
}
pp->state = checker_check(c);
diff --git a/multipathd/main.c b/multipathd/main.c
index e875d14..e7955bd 100644
--- a/multipathd/main.c
+++ b/multipathd/main.c
@@ -948,9 +948,8 @@ check_path (struct vectors * vecs, struct path * pp)
*/
checker_set_async(&pp->checker);
- if (path_offline(pp))
- newstate = PATH_DOWN;
- else
+ newstate = path_offline(pp);
+ if (newstate == PATH_UP)
newstate = checker_check(&pp->checker);
if (newstate < 0) {