diff options
author | Hannes Reinecke <hare@suse.de> | 2010-02-03 14:22:22 +0100 |
---|---|---|
committer | Christophe Varoqui <christophe.varoqui@free.fr> | 2010-02-03 15:29:57 +0100 |
commit | 88c75172cf56e78d87b56fe48627b2e1da4eff48 (patch) | |
tree | c13cffa8a070dcb6a6f97c21d5fa74fe61886cf9 | |
parent | 53bf3a2b0086b1b7c2f3a62335569042f916f4ec (diff) | |
download | multipath-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.c | 23 | ||||
-rw-r--r-- | multipathd/main.c | 5 |
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) { |