device-mapper-multipath-0.4.9-75

Add 0111-RH-dont-show-pg-timeout.patch
  * The kernel doesn't support pg_timeout, so multipath shouldn't
    bother to display it
Add 0112-RHBZ-1194917-add-config_dir-option.patch
  * multipath will now also read its configuration from files with
    the .conf suffix in the directory specified by config_dir
    which defaults to /etc/multipath/conf.d
Add 0113-RHBZ-1194917-cleanup.patch
  * cleanup some unnecessary code
Add 0114-RHBZ-1196394-delayed-reintegration.patch
  * Add "delay_watch_checks" and "delay_wait_checks" options to delay
    reintegration of flakey paths.
Add 0115-RHBZ-1198418-fix-double-free.patch
  * multipath was freeing the multipath alias twice if it failed to create the
    multipath device.
Add 0116-UPBZ-1188179-dell-36xxi.patch
  * new builtin configurations.
Add 0117-RHBZ-1198424-autodetect-clariion-alua.patch
  * configure multipath to automatically detect alua settings on clariion
    devices.
This commit is contained in:
Benjamin Marzinski 2015-03-11 20:40:47 -05:00
parent f3b1b79f2b
commit 3f562fdb0b
8 changed files with 1871 additions and 1 deletions

View File

@ -0,0 +1,147 @@
---
libmultipath/dict.c | 97 ----------------------------------------------------
1 file changed, 97 deletions(-)
Index: multipath-tools-130222/libmultipath/dict.c
===================================================================
--- multipath-tools-130222.orig/libmultipath/dict.c
+++ multipath-tools-130222/libmultipath/dict.c
@@ -473,26 +473,6 @@ def_checker_timeout_handler(vector strve
static int
def_pg_timeout_handler(vector strvec)
{
- int pg_timeout;
- char * buff;
-
- buff = set_value(strvec);
-
- if (!buff)
- return 1;
-
- if (strlen(buff) == 4 && !strcmp(buff, "none"))
- conf->pg_timeout = -PGTIMEOUT_NONE;
- else if (sscanf(buff, "%d", &pg_timeout) == 1 && pg_timeout >= 0) {
- if (pg_timeout == 0)
- conf->pg_timeout = -PGTIMEOUT_NONE;
- else
- conf->pg_timeout = pg_timeout;
- }
- else
- conf->pg_timeout = PGTIMEOUT_UNDEF;
-
- FREE(buff);
return 0;
}
@@ -1358,30 +1338,6 @@ hw_minio_rq_handler(vector strvec)
static int
hw_pg_timeout_handler(vector strvec)
{
- int pg_timeout;
- struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable);
- char *buff;
-
- if (!hwe)
- return 1;
-
- buff = set_value(strvec);
-
- if (!buff)
- return 1;
-
- if (strlen(buff) == 4 && !strcmp(buff, "none"))
- hwe->pg_timeout = -PGTIMEOUT_NONE;
- else if (sscanf(buff, "%d", &pg_timeout) == 1 && pg_timeout >= 0) {
- if (pg_timeout == 0)
- hwe->pg_timeout = -PGTIMEOUT_NONE;
- else
- hwe->pg_timeout = pg_timeout;
- }
- else
- hwe->pg_timeout = PGTIMEOUT_UNDEF;
-
- FREE(buff);
return 0;
}
@@ -1819,29 +1775,6 @@ mp_minio_rq_handler(vector strvec)
static int
mp_pg_timeout_handler(vector strvec)
{
- int pg_timeout;
- struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
- char *buff;
-
- if (!mpe)
- return 1;
-
- buff = set_value(strvec);
-
- if (!buff)
- return 1;
- if (strlen(buff) == 4 && !strcmp(buff, "none"))
- mpe->pg_timeout = -PGTIMEOUT_NONE;
- else if (sscanf(buff, "%d", &pg_timeout) == 1 && pg_timeout >= 0) {
- if (pg_timeout == 0)
- mpe->pg_timeout = -PGTIMEOUT_NONE;
- else
- mpe->pg_timeout = pg_timeout;
- }
- else
- mpe->pg_timeout = PGTIMEOUT_UNDEF;
-
- FREE(buff);
return 0;
}
@@ -2180,16 +2113,6 @@ snprint_mp_rr_min_io_rq (char * buff, in
static int
snprint_mp_pg_timeout (char * buff, int len, void * data)
{
- struct mpentry * mpe = (struct mpentry *)data;
-
- switch (mpe->pg_timeout) {
- case PGTIMEOUT_UNDEF:
- break;
- case -PGTIMEOUT_NONE:
- return snprintf(buff, len, "\"none\"");
- default:
- return snprintf(buff, len, "%i", mpe->pg_timeout);
- }
return 0;
}
@@ -2551,19 +2474,6 @@ snprint_hw_rr_min_io_rq (char * buff, in
static int
snprint_hw_pg_timeout (char * buff, int len, void * data)
{
- struct hwentry * hwe = (struct hwentry *)data;
-
- if (!hwe->pg_timeout)
- return 0;
-
- switch (hwe->pg_timeout) {
- case PGTIMEOUT_UNDEF:
- break;
- case -PGTIMEOUT_NONE:
- return snprintf(buff, len, "\"none\"");
- default:
- return snprintf(buff, len, "%i", hwe->pg_timeout);
- }
return 0;
}
@@ -2895,13 +2805,6 @@ snprint_def_checker_timeout (char *buff,
static int
snprint_def_pg_timeout (char * buff, int len, void * data)
{
- switch (conf->pg_timeout) {
- case PGTIMEOUT_UNDEF:
- case -PGTIMEOUT_NONE:
- return snprintf(buff, len, "\"none\"");
- default:
- return snprintf(buff, len, "%i", conf->pg_timeout);
- }
return 0;
}

View File

@ -0,0 +1,616 @@
---
libmultipath/config.c | 56 +++++++++++++++++++++++++++++++-
libmultipath/config.h | 2 +
libmultipath/defaults.h | 1
libmultipath/dict.c | 69 +++++++++++++++++++++++++++++++++++----
libmultipath/parser.c | 78 +++++++++++++++++++++++----------------------
libmultipath/parser.h | 3 -
multipath.conf.annotated | 10 +++++
multipath.conf.defaults | 1
multipath/multipath.conf.5 | 7 ++++
9 files changed, 179 insertions(+), 48 deletions(-)
Index: multipath-tools-130222/libmultipath/parser.c
===================================================================
--- multipath-tools-130222.orig/libmultipath/parser.c
+++ multipath-tools-130222/libmultipath/parser.c
@@ -18,6 +18,7 @@
*/
#include <syslog.h>
+#include <errno.h>
#include "parser.h"
#include "memory.h"
@@ -453,14 +454,15 @@ set_value(vector strvec)
/* non-recursive configuration stream handler */
static int kw_level = 0;
-int warn_on_duplicates(vector uniques, char *str)
+int warn_on_duplicates(vector uniques, char *str, char *file)
{
char *tmp;
int i;
vector_foreach_slot(uniques, tmp, i) {
if (!strcmp(str, tmp)) {
- condlog(1, "multipath.conf line %d, duplicate keyword: %s", line_nr, str);
+ condlog(1, "%s line %d, duplicate keyword: %s",
+ file, line_nr, str);
return 0;
}
}
@@ -496,65 +498,70 @@ is_sublevel_keyword(char *str)
}
int
-validate_config_strvec(vector strvec)
+validate_config_strvec(vector strvec, char *file)
{
char *str;
int i;
str = VECTOR_SLOT(strvec, 0);
if (str == NULL) {
- condlog(0, "can't parse option on line %d of config file",
- line_nr);
+ condlog(0, "can't parse option on line %d of %s",
+ line_nr, file);
return -1;
}
if (*str == '}') {
if (VECTOR_SIZE(strvec) > 1)
- condlog(0, "ignoring extra data starting with '%s' on line %d of config file", (char *)VECTOR_SLOT(strvec, 1), line_nr);
+ condlog(0, "ignoring extra data starting with '%s' on line %d of %s", (char *)VECTOR_SLOT(strvec, 1), line_nr, file);
return 0;
}
if (*str == '{') {
- condlog(0, "invalid keyword '%s' on line %d of config file", str, line_nr);
+ condlog(0, "invalid keyword '%s' on line %d of %s",
+ str, line_nr, file);
return -1;
}
if (is_sublevel_keyword(str)) {
str = VECTOR_SLOT(strvec, 1);
if (str == NULL)
- condlog(0, "missing '{' on line %d of config file", line_nr);
+ condlog(0, "missing '{' on line %d of %s",
+ line_nr, file);
else if (*str != '{')
- condlog(0, "expecting '{' on line %d of config file. found '%s'", line_nr, str);
+ condlog(0, "expecting '{' on line %d of %s. found '%s'",
+ line_nr, file, str);
else if (VECTOR_SIZE(strvec) > 2)
- condlog(0, "ignoring extra data starting with '%s' on line %d of config file", (char *)VECTOR_SLOT(strvec, 2), line_nr);
+ condlog(0, "ignoring extra data starting with '%s' on line %d of %s", (char *)VECTOR_SLOT(strvec, 2), line_nr, file);
return 0;
}
str = VECTOR_SLOT(strvec, 1);
if (str == NULL) {
- condlog(0, "missing value for option '%s' on line %d of config file", (char *)VECTOR_SLOT(strvec, 0), line_nr);
+ condlog(0, "missing value for option '%s' on line %d of %s",
+ (char *)VECTOR_SLOT(strvec, 0), line_nr, file);
return -1;
}
if (*str != '"') {
if (VECTOR_SIZE(strvec) > 2)
- condlog(0, "ignoring extra data starting with '%s' on line %d of config file", (char *)VECTOR_SLOT(strvec, 2), line_nr);
+ condlog(0, "ignoring extra data starting with '%s' on line %d of %s", (char *)VECTOR_SLOT(strvec, 2), line_nr, file);
return 0;
}
for (i = 2; i < VECTOR_SIZE(strvec); i++) {
str = VECTOR_SLOT(strvec, i);
if (str == NULL) {
- condlog(0, "can't parse value on line %d of config file", line_nr);
+ condlog(0, "can't parse value on line %d of %s",
+ line_nr, file);
return -1;
}
if (*str == '"') {
if (VECTOR_SIZE(strvec) > i + 1)
- condlog(0, "ignoring extra data starting with '%s' on line %d of config file", (char *)VECTOR_SLOT(strvec, (i + 1)), line_nr);
+ condlog(0, "ignoring extra data starting with '%s' on line %d of %s", (char *)VECTOR_SLOT(strvec, (i + 1)), line_nr, file);
return 0;
}
}
- condlog(0, "missing closing quotes on line %d of config file",
- line_nr);
+ condlog(0, "missing closing quotes on line %d of %s",
+ line_nr, file);
return 0;
}
-int
-process_stream(vector keywords)
+static int
+process_stream(vector keywords, char *file)
{
int i;
int r = 0;
@@ -583,7 +590,7 @@ process_stream(vector keywords)
if (!strvec)
continue;
- if (validate_config_strvec(strvec) != 0) {
+ if (validate_config_strvec(strvec, file) != 0) {
free_strvec(strvec);
continue;
}
@@ -595,8 +602,8 @@ process_stream(vector keywords)
free_strvec(strvec);
break;
}
- condlog(0, "unmatched '%s' at line %d of config file",
- EOB, line_nr);
+ condlog(0, "unmatched '%s' at line %d of %s",
+ EOB, line_nr, file);
}
for (i = 0; i < VECTOR_SIZE(keywords); i++) {
@@ -604,7 +611,7 @@ process_stream(vector keywords)
if (!strcmp(keyword->string, str)) {
if (keyword->unique &&
- warn_on_duplicates(uniques, str)) {
+ warn_on_duplicates(uniques, str, file)) {
r = 1;
free_strvec(strvec);
goto out;
@@ -614,15 +621,15 @@ process_stream(vector keywords)
if (keyword->sub) {
kw_level++;
- r += process_stream(keyword->sub);
+ r += process_stream(keyword->sub, file);
kw_level--;
}
break;
}
}
if (i >= VECTOR_SIZE(keywords))
- condlog(1, "multipath.conf +%d, invalid keyword: %s",
- line_nr, str);
+ condlog(1, "%s line %d, invalid keyword: %s",
+ file, line_nr, str);
free_strvec(strvec);
}
@@ -646,27 +653,24 @@ int alloc_keywords(void)
/* Data initialization */
int
-init_data(char *conf_file, void (*init_keywords) (void))
+process_file(char *file)
{
int r;
- stream = fopen(conf_file, "r");
+ if (!keywords) {
+ condlog(0, "No keywords alocated");
+ return 1;
+ }
+ stream = fopen(file, "r");
if (!stream) {
- syslog(LOG_WARNING, "Configuration file open problem");
+ condlog(0, "couldn't open configuration file '%s': %s",
+ file, strerror(errno));
return 1;
}
- /* Init Keywords structure */
- (*init_keywords) ();
-
-/* Dump configuration *
- vector_dump(keywords);
- dump_keywords(keywords, 0);
-*/
-
/* Stream handling */
line_nr = 0;
- r = process_stream(keywords);
+ r = process_stream(keywords, file);
fclose(stream);
//free_keywords(keywords);
Index: multipath-tools-130222/libmultipath/dict.c
===================================================================
--- multipath-tools-130222.orig/libmultipath/dict.c
+++ multipath-tools-130222/libmultipath/dict.c
@@ -117,6 +117,8 @@ reassign_maps_handler(vector strvec)
static int
multipath_dir_handler(vector strvec)
{
+ if (conf->multipath_dir)
+ FREE(conf->multipath_dir);
conf->multipath_dir = set_value(strvec);
if (!conf->multipath_dir)
@@ -128,6 +130,8 @@ multipath_dir_handler(vector strvec)
static int
def_selector_handler(vector strvec)
{
+ if (conf->selector)
+ FREE(conf->selector);
conf->selector = set_value(strvec);
if (!conf->selector)
@@ -155,6 +159,8 @@ def_pgpolicy_handler(vector strvec)
static int
def_uid_attribute_handler(vector strvec)
{
+ if (conf->uid_attribute)
+ FREE(conf->uid_attribute);
conf->uid_attribute = set_value(strvec);
if (!conf->uid_attribute)
@@ -166,6 +172,8 @@ def_uid_attribute_handler(vector strvec)
static int
def_prio_handler(vector strvec)
{
+ if (conf->prio_name)
+ FREE(conf->prio_name);
conf->prio_name = set_value(strvec);
if (!conf->prio_name)
@@ -177,6 +185,8 @@ def_prio_handler(vector strvec)
static int
def_alias_prefix_handler(vector strvec)
{
+ if (conf->alias_prefix)
+ FREE(conf->alias_prefix);
conf->alias_prefix = set_value(strvec);
if (!conf->alias_prefix)
@@ -188,6 +198,8 @@ def_alias_prefix_handler(vector strvec)
static int
def_prio_args_handler(vector strvec)
{
+ if (conf->prio_args)
+ FREE(conf->prio_args);
conf->prio_args = set_value(strvec);
if (!conf->prio_args)
@@ -199,6 +211,8 @@ def_prio_args_handler(vector strvec)
static int
def_features_handler(vector strvec)
{
+ if (conf->features)
+ FREE(conf->features);
conf->features = set_value(strvec);
if (!conf->features)
@@ -210,6 +224,8 @@ def_features_handler(vector strvec)
static int
def_path_checker_handler(vector strvec)
{
+ if (conf->checker_name)
+ FREE(conf->checker_name);
conf->checker_name = set_value(strvec);
if (!conf->checker_name)
@@ -432,6 +448,23 @@ def_no_path_retry_handler(vector strvec)
return 0;
}
+
+static int
+def_config_dir_handler(vector strvec)
+{
+ /* this is only valid in the main config file */
+ if (conf->processed_main_config)
+ return 0;
+ if (conf->config_dir)
+ FREE(conf->config_dir);
+ conf->config_dir = set_value(strvec);
+
+ if (!conf->config_dir)
+ return 1;
+
+ return 0;
+}
+
static int
def_queue_without_daemon(vector strvec)
{
@@ -611,6 +644,8 @@ def_names_handler(vector strvec)
static int
bindings_file_handler(vector strvec)
{
+ if (conf->bindings_file)
+ FREE(conf->bindings_file);
conf->bindings_file = set_value(strvec);
if (!conf->bindings_file)
@@ -622,6 +657,8 @@ bindings_file_handler(vector strvec)
static int
wwids_file_handler(vector strvec)
{
+ if (conf->wwids_file)
+ FREE(conf->wwids_file);
conf->wwids_file = set_value(strvec);
if (!conf->wwids_file)
@@ -770,9 +807,12 @@ def_ignore_new_boot_devs_handler(vector
static int
blacklist_handler(vector strvec)
{
- conf->blist_devnode = vector_alloc();
- conf->blist_wwid = vector_alloc();
- conf->blist_device = vector_alloc();
+ if (!conf->blist_devnode)
+ conf->blist_devnode = vector_alloc();
+ if (!conf->blist_wwid)
+ conf->blist_wwid = vector_alloc();
+ if (!conf->blist_device)
+ conf->blist_device = vector_alloc();
if (!conf->blist_devnode || !conf->blist_wwid || !conf->blist_device)
return 1;
@@ -783,9 +823,12 @@ blacklist_handler(vector strvec)
static int
blacklist_exceptions_handler(vector strvec)
{
- conf->elist_devnode = vector_alloc();
- conf->elist_wwid = vector_alloc();
- conf->elist_device = vector_alloc();
+ if (!conf->elist_devnode)
+ conf->elist_devnode = vector_alloc();
+ if (!conf->elist_wwid)
+ conf->elist_wwid = vector_alloc();
+ if (!conf->elist_device)
+ conf->elist_device = vector_alloc();
if (!conf->elist_devnode || !conf->elist_wwid || !conf->elist_device)
return 1;
@@ -1480,7 +1523,8 @@ hw_deferred_remove_handler(vector strvec
static int
multipaths_handler(vector strvec)
{
- conf->mptable = vector_alloc();
+ if (!conf->mptable)
+ conf->mptable = vector_alloc();
if (!conf->mptable)
return 1;
@@ -2945,6 +2989,16 @@ snprint_def_ignore_new_boot_devs(char *
return snprintf(buff, len, "no");
}
+
+static int
+snprint_def_config_dir (char * buff, int len, void * data)
+{
+ if (!conf->config_dir)
+ return 0;
+
+ return snprintf(buff, len, "\"%s\"", conf->config_dir);
+}
+
static int
snprint_ble_simple (char * buff, int len, void * data)
{
@@ -3016,6 +3070,7 @@ init_keywords(void)
install_keyword("force_sync", &def_force_sync_handler, &snprint_def_force_sync);
install_keyword("deferred_remove", &def_deferred_remove_handler, &snprint_def_deferred_remove);
install_keyword("ignore_new_boot_devs", &def_ignore_new_boot_devs_handler, &snprint_def_ignore_new_boot_devs);
+ install_keyword("config_dir", &def_config_dir_handler, &snprint_def_config_dir);
__deprecated install_keyword("default_selector", &def_selector_handler, NULL);
__deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL);
__deprecated install_keyword("default_uid_attribute", &def_uid_attribute_handler, NULL);
Index: multipath-tools-130222/libmultipath/parser.h
===================================================================
--- multipath-tools-130222.orig/libmultipath/parser.h
+++ multipath-tools-130222/libmultipath/parser.h
@@ -76,9 +76,8 @@ extern int read_line(char *buf, int size
extern vector read_value_block(void);
extern int alloc_value_block(vector strvec, void (*alloc_func) (vector));
extern void *set_value(vector strvec);
-extern int process_stream(vector keywords);
extern int alloc_keywords(void);
-extern int init_data(char *conf_file, void (*init_keywords) (void));
+extern int process_file(char *conf_file);
extern struct keyword * find_keyword(vector v, char * name);
void set_current_keywords (vector *k);
int snprint_keyword(char *buff, int len, char *fmt, struct keyword *kw,
Index: multipath-tools-130222/libmultipath/config.c
===================================================================
--- multipath-tools-130222.orig/libmultipath/config.c
+++ multipath-tools-130222/libmultipath/config.c
@@ -6,6 +6,9 @@
#include <stdio.h>
#include <string.h>
#include <libudev.h>
+#include <dirent.h>
+#include <limits.h>
+#include <errno.h>
#include "checkers.h"
#include "memory.h"
@@ -556,6 +559,7 @@ free_config (struct config * conf)
if (conf->wwids_file)
FREE(conf->wwids_file);
+
if (conf->prio_name)
FREE(conf->prio_name);
@@ -567,6 +571,10 @@ free_config (struct config * conf)
if (conf->checker_name)
FREE(conf->checker_name);
+
+ if (conf->config_dir)
+ FREE(conf->config_dir);
+
if (conf->reservation_key)
FREE(conf->reservation_key);
@@ -584,6 +592,43 @@ free_config (struct config * conf)
FREE(conf);
}
+/* if multipath fails to process the config directory, it should continue,
+ * with just a warning message */
+static void
+process_config_dir(vector keywords, char *dir)
+{
+ struct dirent **namelist;
+ int i, n;
+ char path[LINE_MAX];
+ int old_hwtable_size;
+
+ if (dir[0] != '/') {
+ condlog(1, "config_dir '%s' must be a fully qualified path",
+ dir);
+ return;
+ }
+ n = scandir(dir, &namelist, NULL, alphasort);
+ if (n < 0) {
+ if (errno == ENOENT)
+ condlog(3, "No configuration dir '%s'", dir);
+ else
+ condlog(0, "couldn't open configuration dir '%s': %s",
+ dir, strerror(errno));
+ return;
+ }
+ for (i = 0; i < n; i++) {
+ if (!strstr(namelist[i]->d_name, ".conf"))
+ continue;
+ old_hwtable_size = VECTOR_SIZE(conf->hwtable);
+ snprintf(path, LINE_MAX, "%s/%s", dir, namelist[i]->d_name);
+ path[LINE_MAX-1] = '\0';
+ process_file(path);
+ if (VECTOR_SIZE(conf->hwtable) > old_hwtable_size)
+ factorize_hwtable(conf->hwtable, old_hwtable_size);
+
+ }
+}
+
int
load_config (char * file, struct udev *udev)
{
@@ -623,6 +668,7 @@ load_config (char * file, struct udev *u
conf->hw_strmatch = 0;
conf->force_sync = 0;
conf->ignore_new_boot_devs = 0;
+ conf->processed_main_config = 0;
/*
* preload default hwtable
@@ -641,11 +687,12 @@ load_config (char * file, struct udev *u
*/
set_current_keywords(&conf->keywords);
alloc_keywords();
+ init_keywords();
if (filepresent(file)) {
int builtin_hwtable_size;
builtin_hwtable_size = VECTOR_SIZE(conf->hwtable);
- if (init_data(file, init_keywords)) {
+ if (process_file(file)) {
condlog(0, "error parsing config file");
goto out;
}
@@ -658,7 +705,6 @@ load_config (char * file, struct udev *u
}
} else {
- init_keywords();
condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices.");
condlog(0, "A default multipath.conf file is located at");
condlog(0, "/usr/share/doc/device-mapper-multipath-%d.%d.%d/multipath.conf", MULTIPATH_VERSION(VERSION_CODE));
@@ -677,6 +723,12 @@ load_config (char * file, struct udev *u
}
}
+ conf->processed_main_config = 1;
+ if (conf->config_dir == NULL)
+ conf->config_dir = set_default(DEFAULT_CONFIG_DIR);
+ if (conf->config_dir && conf->config_dir[0] != '\0')
+ process_config_dir(conf->keywords, conf->config_dir);
+
/*
* fill the voids left in the config file
*/
Index: multipath-tools-130222/libmultipath/config.h
===================================================================
--- multipath-tools-130222.orig/libmultipath/config.h
+++ multipath-tools-130222/libmultipath/config.h
@@ -132,6 +132,7 @@ struct config {
int force_sync;
int deferred_remove;
int ignore_new_boot_devs;
+ int processed_main_config;
unsigned int version[3];
char * dev;
@@ -147,6 +148,7 @@ struct config {
char * prio_args;
char * checker_name;
char * alias_prefix;
+ char * config_dir;
unsigned char * reservation_key;
vector keywords;
Index: multipath-tools-130222/libmultipath/defaults.h
===================================================================
--- multipath-tools-130222.orig/libmultipath/defaults.h
+++ multipath-tools-130222/libmultipath/defaults.h
@@ -31,5 +31,6 @@
#define DEFAULT_CONFIGFILE "/etc/multipath.conf"
#define DEFAULT_BINDINGS_FILE "/etc/multipath/bindings"
#define DEFAULT_WWIDS_FILE "/etc/multipath/wwids"
+#define DEFAULT_CONFIG_DIR "/etc/multipath/conf.d"
char * set_default (char * str);
Index: multipath-tools-130222/multipath.conf.annotated
===================================================================
--- multipath-tools-130222.orig/multipath.conf.annotated
+++ multipath-tools-130222/multipath.conf.annotated
@@ -232,6 +232,16 @@
# # values : yes|no
# # default : no
# force_sync yes
+#
+# #
+# # name : config_dir
+# # scope : multipath & multipathd
+# # desc : If not set to an empty string, multipath will search
+# # this directory alphabetically for files ending in ".conf"
+# # and it will read configuration information from these
+# # files, just as if it was in /etc/multipath.conf
+# # values : "" or a fully qualified pathname
+# # default : "/etc/multipath/conf.d"
#}
#
##
Index: multipath-tools-130222/multipath.conf.defaults
===================================================================
--- multipath-tools-130222.orig/multipath.conf.defaults
+++ multipath-tools-130222/multipath.conf.defaults
@@ -26,6 +26,7 @@
# log_checker_err always
# retain_attached_hw_handler no
# detect_prio no
+# config_dir "/etc/multipath/conf.d"
#}
#blacklist {
# devnode "^(ram|raw|loop|fd|md|dm-|sr|scd|st)[0-9]*"
Index: multipath-tools-130222/multipath/multipath.conf.5
===================================================================
--- multipath-tools-130222.orig/multipath/multipath.conf.5
+++ multipath-tools-130222/multipath/multipath.conf.5
@@ -430,6 +430,13 @@ still in use, it will be freed when the
to the multipath device before the last user closes it, the deferred remove
will be canceled. Default is
.I no
+.TP
+.B config_dir
+If set to anything other than "", multipath will search this directory
+alphabetically for file ending in ".conf" and it will read configuration
+information from them, just as if it was in /etc/multipath.conf. config_dir
+must either be "" or a fully qualified directory name. Default is
+.I "/etc/multipath/conf.d"
.
.SH "blacklist section"
The

View File

@ -0,0 +1,185 @@
---
libmultipath/parser.c | 103 +++-----------------------------------------------
libmultipath/parser.h | 6 --
2 files changed, 8 insertions(+), 101 deletions(-)
Index: multipath-tools-130222/libmultipath/parser.c
===================================================================
--- multipath-tools-130222.orig/libmultipath/parser.c
+++ multipath-tools-130222/libmultipath/parser.c
@@ -280,8 +280,8 @@ out:
return NULL;
}
-int
-read_line(char *buf, int size)
+static int
+read_line(FILE *stream, char *buf, int size)
{
int ch;
int count = 0;
@@ -297,95 +297,6 @@ read_line(char *buf, int size)
return (ch == EOF) ? 0 : 1;
}
-vector
-read_value_block(void)
-{
- char *buf;
- int i;
- char *str = NULL;
- char *dup;
- vector vec = NULL;
- vector elements = vector_alloc();
-
- if (!elements)
- return NULL;
-
- buf = (char *) MALLOC(MAXBUF);
-
- if (!buf) {
- vector_free(elements);
- return NULL;
- }
-
- while (read_line(buf, MAXBUF)) {
- vec = alloc_strvec(buf);
- if (vec) {
- str = VECTOR_SLOT(vec, 0);
- if (!strcmp(str, EOB)) {
- free_strvec(vec);
- break;
- }
-
- for (i = 0; i < VECTOR_SIZE(vec); i++) {
- str = VECTOR_SLOT(vec, i);
- dup = (char *) MALLOC(strlen(str) + 1);
- if (!dup)
- goto out;
- memcpy(dup, str, strlen(str));
-
- if (!vector_alloc_slot(elements)) {
- free_strvec(vec);
- goto out1;
- }
-
- vector_set_slot(elements, dup);
- }
- free_strvec(vec);
- }
- memset(buf, 0, MAXBUF);
- }
- FREE(buf);
- return elements;
-out1:
- FREE(dup);
-out:
- FREE(buf);
- vector_free(elements);
- return NULL;
-}
-
-int
-alloc_value_block(vector strvec, void (*alloc_func) (vector))
-{
- char *buf;
- char *str = NULL;
- vector vec = NULL;
-
- buf = (char *) MALLOC(MAXBUF);
-
- if (!buf)
- return 1;
-
- while (read_line(buf, MAXBUF)) {
- vec = alloc_strvec(buf);
- if (vec) {
- str = VECTOR_SLOT(vec, 0);
- if (!strcmp(str, EOB)) {
- free_strvec(vec);
- break;
- }
-
- if (VECTOR_SIZE(vec))
- (*alloc_func) (vec);
-
- free_strvec(vec);
- }
- memset(buf, 0, MAXBUF);
- }
- FREE(buf);
- return 0;
-}
-
void *
set_value(vector strvec)
{
@@ -561,7 +472,7 @@ validate_config_strvec(vector strvec, ch
}
static int
-process_stream(vector keywords, char *file)
+process_stream(FILE *stream, vector keywords, char *file)
{
int i;
int r = 0;
@@ -582,7 +493,7 @@ process_stream(vector keywords, char *fi
return 1;
}
- while (read_line(buf, MAXBUF)) {
+ while (read_line(stream, buf, MAXBUF)) {
line_nr++;
strvec = alloc_strvec(buf);
memset(buf,0, MAXBUF);
@@ -621,7 +532,8 @@ process_stream(vector keywords, char *fi
if (keyword->sub) {
kw_level++;
- r += process_stream(keyword->sub, file);
+ r += process_stream(stream,
+ keyword->sub, file);
kw_level--;
}
break;
@@ -656,6 +568,7 @@ int
process_file(char *file)
{
int r;
+ FILE *stream;
if (!keywords) {
condlog(0, "No keywords alocated");
@@ -670,7 +583,7 @@ process_file(char *file)
/* Stream handling */
line_nr = 0;
- r = process_stream(keywords, file);
+ r = process_stream(stream, keywords, file);
fclose(stream);
//free_keywords(keywords);
Index: multipath-tools-130222/libmultipath/parser.h
===================================================================
--- multipath-tools-130222.orig/libmultipath/parser.h
+++ multipath-tools-130222/libmultipath/parser.h
@@ -47,9 +47,6 @@ struct keyword {
int unique;
};
-/* global var exported */
-FILE *stream;
-
/* Reloading helpers */
#define SET_RELOAD (reload = 1)
#define UNSET_RELOAD (reload = 0)
@@ -72,9 +69,6 @@ extern int _install_keyword(char *string
extern void dump_keywords(vector keydump, int level);
extern void free_keywords(vector keywords);
extern vector alloc_strvec(char *string);
-extern int read_line(char *buf, int size);
-extern vector read_value_block(void);
-extern int alloc_value_block(vector strvec, void (*alloc_func) (vector));
extern void *set_value(vector strvec);
extern int alloc_keywords(void);
extern int process_file(char *conf_file);

View File

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

View File

@ -0,0 +1,28 @@
---
multipathd/main.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
Index: multipath-tools-130222/multipathd/main.c
===================================================================
--- multipath-tools-130222.orig/multipathd/main.c
+++ multipath-tools-130222/multipathd/main.c
@@ -310,10 +310,15 @@ ev_add_map (char * dev, char * alias, st
/*
* now we can register the map
*/
- if (map_present && (mpp = add_map_without_path(vecs, alias))) {
- sync_map_state(mpp);
- condlog(2, "%s: devmap %s registered", alias, dev);
- return 0;
+ if (map_present) {
+ if ((mpp = add_map_without_path(vecs, alias))) {
+ sync_map_state(mpp);
+ condlog(2, "%s: devmap %s registered", alias, dev);
+ return 0;
+ } else {
+ condlog(2, "%s: uev_add_map failed", dev);
+ return 1;
+ }
}
r = get_refwwid(dev, DEV_DEVMAP, vecs->pathvec, &refwwid);

View File

@ -0,0 +1,83 @@
---
libmultipath/hwtable.c | 30 ++++++++++++++++++++++++++++++
multipath.conf.defaults | 26 ++++++++++++++++++++++++++
2 files changed, 56 insertions(+)
Index: multipath-tools-130222/libmultipath/hwtable.c
===================================================================
--- multipath-tools-130222.orig/libmultipath/hwtable.c
+++ multipath-tools-130222/libmultipath/hwtable.c
@@ -772,6 +772,36 @@ static struct hwentry default_hw[] = {
.prio_name = PRIO_RDAC,
.prio_args = NULL,
},
+ {
+ /* DELL MD36xxi */
+ .vendor = "DELL",
+ .product = "MD36xxi",
+ .bl_product = "Universal Xport",
+ .features = "2 pg_init_retries 50",
+ .hwhandler = "1 rdac",
+ .pgpolicy = GROUP_BY_PRIO,
+ .pgfailback = -FAILBACK_IMMEDIATE,
+ .rr_weight = RR_WEIGHT_NONE,
+ .no_path_retry = 15,
+ .checker_name = RDAC,
+ .prio_name = PRIO_RDAC,
+ .prio_args = NULL,
+ },
+ {
+ /* DELL MD36xxf */
+ .vendor = "DELL",
+ .product = "MD36xxf",
+ .bl_product = "Universal Xport",
+ .features = "2 pg_init_retries 50",
+ .hwhandler = "1 rdac",
+ .pgpolicy = GROUP_BY_PRIO,
+ .pgfailback = -FAILBACK_IMMEDIATE,
+ .rr_weight = RR_WEIGHT_NONE,
+ .no_path_retry = 15,
+ .checker_name = RDAC,
+ .prio_name = PRIO_RDAC,
+ .prio_args = NULL,
+ },
/*
* NETAPP controller family
*
Index: multipath-tools-130222/multipath.conf.defaults
===================================================================
--- multipath-tools-130222.orig/multipath.conf.defaults
+++ multipath-tools-130222/multipath.conf.defaults
@@ -655,6 +655,32 @@
# no_path_retry 15
# }
# device {
+# vendor "DELL"
+# product "MD36xxi"
+# product_blacklist "Universal Xport"
+# path_grouping_policy "group_by_prio"
+# path_checker "rdac"
+# features "2 pg_init_retries 50"
+# hardware_handler "1 rdac"
+# prio "rdac"
+# failback "immediate"
+# rr_weight "uniform"
+# no_path_retry 15
+# }
+# device {
+# vendor "DELL"
+# product "MD36xxf"
+# product_blacklist "Universal Xport"
+# path_grouping_policy "group_by_prio"
+# path_checker "rdac"
+# features "2 pg_init_retries 50"
+# hardware_handler "1 rdac"
+# prio "rdac"
+# failback "immediate"
+# rr_weight "uniform"
+# no_path_retry 15
+# }
+# device {
# vendor "NETAPP"
# product "LUN.*"
# path_grouping_policy "group_by_prio"

View File

@ -0,0 +1,31 @@
---
libmultipath/hwtable.c | 2 ++
multipath.conf.defaults | 2 ++
2 files changed, 4 insertions(+)
Index: multipath-tools-130222/libmultipath/hwtable.c
===================================================================
--- multipath-tools-130222.orig/libmultipath/hwtable.c
+++ multipath-tools-130222/libmultipath/hwtable.c
@@ -272,6 +272,8 @@ static struct hwentry default_hw[] = {
.checker_name = EMC_CLARIION,
.prio_name = PRIO_EMC,
.prio_args = NULL,
+ .retain_hwhandler = RETAIN_HWHANDLER_ON,
+ .detect_prio = DETECT_PRIO_ON,
},
{
.vendor = "EMC",
Index: multipath-tools-130222/multipath.conf.defaults
===================================================================
--- multipath-tools-130222.orig/multipath.conf.defaults
+++ multipath-tools-130222/multipath.conf.defaults
@@ -261,6 +261,8 @@
# failback immediate
# rr_weight "uniform"
# no_path_retry 60
+# retain_attached_hw_handler yes
+# detect_prio yes
# }
# device {
# vendor "EMC"

View File

@ -1,7 +1,7 @@
Summary: Tools to manage multipath devices using device-mapper
Name: device-mapper-multipath
Version: 0.4.9
Release: 74%{?dist}
Release: 75%{?dist}
License: GPL+
Group: System Environment/Base
URL: http://christophe.varoqui.free.fr/
@ -118,6 +118,13 @@ Patch0107: 0107-RHBZ-1169935-no-new-devs.patch
Patch0108: 0108-RHBZ-1153832-kpartx-remove-devs.patch
Patch0109: 0109-RH-read-only-bindings.patch
Patch0110: 0110-RHBZ-blacklist-vd-devs.patch
Patch0111: 0111-RH-dont-show-pg-timeout.patch
Patch0112: 0112-RHBZ-1194917-add-config_dir-option.patch
Patch0113: 0113-RHBZ-1194917-cleanup.patch
Patch0114: 0114-RHBZ-1196394-delayed-reintegration.patch
Patch0115: 0115-RHBZ-1198418-fix-double-free.patch
Patch0116: 0116-UPBZ-1188179-dell-36xxi.patch
Patch0117: 0117-RHBZ-1198424-autodetect-clariion-alua.patch
# runtime
Requires: %{name}-libs = %{version}-%{release}
@ -281,6 +288,13 @@ kpartx manages partition creation and removal for device-mapper devices.
%patch0108 -p1
%patch0109 -p1
%patch0110 -p1
%patch0111 -p1
%patch0112 -p1
%patch0113 -p1
%patch0114 -p1
%patch0115 -p1
%patch0116 -p1
%patch0117 -p1
cp %{SOURCE1} .
%build
@ -388,6 +402,28 @@ bin/systemctl --no-reload enable multipathd.service >/dev/null 2>&1 ||:
%{_mandir}/man8/kpartx.8.gz
%changelog
* Wed Mar 11 2015 Benjamin Marzinski <bmarzins@redhat.com> 0.4.9-75
- Add 0111-RH-dont-show-pg-timeout.patch
* The kernel doesn't support pg_timeout, so multipath shouldn't
bother to display it
- Add 0112-RHBZ-1194917-add-config_dir-option.patch
* multipath will now also read its configuration from files with
the .conf suffix in the directory specified by config_dir
which defaults to /etc/multipath/conf.d
- Add 0113-RHBZ-1194917-cleanup.patch
* cleanup some unnecessary code
- Add 0114-RHBZ-1196394-delayed-reintegration.patch
* Add "delay_watch_checks" and "delay_wait_checks" options to delay
reintegration of flakey paths.
- Add 0115-RHBZ-1198418-fix-double-free.patch
* multipath was freeing the multipath alias twice if it failed to create the
multipath device.
- Add 0116-UPBZ-1188179-dell-36xxi.patch
* new builtin configurations.
- Add 0117-RHBZ-1198424-autodetect-clariion-alua.patch
* configure multipath to automatically detect alua settings on clariion
devices.
* Thu Mar 05 2015 Adam Jackson <ajax@redhat.com> 0.4.9-74
- Drop sysvinit subpackage from F23+