From 507227ffc4731bd10ef9850048d12e454abd3bb0 Mon Sep 17 00:00:00 2001 From: Christophe Varoqui Date: Sat, 11 Oct 2008 02:00:22 +0200 Subject: [PATCH] [lib] add offlined paths logic o don't check offlined paths Avoids log polution and useless work o display offlined status This information is quite useful because offlining can be done by the kernel as a response to an unsane situation, but un-offlining is not automatic. This helps the offlining being aknowledged by admins. --- libmultipath/discovery.c | 32 ++++++++++++++++++++++++++++++++ libmultipath/discovery.h | 1 + libmultipath/print.c | 10 ++++++++++ libmultipath/print.h | 6 +++--- libmultipath/structs.h | 2 ++ multipathd/main.c | 3 ++- 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); -- 2.7.4