|
|
f20720 |
---
|
|
|
f20720 |
libmultipath/checkers.c | 3
|
|
|
f20720 |
libmultipath/checkers.h | 9 +
|
|
|
f20720 |
libmultipath/config.c | 4
|
|
|
f20720 |
libmultipath/config.h | 6 +
|
|
|
f20720 |
libmultipath/configure.c | 2
|
|
|
f20720 |
libmultipath/defaults.h | 1
|
|
|
f20720 |
libmultipath/dict.c | 204 ++++++++++++++++++++++++++++++++++++++++++++-
|
|
|
f20720 |
libmultipath/print.c | 2
|
|
|
f20720 |
libmultipath/propsel.c | 52 +++++++++++
|
|
|
f20720 |
libmultipath/propsel.h | 2
|
|
|
f20720 |
libmultipath/structs.h | 9 +
|
|
|
f20720 |
multipath.conf.annotated | 40 ++++++++
|
|
|
f20720 |
multipath.conf.defaults | 2
|
|
|
f20720 |
multipath/multipath.conf.5 | 27 +++++
|
|
|
f20720 |
multipathd/main.c | 34 ++++++-
|
|
|
f20720 |
15 files changed, 388 insertions(+), 9 deletions(-)
|
|
|
f20720 |
|
|
|
f20720 |
Index: multipath-tools-130222/libmultipath/config.h
|
|
|
f20720 |
===================================================================
|
|
|
f20720 |
--- multipath-tools-130222.orig/libmultipath/config.h
|
|
|
f20720 |
+++ multipath-tools-130222/libmultipath/config.h
|
|
|
f20720 |
@@ -62,6 +62,8 @@ struct hwentry {
|
|
|
f20720 |
int retain_hwhandler;
|
|
|
f20720 |
int detect_prio;
|
|
|
f20720 |
int deferred_remove;
|
|
|
f20720 |
+ int delay_watch_checks;
|
|
|
f20720 |
+ int delay_wait_checks;
|
|
|
f20720 |
char * bl_product;
|
|
|
f20720 |
};
|
|
|
f20720 |
|
|
|
f20720 |
@@ -86,6 +88,8 @@ struct mpentry {
|
|
|
f20720 |
int attribute_flags;
|
|
|
f20720 |
int user_friendly_names;
|
|
|
f20720 |
int deferred_remove;
|
|
|
f20720 |
+ int delay_watch_checks;
|
|
|
f20720 |
+ int delay_wait_checks;
|
|
|
f20720 |
uid_t uid;
|
|
|
f20720 |
gid_t gid;
|
|
|
f20720 |
mode_t mode;
|
|
|
f20720 |
@@ -133,6 +137,8 @@ struct config {
|
|
|
f20720 |
int deferred_remove;
|
|
|
f20720 |
int ignore_new_boot_devs;
|
|
|
f20720 |
int processed_main_config;
|
|
|
f20720 |
+ int delay_watch_checks;
|
|
|
f20720 |
+ int delay_wait_checks;
|
|
|
f20720 |
unsigned int version[3];
|
|
|
f20720 |
|
|
|
f20720 |
char * dev;
|
|
|
f20720 |
Index: multipath-tools-130222/libmultipath/structs.h
|
|
|
f20720 |
===================================================================
|
|
|
f20720 |
--- multipath-tools-130222.orig/libmultipath/structs.h
|
|
|
f20720 |
+++ multipath-tools-130222/libmultipath/structs.h
|
|
|
f20720 |
@@ -134,6 +134,11 @@ enum scsi_protocol {
|
|
|
f20720 |
SCSI_PROTOCOL_UNSPEC = 0xf, /* No specific protocol */
|
|
|
f20720 |
};
|
|
|
f20720 |
|
|
|
f20720 |
+enum delay_checks_states {
|
|
|
f20720 |
+ DELAY_CHECKS_OFF = -1,
|
|
|
f20720 |
+ DELAY_CHECKS_UNDEF = 0,
|
|
|
f20720 |
+};
|
|
|
f20720 |
+
|
|
|
f20720 |
struct sg_id {
|
|
|
f20720 |
int host_no;
|
|
|
f20720 |
int channel;
|
|
|
f20720 |
@@ -180,6 +185,8 @@ struct path {
|
|
|
f20720 |
int priority;
|
|
|
f20720 |
int pgindex;
|
|
|
f20720 |
int detect_prio;
|
|
|
f20720 |
+ int watch_checks;
|
|
|
f20720 |
+ int wait_checks;
|
|
|
f20720 |
char * uid_attribute;
|
|
|
f20720 |
struct prio prio;
|
|
|
f20720 |
char * prio_args;
|
|
|
f20720 |
@@ -215,6 +222,8 @@ struct multipath {
|
|
|
f20720 |
int fast_io_fail;
|
|
|
f20720 |
int retain_hwhandler;
|
|
|
f20720 |
int deferred_remove;
|
|
|
f20720 |
+ int delay_watch_checks;
|
|
|
f20720 |
+ int delay_wait_checks;
|
|
|
f20720 |
unsigned int dev_loss;
|
|
|
f20720 |
uid_t uid;
|
|
|
f20720 |
gid_t gid;
|
|
|
f20720 |
Index: multipath-tools-130222/libmultipath/checkers.h
|
|
|
f20720 |
===================================================================
|
|
|
f20720 |
--- multipath-tools-130222.orig/libmultipath/checkers.h
|
|
|
f20720 |
+++ multipath-tools-130222/libmultipath/checkers.h
|
|
|
f20720 |
@@ -46,6 +46,14 @@
|
|
|
f20720 |
* PATH_PENDING:
|
|
|
f20720 |
* - Use: All async checkers
|
|
|
f20720 |
* - Description: Indicates a check IO is in flight.
|
|
|
f20720 |
+ *
|
|
|
f20720 |
+ * PATH_DELAYED:
|
|
|
f20720 |
+ * - Use: None of the checkers (returned if the path is being delayed before
|
|
|
f20720 |
+ * reintegration.
|
|
|
f20720 |
+ * - Description: If a path fails after being up for less than
|
|
|
f20720 |
+ * delay_watch_checks checks, when it comes back up again, it will not
|
|
|
f20720 |
+ * be marked as up until it has been up for delay_wait_checks checks.
|
|
|
f20720 |
+ * During this time, it is marked as "delayed"
|
|
|
f20720 |
*/
|
|
|
f20720 |
enum path_check_state {
|
|
|
f20720 |
PATH_WILD,
|
|
|
f20720 |
@@ -55,6 +63,7 @@ enum path_check_state {
|
|
|
f20720 |
PATH_SHAKY,
|
|
|
f20720 |
PATH_GHOST,
|
|
|
f20720 |
PATH_PENDING,
|
|
|
f20720 |
+ PATH_DELAYED,
|
|
|
f20720 |
PATH_MAX_STATE
|
|
|
f20720 |
};
|
|
|
f20720 |
|
|
|
f20720 |
Index: multipath-tools-130222/libmultipath/configure.c
|
|
|
f20720 |
===================================================================
|
|
|
f20720 |
--- multipath-tools-130222.orig/libmultipath/configure.c
|
|
|
f20720 |
+++ multipath-tools-130222/libmultipath/configure.c
|
|
|
f20720 |
@@ -291,6 +291,8 @@ setup_map (struct multipath * mpp, char
|
|
|
f20720 |
select_reservation_key(mpp);
|
|
|
f20720 |
select_retain_hwhandler(mpp);
|
|
|
f20720 |
select_deferred_remove(mpp);
|
|
|
f20720 |
+ select_delay_watch_checks(mpp);
|
|
|
f20720 |
+ select_delay_wait_checks(mpp);
|
|
|
f20720 |
|
|
|
f20720 |
sysfs_set_scsi_tmo(mpp);
|
|
|
f20720 |
/*
|
|
|
f20720 |
Index: multipath-tools-130222/libmultipath/defaults.h
|
|
|
f20720 |
===================================================================
|
|
|
f20720 |
--- multipath-tools-130222.orig/libmultipath/defaults.h
|
|
|
f20720 |
+++ multipath-tools-130222/libmultipath/defaults.h
|
|
|
f20720 |
@@ -20,6 +20,7 @@
|
|
|
f20720 |
#define DEFAULT_RETAIN_HWHANDLER RETAIN_HWHANDLER_OFF
|
|
|
f20720 |
#define DEFAULT_DETECT_PRIO DETECT_PRIO_OFF
|
|
|
f20720 |
#define DEFAULT_DEFERRED_REMOVE DEFERRED_REMOVE_OFF
|
|
|
f20720 |
+#define DEFAULT_DELAY_CHECKS DELAY_CHECKS_OFF
|
|
|
f20720 |
|
|
|
f20720 |
#define DEFAULT_CHECKINT 5
|
|
|
f20720 |
#define MAX_CHECKINT(a) (a << 2)
|
|
|
f20720 |
Index: multipath-tools-130222/libmultipath/dict.c
|
|
|
f20720 |
===================================================================
|
|
|
f20720 |
--- multipath-tools-130222.orig/libmultipath/dict.c
|
|
|
f20720 |
+++ multipath-tools-130222/libmultipath/dict.c
|
|
|
f20720 |
@@ -801,6 +801,44 @@ def_ignore_new_boot_devs_handler(vector
|
|
|
f20720 |
return 0;
|
|
|
f20720 |
}
|
|
|
f20720 |
|
|
|
f20720 |
+static int
|
|
|
f20720 |
+def_delay_watch_checks_handler(vector strvec)
|
|
|
f20720 |
+{
|
|
|
f20720 |
+ char * buff;
|
|
|
f20720 |
+
|
|
|
f20720 |
+ buff = set_value(strvec);
|
|
|
f20720 |
+ if (!buff)
|
|
|
f20720 |
+ return 1;
|
|
|
f20720 |
+
|
|
|
f20720 |
+ if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
|
|
|
f20720 |
+ (strlen(buff) == 1 && !strcmp(buff, "0")))
|
|
|
f20720 |
+ conf->delay_watch_checks = DELAY_CHECKS_OFF;
|
|
|
f20720 |
+ else if ((conf->delay_watch_checks = atoi(buff)) < 1)
|
|
|
f20720 |
+ conf->delay_watch_checks = DELAY_CHECKS_OFF;
|
|
|
f20720 |
+
|
|
|
f20720 |
+ FREE(buff);
|
|
|
f20720 |
+ return 0;
|
|
|
f20720 |
+}
|
|
|
f20720 |
+
|
|
|
f20720 |
+static int
|
|
|
f20720 |
+def_delay_wait_checks_handler(vector strvec)
|
|
|
f20720 |
+{
|
|
|
f20720 |
+ char * buff;
|
|
|
f20720 |
+
|
|
|
f20720 |
+ buff = set_value(strvec);
|
|
|
f20720 |
+ if (!buff)
|
|
|
f20720 |
+ return 1;
|
|
|
f20720 |
+
|
|
|
f20720 |
+ if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
|
|
|
f20720 |
+ (strlen(buff) == 1 && !strcmp(buff, "0")))
|
|
|
f20720 |
+ conf->delay_wait_checks = DELAY_CHECKS_OFF;
|
|
|
f20720 |
+ else if ((conf->delay_wait_checks = atoi(buff)) < 1)
|
|
|
f20720 |
+ conf->delay_wait_checks = DELAY_CHECKS_OFF;
|
|
|
f20720 |
+
|
|
|
f20720 |
+ FREE(buff);
|
|
|
f20720 |
+ return 0;
|
|
|
f20720 |
+}
|
|
|
f20720 |
+
|
|
|
f20720 |
/*
|
|
|
f20720 |
* blacklist block handlers
|
|
|
f20720 |
*/
|
|
|
f20720 |
@@ -1517,6 +1555,52 @@ hw_deferred_remove_handler(vector strvec
|
|
|
f20720 |
return 0;
|
|
|
f20720 |
}
|
|
|
f20720 |
|
|
|
f20720 |
+static int
|
|
|
f20720 |
+hw_delay_watch_checks_handler(vector strvec)
|
|
|
f20720 |
+{
|
|
|
f20720 |
+ struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable);
|
|
|
f20720 |
+ char * buff;
|
|
|
f20720 |
+
|
|
|
f20720 |
+ if (!hwe)
|
|
|
f20720 |
+ return 1;
|
|
|
f20720 |
+
|
|
|
f20720 |
+ buff = set_value(strvec);
|
|
|
f20720 |
+ if (!buff)
|
|
|
f20720 |
+ return 1;
|
|
|
f20720 |
+
|
|
|
f20720 |
+ if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
|
|
|
f20720 |
+ (strlen(buff) == 1 && !strcmp(buff, "0")))
|
|
|
f20720 |
+ hwe->delay_watch_checks = DELAY_CHECKS_OFF;
|
|
|
f20720 |
+ else if ((hwe->delay_watch_checks = atoi(buff)) < 1)
|
|
|
f20720 |
+ hwe->delay_watch_checks = DELAY_CHECKS_OFF;
|
|
|
f20720 |
+
|
|
|
f20720 |
+ FREE(buff);
|
|
|
f20720 |
+ return 0;
|
|
|
f20720 |
+}
|
|
|
f20720 |
+
|
|
|
f20720 |
+static int
|
|
|
f20720 |
+hw_delay_wait_checks_handler(vector strvec)
|
|
|
f20720 |
+{
|
|
|
f20720 |
+ struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable);
|
|
|
f20720 |
+ char * buff;
|
|
|
f20720 |
+
|
|
|
f20720 |
+ if (!hwe)
|
|
|
f20720 |
+ return 1;
|
|
|
f20720 |
+
|
|
|
f20720 |
+ buff = set_value(strvec);
|
|
|
f20720 |
+ if (!buff)
|
|
|
f20720 |
+ return 1;
|
|
|
f20720 |
+
|
|
|
f20720 |
+ if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
|
|
|
f20720 |
+ (strlen(buff) == 1 && !strcmp(buff, "0")))
|
|
|
f20720 |
+ hwe->delay_wait_checks = DELAY_CHECKS_OFF;
|
|
|
f20720 |
+ else if ((hwe->delay_wait_checks = atoi(buff)) < 1)
|
|
|
f20720 |
+ hwe->delay_wait_checks = DELAY_CHECKS_OFF;
|
|
|
f20720 |
+
|
|
|
f20720 |
+ FREE(buff);
|
|
|
f20720 |
+ return 0;
|
|
|
f20720 |
+}
|
|
|
f20720 |
+
|
|
|
f20720 |
/*
|
|
|
f20720 |
* multipaths block handlers
|
|
|
f20720 |
*/
|
|
|
f20720 |
@@ -1996,6 +2080,52 @@ mp_deferred_remove_handler(vector strvec
|
|
|
f20720 |
return 0;
|
|
|
f20720 |
}
|
|
|
f20720 |
|
|
|
f20720 |
+static int
|
|
|
f20720 |
+mp_delay_watch_checks_handler(vector strvec)
|
|
|
f20720 |
+{
|
|
|
f20720 |
+ struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
|
|
|
f20720 |
+ char * buff;
|
|
|
f20720 |
+
|
|
|
f20720 |
+ if (!mpe)
|
|
|
f20720 |
+ return 1;
|
|
|
f20720 |
+
|
|
|
f20720 |
+ buff = set_value(strvec);
|
|
|
f20720 |
+ if (!buff)
|
|
|
f20720 |
+ return 1;
|
|
|
f20720 |
+
|
|
|
f20720 |
+ if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
|
|
|
f20720 |
+ (strlen(buff) == 1 && !strcmp(buff, "0")))
|
|
|
f20720 |
+ mpe->delay_watch_checks = DELAY_CHECKS_OFF;
|
|
|
f20720 |
+ else if ((mpe->delay_watch_checks = atoi(buff)) < 1)
|
|
|
f20720 |
+ mpe->delay_watch_checks = DELAY_CHECKS_OFF;
|
|
|
f20720 |
+
|
|
|
f20720 |
+ FREE(buff);
|
|
|
f20720 |
+ return 0;
|
|
|
f20720 |
+}
|
|
|
f20720 |
+
|
|
|
f20720 |
+static int
|
|
|
f20720 |
+mp_delay_wait_checks_handler(vector strvec)
|
|
|
f20720 |
+{
|
|
|
f20720 |
+ struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
|
|
|
f20720 |
+ char * buff;
|
|
|
f20720 |
+
|
|
|
f20720 |
+ if (!mpe)
|
|
|
f20720 |
+ return 1;
|
|
|
f20720 |
+
|
|
|
f20720 |
+ buff = set_value(strvec);
|
|
|
f20720 |
+ if (!buff)
|
|
|
f20720 |
+ return 1;
|
|
|
f20720 |
+
|
|
|
f20720 |
+ if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
|
|
|
f20720 |
+ (strlen(buff) == 1 && !strcmp(buff, "0")))
|
|
|
f20720 |
+ mpe->delay_wait_checks = DELAY_CHECKS_OFF;
|
|
|
f20720 |
+ else if ((mpe->delay_wait_checks = atoi(buff)) < 1)
|
|
|
f20720 |
+ mpe->delay_wait_checks = DELAY_CHECKS_OFF;
|
|
|
f20720 |
+
|
|
|
f20720 |
+ FREE(buff);
|
|
|
f20720 |
+ return 0;
|
|
|
f20720 |
+}
|
|
|
f20720 |
+
|
|
|
f20720 |
/*
|
|
|
f20720 |
* config file keywords printing
|
|
|
f20720 |
*/
|
|
|
f20720 |
@@ -2258,6 +2388,30 @@ snprint_mp_deferred_remove (char * buff,
|
|
|
f20720 |
}
|
|
|
f20720 |
|
|
|
f20720 |
static int
|
|
|
f20720 |
+snprint_mp_delay_watch_checks(char * buff, int len, void * data)
|
|
|
f20720 |
+{
|
|
|
f20720 |
+ struct mpentry * mpe = (struct mpentry *)data;
|
|
|
f20720 |
+
|
|
|
f20720 |
+ if (mpe->delay_watch_checks == DELAY_CHECKS_UNDEF)
|
|
|
f20720 |
+ return 0;
|
|
|
f20720 |
+ if (mpe->delay_watch_checks == DELAY_CHECKS_OFF)
|
|
|
f20720 |
+ return snprintf(buff, len, "no");
|
|
|
f20720 |
+ return snprintf(buff, len, "%d", mpe->delay_watch_checks);
|
|
|
f20720 |
+}
|
|
|
f20720 |
+
|
|
|
f20720 |
+static int
|
|
|
f20720 |
+snprint_mp_delay_wait_checks(char * buff, int len, void * data)
|
|
|
f20720 |
+{
|
|
|
f20720 |
+ struct mpentry * mpe = (struct mpentry *)data;
|
|
|
f20720 |
+
|
|
|
f20720 |
+ if (mpe->delay_wait_checks == DELAY_CHECKS_UNDEF)
|
|
|
f20720 |
+ return 0;
|
|
|
f20720 |
+ if (mpe->delay_wait_checks == DELAY_CHECKS_OFF)
|
|
|
f20720 |
+ return snprintf(buff, len, "no");
|
|
|
f20720 |
+ return snprintf(buff, len, "%d", mpe->delay_wait_checks);
|
|
|
f20720 |
+}
|
|
|
f20720 |
+
|
|
|
f20720 |
+static int
|
|
|
f20720 |
snprint_hw_fast_io_fail(char * buff, int len, void * data)
|
|
|
f20720 |
{
|
|
|
f20720 |
struct hwentry * hwe = (struct hwentry *)data;
|
|
|
f20720 |
@@ -2586,6 +2740,30 @@ snprint_hw_deferred_remove(char * buff,
|
|
|
f20720 |
}
|
|
|
f20720 |
|
|
|
f20720 |
static int
|
|
|
f20720 |
+snprint_hw_delay_watch_checks(char * buff, int len, void * data)
|
|
|
f20720 |
+{
|
|
|
f20720 |
+ struct hwentry * hwe = (struct hwentry *)data;
|
|
|
f20720 |
+
|
|
|
f20720 |
+ if (hwe->delay_watch_checks == DELAY_CHECKS_UNDEF)
|
|
|
f20720 |
+ return 0;
|
|
|
f20720 |
+ if (hwe->delay_watch_checks == DELAY_CHECKS_OFF)
|
|
|
f20720 |
+ return snprintf(buff, len, "no");
|
|
|
f20720 |
+ return snprintf(buff, len, "%d", hwe->delay_watch_checks);
|
|
|
f20720 |
+}
|
|
|
f20720 |
+
|
|
|
f20720 |
+static int
|
|
|
f20720 |
+snprint_hw_delay_wait_checks(char * buff, int len, void * data)
|
|
|
f20720 |
+{
|
|
|
f20720 |
+ struct hwentry * hwe = (struct hwentry *)data;
|
|
|
f20720 |
+
|
|
|
f20720 |
+ if (hwe->delay_wait_checks == DELAY_CHECKS_UNDEF)
|
|
|
f20720 |
+ return 0;
|
|
|
f20720 |
+ if (hwe->delay_wait_checks == DELAY_CHECKS_OFF)
|
|
|
f20720 |
+ return snprintf(buff, len, "no");
|
|
|
f20720 |
+ return snprintf(buff, len, "%d", hwe->delay_wait_checks);
|
|
|
f20720 |
+}
|
|
|
f20720 |
+
|
|
|
f20720 |
+static int
|
|
|
f20720 |
snprint_detect_prio(char * buff, int len, void * data)
|
|
|
f20720 |
{
|
|
|
f20720 |
struct hwentry * hwe = (struct hwentry *)data;
|
|
|
f20720 |
@@ -2883,7 +3061,6 @@ snprint_def_find_multipaths (char * buff
|
|
|
f20720 |
return snprintf(buff, len, "yes");
|
|
|
f20720 |
}
|
|
|
f20720 |
|
|
|
f20720 |
-
|
|
|
f20720 |
static int
|
|
|
f20720 |
snprint_def_user_friendly_names (char * buff, int len, void * data)
|
|
|
f20720 |
{
|
|
|
f20720 |
@@ -2989,7 +3166,6 @@ snprint_def_ignore_new_boot_devs(char *
|
|
|
f20720 |
return snprintf(buff, len, "no");
|
|
|
f20720 |
}
|
|
|
f20720 |
|
|
|
f20720 |
-
|
|
|
f20720 |
static int
|
|
|
f20720 |
snprint_def_config_dir (char * buff, int len, void * data)
|
|
|
f20720 |
{
|
|
|
f20720 |
@@ -3000,6 +3176,24 @@ snprint_def_config_dir (char * buff, int
|
|
|
f20720 |
}
|
|
|
f20720 |
|
|
|
f20720 |
static int
|
|
|
f20720 |
+snprint_def_delay_watch_checks(char * buff, int len, void * data)
|
|
|
f20720 |
+{
|
|
|
f20720 |
+ if (conf->delay_watch_checks == DELAY_CHECKS_UNDEF ||
|
|
|
f20720 |
+ conf->delay_watch_checks == DELAY_CHECKS_OFF)
|
|
|
f20720 |
+ return snprintf(buff, len, "no");
|
|
|
f20720 |
+ return snprintf(buff, len, "%d", conf->delay_watch_checks);
|
|
|
f20720 |
+}
|
|
|
f20720 |
+
|
|
|
f20720 |
+static int
|
|
|
f20720 |
+snprint_def_delay_wait_checks(char * buff, int len, void * data)
|
|
|
f20720 |
+{
|
|
|
f20720 |
+ if (conf->delay_wait_checks == DELAY_CHECKS_UNDEF ||
|
|
|
f20720 |
+ conf->delay_wait_checks == DELAY_CHECKS_OFF)
|
|
|
f20720 |
+ return snprintf(buff, len, "no");
|
|
|
f20720 |
+ return snprintf(buff, len, "%d", conf->delay_wait_checks);
|
|
|
f20720 |
+}
|
|
|
f20720 |
+
|
|
|
f20720 |
+static int
|
|
|
f20720 |
snprint_ble_simple (char * buff, int len, void * data)
|
|
|
f20720 |
{
|
|
|
f20720 |
struct blentry * ble = (struct blentry *)data;
|
|
|
f20720 |
@@ -3071,6 +3265,8 @@ init_keywords(void)
|
|
|
f20720 |
install_keyword("deferred_remove", &def_deferred_remove_handler, &snprint_def_deferred_remove);
|
|
|
f20720 |
install_keyword("ignore_new_boot_devs", &def_ignore_new_boot_devs_handler, &snprint_def_ignore_new_boot_devs);
|
|
|
f20720 |
install_keyword("config_dir", &def_config_dir_handler, &snprint_def_config_dir);
|
|
|
f20720 |
+ install_keyword("delay_watch_checks", &def_delay_watch_checks_handler, &snprint_def_delay_watch_checks);
|
|
|
f20720 |
+ install_keyword("delay_wait_checks", &def_delay_wait_checks_handler, &snprint_def_delay_wait_checks);
|
|
|
f20720 |
__deprecated install_keyword("default_selector", &def_selector_handler, NULL);
|
|
|
f20720 |
__deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL);
|
|
|
f20720 |
__deprecated install_keyword("default_uid_attribute", &def_uid_attribute_handler, NULL);
|
|
|
f20720 |
@@ -3136,6 +3332,8 @@ init_keywords(void)
|
|
|
f20720 |
install_keyword("retain_attached_hw_handler", &hw_retain_hwhandler_handler, &snprint_hw_retain_hwhandler_handler);
|
|
|
f20720 |
install_keyword("detect_prio", &hw_detect_prio_handler, &snprint_detect_prio);
|
|
|
f20720 |
install_keyword("deferred_remove", &hw_deferred_remove_handler, &snprint_hw_deferred_remove);
|
|
|
f20720 |
+ install_keyword("delay_watch_checks", &hw_delay_watch_checks_handler, &snprint_hw_delay_watch_checks);
|
|
|
f20720 |
+ install_keyword("delay_wait_checks", &hw_delay_wait_checks_handler, &snprint_hw_delay_wait_checks);
|
|
|
f20720 |
install_sublevel_end();
|
|
|
f20720 |
|
|
|
f20720 |
install_keyword_root("multipaths", &multipaths_handler);
|
|
|
f20720 |
@@ -3161,5 +3359,7 @@ init_keywords(void)
|
|
|
f20720 |
install_keyword("reservation_key", &mp_reservation_key_handler, &snprint_mp_reservation_key);
|
|
|
f20720 |
install_keyword("user_friendly_names", &mp_names_handler, &snprint_mp_user_friendly_names);
|
|
|
f20720 |
install_keyword("deferred_remove", &mp_deferred_remove_handler, &snprint_mp_deferred_remove);
|
|
|
f20720 |
+ install_keyword("delay_watch_checks", &mp_delay_watch_checks_handler, &snprint_mp_delay_watch_checks);
|
|
|
f20720 |
+ install_keyword("delay_wait_checks", &mp_delay_wait_checks_handler, &snprint_mp_delay_wait_checks);
|
|
|
f20720 |
install_sublevel_end();
|
|
|
f20720 |
}
|
|
|
f20720 |
Index: multipath-tools-130222/libmultipath/print.c
|
|
|
f20720 |
===================================================================
|
|
|
f20720 |
--- multipath-tools-130222.orig/libmultipath/print.c
|
|
|
f20720 |
+++ multipath-tools-130222/libmultipath/print.c
|
|
|
f20720 |
@@ -336,6 +336,8 @@ snprint_chk_state (char * buff, size_t l
|
|
|
f20720 |
return snprintf(buff, len, "shaky");
|
|
|
f20720 |
case PATH_GHOST:
|
|
|
f20720 |
return snprintf(buff, len, "ghost");
|
|
|
f20720 |
+ case PATH_DELAYED:
|
|
|
f20720 |
+ return snprintf(buff, len, "delayed");
|
|
|
f20720 |
default:
|
|
|
f20720 |
return snprintf(buff, len, "undef");
|
|
|
f20720 |
}
|
|
|
f20720 |
Index: multipath-tools-130222/libmultipath/propsel.c
|
|
|
f20720 |
===================================================================
|
|
|
f20720 |
--- multipath-tools-130222.orig/libmultipath/propsel.c
|
|
|
f20720 |
+++ multipath-tools-130222/libmultipath/propsel.c
|
|
|
f20720 |
@@ -788,3 +788,55 @@ select_detect_prio (struct path * pp)
|
|
|
f20720 |
condlog(3, "%s: detect_prio = %d (compiled in default)", pp->dev, pp->detect_prio);
|
|
|
f20720 |
return 0;
|
|
|
f20720 |
}
|
|
|
f20720 |
+
|
|
|
f20720 |
+extern int
|
|
|
f20720 |
+select_delay_watch_checks (struct multipath * mp)
|
|
|
f20720 |
+{
|
|
|
f20720 |
+ if (mp->mpe && mp->mpe->delay_watch_checks != DELAY_CHECKS_UNDEF) {
|
|
|
f20720 |
+ mp->delay_watch_checks = mp->mpe->delay_watch_checks;
|
|
|
f20720 |
+ condlog(3, "delay_watch_checks = %i (multipath setting)",
|
|
|
f20720 |
+ mp->delay_watch_checks);
|
|
|
f20720 |
+ return 0;
|
|
|
f20720 |
+ }
|
|
|
f20720 |
+ if (mp->hwe && mp->hwe->delay_watch_checks != DELAY_CHECKS_UNDEF) {
|
|
|
f20720 |
+ mp->delay_watch_checks = mp->hwe->delay_watch_checks;
|
|
|
f20720 |
+ condlog(3, "delay_watch_checks = %i (controler setting)",
|
|
|
f20720 |
+ mp->delay_watch_checks);
|
|
|
f20720 |
+ return 0;
|
|
|
f20720 |
+ }
|
|
|
f20720 |
+ if (conf->delay_watch_checks != DELAY_CHECKS_UNDEF) {
|
|
|
f20720 |
+ mp->delay_watch_checks = conf->delay_watch_checks;
|
|
|
f20720 |
+ condlog(3, "delay_watch_checks = %i (config file default)",
|
|
|
f20720 |
+ mp->delay_watch_checks);
|
|
|
f20720 |
+ return 0;
|
|
|
f20720 |
+ }
|
|
|
f20720 |
+ mp->delay_watch_checks = DEFAULT_DELAY_CHECKS;
|
|
|
f20720 |
+ condlog(3, "delay_watch_checks = DISABLED (internal default)");
|
|
|
f20720 |
+ return 0;
|
|
|
f20720 |
+}
|
|
|
f20720 |
+
|
|
|
f20720 |
+extern int
|
|
|
f20720 |
+select_delay_wait_checks (struct multipath * mp)
|
|
|
f20720 |
+{
|
|
|
f20720 |
+ if (mp->mpe && mp->mpe->delay_wait_checks != DELAY_CHECKS_UNDEF) {
|
|
|
f20720 |
+ mp->delay_wait_checks = mp->mpe->delay_wait_checks;
|
|
|
f20720 |
+ condlog(3, "delay_wait_checks = %i (multipath setting)",
|
|
|
f20720 |
+ mp->delay_wait_checks);
|
|
|
f20720 |
+ return 0;
|
|
|
f20720 |
+ }
|
|
|
f20720 |
+ if (mp->hwe && mp->hwe->delay_wait_checks != DELAY_CHECKS_UNDEF) {
|
|
|
f20720 |
+ mp->delay_wait_checks = mp->hwe->delay_wait_checks;
|
|
|
f20720 |
+ condlog(3, "delay_wait_checks = %i (controler setting)",
|
|
|
f20720 |
+ mp->delay_wait_checks);
|
|
|
f20720 |
+ return 0;
|
|
|
f20720 |
+ }
|
|
|
f20720 |
+ if (conf->delay_wait_checks != DELAY_CHECKS_UNDEF) {
|
|
|
f20720 |
+ mp->delay_wait_checks = conf->delay_wait_checks;
|
|
|
f20720 |
+ condlog(3, "delay_wait_checks = %i (config file default)",
|
|
|
f20720 |
+ mp->delay_wait_checks);
|
|
|
f20720 |
+ return 0;
|
|
|
f20720 |
+ }
|
|
|
f20720 |
+ mp->delay_wait_checks = DEFAULT_DELAY_CHECKS;
|
|
|
f20720 |
+ condlog(3, "delay_wait_checks = DISABLED (internal default)");
|
|
|
f20720 |
+ return 0;
|
|
|
f20720 |
+}
|
|
|
f20720 |
Index: multipath-tools-130222/libmultipath/propsel.h
|
|
|
f20720 |
===================================================================
|
|
|
f20720 |
--- multipath-tools-130222.orig/libmultipath/propsel.h
|
|
|
f20720 |
+++ multipath-tools-130222/libmultipath/propsel.h
|
|
|
f20720 |
@@ -21,3 +21,5 @@ int select_reservation_key(struct multip
|
|
|
f20720 |
int select_retain_hwhandler (struct multipath * mp);
|
|
|
f20720 |
int select_detect_prio(struct path * pp);
|
|
|
f20720 |
int select_deferred_remove(struct multipath *mp);
|
|
|
f20720 |
+int select_delay_watch_checks (struct multipath * mp);
|
|
|
f20720 |
+int select_delay_wait_checks (struct multipath * mp);
|
|
|
f20720 |
Index: multipath-tools-130222/multipathd/main.c
|
|
|
f20720 |
===================================================================
|
|
|
f20720 |
--- multipath-tools-130222.orig/multipathd/main.c
|
|
|
f20720 |
+++ multipath-tools-130222/multipathd/main.c
|
|
|
f20720 |
@@ -188,7 +188,8 @@ sync_map_state(struct multipath *mpp)
|
|
|
f20720 |
vector_foreach_slot (mpp->pg, pgp, i){
|
|
|
f20720 |
vector_foreach_slot (pgp->paths, pp, j){
|
|
|
f20720 |
if (pp->state == PATH_UNCHECKED ||
|
|
|
f20720 |
- pp->state == PATH_WILD)
|
|
|
f20720 |
+ pp->state == PATH_WILD ||
|
|
|
f20720 |
+ pp->state == PATH_DELAYED)
|
|
|
f20720 |
continue;
|
|
|
f20720 |
if ((pp->dmstate == PSTATE_FAILED ||
|
|
|
f20720 |
pp->dmstate == PSTATE_UNDEF) &&
|
|
|
f20720 |
@@ -1165,6 +1166,16 @@ check_path (struct vectors * vecs, struc
|
|
|
f20720 |
if (!pp->mpp)
|
|
|
f20720 |
return;
|
|
|
f20720 |
|
|
|
f20720 |
+ if ((newstate == PATH_UP || newstate == PATH_GHOST) &&
|
|
|
f20720 |
+ pp->wait_checks > 0) {
|
|
|
f20720 |
+ if (pp->mpp && pp->mpp->nr_active > 0) {
|
|
|
f20720 |
+ pp->state = PATH_DELAYED;
|
|
|
f20720 |
+ pp->wait_checks--;
|
|
|
f20720 |
+ return;
|
|
|
f20720 |
+ } else
|
|
|
f20720 |
+ pp->wait_checks = 0;
|
|
|
f20720 |
+ }
|
|
|
f20720 |
+
|
|
|
f20720 |
pp->chkrstate = newstate;
|
|
|
f20720 |
if (newstate != pp->state) {
|
|
|
f20720 |
int oldstate = pp->state;
|
|
|
f20720 |
@@ -1182,9 +1193,14 @@ check_path (struct vectors * vecs, struc
|
|
|
f20720 |
* proactively fail path in the DM
|
|
|
f20720 |
*/
|
|
|
f20720 |
if (oldstate == PATH_UP ||
|
|
|
f20720 |
- oldstate == PATH_GHOST)
|
|
|
f20720 |
+ oldstate == PATH_GHOST) {
|
|
|
f20720 |
fail_path(pp, 1);
|
|
|
f20720 |
- else
|
|
|
f20720 |
+ if (pp->mpp->delay_wait_checks > 0 &&
|
|
|
f20720 |
+ pp->watch_checks > 0) {
|
|
|
f20720 |
+ pp->wait_checks = pp->mpp->delay_wait_checks;
|
|
|
f20720 |
+ pp->watch_checks = 0;
|
|
|
f20720 |
+ }
|
|
|
f20720 |
+ }else
|
|
|
f20720 |
fail_path(pp, 0);
|
|
|
f20720 |
|
|
|
f20720 |
/*
|
|
|
f20720 |
@@ -1211,11 +1227,15 @@ check_path (struct vectors * vecs, struc
|
|
|
f20720 |
* reinstate this path
|
|
|
f20720 |
*/
|
|
|
f20720 |
if (oldstate != PATH_UP &&
|
|
|
f20720 |
- oldstate != PATH_GHOST)
|
|
|
f20720 |
+ oldstate != PATH_GHOST) {
|
|
|
f20720 |
+ if (pp->mpp->delay_watch_checks > 0)
|
|
|
f20720 |
+ pp->watch_checks = pp->mpp->delay_watch_checks;
|
|
|
f20720 |
reinstate_path(pp, 1);
|
|
|
f20720 |
- else
|
|
|
f20720 |
+ } else {
|
|
|
f20720 |
+ if (pp->watch_checks > 0)
|
|
|
f20720 |
+ pp->watch_checks--;
|
|
|
f20720 |
reinstate_path(pp, 0);
|
|
|
f20720 |
-
|
|
|
f20720 |
+ }
|
|
|
f20720 |
new_path_up = 1;
|
|
|
f20720 |
|
|
|
f20720 |
if (oldchkrstate != PATH_UP && oldchkrstate != PATH_GHOST)
|
|
|
f20720 |
@@ -1245,6 +1265,8 @@ check_path (struct vectors * vecs, struc
|
|
|
f20720 |
else
|
|
|
f20720 |
pp->checkint = conf->max_checkint;
|
|
|
f20720 |
}
|
|
|
f20720 |
+ if (pp->watch_checks > 0)
|
|
|
f20720 |
+ pp->watch_checks--;
|
|
|
f20720 |
pp->tick = pp->checkint;
|
|
|
f20720 |
condlog(4, "%s: delay next check %is",
|
|
|
f20720 |
pp->dev_t, pp->tick);
|
|
|
f20720 |
Index: multipath-tools-130222/multipath.conf.annotated
|
|
|
f20720 |
===================================================================
|
|
|
f20720 |
--- multipath-tools-130222.orig/multipath.conf.annotated
|
|
|
f20720 |
+++ multipath-tools-130222/multipath.conf.annotated
|
|
|
f20720 |
@@ -242,6 +242,30 @@
|
|
|
f20720 |
# # files, just as if it was in /etc/multipath.conf
|
|
|
f20720 |
# # values : "" or a fully qualified pathname
|
|
|
f20720 |
# # default : "/etc/multipath/conf.d"
|
|
|
f20720 |
+#
|
|
|
f20720 |
+# #
|
|
|
f20720 |
+# # name : delay_watch_checks
|
|
|
f20720 |
+# # scope : multipathd
|
|
|
f20720 |
+# # desc : If set to a value greater than 0, multipathd will watch
|
|
|
f20720 |
+# # paths that have recently become valid for this many
|
|
|
f20720 |
+# # checks. If they fail again while they are being watched,
|
|
|
f20720 |
+# # when they next become valid, they will not be used until
|
|
|
f20720 |
+# # they have stayed up for delay_wait_checks checks.
|
|
|
f20720 |
+# # values : no|<n> > 0
|
|
|
f20720 |
+# # default : no
|
|
|
f20720 |
+# delay_watch_checks 12
|
|
|
f20720 |
+#
|
|
|
f20720 |
+# #
|
|
|
f20720 |
+# # name : delay_wait_checks
|
|
|
f20720 |
+# # scope : multipathd
|
|
|
f20720 |
+# # desc : If set to a value greater than 0, when a device that has
|
|
|
f20720 |
+# # recently come back online fails again within
|
|
|
f20720 |
+# # delay_watch_checks checks, the next time it comes back
|
|
|
f20720 |
+# # online, it will marked and delayed, and not used until
|
|
|
f20720 |
+# # it has passed delay_wait_checks checks.
|
|
|
f20720 |
+# # values : no|<n> > 0
|
|
|
f20720 |
+# # default : no
|
|
|
f20720 |
+# delay_wait_checks 12
|
|
|
f20720 |
#}
|
|
|
f20720 |
#
|
|
|
f20720 |
##
|
|
|
f20720 |
@@ -383,6 +407,13 @@
|
|
|
f20720 |
# #
|
|
|
f20720 |
# flush_on_last_del yes
|
|
|
f20720 |
#
|
|
|
f20720 |
+# #
|
|
|
f20720 |
+# # name : delay_watch_checks
|
|
|
f20720 |
+# # See defualts section for information.
|
|
|
f20720 |
+#
|
|
|
f20720 |
+# #
|
|
|
f20720 |
+# # name : delay_wait_checks
|
|
|
f20720 |
+# # See defualts section for information.
|
|
|
f20720 |
# }
|
|
|
f20720 |
# multipath {
|
|
|
f20720 |
# wwid 1DEC_____321816758474
|
|
|
f20720 |
@@ -566,6 +597,15 @@
|
|
|
f20720 |
# # before removing it from the system.
|
|
|
f20720 |
# # values : n > 0
|
|
|
f20720 |
# dev_loss_tmo 600
|
|
|
f20720 |
+#
|
|
|
f20720 |
+# #
|
|
|
f20720 |
+# # name : delay_watch_checks
|
|
|
f20720 |
+# # See defaults section for information.
|
|
|
f20720 |
+#
|
|
|
f20720 |
+# #
|
|
|
f20720 |
+# # name : delay_wait_checks
|
|
|
f20720 |
+# # See defaults section for information.
|
|
|
f20720 |
+#
|
|
|
f20720 |
# }
|
|
|
f20720 |
# device {
|
|
|
f20720 |
# vendor "COMPAQ "
|
|
|
f20720 |
Index: multipath-tools-130222/multipath.conf.defaults
|
|
|
f20720 |
===================================================================
|
|
|
f20720 |
--- multipath-tools-130222.orig/multipath.conf.defaults
|
|
|
f20720 |
+++ multipath-tools-130222/multipath.conf.defaults
|
|
|
f20720 |
@@ -27,6 +27,8 @@
|
|
|
f20720 |
# retain_attached_hw_handler no
|
|
|
f20720 |
# detect_prio no
|
|
|
f20720 |
# config_dir "/etc/multipath/conf.d"
|
|
|
f20720 |
+# delay_watch_checks no
|
|
|
f20720 |
+# delay_wait_checks no
|
|
|
f20720 |
#}
|
|
|
f20720 |
#blacklist {
|
|
|
f20720 |
# devnode "^(ram|raw|loop|fd|md|dm-|sr|scd|st)[0-9]*"
|
|
|
f20720 |
Index: multipath-tools-130222/multipath/multipath.conf.5
|
|
|
f20720 |
===================================================================
|
|
|
f20720 |
--- multipath-tools-130222.orig/multipath/multipath.conf.5
|
|
|
f20720 |
+++ multipath-tools-130222/multipath/multipath.conf.5
|
|
|
f20720 |
@@ -459,6 +459,25 @@ alphabetically for file ending in ".conf
|
|
|
f20720 |
information from them, just as if it was in /etc/multipath.conf. config_dir
|
|
|
f20720 |
must either be "" or a fully qualified directory name. Default is
|
|
|
f20720 |
.I "/etc/multipath/conf.d"
|
|
|
f20720 |
+.TP
|
|
|
f20720 |
+.B delay_watch_checks
|
|
|
f20720 |
+If set to a value greater than 0, multipathd will watch paths that have
|
|
|
f20720 |
+recently become valid for this many checks. If they fail again while they are
|
|
|
f20720 |
+being watched, when they next become valid, they will not be used until they
|
|
|
f20720 |
+have stayed up for
|
|
|
f20720 |
+.I delay_wait_checks
|
|
|
f20720 |
+checks. Default is
|
|
|
f20720 |
+.I no
|
|
|
f20720 |
+.TP
|
|
|
f20720 |
+.B delay_wait_checks
|
|
|
f20720 |
+If set to a value greater than 0, when a device that has recently come back
|
|
|
f20720 |
+online fails again within
|
|
|
f20720 |
+.I delay_watch_checks
|
|
|
f20720 |
+checks, the next time it comes back online, it will marked and delayed, and not
|
|
|
f20720 |
+used until it has passed
|
|
|
f20720 |
+.I delay_wait_checks
|
|
|
f20720 |
+checks. Default is
|
|
|
f20720 |
+.I no
|
|
|
f20720 |
.
|
|
|
f20720 |
.SH "blacklist section"
|
|
|
f20720 |
The
|
|
|
f20720 |
@@ -562,6 +581,10 @@ section:
|
|
|
f20720 |
.B reservation_key
|
|
|
f20720 |
.TP
|
|
|
f20720 |
.B deferred_remove
|
|
|
f20720 |
+.TP
|
|
|
f20720 |
+.B delay_watch_checks
|
|
|
f20720 |
+.TP
|
|
|
f20720 |
+.B delay_wait_checks
|
|
|
f20720 |
.RE
|
|
|
f20720 |
.PD
|
|
|
f20720 |
.LP
|
|
|
f20720 |
@@ -654,6 +677,10 @@ section:
|
|
|
f20720 |
.B detect_prio
|
|
|
f20720 |
.TP
|
|
|
f20720 |
.B deferred_remove
|
|
|
f20720 |
+.TP
|
|
|
f20720 |
+.B delay_watch_checks
|
|
|
f20720 |
+.TP
|
|
|
f20720 |
+.B delay_wait_checks
|
|
|
f20720 |
.RE
|
|
|
f20720 |
.PD
|
|
|
f20720 |
.LP
|
|
|
f20720 |
Index: multipath-tools-130222/libmultipath/checkers.c
|
|
|
f20720 |
===================================================================
|
|
|
f20720 |
--- multipath-tools-130222.orig/libmultipath/checkers.c
|
|
|
f20720 |
+++ multipath-tools-130222/libmultipath/checkers.c
|
|
|
f20720 |
@@ -16,7 +16,8 @@ char *checker_state_names[] = {
|
|
|
f20720 |
"up",
|
|
|
f20720 |
"shaky",
|
|
|
f20720 |
"ghost",
|
|
|
f20720 |
- "pending"
|
|
|
f20720 |
+ "pending",
|
|
|
f20720 |
+ "delayed"
|
|
|
f20720 |
};
|
|
|
f20720 |
|
|
|
f20720 |
static LIST_HEAD(checkers);
|
|
|
f20720 |
Index: multipath-tools-130222/libmultipath/config.c
|
|
|
f20720 |
===================================================================
|
|
|
f20720 |
--- multipath-tools-130222.orig/libmultipath/config.c
|
|
|
f20720 |
+++ multipath-tools-130222/libmultipath/config.c
|
|
|
f20720 |
@@ -341,6 +341,8 @@ merge_hwe (struct hwentry * dst, struct
|
|
|
f20720 |
merge_num(retain_hwhandler);
|
|
|
f20720 |
merge_num(detect_prio);
|
|
|
f20720 |
merge_num(deferred_remove);
|
|
|
f20720 |
+ merge_num(delay_watch_checks);
|
|
|
f20720 |
+ merge_num(delay_wait_checks);
|
|
|
f20720 |
|
|
|
f20720 |
/*
|
|
|
f20720 |
* Make sure features is consistent with
|
|
|
f20720 |
@@ -399,6 +401,8 @@ overwrite_hwe (struct hwentry * dst, str
|
|
|
f20720 |
overwrite_num(retain_hwhandler);
|
|
|
f20720 |
overwrite_num(detect_prio);
|
|
|
f20720 |
overwrite_num(deferred_remove);
|
|
|
f20720 |
+ overwrite_num(delay_watch_checks);
|
|
|
f20720 |
+ overwrite_num(delay_wait_checks);
|
|
|
f20720 |
|
|
|
f20720 |
/*
|
|
|
f20720 |
* Make sure features is consistent with
|