summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libmultipath/discovery.c32
-rw-r--r--libmultipath/discovery.h1
-rw-r--r--libmultipath/print.c10
-rw-r--r--libmultipath/print.h6
-rw-r--r--libmultipath/structs.h2
-rw-r--r--multipathd/main.c3
6 files changed, 50 insertions, 4 deletions
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
index dd45e03..3bcee66 100644
--- a/libmultipath/discovery.c
+++ b/libmultipath/discovery.c
@@ -144,6 +144,7 @@ declare_sysfs_get_str(cutype);
declare_sysfs_get_str(vendor);
declare_sysfs_get_str(model);
declare_sysfs_get_str(rev);
+declare_sysfs_get_str(state);
int
sysfs_get_dev (struct sysfs_device * dev, char * buff, size_t len)
@@ -528,6 +529,33 @@ struct sysfs_device *sysfs_device_from_path(struct path *pp)
return sysfs_device_get(sysdev);
}
+int
+path_offline (struct path * pp)
+{
+ struct sysfs_device * parent;
+ char buff[SCSI_STATE_SIZE];
+
+ pp->sysdev = sysfs_device_from_path(pp);
+ if (!pp->sysdev) {
+ condlog(1, "%s: failed to get sysfs information", pp->dev);
+ return 1;
+ }
+ parent = sysfs_device_get_parent(pp->sysdev);
+ if (!parent)
+ parent = pp->sysdev;
+ if (sysfs_get_state(parent, buff, SCSI_STATE_SIZE))
+ return 1;
+
+ condlog(3, "%s: state = %s", pp->dev, buff);
+
+ if (!strncmp(buff, "offline", 7)) {
+ pp->offline = 1;
+ return 1;
+ }
+ pp->offline = 0;
+ return 0;
+}
+
extern int
sysfs_pathinfo(struct path * pp)
{
@@ -618,6 +646,10 @@ get_state (struct path * pp)
if (checker_init(c, &pp->mpp->mpcontext))
return 1;
}
+ if (path_offline(pp)) {
+ condlog(3, "%s: path offline", pp->dev);
+ return 0;
+ }
pp->state = checker_check(c);
condlog(3, "%s: state = %i", pp->dev, pp->state);
if (pp->state == PATH_DOWN && strlen(checker_message(c)))
diff --git a/libmultipath/discovery.h b/libmultipath/discovery.h
index c7cf7e8..1c7590d 100644
--- a/libmultipath/discovery.h
+++ b/libmultipath/discovery.h
@@ -30,6 +30,7 @@ int path_discovery (vector pathvec, struct config * conf, int flag);
void basename (char *, char *);
int do_tur (char *);
int devt2devname (char *, char *);
+int path_offline (struct path *);
int pathinfo (struct path *, vector hwtable, int mask);
struct path * store_pathinfo (vector pathvec, vector hwtable,
char * devname, int flag);
diff --git a/libmultipath/print.c b/libmultipath/print.c
index 09b3579..a3f22f4 100644
--- a/libmultipath/print.c
+++ b/libmultipath/print.c
@@ -305,6 +305,15 @@ snprint_dev_t (char * buff, size_t len, struct path * pp)
}
static int
+snprint_offline (char * buff, size_t len, struct path * pp)
+{
+ if (pp->offline)
+ return snprintf(buff, len, "offline");
+ else
+ return snprintf(buff, len, "running");
+}
+
+static int
snprint_chk_state (char * buff, size_t len, struct path * pp)
{
switch (pp->state) {
@@ -424,6 +433,7 @@ struct path_data pd[] = {
{'d', "dev", 0, snprint_dev},
{'D', "dev_t", 0, snprint_dev_t},
{'t', "dm_st", 0, snprint_dm_path_state},
+ {'o', "dev_st", 0, snprint_offline},
{'T', "chk_st", 0, snprint_chk_state},
{'s', "vend/prod/rev", 0, snprint_vpr},
{'C', "next_check", 0, snprint_next_check},
diff --git a/libmultipath/print.h b/libmultipath/print.h
index a8be408..ea9160f 100644
--- a/libmultipath/print.h
+++ b/libmultipath/print.h
@@ -1,6 +1,6 @@
-#define PRINT_PATH_LONG "%w %i %d %D %p %t%T %s"
-#define PRINT_PATH_INDENT " \\_ %i %d %D %t%T"
-#define PRINT_PATH_CHECKER "%i %d %D %p %t%T %C"
+#define PRINT_PATH_LONG "%w %i %d %D %p %t%T %s %o"
+#define PRINT_PATH_INDENT " \\_ %i %d %D %t%T %o"
+#define PRINT_PATH_CHECKER "%i %d %D %p %t%T %o %C"
#define PRINT_MAP_STATUS "%n %F %Q %N %t %r"
#define PRINT_MAP_STATS "%n %0 %1 %2 %3 %4"
#define PRINT_MAP_NAMES "%n %d %w"
diff --git a/libmultipath/structs.h b/libmultipath/structs.h
index 85d5109..aeb4afd 100644
--- a/libmultipath/structs.h
+++ b/libmultipath/structs.h
@@ -16,6 +16,7 @@
#define SCSI_VENDOR_SIZE 9
#define SCSI_PRODUCT_SIZE 17
#define SCSI_REV_SIZE 5
+#define SCSI_STATE_SIZE 9
#define NO_PATH_RETRY_UNDEF 0
#define NO_PATH_RETRY_FAIL -1
@@ -114,6 +115,7 @@ struct path {
unsigned int checkint;
unsigned int tick;
int bus;
+ int offline;
int state;
int dmstate;
int failcount;
diff --git a/multipathd/main.c b/multipathd/main.c
index 7879758..87f878c 100644
--- a/multipathd/main.c
+++ b/multipathd/main.c
@@ -875,7 +875,8 @@ check_path (struct vectors * vecs, struct path * pp)
*/
checker_set_async(&pp->checker);
- newstate = checker_check(&pp->checker);
+ if (!path_offline(pp))
+ newstate = checker_check(&pp->checker);
if (newstate < 0) {
condlog(2, "%s: unusable path", pp->dev);