diff --git a/0050-RH-listing-speedup.patch b/0050-RH-listing-speedup.patch new file mode 100644 index 0000000..4742634 --- /dev/null +++ b/0050-RH-listing-speedup.patch @@ -0,0 +1,17 @@ +--- + multipath/main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: multipath-tools-130222/multipath/main.c +=================================================================== +--- multipath-tools-130222.orig/multipath/main.c ++++ multipath-tools-130222/multipath/main.c +@@ -311,7 +311,7 @@ configure (void) + /* + * get a path list + */ +- if (conf->dev) ++ if (conf->dev && !conf->list) + di_flag = DI_WWID; + + if (conf->list > 1) diff --git a/0081-RHBZ-1066264-check-prefix-on-rename.patch b/0081-RHBZ-1066264-check-prefix-on-rename.patch new file mode 100644 index 0000000..791f32e --- /dev/null +++ b/0081-RHBZ-1066264-check-prefix-on-rename.patch @@ -0,0 +1,41 @@ +--- + libmultipath/devmapper.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +Index: multipath-tools-130222/libmultipath/devmapper.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/devmapper.c ++++ multipath-tools-130222/libmultipath/devmapper.c +@@ -1151,6 +1151,8 @@ dm_rename_partmaps (char * old, char * n + unsigned long long size; + char dev_t[32]; + int r = 1; ++ int offset; ++ char *delim; + + if (!(dmt = dm_task_create(DM_DEVICE_LIST))) + return 1; +@@ -1171,6 +1173,11 @@ dm_rename_partmaps (char * old, char * n + if (dm_dev_t(old, &dev_t[0], 32)) + goto out; + ++ if (isdigit(new[strlen(new)-1])) ++ delim = "p"; ++ else ++ delim = ""; ++ + do { + if ( + /* +@@ -1198,8 +1205,9 @@ dm_rename_partmaps (char * old, char * n + * then it's a kpartx generated partition. + * Rename it. + */ +- snprintf(buff, PARAMS_SIZE, "%s%s", +- new, names->name + strlen(old)); ++ for (offset = strlen(old); names->name[offset] && !(isdigit(names->name[offset])); offset++); /* do nothing */ ++ snprintf(buff, PARAMS_SIZE, "%s%s%s", ++ new, delim, names->name + offset); + dm_rename(names->name, buff); + condlog(4, "partition map %s renamed", + names->name); diff --git a/0082-UPBZ-1109995-no-sync-turs-on-pthread_cancel.patch b/0082-UPBZ-1109995-no-sync-turs-on-pthread_cancel.patch new file mode 100644 index 0000000..9a1bd34 --- /dev/null +++ b/0082-UPBZ-1109995-no-sync-turs-on-pthread_cancel.patch @@ -0,0 +1,32 @@ +--- + libmultipath/checkers/tur.c | 9 +++------ + 1 file changed, 3 insertions(+), 6 deletions(-) + +Index: multipath-tools-130222/libmultipath/checkers/tur.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/checkers/tur.c ++++ multipath-tools-130222/libmultipath/checkers/tur.c +@@ -409,7 +409,6 @@ libcheck_check (struct checker * c) + ct->running = 0; + MSG(c, MSG_TUR_TIMEOUT); + tur_status = PATH_DOWN; +- ct->state = PATH_UNCHECKED; + } else { + condlog(3, "%d:%d: tur checker not finished", + TUR_DEVT(ct)); +@@ -426,12 +425,10 @@ libcheck_check (struct checker * c) + pthread_mutex_unlock(&ct->lock); + } else { + if (ct->thread) { +- /* pthread cancel failed. continue in sync mode */ + pthread_mutex_unlock(&ct->lock); +- condlog(3, "%d:%d: tur thread not responding, " +- "using sync mode", TUR_DEVT(ct)); +- return tur_check(c->fd, c->timeout, c->message, +- ct->wwid); ++ condlog(3, "%d:%d: tur thread not responding, ", ++ TUR_DEVT(ct)); ++ return PATH_DOWN; + } + /* Start new TUR checker */ + ct->state = PATH_UNCHECKED; diff --git a/0083-RHBZ-1080055-orphan-paths-on-reload.patch b/0083-RHBZ-1080055-orphan-paths-on-reload.patch new file mode 100644 index 0000000..8eaee74 --- /dev/null +++ b/0083-RHBZ-1080055-orphan-paths-on-reload.patch @@ -0,0 +1,85 @@ +--- + libmultipath/structs_vec.c | 31 +++++++++++++++++++++++++++---- + multipathd/main.c | 4 ++++ + 2 files changed, 31 insertions(+), 4 deletions(-) + +Index: multipath-tools-130222/libmultipath/structs_vec.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/structs_vec.c ++++ multipath-tools-130222/libmultipath/structs_vec.c +@@ -280,12 +280,38 @@ update_multipath_status (struct multipat + return 0; + } + ++void sync_paths(struct multipath *mpp, vector pathvec) ++{ ++ struct path *pp; ++ struct pathgroup *pgp; ++ int found, i, j; ++ ++ vector_foreach_slot (mpp->paths, pp, i) { ++ found = 0; ++ vector_foreach_slot(mpp->pg, pgp, j) { ++ if (find_slot(pgp->paths, (void *)pp) != -1) { ++ found = 1; ++ break; ++ } ++ } ++ if (!found) { ++ condlog(3, "%s dropped path %s", mpp->alias, pp->dev); ++ vector_del_slot(mpp->paths, i--); ++ orphan_path(pp); ++ } ++ } ++ update_mpp_paths(mpp, pathvec); ++ vector_foreach_slot (mpp->paths, pp, i) ++ pp->mpp = mpp; ++} ++ + extern int + update_multipath_strings (struct multipath *mpp, vector pathvec) + { + if (!mpp) + return 1; + ++ update_mpp_paths(mpp, pathvec); + condlog(4, "%s: %s", mpp->alias, __FUNCTION__); + + free_multipath_attributes(mpp); +@@ -294,6 +320,7 @@ update_multipath_strings (struct multipa + + if (update_multipath_table(mpp, pathvec)) + return 1; ++ sync_paths(mpp, pathvec); + + if (update_multipath_status(mpp)) + return 1; +@@ -494,13 +521,9 @@ int update_multipath (struct vectors *ve + return 2; + } + +- free_pgvec(mpp->pg, KEEP_PATHS); +- mpp->pg = NULL; +- + if (__setup_multipath(vecs, mpp, reset)) + return 1; /* mpp freed in setup_multipath */ + +- adopt_paths(vecs->pathvec, mpp, 0); + /* + * compare checkers states with DM states + */ +Index: multipath-tools-130222/multipathd/main.c +=================================================================== +--- multipath-tools-130222.orig/multipathd/main.c ++++ multipath-tools-130222/multipathd/main.c +@@ -1152,6 +1152,10 @@ check_path (struct vectors * vecs, struc + pp->dev); + pp->dmstate = PSTATE_UNDEF; + } ++ /* if update_multipath_strings orphaned the path, quit early */ ++ if (!pp->mpp) ++ return; ++ + pp->chkrstate = newstate; + if (newstate != pp->state) { + int oldstate = pp->state; diff --git a/0084-RHBZ-1110000-multipath-man.patch b/0084-RHBZ-1110000-multipath-man.patch new file mode 100644 index 0000000..4ea422a --- /dev/null +++ b/0084-RHBZ-1110000-multipath-man.patch @@ -0,0 +1,101 @@ +--- + libmultipath/prioritizers/alua.c | 4 ++-- + multipathd/multipathd.8 | 37 +++++++++++++++++++++++++++++++++---- + 2 files changed, 35 insertions(+), 6 deletions(-) + +Index: multipath-tools-130222/multipathd/multipathd.8 +=================================================================== +--- multipath-tools-130222.orig/multipathd/multipathd.8 ++++ multipath-tools-130222/multipathd/multipathd.8 +@@ -42,6 +42,9 @@ format wildcards. + .B list|show maps|multipaths + Show the multipath devices that the multipathd is monitoring. + .TP ++.B list|show daemon ++Show the current state of the multipathd daemon ++.TP + .B list|show maps|multipaths format $format + Show the status of all multipath devices that the multipathd is monitoring, + using a format string with multipath format wildcards. +@@ -83,16 +86,16 @@ Add a path to the list of monitored path + .B remove|del path $path + Stop monitoring a path. $path is as listed in /sys/block (e.g. sda). + .TP +-.B add map $map ++.B add map|multipath $map + Add a multipath device to the list of monitored devices. $map can either be a device-mapper device as listed in /sys/block (e.g. dm-0) or it can be the alias for the multipath device (e.g. mpath1) or the uid of the multipath device (e.g. 36005076303ffc56200000000000010aa). + .TP +-.B remove|del map $map ++.B remove|del map|multipath $map + Stop monitoring a multipath device. + .TP + .B resize map|multipath $map + Resizes map $map to the given size + .TP +-.B switch|switchgroup map $map group $group ++.B switch|switchgroup map|multipath $map group $group + Force a multipath device to switch to a specific path group. $group is the path group index, starting with 1. + .TP + .B reconfigure +@@ -104,6 +107,13 @@ Sets map $map into suspend state. + .B resume map|multipath $map + Resumes map $map from suspend state. + .TP ++.B reset map|multipath $map ++Reassign existing device-mapper table(s) use use the multipath device, instead ++of its path devices. ++.TP ++.B reload map|multipath $map ++Reload a multipath device. ++.TP + .B fail path $path + Sets path $path into failed state. + .TP +@@ -120,10 +130,29 @@ Restore queueing on all multipath device + Disable queuing on multipathed map $map + .TP + .B restorequeueing map|multipath $map +-Restore queuing on multipahted map $map ++Restore queuing on multipathed map $map ++.TP ++.B forcequeueing daemon ++Forces multipathd into queue_without_daemon mode, so that no_path_retry queueing ++will not be disabled when the daemon stops ++.TP ++.B restorequeueing daemon ++Restores configured queue_without_daemon mode ++.TP ++.B map|multipath $map setprstatus ++Enable persistent reservation management on $map ++.TP ++.B map|multipath $map unsetprstatus ++Disable persistent reservation management on $map ++.TP ++.B map|multipath $map getprstatus ++Get the current persistent reservation management status of $map + .TP + .B quit|exit + End interactive session. ++.TP ++.B shutdown ++Stop multipathd. + + .SH "SEE ALSO" + .BR multipath (8) +Index: multipath-tools-130222/libmultipath/prioritizers/alua.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/prioritizers/alua.c ++++ multipath-tools-130222/libmultipath/prioritizers/alua.c +@@ -119,10 +119,10 @@ int getprio (struct path * pp, char * ar + condlog(0, "%s: couldn't get target port group", pp->dev); + break; + case ALUA_PRIO_GETAAS_FAILED: +- condlog(0, "%s: couln't get asymmetric access state", pp->dev); ++ condlog(0, "%s: couldn't get asymmetric access state", pp->dev); + break; + case ALUA_PRIO_TPGS_FAILED: +- condlog(3, "%s: couln't get supported alua states", pp->dev); ++ condlog(3, "%s: couldn't get supported alua states", pp->dev); + break; + } + } diff --git a/0085-UPBZ-1110006-datacore-config.patch b/0085-UPBZ-1110006-datacore-config.patch new file mode 100644 index 0000000..cedb5e3 --- /dev/null +++ b/0085-UPBZ-1110006-datacore-config.patch @@ -0,0 +1,28 @@ +--- + libmultipath/hwtable.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +Index: multipath-tools-130222/libmultipath/hwtable.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/hwtable.c ++++ multipath-tools-130222/libmultipath/hwtable.c +@@ -1108,6 +1108,19 @@ static struct hwentry default_hw[] = { + .prio_name = PRIO_ALUA, + .prio_args = NULL, + }, ++ { ++ .vendor = "DataCore", ++ .product = "Virtual Disk", ++ .features = DEFAULT_FEATURES, ++ .hwhandler = DEFAULT_HWHANDLER, ++ .pgpolicy = GROUP_BY_PRIO, ++ .pgfailback = -FAILBACK_IMMEDIATE, ++ .rr_weight = RR_WEIGHT_NONE, ++ .no_path_retry = NO_PATH_RETRY_QUEUE, ++ .checker_name = TUR, ++ .prio_name = PRIO_ALUA, ++ .prio_args = NULL, ++ }, + /* + * EOL + */ diff --git a/0086-RHBZ-1110007-orphan-path-on-failed-add.patch b/0086-RHBZ-1110007-orphan-path-on-failed-add.patch new file mode 100644 index 0000000..0d6aa58 --- /dev/null +++ b/0086-RHBZ-1110007-orphan-path-on-failed-add.patch @@ -0,0 +1,17 @@ +--- + multipathd/main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: multipath-tools-130222/multipathd/main.c +=================================================================== +--- multipath-tools-130222.orig/multipathd/main.c ++++ multipath-tools-130222/multipathd/main.c +@@ -562,7 +562,7 @@ rescan: + return 0; + } + else +- return 1; ++ goto fail; + + fail_map: + remove_map(mpp, vecs, 1); diff --git a/0087-RHBZ-1110013-config-error-checking.patch b/0087-RHBZ-1110013-config-error-checking.patch new file mode 100644 index 0000000..c774bc5 --- /dev/null +++ b/0087-RHBZ-1110013-config-error-checking.patch @@ -0,0 +1,190 @@ +--- + libmultipath/parser.c | 154 ++++++++++++++++++++++++++++++++++++++++---------- + 1 file changed, 126 insertions(+), 28 deletions(-) + +Index: multipath-tools-130222/libmultipath/parser.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/parser.c ++++ multipath-tools-130222/libmultipath/parser.c +@@ -395,36 +395,57 @@ set_value(vector strvec) + char *alloc = NULL; + char *tmp; + +- if (!str) ++ if (!str) { ++ condlog(0, "option '%s' missing value", ++ (char *)VECTOR_SLOT(strvec, 0)); + return NULL; +- ++ } + size = strlen(str); +- if (size == 0) ++ if (size == 0) { ++ condlog(0, "option '%s' has empty value", ++ (char *)VECTOR_SLOT(strvec, 0)); + return NULL; +- +- if (*str == '"') { +- for (i = 2; i < VECTOR_SIZE(strvec); i++) { +- str = VECTOR_SLOT(strvec, i); +- len += strlen(str); +- if (!alloc) +- alloc = +- (char *) MALLOC(sizeof (char *) * +- (len + 1)); +- else { +- alloc = +- REALLOC(alloc, sizeof (char *) * (len + 1)); +- tmp = VECTOR_SLOT(strvec, i-1); +- if (alloc && *str != '"' && *tmp != '"') +- strncat(alloc, " ", 1); +- } +- +- if (alloc && i != VECTOR_SIZE(strvec)-1) +- strncat(alloc, str, strlen(str)); +- } +- } else { +- alloc = MALLOC(sizeof (char *) * (size + 1)); ++ } ++ if (*str != '"') { ++ alloc = MALLOC(sizeof (char) * (size + 1)); + if (alloc) + memcpy(alloc, str, size); ++ else ++ condlog(0, "can't allocate memeory for option '%s'", ++ (char *)VECTOR_SLOT(strvec, 0)); ++ return alloc; ++ } ++ /* Even empty quotes counts as a value (An empty string) */ ++ alloc = (char *) MALLOC(sizeof (char)); ++ if (!alloc) { ++ condlog(0, "can't allocate memeory for option '%s'", ++ (char *)VECTOR_SLOT(strvec, 0)); ++ return NULL; ++ } ++ for (i = 2; i < VECTOR_SIZE(strvec); i++) { ++ str = VECTOR_SLOT(strvec, i); ++ if (!str) { ++ free(alloc); ++ condlog(0, "parse error for option '%s'", ++ (char *)VECTOR_SLOT(strvec, 0)); ++ return NULL; ++ } ++ if (*str == '"') ++ break; ++ tmp = alloc; ++ /* The first +1 is for the NULL byte. The rest are for the ++ * spaces between words */ ++ len += strlen(str) + 1; ++ alloc = REALLOC(alloc, sizeof (char) * len); ++ if (!alloc) { ++ FREE(tmp); ++ condlog(0, "can't allocate memeory for option '%s'", ++ (char *)VECTOR_SLOT(strvec, 0)); ++ return NULL; ++ } ++ if (*alloc != '\0') ++ strncat(alloc, " ", 1); ++ strncat(alloc, str, strlen(str)); + } + return alloc; + } +@@ -465,6 +486,74 @@ void free_uniques(vector uniques) + } + + int ++is_sublevel_keyword(char *str) ++{ ++ return (strcmp(str, "defaults") == 0 || strcmp(str, "blacklist") == 0 || ++ strcmp(str, "blacklist_exceptions") == 0 || ++ strcmp(str, "devices") == 0 || strcmp(str, "devices") == 0 || ++ strcmp(str, "device") == 0 || strcmp(str, "multipaths") == 0 || ++ strcmp(str, "multipath") == 0); ++} ++ ++int ++validate_config_strvec(vector strvec) ++{ ++ 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); ++ 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); ++ return 0; ++ } ++ if (*str == '{') { ++ condlog(0, "invalid keyword '%s' on line %d of config file", str, line_nr); ++ 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); ++ else if (*str != '{') ++ condlog(0, "expecting '{' on line %d of config file. found '%s'", line_nr, 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); ++ 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); ++ 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); ++ 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); ++ 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); ++ return 0; ++ } ++ } ++ condlog(0, "missing closing quotes on line %d of config file", ++ line_nr); ++ return 0; ++} ++ ++int + process_stream(vector keywords) + { + int i; +@@ -494,11 +583,20 @@ process_stream(vector keywords) + if (!strvec) + continue; + ++ if (validate_config_strvec(strvec) != 0) { ++ free_strvec(strvec); ++ continue; ++ } ++ + str = VECTOR_SLOT(strvec, 0); + +- if (!strcmp(str, EOB) && kw_level > 0) { +- free_strvec(strvec); +- break; ++ if (!strcmp(str, EOB)) { ++ if (kw_level > 0) { ++ free_strvec(strvec); ++ break; ++ } ++ condlog(0, "unmatched '%s' at line %d of config file", ++ EOB, line_nr); + } + + for (i = 0; i < VECTOR_SIZE(keywords); i++) { diff --git a/0088-RHBZ-1069811-configurable-prio-timeout.patch b/0088-RHBZ-1069811-configurable-prio-timeout.patch new file mode 100644 index 0000000..60f374b --- /dev/null +++ b/0088-RHBZ-1069811-configurable-prio-timeout.patch @@ -0,0 +1,178 @@ +--- + libmultipath/prio.c | 7 +++++++ + libmultipath/prio.h | 1 + + libmultipath/prioritizers/alua_rtpg.c | 5 +++-- + libmultipath/prioritizers/emc.c | 2 +- + libmultipath/prioritizers/hds.c | 2 +- + libmultipath/prioritizers/hp_sw.c | 2 +- + libmultipath/prioritizers/ontap.c | 4 ++-- + libmultipath/prioritizers/rdac.c | 2 +- + multipath.conf.annotated | 5 +++-- + multipath/multipath.conf.5 | 4 ++-- + 10 files changed, 22 insertions(+), 12 deletions(-) + +Index: multipath-tools-130222/libmultipath/prio.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/prio.c ++++ multipath-tools-130222/libmultipath/prio.c +@@ -10,6 +10,13 @@ + + static LIST_HEAD(prioritizers); + ++unsigned int get_prio_timeout(unsigned int default_timeout) ++{ ++ if (conf->checker_timeout) ++ return conf->checker_timeout * 1000; ++ return default_timeout; ++} ++ + int init_prio (void) + { + if (!add_prio(DEFAULT_PRIO)) +Index: multipath-tools-130222/libmultipath/prio.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/prio.h ++++ multipath-tools-130222/libmultipath/prio.h +@@ -51,6 +51,7 @@ struct prio { + int (*getprio)(struct path *, char *); + }; + ++unsigned int get_prio_timeout(unsigned int default_timeout); + int init_prio (void); + void cleanup_prio (void); + struct prio * add_prio (char *); +Index: multipath-tools-130222/libmultipath/prioritizers/alua_rtpg.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/prioritizers/alua_rtpg.c ++++ multipath-tools-130222/libmultipath/prioritizers/alua_rtpg.c +@@ -21,6 +21,7 @@ + #define __user + #include + ++#include "../prio.h" + #include "alua_rtpg.h" + + #define SENSE_BUFF_LEN 32 +@@ -134,7 +135,7 @@ do_inquiry(int fd, int evpd, unsigned in + hdr.dxfer_len = resplen; + hdr.sbp = sense; + hdr.mx_sb_len = sizeof(sense); +- hdr.timeout = DEF_TIMEOUT; ++ hdr.timeout = get_prio_timeout(DEF_TIMEOUT); + + if (ioctl(fd, SG_IO, &hdr) < 0) { + PRINT_DEBUG("do_inquiry: IOCTL failed!\n"); +@@ -253,7 +254,7 @@ do_rtpg(int fd, void* resp, long resplen + hdr.dxfer_len = resplen; + hdr.mx_sb_len = sizeof(sense); + hdr.sbp = sense; +- hdr.timeout = DEF_TIMEOUT; ++ hdr.timeout = get_prio_timeout(DEF_TIMEOUT); + + if (ioctl(fd, SG_IO, &hdr) < 0) + return -RTPG_RTPG_FAILED; +Index: multipath-tools-130222/libmultipath/prioritizers/emc.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/prioritizers/emc.c ++++ multipath-tools-130222/libmultipath/prioritizers/emc.c +@@ -31,7 +31,7 @@ int emc_clariion_prio(const char *dev, i + io_hdr.dxferp = sense_buffer; + io_hdr.cmdp = inqCmdBlk; + io_hdr.sbp = sb; +- io_hdr.timeout = 60000; ++ io_hdr.timeout = get_prio_timeout(60000); + io_hdr.pack_id = 0; + if (ioctl(fd, SG_IO, &io_hdr) < 0) { + pp_emc_log(0, "sending query command failed"); +Index: multipath-tools-130222/libmultipath/prioritizers/hds.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/prioritizers/hds.c ++++ multipath-tools-130222/libmultipath/prioritizers/hds.c +@@ -114,7 +114,7 @@ int hds_modular_prio (const char *dev, i + io_hdr.dxferp = inqBuff; + io_hdr.cmdp = inqCmdBlk; + io_hdr.sbp = sense_buffer; +- io_hdr.timeout = 2000; /* TimeOut = 2 seconds */ ++ io_hdr.timeout = get_prio_timeout(2000); /* TimeOut = 2 seconds */ + + if (ioctl (fd, SG_IO, &io_hdr) < 0) { + pp_hds_log(0, "SG_IO error"); +Index: multipath-tools-130222/libmultipath/prioritizers/hp_sw.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/prioritizers/hp_sw.c ++++ multipath-tools-130222/libmultipath/prioritizers/hp_sw.c +@@ -46,7 +46,7 @@ int hp_sw_prio(const char *dev, int fd) + io_hdr.dxfer_direction = SG_DXFER_NONE; + io_hdr.cmdp = turCmdBlk; + io_hdr.sbp = sb; +- io_hdr.timeout = 60000; ++ io_hdr.timeout = get_prio_timeout(60000); + io_hdr.pack_id = 0; + retry: + if (ioctl(fd, SG_IO, &io_hdr) < 0) { +Index: multipath-tools-130222/libmultipath/prioritizers/ontap.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/prioritizers/ontap.c ++++ multipath-tools-130222/libmultipath/prioritizers/ontap.c +@@ -89,7 +89,7 @@ static int send_gva(const char *dev, int + io_hdr.dxferp = results; + io_hdr.cmdp = cdb; + io_hdr.sbp = sb; +- io_hdr.timeout = SG_TIMEOUT; ++ io_hdr.timeout = get_prio_timeout(SG_TIMEOUT); + io_hdr.pack_id = 0; + if (ioctl(fd, SG_IO, &io_hdr) < 0) { + pp_ontap_log(0, "SG_IO ioctl failed, errno=%d", errno); +@@ -141,7 +141,7 @@ static int get_proxy(const char *dev, in + io_hdr.dxferp = results; + io_hdr.cmdp = cdb; + io_hdr.sbp = sb; +- io_hdr.timeout = SG_TIMEOUT; ++ io_hdr.timeout = get_prio_timeout(SG_TIMEOUT); + io_hdr.pack_id = 0; + if (ioctl(fd, SG_IO, &io_hdr) < 0) { + pp_ontap_log(0, "ioctl sending inquiry command failed, " +Index: multipath-tools-130222/libmultipath/prioritizers/rdac.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/prioritizers/rdac.c ++++ multipath-tools-130222/libmultipath/prioritizers/rdac.c +@@ -31,7 +31,7 @@ int rdac_prio(const char *dev, int fd) + io_hdr.dxferp = sense_buffer; + io_hdr.cmdp = inqCmdBlk; + io_hdr.sbp = sb; +- io_hdr.timeout = 60000; ++ io_hdr.timeout = get_prio_timeout(60000); + io_hdr.pack_id = 0; + if (ioctl(fd, SG_IO, &io_hdr) < 0) { + pp_rdac_log(0, "sending inquiry command failed"); +Index: multipath-tools-130222/multipath.conf.annotated +=================================================================== +--- multipath-tools-130222.orig/multipath.conf.annotated ++++ multipath-tools-130222/multipath.conf.annotated +@@ -188,8 +188,9 @@ + # # + # # name : checker_timeout + # # scope : multipath & multipathd +-# # desc : The timeout to use for path checkers that issue scsi +-# # commands with an explicit timeout, in seconds. ++# # desc : The timeout to use for path checkers and prioritizers ++# # that issue scsi commands with an explicit timeout, in ++# # seconds. + # # values : n > 0 + # # default : taken from /sys/block/sd/device/timeout + # checker_timeout 60 +Index: multipath-tools-130222/multipath/multipath.conf.5 +=================================================================== +--- multipath-tools-130222.orig/multipath/multipath.conf.5 ++++ multipath-tools-130222/multipath/multipath.conf.5 +@@ -321,8 +321,8 @@ maximum number of open fds is taken from + if that number is greated than 1024. + .TP + .B checker_timeout +-Specify the timeout to user for path checkers that issue scsi commands with an +-explicit timeout, in seconds; default taken from ++Specify the timeout to use for path checkers and prioritizers that issue scsi ++commands with an explicit timeout, in seconds; default taken from + .I /sys/block/sd/device/timeout + .TP + .B fast_io_fail_tmo diff --git a/0089-RHBZ-1110016-add-noasync-option.patch b/0089-RHBZ-1110016-add-noasync-option.patch new file mode 100644 index 0000000..2651c0e --- /dev/null +++ b/0089-RHBZ-1110016-add-noasync-option.patch @@ -0,0 +1,158 @@ +--- + libmultipath/config.c | 1 + + libmultipath/config.h | 1 + + libmultipath/dict.c | 33 +++++++++++++++++++++++++++++++++ + libmultipath/discovery.c | 8 ++++++-- + multipath.conf.annotated | 10 ++++++++++ + multipath/multipath.conf.5 | 9 +++++++++ + 6 files changed, 60 insertions(+), 2 deletions(-) + +Index: multipath-tools-130222/libmultipath/config.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/config.c ++++ multipath-tools-130222/libmultipath/config.c +@@ -556,6 +556,7 @@ load_config (char * file, struct udev *u + conf->retain_hwhandler = DEFAULT_RETAIN_HWHANDLER; + conf->detect_prio = DEFAULT_DETECT_PRIO; + conf->hw_strmatch = 0; ++ conf->force_sync = 0; + + /* + * preload default hwtable +Index: multipath-tools-130222/libmultipath/config.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/config.h ++++ multipath-tools-130222/libmultipath/config.h +@@ -115,6 +115,7 @@ struct config { + int reassign_maps; + int retain_hwhandler; + int detect_prio; ++ int force_sync; + unsigned int version[3]; + + char * dev; +Index: multipath-tools-130222/libmultipath/dict.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/dict.c ++++ multipath-tools-130222/libmultipath/dict.c +@@ -712,6 +712,29 @@ def_hw_strmatch_handler(vector strvec) + return 0; + } + ++static int ++def_force_sync_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->force_sync = 0; ++ else if ((strlen(buff) == 3 && !strcmp(buff, "yes")) || ++ (strlen(buff) == 1 && !strcmp(buff, "1"))) ++ conf->force_sync = 1; ++ else ++ conf->force_sync = 0; ++ ++ FREE(buff); ++ return 0; ++} ++ + /* + * blacklist block handlers + */ +@@ -2822,6 +2845,15 @@ snprint_def_hw_strmatch(char * buff, int + } + + static int ++snprint_def_force_sync(char * buff, int len, void * data) ++{ ++ if (conf->force_sync) ++ return snprintf(buff, len, "yes"); ++ else ++ return snprintf(buff, len, "no"); ++} ++ ++static int + snprint_ble_simple (char * buff, int len, void * data) + { + struct blentry * ble = (struct blentry *)data; +@@ -2889,6 +2921,7 @@ init_keywords(void) + install_keyword("retain_attached_hw_handler", &def_retain_hwhandler_handler, &snprint_def_retain_hwhandler_handler); + install_keyword("detect_prio", &def_detect_prio_handler, &snprint_def_detect_prio); + install_keyword("hw_str_match", &def_hw_strmatch_handler, &snprint_def_hw_strmatch); ++ install_keyword("force_sync", &def_force_sync_handler, &snprint_def_force_sync); + __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/discovery.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/discovery.c ++++ multipath-tools-130222/libmultipath/discovery.c +@@ -952,8 +952,12 @@ get_state (struct path * pp, int daemon) + } + } + checker_clear_message(c); +- if (daemon) +- checker_set_async(c); ++ if (daemon) { ++ if (conf->force_sync == 0) ++ checker_set_async(c); ++ else ++ checker_set_sync(c); ++ } + if (!conf->checker_timeout && + (pp->bus != SYSFS_BUS_SCSI || + sysfs_get_timeout(pp, &(c->timeout)))) +Index: multipath-tools-130222/multipath.conf.annotated +=================================================================== +--- multipath-tools-130222.orig/multipath.conf.annotated ++++ multipath-tools-130222/multipath.conf.annotated +@@ -214,6 +214,8 @@ + # # values : n > 0 + # # default : determined by the OS + # dev_loss_tmo 600 ++# ++# # + # # name : bindings_file + # # scope : multipath + # # desc : The location of the bindings file that is used with +@@ -222,6 +224,14 @@ + # # default : "/var/lib/multipath/bindings" + # bindings_file "/etc/multipath_bindings" + # ++# # ++# # name : force_sync ++# # scope : multipathd ++# # desc : If set to yes, multipath will run all of the checkers in ++# # sync mode, even if the checker has an async mode. ++# # values : yes|no ++# # default : no ++# force_sync yes + #} + # + ## +Index: multipath-tools-130222/multipath/multipath.conf.5 +=================================================================== +--- multipath-tools-130222.orig/multipath/multipath.conf.5 ++++ multipath-tools-130222/multipath/multipath.conf.5 +@@ -411,6 +411,15 @@ modify an existing config, or create a n + , the user device configs will be regular expression matched against the + built-in configs instead. Default is + .I no ++.TP ++.B force_sync ++If set to ++.I yes ++, multipathd will call the path checkers in sync mode only. This means that ++only one checker will run at a time. This is useful in the case where many ++multipathd checkers running in parallel causes significant CPU pressure. The ++Default is ++.I no + . + .SH "blacklist section" + The diff --git a/0090-UPBZ-1080038-reorder-paths-for-round-robin.patch b/0090-UPBZ-1080038-reorder-paths-for-round-robin.patch new file mode 100644 index 0000000..44f8407 --- /dev/null +++ b/0090-UPBZ-1080038-reorder-paths-for-round-robin.patch @@ -0,0 +1,529 @@ +--- + libmultipath/configure.c | 229 +++++++++++++++++++++++++++++++++++++++++++++++ + libmultipath/configure.h | 2 + libmultipath/discovery.c | 87 +++++++++++++++++ + libmultipath/discovery.h | 2 + libmultipath/structs.c | 84 +++++++++++++++++ + libmultipath/structs.h | 25 ++++- + 6 files changed, 427 insertions(+), 2 deletions(-) + +Index: multipath-tools-130222/libmultipath/configure.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/configure.c ++++ multipath-tools-130222/libmultipath/configure.c +@@ -39,6 +39,219 @@ + #include "uxsock.h" + #include "wwids.h" + ++/* group paths in pg by host adapter ++ */ ++int group_by_host_adapter(struct pathgroup *pgp, vector adapters) ++{ ++ struct adapter_group *agp; ++ struct host_group *hgp; ++ struct path *pp, *pp1; ++ char adapter_name1[SLOT_NAME_SIZE]; ++ char adapter_name2[SLOT_NAME_SIZE]; ++ int i, j; ++ int found_hostgroup = 0; ++ ++ while (VECTOR_SIZE(pgp->paths) > 0) { ++ ++ pp = VECTOR_SLOT(pgp->paths, 0); ++ ++ if (sysfs_get_host_adapter_name(pp, adapter_name1)) ++ goto out; ++ /* create a new host adapter group ++ */ ++ agp = alloc_adaptergroup(); ++ if (!agp) ++ goto out; ++ agp->pgp = pgp; ++ ++ strncpy(agp->adapter_name, adapter_name1, SLOT_NAME_SIZE); ++ store_adaptergroup(adapters, agp); ++ ++ /* create a new host port group ++ */ ++ hgp = alloc_hostgroup(); ++ if (!hgp) ++ goto out; ++ if (store_hostgroup(agp->host_groups, hgp)) ++ goto out; ++ ++ hgp->host_no = pp->sg_id.host_no; ++ agp->num_hosts++; ++ if (store_path(hgp->paths, pp)) ++ goto out; ++ ++ hgp->num_paths++; ++ /* delete path from path group ++ */ ++ vector_del_slot(pgp->paths, 0); ++ ++ /* add all paths belonging to same host adapter ++ */ ++ vector_foreach_slot(pgp->paths, pp1, i) { ++ if (sysfs_get_host_adapter_name(pp1, adapter_name2)) ++ goto out; ++ if (strcmp(adapter_name1, adapter_name2) == 0) { ++ found_hostgroup = 0; ++ vector_foreach_slot(agp->host_groups, hgp, j) { ++ if (hgp->host_no == pp1->sg_id.host_no) { ++ if (store_path(hgp->paths, pp1)) ++ goto out; ++ hgp->num_paths++; ++ found_hostgroup = 1; ++ break; ++ } ++ } ++ if (!found_hostgroup) { ++ /* this path belongs to new host port ++ * within this adapter ++ */ ++ hgp = alloc_hostgroup(); ++ if (!hgp) ++ goto out; ++ ++ if (store_hostgroup(agp->host_groups, hgp)) ++ goto out; ++ ++ agp->num_hosts++; ++ if (store_path(hgp->paths, pp1)) ++ goto out; ++ ++ hgp->host_no = pp1->sg_id.host_no; ++ hgp->num_paths++; ++ } ++ /* delete paths from original path_group ++ * as they are added into adapter group now ++ */ ++ vector_del_slot(pgp->paths, i); ++ i--; ++ } ++ } ++ } ++ return 0; ++ ++out: /* add back paths into pg as re-ordering failed ++ */ ++ vector_foreach_slot(adapters, agp, i) { ++ vector_foreach_slot(agp->host_groups, hgp, j) { ++ while (VECTOR_SIZE(hgp->paths) > 0) { ++ pp = VECTOR_SLOT(hgp->paths, 0); ++ if (store_path(pgp->paths, pp)) ++ condlog(3, "failed to restore " ++ "path %s into path group", ++ pp->dev); ++ vector_del_slot(hgp->paths, 0); ++ } ++ } ++ } ++ free_adaptergroup(adapters); ++ return 1; ++} ++ ++/* re-order paths in pg by alternating adapters and host ports ++ * for optimized selection ++ */ ++int order_paths_in_pg_by_alt_adapters(struct pathgroup *pgp, vector adapters, ++ int total_paths) ++{ ++ int next_adapter_index = 0; ++ struct adapter_group *agp; ++ struct host_group *hgp; ++ struct path *pp; ++ ++ while (total_paths > 0) { ++ agp = VECTOR_SLOT(adapters, next_adapter_index); ++ if (!agp) { ++ condlog(0, "can't get adapter group %d", next_adapter_index); ++ return 1; ++ } ++ ++ hgp = VECTOR_SLOT(agp->host_groups, agp->next_host_index); ++ if (!hgp) { ++ condlog(0, "can't get host group %d of adapter group %d", next_adapter_index, agp->next_host_index); ++ return 1; ++ } ++ ++ if (!hgp->num_paths) { ++ agp->next_host_index++; ++ agp->next_host_index %= agp->num_hosts; ++ next_adapter_index++; ++ next_adapter_index %= VECTOR_SIZE(adapters); ++ continue; ++ } ++ ++ pp = VECTOR_SLOT(hgp->paths, 0); ++ ++ if (store_path(pgp->paths, pp)) ++ return 1; ++ ++ total_paths--; ++ ++ vector_del_slot(hgp->paths, 0); ++ ++ hgp->num_paths--; ++ ++ agp->next_host_index++; ++ agp->next_host_index %= agp->num_hosts; ++ next_adapter_index++; ++ next_adapter_index %= VECTOR_SIZE(adapters); ++ } ++ ++ /* all paths are added into path_group ++ * in crafted child order ++ */ ++ return 0; ++} ++ ++/* round-robin: order paths in path group to alternate ++ * between all host adapters ++ */ ++int rr_optimize_path_order(struct pathgroup *pgp) ++{ ++ vector adapters; ++ struct path *pp; ++ int total_paths; ++ int i; ++ ++ total_paths = VECTOR_SIZE(pgp->paths); ++ vector_foreach_slot(pgp->paths, pp, i) { ++ if (pp->sg_id.proto_id != SCSI_PROTOCOL_FCP && ++ pp->sg_id.proto_id != SCSI_PROTOCOL_SAS && ++ pp->sg_id.proto_id != SCSI_PROTOCOL_ISCSI && ++ pp->sg_id.proto_id != SCSI_PROTOCOL_SRP) { ++ /* return success as default path order ++ * is maintained in path group ++ */ ++ return 0; ++ } ++ } ++ adapters = vector_alloc(); ++ if (!adapters) ++ return 0; ++ ++ /* group paths in path group by host adapters ++ */ ++ if (group_by_host_adapter(pgp, adapters)) { ++ /* already freed adapters */ ++ condlog(3, "Failed to group paths by adapters"); ++ return 0; ++ } ++ ++ /* re-order paths in pg to alternate between adapters and host ports ++ */ ++ if (order_paths_in_pg_by_alt_adapters(pgp, adapters, total_paths)) { ++ condlog(3, "Failed to re-order paths in pg by adapters " ++ "and host ports"); ++ free_adaptergroup(adapters); ++ /* return failure as original paths are ++ * removed form pgp ++ */ ++ return 1; ++ } ++ ++ free_adaptergroup(adapters); ++ return 0; ++} ++ + extern int + setup_map (struct multipath * mpp, char * params, int params_size) + { +@@ -101,6 +314,22 @@ setup_map (struct multipath * mpp, char + */ + mpp->bestpg = select_path_group(mpp); + ++ /* re-order paths in all path groups in an optimized way ++ * for round-robin path selectors to get maximum throughput. ++ */ ++ if (!strncmp(mpp->selector, "round-robin", 11)) { ++ vector_foreach_slot(mpp->pg, pgp, i) { ++ if (VECTOR_SIZE(pgp->paths) <= 2) ++ continue; ++ if (rr_optimize_path_order(pgp)) { ++ condlog(2, "cannot re-order paths for " ++ "optimization: %s", ++ mpp->alias); ++ return 1; ++ } ++ } ++ } ++ + /* + * transform the mp->pg vector of vectors of paths + * into a mp->params strings to feed the device-mapper +Index: multipath-tools-130222/libmultipath/configure.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/configure.h ++++ multipath-tools-130222/libmultipath/configure.h +@@ -29,4 +29,4 @@ int reinstate_paths (struct multipath *m + int coalesce_paths (struct vectors *vecs, vector curmp, char * refwwid, int force_reload); + int get_refwwid (char * dev, enum devtypes dev_type, vector pathvec, char **wwid); + int reload_map(struct vectors *vecs, struct multipath *mpp, int refresh); +- ++int sysfs_get_host_adapter_name(struct path *pp, char *adapter_name); +Index: multipath-tools-130222/libmultipath/discovery.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/discovery.c ++++ multipath-tools-130222/libmultipath/discovery.c +@@ -310,6 +310,93 @@ sysfs_get_tgt_nodename (struct path *pp, + return 1; + } + ++int sysfs_get_host_adapter_name(struct path *pp, char *adapter_name) ++{ ++ int proto_id; ++ ++ if (!pp || !adapter_name) ++ return 1; ++ ++ proto_id = pp->sg_id.proto_id; ++ ++ if (proto_id != SCSI_PROTOCOL_FCP && ++ proto_id != SCSI_PROTOCOL_SAS && ++ proto_id != SCSI_PROTOCOL_ISCSI && ++ proto_id != SCSI_PROTOCOL_SRP) { ++ return 1; ++ } ++ /* iscsi doesn't have adapter info in sysfs ++ * get ip_address for grouping paths ++ */ ++ if (pp->sg_id.proto_id == SCSI_PROTOCOL_ISCSI) ++ return sysfs_get_iscsi_ip_address(pp, adapter_name); ++ ++ /* fetch adapter pci name for other protocols ++ */ ++ return sysfs_get_host_pci_name(pp, adapter_name); ++} ++ ++int sysfs_get_host_pci_name(struct path *pp, char *pci_name) ++{ ++ struct udev_device *hostdev, *parent; ++ char host_name[HOST_NAME_LEN]; ++ const char *driver_name, *value; ++ ++ if (!pp || !pci_name) ++ return 1; ++ ++ sprintf(host_name, "host%d", pp->sg_id.host_no); ++ hostdev = udev_device_new_from_subsystem_sysname(conf->udev, ++ "scsi_host", host_name); ++ if (!hostdev) ++ return 1; ++ ++ parent = udev_device_get_parent(hostdev); ++ while (parent) { ++ driver_name = udev_device_get_driver(parent); ++ if (!driver_name) { ++ parent = udev_device_get_parent(parent); ++ continue; ++ } ++ if (!strcmp(driver_name, "pcieport")) ++ break; ++ parent = udev_device_get_parent(parent); ++ } ++ if (parent) { ++ /* pci_device found ++ */ ++ value = udev_device_get_sysname(parent); ++ ++ strncpy(pci_name, value, SLOT_NAME_SIZE); ++ udev_device_unref(hostdev); ++ return 0; ++ } ++ udev_device_unref(hostdev); ++ return 1; ++} ++ ++int sysfs_get_iscsi_ip_address(struct path *pp, char *ip_address) ++{ ++ struct udev_device *hostdev; ++ char host_name[HOST_NAME_LEN]; ++ const char *value; ++ ++ sprintf(host_name, "host%d", pp->sg_id.host_no); ++ hostdev = udev_device_new_from_subsystem_sysname(conf->udev, ++ "iscsi_host", host_name); ++ if (hostdev) { ++ value = udev_device_get_sysattr_value(hostdev, ++ "ipaddress"); ++ if (value) { ++ strncpy(ip_address, value, SLOT_NAME_SIZE); ++ udev_device_unref(hostdev); ++ return 0; ++ } else ++ udev_device_unref(hostdev); ++ } ++ return 1; ++} ++ + static void + sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp) + { +Index: multipath-tools-130222/libmultipath/discovery.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/discovery.h ++++ multipath-tools-130222/libmultipath/discovery.h +@@ -38,6 +38,8 @@ int store_pathinfo (vector pathvec, vect + struct path **pp_ptr); + int sysfs_set_scsi_tmo (struct multipath *mpp); + int sysfs_get_timeout(struct path *pp, unsigned int *timeout); ++int sysfs_get_host_pci_name(struct path *pp, char *pci_name); ++int sysfs_get_iscsi_ip_address(struct path *pp, char *ip_address); + + /* + * discovery bitmask +Index: multipath-tools-130222/libmultipath/structs.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/structs.c ++++ multipath-tools-130222/libmultipath/structs.c +@@ -18,6 +18,70 @@ + #include "blacklist.h" + #include "prio.h" + ++struct adapter_group * ++alloc_adaptergroup(void) ++{ ++ struct adapter_group *agp; ++ ++ agp = (struct adapter_group *)MALLOC(sizeof(struct adapter_group)); ++ ++ if (!agp) ++ return NULL; ++ ++ agp->host_groups = vector_alloc(); ++ if (!agp->host_groups) { ++ FREE(agp); ++ agp = NULL; ++ } ++ return agp; ++} ++ ++void free_adaptergroup(vector adapters) ++{ ++ int i; ++ struct adapter_group *agp; ++ ++ vector_foreach_slot(adapters, agp, i) { ++ free_hostgroup(agp->host_groups); ++ FREE(agp); ++ } ++ vector_free(adapters); ++} ++ ++void free_hostgroup(vector hostgroups) ++{ ++ int i; ++ struct host_group *hgp; ++ ++ if (!hostgroups) ++ return; ++ ++ vector_foreach_slot(hostgroups, hgp, i) { ++ vector_free(hgp->paths); ++ FREE(hgp); ++ } ++ vector_free(hostgroups); ++} ++ ++struct host_group * ++alloc_hostgroup(void) ++{ ++ struct host_group *hgp; ++ ++ hgp = (struct host_group *)MALLOC(sizeof(struct host_group)); ++ ++ if (!hgp) ++ return NULL; ++ ++ hgp->paths = vector_alloc(); ++ ++ if (!hgp->paths) { ++ FREE(hgp); ++ hgp = NULL; ++ } ++ return hgp; ++} ++ + struct path * + alloc_path (void) + { +@@ -242,6 +306,26 @@ store_pathgroup (vector pgvec, struct pa + return 0; + } + ++int ++store_hostgroup(vector hostgroupvec, struct host_group * hgp) ++{ ++ if (!vector_alloc_slot(hostgroupvec)) ++ return 1; ++ ++ vector_set_slot(hostgroupvec, hgp); ++ return 0; ++} ++ ++int ++store_adaptergroup(vector adapters, struct adapter_group * agp) ++{ ++ if (!vector_alloc_slot(adapters)) ++ return 1; ++ ++ vector_set_slot(adapters, agp); ++ return 0; ++} ++ + struct multipath * + find_mp_by_minor (vector mpvec, int minor) + { +Index: multipath-tools-130222/libmultipath/structs.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/structs.h ++++ multipath-tools-130222/libmultipath/structs.h +@@ -15,7 +15,8 @@ + #define BLK_DEV_SIZE 33 + #define PATH_SIZE 512 + #define NAME_SIZE 512 +- ++#define HOST_NAME_LEN 8 ++#define SLOT_NAME_SIZE 40 + + #define SCSI_VENDOR_SIZE 9 + #define SCSI_PRODUCT_SIZE 17 +@@ -251,6 +252,20 @@ struct pathgroup { + char * selector; + }; + ++struct adapter_group { ++ char adapter_name[SLOT_NAME_SIZE]; ++ struct pathgroup *pgp; ++ int num_hosts; ++ vector host_groups; ++ int next_host_index; ++}; ++ ++struct host_group { ++ int host_no; ++ int num_paths; ++ vector paths; ++}; ++ + struct path * alloc_path (void); + struct pathgroup * alloc_pathgroup (void); + struct multipath * alloc_multipath (void); +@@ -263,6 +278,14 @@ void free_multipath_attributes (struct m + void drop_multipath (vector mpvec, char * wwid, enum free_path_mode free_paths); + void free_multipathvec (vector mpvec, enum free_path_mode free_paths); + ++struct adapter_group * alloc_adaptergroup(void); ++struct host_group * alloc_hostgroup(void); ++void free_adaptergroup(vector adapters); ++void free_hostgroup(vector hostgroups); ++ ++int store_adaptergroup(vector adapters, struct adapter_group *agp); ++int store_hostgroup(vector hostgroupvec, struct host_group *hgp); ++ + int store_path (vector pathvec, struct path * pp); + int store_pathgroup (vector pgvec, struct pathgroup * pgp); + diff --git a/0091-RHBZ-1069584-fix-empty-values-fast-io-fail-and-dev-loss.patch b/0091-RHBZ-1069584-fix-empty-values-fast-io-fail-and-dev-loss.patch new file mode 100644 index 0000000..d164de1 --- /dev/null +++ b/0091-RHBZ-1069584-fix-empty-values-fast-io-fail-and-dev-loss.patch @@ -0,0 +1,38 @@ +--- + libmultipath/dict.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +Index: multipath-tools-130222/libmultipath/dict.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/dict.c ++++ multipath-tools-130222/libmultipath/dict.c +@@ -43,6 +43,9 @@ def_fast_io_fail_handler(vector strvec) + char * buff; + + buff = set_value(strvec); ++ if (!buff) ++ return 1; ++ + if (strlen(buff) == 3 && !strcmp(buff, "off")) + conf->fast_io_fail = MP_FAST_IO_FAIL_OFF; + else if (sscanf(buff, "%d", &conf->fast_io_fail) != 1 || +@@ -1002,6 +1005,9 @@ hw_dev_loss_handler(vector strvec) + char * buff; + struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable); + ++ if (!hwe) ++ return 1; ++ + buff = set_value(strvec); + if (!buff) + return 1; +@@ -1021,6 +1027,9 @@ hw_pgpolicy_handler(vector strvec) + char * buff; + struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable); + ++ if (!hwe) ++ return 1; ++ + buff = set_value(strvec); + + if (!buff) diff --git a/0092-UPBZ-1104605-reload-on-rename.patch b/0092-UPBZ-1104605-reload-on-rename.patch new file mode 100644 index 0000000..465257c --- /dev/null +++ b/0092-UPBZ-1104605-reload-on-rename.patch @@ -0,0 +1,63 @@ +--- + libmultipath/configure.c | 11 +++++++++++ + libmultipath/configure.h | 1 + + libmultipath/devmapper.c | 3 +-- + 3 files changed, 13 insertions(+), 2 deletions(-) + +Index: multipath-tools-130222/libmultipath/configure.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/configure.c ++++ multipath-tools-130222/libmultipath/configure.c +@@ -394,6 +394,8 @@ select_action (struct multipath * mpp, v + cmpp->alias, mpp->alias); + strncpy(mpp->alias_old, cmpp->alias, WWID_SIZE); + mpp->action = ACT_RENAME; ++ if (force_reload) ++ mpp->action = ACT_RENAME2; + return; + } + mpp->action = ACT_CREATE; +@@ -632,6 +634,15 @@ domap (struct multipath * mpp, char * pa + r = dm_rename(mpp->alias_old, mpp->alias); + break; + ++ case ACT_RENAME2: ++ r = dm_rename(mpp->alias_old, mpp->alias); ++ if (r) { ++ r = dm_addmap_reload(mpp, params); ++ if (r) ++ r = dm_simplecmd_noflush(DM_DEVICE_RESUME, mpp->alias, MPATH_UDEV_RELOAD_FLAG); ++ } ++ break; ++ + default: + break; + } +Index: multipath-tools-130222/libmultipath/configure.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/configure.h ++++ multipath-tools-130222/libmultipath/configure.h +@@ -18,6 +18,7 @@ enum actions { + ACT_RENAME, + ACT_CREATE, + ACT_RESIZE, ++ ACT_RENAME2, + }; + + #define FLUSH_ONE 1 +Index: multipath-tools-130222/libmultipath/devmapper.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/devmapper.c ++++ multipath-tools-130222/libmultipath/devmapper.c +@@ -565,10 +565,9 @@ dm_dev_t (const char * mapname, char * d + if (!dm_task_run(dmt)) + goto out; + +- if (!dm_task_get_info(dmt, &info)) ++ if (!dm_task_get_info(dmt, &info) || !info.exists) + goto out; + +- r = info.open_count; + if (snprintf(dev_t, len, "%i:%i", info.major, info.minor) > len) + goto out; + diff --git a/0093-UPBZ-1086825-user-friendly-name-remap.patch b/0093-UPBZ-1086825-user-friendly-name-remap.patch new file mode 100644 index 0000000..ab5abbd --- /dev/null +++ b/0093-UPBZ-1086825-user-friendly-name-remap.patch @@ -0,0 +1,199 @@ +--- + libmultipath/alias.c | 64 ++++++++++++++++++++++++++++++++++++++++++--- + libmultipath/alias.h | 2 + + libmultipath/propsel.c | 32 +++++++++++++++------- + libmultipath/structs_vec.c | 15 ++++++++++ + 4 files changed, 100 insertions(+), 13 deletions(-) + +Index: multipath-tools-130222/libmultipath/alias.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/alias.c ++++ multipath-tools-130222/libmultipath/alias.c +@@ -145,7 +145,7 @@ lookup_binding(FILE *f, char *map_wwid, + } + + static int +-rlookup_binding(FILE *f, char *buff, char *map_alias) ++rlookup_binding(FILE *f, char *buff, char *map_alias, char *prefix) + { + char line[LINE_MAX]; + unsigned int line_nr = 0; +@@ -164,7 +164,7 @@ rlookup_binding(FILE *f, char *buff, cha + alias = strtok(line, " \t"); + if (!alias) /* blank line */ + continue; +- curr_id = scan_devname(alias, NULL); /* TBD: Why this call? */ ++ curr_id = scan_devname(alias, prefix); + if (curr_id >= id) + id = curr_id + 1; + wwid = strtok(NULL, " \t"); +@@ -188,6 +188,11 @@ rlookup_binding(FILE *f, char *buff, cha + } + } + condlog(3, "No matching alias [%s] in bindings file.", map_alias); ++ ++ /* Get the theoretical id for this map alias. ++ * Used by use_existing_alias ++ */ ++ id = scan_devname(map_alias, prefix); + return id; + } + +@@ -237,6 +242,59 @@ allocate_binding(int fd, char *wwid, int + } + + char * ++use_existing_alias (char *wwid, char *file, char *alias_old, ++ char *prefix, int bindings_read_only) ++{ ++ char *alias = NULL; ++ int id = 0; ++ int fd, can_write; ++ char buff[WWID_SIZE]; ++ FILE *f; ++ ++ fd = open_file(file, &can_write, BINDINGS_FILE_HEADER); ++ if (fd < 0) ++ return NULL; ++ ++ f = fdopen(fd, "r"); ++ if (!f) { ++ condlog(0, "cannot fdopen on bindings file descriptor"); ++ close(fd); ++ return NULL; ++ } ++ /* lookup the binding. if it exsists, the wwid will be in buff ++ * either way, id contains the id for the alias ++ */ ++ id = rlookup_binding(f , buff, alias_old, prefix); ++ if (id < 0) ++ goto out; ++ ++ if (strlen(buff) > 0) { ++ /* if buff is our wwid, it's already ++ * allocated correctly ++ */ ++ if (strcmp(buff, wwid) == 0) ++ alias = STRDUP(alias_old); ++ else { ++ alias = NULL; ++ condlog(0, "alias %s already bound to wwid %s, cannot reuse", ++ alias_old, buff); ++ } ++ goto out; ++ } ++ ++ /* allocate the existing alias in the bindings file */ ++ if (can_write && id && !bindings_read_only) { ++ alias = allocate_binding(fd, wwid, id, prefix); ++ condlog(0, "Allocated existing binding [%s] for WWID [%s]", ++ alias, wwid); ++ } ++ ++out: ++ fclose(f); ++ return alias; ++} ++ ++char * + get_user_friendly_alias(char *wwid, char *file, char *prefix, + int bindings_read_only) + { +@@ -305,7 +363,7 @@ get_user_friendly_wwid(char *alias, char + return -1; + } + +- rlookup_binding(f, buff, alias); ++ rlookup_binding(f, buff, alias, NULL); + if (!strlen(buff)) { + fclose(f); + return -1; +Index: multipath-tools-130222/libmultipath/alias.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/alias.h ++++ multipath-tools-130222/libmultipath/alias.h +@@ -10,3 +10,5 @@ + char *get_user_friendly_alias(char *wwid, char *file, char *prefix, + int bindings_readonly); + int get_user_friendly_wwid(char *alias, char *buff, char *file); ++char *use_existing_alias (char *wwid, char *file, char *alias_old, ++ char *prefix, int bindings_read_only); +Index: multipath-tools-130222/libmultipath/propsel.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/propsel.c ++++ multipath-tools-130222/libmultipath/propsel.c +@@ -253,19 +253,31 @@ want_user_friendly_names(struct multipat + extern int + select_alias (struct multipath * mp) + { +- if (mp->mpe && mp->mpe->alias) ++ if (mp->mpe && mp->mpe->alias) { + mp->alias = STRDUP(mp->mpe->alias); +- else { +- mp->alias = NULL; +- if (want_user_friendly_names(mp)) { +- select_alias_prefix(mp); +- mp->alias = get_user_friendly_alias(mp->wwid, +- conf->bindings_file, mp->alias_prefix, conf->bindings_read_only); +- } +- if (mp->alias == NULL) +- mp->alias = STRDUP(mp->wwid); ++ goto out; + } + ++ mp->alias = NULL; ++ if (!want_user_friendly_names(mp)) ++ goto out; ++ ++ select_alias_prefix(mp); ++ ++ if (strlen(mp->alias_old) > 0) { ++ mp->alias = use_existing_alias(mp->wwid, conf->bindings_file, ++ mp->alias_old, mp->alias_prefix, ++ conf->bindings_read_only); ++ memset (mp->alias_old, 0, WWID_SIZE); ++ } ++ ++ if (mp->alias == NULL) ++ mp->alias = get_user_friendly_alias(mp->wwid, ++ conf->bindings_file, mp->alias_prefix, conf->bindings_read_only); ++out: ++ if (mp->alias == NULL) ++ mp->alias = STRDUP(mp->wwid); ++ + return mp->alias ? 0 : 1; + } + +Index: multipath-tools-130222/libmultipath/structs_vec.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/structs_vec.c ++++ multipath-tools-130222/libmultipath/structs_vec.c +@@ -430,6 +430,20 @@ out: + return NULL; + } + ++static void ++find_existing_alias (struct multipath * mpp, ++ struct vectors *vecs) ++{ ++ struct multipath * mp; ++ int i; ++ ++ vector_foreach_slot (vecs->mpvec, mp, i) ++ if (strcmp(mp->wwid, mpp->wwid) == 0) { ++ strncpy(mpp->alias_old, mp->alias, WWID_SIZE); ++ return; ++ } ++} ++ + extern struct multipath * + add_map_with_path (struct vectors * vecs, + struct path * pp, int add_vec) +@@ -443,6 +457,7 @@ add_map_with_path (struct vectors * vecs + mpp->hwe = pp->hwe; + + strcpy(mpp->wwid, pp->wwid); ++ find_existing_alias(mpp, vecs); + if (select_alias(mpp)) + goto out; + mpp->size = pp->size; diff --git a/0094-RHBZ-1086825-cleanup-remap.patch b/0094-RHBZ-1086825-cleanup-remap.patch new file mode 100644 index 0000000..7d85c2d --- /dev/null +++ b/0094-RHBZ-1086825-cleanup-remap.patch @@ -0,0 +1,107 @@ +--- + libmultipath/alias.c | 31 +++++++++++++++---------------- + libmultipath/propsel.c | 4 ++-- + 2 files changed, 17 insertions(+), 18 deletions(-) + +Index: multipath-tools-130222/libmultipath/alias.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/alias.c ++++ multipath-tools-130222/libmultipath/alias.c +@@ -149,13 +149,11 @@ rlookup_binding(FILE *f, char *buff, cha + { + char line[LINE_MAX]; + unsigned int line_nr = 0; +- int id = 0; + + buff[0] = '\0'; + + while (fgets(line, LINE_MAX, f)) { + char *c, *alias, *wwid; +- int curr_id; + + line_nr++; + c = strpbrk(line, "#\n\r"); +@@ -164,9 +162,6 @@ rlookup_binding(FILE *f, char *buff, cha + alias = strtok(line, " \t"); + if (!alias) /* blank line */ + continue; +- curr_id = scan_devname(alias, prefix); +- if (curr_id >= id) +- id = curr_id + 1; + wwid = strtok(NULL, " \t"); + if (!wwid){ + condlog(3, +@@ -184,16 +179,12 @@ rlookup_binding(FILE *f, char *buff, cha + "\nSetting wwid to %s", alias, wwid); + strncpy(buff, wwid, WWID_SIZE); + buff[WWID_SIZE - 1] = '\0'; +- return id; ++ return 0; + } + } + condlog(3, "No matching alias [%s] in bindings file.", map_alias); + +- /* Get the theoretical id for this map alias. +- * Used by use_existing_alias +- */ +- id = scan_devname(map_alias, prefix); +- return id; ++ return -1; + } + + static char * +@@ -264,9 +255,7 @@ use_existing_alias (char *wwid, char *fi + /* lookup the binding. if it exsists, the wwid will be in buff + * either way, id contains the id for the alias + */ +- id = rlookup_binding(f , buff, alias_old, prefix); +- if (id < 0) +- goto out; ++ rlookup_binding(f, buff, alias_old, prefix); + + if (strlen(buff) > 0) { + /* if buff is our wwid, it's already +@@ -279,11 +268,21 @@ use_existing_alias (char *wwid, char *fi + condlog(0, "alias %s already bound to wwid %s, cannot reuse", + alias_old, buff); + } +- goto out; ++ goto out; + } + + /* allocate the existing alias in the bindings file */ +- if (can_write && id && !bindings_read_only) { ++ id = scan_devname(alias_old, prefix); ++ if (id <= 0) ++ goto out; ++ ++ if (fflush(f) != 0) { ++ condlog(0, "cannot fflush bindings file stream : %s", ++ strerror(errno)); ++ goto out; ++ } ++ ++ if (can_write && !bindings_read_only) { + alias = allocate_binding(fd, wwid, id, prefix); + condlog(0, "Allocated existing binding [%s] for WWID [%s]", + alias, wwid); +Index: multipath-tools-130222/libmultipath/propsel.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/propsel.c ++++ multipath-tools-130222/libmultipath/propsel.c +@@ -263,13 +263,13 @@ select_alias (struct multipath * mp) + goto out; + + select_alias_prefix(mp); +- ++ + if (strlen(mp->alias_old) > 0) { + mp->alias = use_existing_alias(mp->wwid, conf->bindings_file, + mp->alias_old, mp->alias_prefix, + conf->bindings_read_only); + memset (mp->alias_old, 0, WWID_SIZE); +- } ++ } + + if (mp->alias == NULL) + mp->alias = get_user_friendly_alias(mp->wwid, diff --git a/0095-RHBZ-1127944-xtremIO-config.patch b/0095-RHBZ-1127944-xtremIO-config.patch new file mode 100644 index 0000000..6807cbc --- /dev/null +++ b/0095-RHBZ-1127944-xtremIO-config.patch @@ -0,0 +1,28 @@ +--- + libmultipath/hwtable.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +Index: multipath-tools-130222/libmultipath/hwtable.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/hwtable.c ++++ multipath-tools-130222/libmultipath/hwtable.c +@@ -1121,6 +1121,19 @@ static struct hwentry default_hw[] = { + .prio_name = PRIO_ALUA, + .prio_args = NULL, + }, ++ { ++ .vendor = "XtremIO", ++ .product = "XtremApp", ++ .features = DEFAULT_FEATURES, ++ .hwhandler = DEFAULT_HWHANDLER, ++ .selector = "queue-length 0", ++ .pgpolicy = MULTIBUS, ++ .pgfailback = -FAILBACK_IMMEDIATE, ++ .checker_name = DIRECTIO, ++ .fast_io_fail = 15, ++ .prio_name = DEFAULT_PRIO, ++ .prio_args = NULL, ++ }, + /* + * EOL + */ diff --git a/0096-RHBZ-979474-new-wildcards.patch b/0096-RHBZ-979474-new-wildcards.patch new file mode 100644 index 0000000..9025efe --- /dev/null +++ b/0096-RHBZ-979474-new-wildcards.patch @@ -0,0 +1,120 @@ +--- + libmultipath/print.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 83 insertions(+), 1 deletion(-) + +Index: multipath-tools-130222/libmultipath/print.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/print.c ++++ multipath-tools-130222/libmultipath/print.c +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + + #include "checkers.h" + #include "vector.h" +@@ -44,7 +45,7 @@ + * information printing helpers + */ + static int +-snprint_str (char * buff, size_t len, char * str) ++snprint_str (char * buff, size_t len, const char * str) + { + return snprintf(buff, len, "%s", str); + } +@@ -432,6 +433,83 @@ snprint_path_mpp (char * buff, size_t le + } + + static int ++snprint_host_attr (char * buff, size_t len, struct path * pp, char *attr) ++{ ++ struct udev_device *host_dev = NULL; ++ char host_id[32]; ++ const char *value = NULL; ++ int ret; ++ ++ if (pp->sg_id.proto_id != SCSI_PROTOCOL_FCP) ++ return snprintf(buff, len, "[undef]"); ++ sprintf(host_id, "host%d", pp->sg_id.host_no); ++ host_dev = udev_device_new_from_subsystem_sysname(conf->udev, "fc_host", ++ host_id); ++ if (!host_dev) { ++ condlog(1, "%s: No fc_host device for '%s'", pp->dev, host_id); ++ goto out; ++ } ++ value = udev_device_get_sysattr_value(host_dev, attr); ++ if (value) ++ ret = snprint_str(buff, len, value); ++ udev_device_unref(host_dev); ++out: ++ if (!value) ++ ret = snprintf(buff, len, "[unknown]"); ++ return ret; ++} ++ ++static int ++snprint_host_wwnn (char * buff, size_t len, struct path * pp) ++{ ++ return snprint_host_attr(buff, len, pp, "node_name"); ++} ++ ++static int ++snprint_host_wwpn (char * buff, size_t len, struct path * pp) ++{ ++ return snprint_host_attr(buff, len, pp, "port_name"); ++} ++ ++static int ++snprint_tgt_wwpn (char * buff, size_t len, struct path * pp) ++{ ++ struct udev_device *rport_dev = NULL; ++ char rport_id[32]; ++ const char *value = NULL; ++ int ret; ++ ++ if (pp->sg_id.proto_id != SCSI_PROTOCOL_FCP) ++ return snprintf(buff, len, "[undef]"); ++ sprintf(rport_id, "rport-%d:%d-%d", ++ pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.transport_id); ++ rport_dev = udev_device_new_from_subsystem_sysname(conf->udev, ++ "fc_remote_ports", rport_id); ++ if (!rport_dev) { ++ condlog(1, "%s: No fc_remote_port device for '%s'", pp->dev, ++ rport_id); ++ goto out; ++ } ++ value = udev_device_get_sysattr_value(rport_dev, "port_name"); ++ if (value) ++ ret = snprint_str(buff, len, value); ++ udev_device_unref(rport_dev); ++out: ++ if (!value) ++ ret = snprintf(buff, len, "[unknown]"); ++ return ret; ++} ++ ++ ++static int ++snprint_tgt_wwnn (char * buff, size_t len, struct path * pp) ++{ ++ if (pp->tgt_node_name[0] == '\0') ++ return snprintf(buff, len, "[undef]"); ++ return snprint_str(buff, len, pp->tgt_node_name); ++} ++ ++static int + snprint_path_checker (char * buff, size_t len, struct path * pp) + { + struct checker * c = &pp->checker; +@@ -475,6 +553,10 @@ struct path_data pd[] = { + {'S', "size", 0, snprint_path_size}, + {'z', "serial", 0, snprint_path_serial}, + {'m', "multipath", 0, snprint_path_mpp}, ++ {'N', "host WWNN", 0, snprint_host_wwnn}, ++ {'n', "target WWNN", 0, snprint_tgt_wwnn}, ++ {'R', "host WWPN", 0, snprint_host_wwpn}, ++ {'r', "target WWPN", 0, snprint_tgt_wwpn}, + {0, NULL, 0 , NULL} + }; + diff --git a/0097-RH-fix-coverity-errors.patch b/0097-RH-fix-coverity-errors.patch new file mode 100644 index 0000000..8ce0e87 --- /dev/null +++ b/0097-RH-fix-coverity-errors.patch @@ -0,0 +1,158 @@ +--- + kpartx/devmapper.c | 3 ++- + libmultipath/alias.c | 1 + + libmultipath/blacklist.c | 7 +++++++ + libmultipath/prioritizers/iet.c | 2 ++ + libmultipath/prioritizers/weightedpath.c | 5 ++++- + libmultipath/regex.c | 5 ++++- + libmultipath/sysfs.c | 3 ++- + libmultipath/util.c | 2 +- + 8 files changed, 23 insertions(+), 5 deletions(-) + +Index: multipath-tools-130222/kpartx/devmapper.c +=================================================================== +--- multipath-tools-130222.orig/kpartx/devmapper.c ++++ multipath-tools-130222/kpartx/devmapper.c +@@ -132,8 +132,9 @@ dm_addmap (int task, const char *name, c + goto addout; + r = dm_task_run (dmt); + +- addout: ++addout: + dm_task_destroy (dmt); ++ free(prefixed_uuid); + + return r; + } +Index: multipath-tools-130222/libmultipath/alias.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/alias.c ++++ multipath-tools-130222/libmultipath/alias.c +@@ -328,6 +328,7 @@ get_user_friendly_alias(char *wwid, char + if (fflush(f) != 0) { + condlog(0, "cannot fflush bindings file stream : %s", + strerror(errno)); ++ free(alias); + fclose(f); + return NULL; + } +Index: multipath-tools-130222/libmultipath/blacklist.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/blacklist.c ++++ multipath-tools-130222/libmultipath/blacklist.c +@@ -79,6 +79,8 @@ set_ble_device (vector blist, char * ven + if (regcomp(&ble->vendor_reg, vendor, + REG_EXTENDED|REG_NOSUB)) { + FREE(vendor); ++ if (product) ++ FREE(product); + return 1; + } + ble->vendor = vendor; +@@ -87,6 +89,10 @@ set_ble_device (vector blist, char * ven + if (regcomp(&ble->product_reg, product, + REG_EXTENDED|REG_NOSUB)) { + FREE(product); ++ if (vendor) { ++ ble->vendor = NULL; ++ FREE(vendor); ++ } + return 1; + } + ble->product = product; +@@ -189,6 +195,7 @@ setup_default_blist (struct config * con + STRDUP(hwe->bl_product), + ORIGIN_DEFAULT)) { + FREE(ble); ++ vector_del_slot(conf->blist_device, VECTOR_SIZE(conf->blist_device) - 1); + return 1; + } + } +Index: multipath-tools-130222/libmultipath/prioritizers/iet.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/prioritizers/iet.c ++++ multipath-tools-130222/libmultipath/prioritizers/iet.c +@@ -109,6 +109,7 @@ int iet_prio(const char *dev, char * arg + ssize_t nchars = readlink(path, buffer, sizeof(buffer)-1); + if (nchars != -1) { + char *device; ++ buffer[nchars] = '\0'; + device = find_regex(buffer,"(sd[a-z]+)"); + // if device parsed is the right one + if (device!=NULL && strncmp(device, dev, strlen(device)) == 0) { +@@ -118,6 +119,7 @@ int iet_prio(const char *dev, char * arg + if (ip!=NULL && strncmp(ip, preferredip, strlen(ip)) == 0) { + // high prio + free(ip); ++ free(device); + closedir(dir_p); + return 20; + } +Index: multipath-tools-130222/libmultipath/prioritizers/weightedpath.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/prioritizers/weightedpath.c ++++ multipath-tools-130222/libmultipath/prioritizers/weightedpath.c +@@ -61,8 +61,10 @@ int prio_path_weight(struct path *pp, ch + regex = get_next_string(&temp, split_char); + + /* Return default priority if the argument is not parseable */ +- if (!regex) ++ if (!regex) { ++ FREE(arg); + return priority; ++ } + + if (!strcmp(regex, HBTL)) { + sprintf(path, "%d:%d:%d:%d", pp->sg_id.host_no, +@@ -72,6 +74,7 @@ int prio_path_weight(struct path *pp, ch + } else { + condlog(0, "%s: %s - Invalid arguments", pp->dev, + pp->prio.name); ++ FREE(arg); + return priority; + } + +Index: multipath-tools-130222/libmultipath/regex.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/regex.c ++++ multipath-tools-130222/libmultipath/regex.c +@@ -3936,8 +3936,11 @@ int eflags; + regs.num_regs = nmatch; + regs.start = TALLOC(nmatch, regoff_t); + regs.end = TALLOC(nmatch, regoff_t); +- if (regs.start == NULL || regs.end == NULL) ++ if (regs.start == NULL || regs.end == NULL) { ++ free(regs.start); ++ free(regs.end); + return (int) REG_NOMATCH; ++ } + } + + /* Perform the searching operation. */ +Index: multipath-tools-130222/libmultipath/sysfs.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/sysfs.c ++++ multipath-tools-130222/libmultipath/sysfs.c +@@ -88,7 +88,8 @@ ssize_t sysfs_attr_get_value(struct udev + } else if (size == value_len) { + condlog(4, "overflow while reading from %s", devpath); + size = 0; +- } ++ } else ++ value[size] = '\0'; + + close(fd); + return size; +Index: multipath-tools-130222/libmultipath/util.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/util.c ++++ multipath-tools-130222/libmultipath/util.c +@@ -175,7 +175,7 @@ devt2devname (char *devname, int devname + sprintf(block_path,"/sys/dev/block/%u:%u", major, minor); + if (lstat(block_path, &statbuf) == 0) { + if (S_ISLNK(statbuf.st_mode) && +- readlink(block_path, dev, FILE_NAME_SIZE) > 0) { ++ readlink(block_path, dev, FILE_NAME_SIZE-1) > 0) { + char *p = strrchr(dev, '/'); + + if (!p) { diff --git a/0098-UPBZ-1067171-mutipath-i.patch b/0098-UPBZ-1067171-mutipath-i.patch new file mode 100644 index 0000000..cf41863 --- /dev/null +++ b/0098-UPBZ-1067171-mutipath-i.patch @@ -0,0 +1,332 @@ +--- + libmultipath/config.h | 15 ++++++++- + libmultipath/configure.c | 2 - + libmultipath/discovery.c | 5 +-- + multipath/main.c | 75 +++++++++++++++++++++++++---------------------- + multipath/multipath.8 | 5 ++- + 5 files changed, 61 insertions(+), 41 deletions(-) + +Index: multipath-tools-130222/libmultipath/config.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/config.h ++++ multipath-tools-130222/libmultipath/config.h +@@ -23,6 +23,17 @@ enum devtypes { + DEV_DEVMAP + }; + ++enum mpath_cmds { ++ CMD_CREATE, ++ CMD_DRY_RUN, ++ CMD_LIST_SHORT, ++ CMD_LIST_LONG, ++ CMD_VALID_PATH, ++ CMD_REMOVE_WWID, ++ CMD_RESET_WWIDS, ++ CMD_ADD_WWID, ++}; ++ + struct hwentry { + char * vendor; + char * product; +@@ -79,8 +90,7 @@ struct mpentry { + + struct config { + int verbosity; +- int dry_run; +- int list; ++ enum mpath_cmds cmd; + int pgpolicy_flag; + int pgpolicy; + enum devtypes dev_type; +@@ -98,6 +108,7 @@ struct config { + int max_fds; + int force_reload; + int queue_without_daemon; ++ int ignore_wwids; + int checker_timeout; + int daemon; + int flush_on_last_del; +Index: multipath-tools-130222/multipath/main.c +=================================================================== +--- multipath-tools-130222.orig/multipath/main.c ++++ multipath-tools-130222/multipath/main.c +@@ -85,7 +85,7 @@ usage (char * progname) + { + fprintf (stderr, VERSION_STRING); + fprintf (stderr, "Usage:\n"); +- fprintf (stderr, " %s [-a|-A|-c|-w|-W] [-d] [-T tm:val] [-r] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname); ++ fprintf (stderr, " %s [-a|-A|-c|-w|-W] [-d] [-T tm:val] [-r] [-i] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname); + fprintf (stderr, " %s -l|-ll|-f [-v lvl] [-b fil] [dev]\n", progname); + fprintf (stderr, " %s -F [-v lvl]\n", progname); + fprintf (stderr, " %s -t\n", progname); +@@ -109,6 +109,7 @@ usage (char * progname) + " -d dry run, do not create or update devmaps\n" \ + " -t dump internal hardware table\n" \ + " -r force devmap reload\n" \ ++ " -i ignore wwids file\n" \ + " -B treat the bindings file as read only\n" \ + " -p policy failover|multibus|group_by_serial|group_by_prio\n" \ + " -b fil bindings file location\n" \ +@@ -209,18 +210,19 @@ get_dm_mpvec (vector curmp, vector pathv + * If not in "fast list mode", we need to fetch information + * about them + */ +- if (conf->list != 1) ++ if (conf->cmd != CMD_LIST_SHORT) + update_paths(mpp); + +- if (conf->list > 1) ++ if (conf->cmd == CMD_LIST_LONG) + mpp->bestpg = select_path_group(mpp); + + disassemble_status(status, mpp); + +- if (conf->list) ++ if (conf->cmd == CMD_LIST_SHORT || ++ conf->cmd == CMD_LIST_LONG) + print_multipath_topology(mpp, conf->verbosity); + +- if (!conf->dry_run) ++ if (conf->cmd == CMD_CREATE) + reinstate_paths(mpp); + } + return 0; +@@ -262,10 +264,11 @@ configure (void) + /* + * if we have a blacklisted device parameter, exit early + */ +- if (dev && conf->dev_type == DEV_DEVNODE && conf->dry_run != 3 && ++ if (dev && conf->dev_type == DEV_DEVNODE && ++ conf->cmd != CMD_REMOVE_WWID && + (filter_devnode(conf->blist_devnode, + conf->elist_devnode, dev) > 0)) { +- if (conf->dry_run == 2) ++ if (conf->cmd == CMD_VALID_PATH) + printf("%s is not a valid multipath device path\n", + conf->dev); + goto out; +@@ -278,13 +281,13 @@ configure (void) + int failed = get_refwwid(conf->dev, conf->dev_type, pathvec, + &refwwid); + if (!refwwid) { +- if (failed == 2 && conf->dry_run == 2) ++ if (failed == 2 && conf->cmd == CMD_VALID_PATH) + printf("%s is not a valid multipath device path\n", conf->dev); + else + condlog(3, "scope is nul"); + goto out; + } +- if (conf->dry_run == 3) { ++ if (conf->cmd == CMD_REMOVE_WWID) { + r = remove_wwid(refwwid); + if (r == 0) + printf("wwid '%s' removed\n", refwwid); +@@ -295,7 +298,7 @@ configure (void) + } + goto out; + } +- if (conf->dry_run == 5) { ++ if (conf->cmd == CMD_ADD_WWID) { + r = remember_wwid(refwwid); + if (r == 0) + printf("wwid '%s' added\n", refwwid); +@@ -305,13 +308,13 @@ configure (void) + goto out; + } + condlog(3, "scope limited to %s", refwwid); +- if (conf->dry_run == 2) { +- if (check_wwids_file(refwwid, 0) == 0){ +- printf("%s is a valid multipath device path\n", conf->dev); ++ if (conf->cmd == CMD_VALID_PATH) { ++ if (conf->ignore_wwids || ++ check_wwids_file(refwwid, 0) == 0) + r = 0; +- } +- else +- printf("%s is not a valid multipath device path\n", conf->dev); ++ ++ printf("%s %s a valid multipath device path\n", ++ conf->dev, r == 0 ? "is" : "is not"); + goto out; + } + } +@@ -319,13 +322,13 @@ configure (void) + /* + * get a path list + */ +- if (conf->dev && !conf->list) ++ if (conf->dev) + di_flag = DI_WWID; + +- if (conf->list > 1) ++ if (conf->cmd == CMD_LIST_LONG) + /* extended path info '-ll' */ + di_flag |= DI_SYSFS | DI_CHECKER; +- else if (conf->list) ++ else if (conf->cmd == CMD_LIST_SHORT) + /* minimum path info '-l' */ + di_flag |= DI_SYSFS; + else +@@ -345,7 +348,7 @@ configure (void) + + filter_pathvec(pathvec, refwwid); + +- if (conf->list) { ++ if (conf->cmd != CMD_CREATE && conf->cmd != CMD_DRY_RUN) { + r = 0; + goto out; + } +@@ -440,7 +443,7 @@ main (int argc, char *argv[]) + int r = 1; + long int timestamp = -1; + int valid = -1; +- while ((arg = getopt(argc, argv, ":aAdchl::FfM:v:p:b:BrtT:qwW")) != EOF ) { ++ while ((arg = getopt(argc, argv, ":aAdchl::FfM:v:p:b:BritT:qwW")) != EOF ) { + switch(arg) { + case 'T': + if (optarg[0] == ':') +@@ -476,7 +479,7 @@ main (int argc, char *argv[]) + if (dm_prereq()) + exit(1); + +- while ((arg = getopt(argc, argv, ":aAdchl::FfM:v:p:b:BrtT:qwW")) != EOF ) { ++ while ((arg = getopt(argc, argv, ":aAdchl::FfM:v:p:b:BritT:qwW")) != EOF ) { + switch(arg) { + case 1: printf("optarg : %s\n",optarg); + break; +@@ -499,11 +502,11 @@ main (int argc, char *argv[]) + conf->allow_queueing = 1; + break; + case 'c': +- conf->dry_run = 2; ++ conf->cmd = CMD_VALID_PATH; + break; + case 'd': +- if (!conf->dry_run) +- conf->dry_run = 1; ++ if (conf->cmd == CMD_CREATE) ++ conf->cmd = CMD_DRY_RUN; + break; + case 'f': + conf->remove = FLUSH_ONE; +@@ -512,11 +515,10 @@ main (int argc, char *argv[]) + conf->remove = FLUSH_ALL; + break; + case 'l': +- conf->list = 1; +- conf->dry_run = 1; +- + if (optarg && !strncmp(optarg, "l", 1)) +- conf->list++; ++ conf->cmd = CMD_LIST_LONG; ++ else ++ conf->cmd = CMD_LIST_SHORT; + + break; + case 'M': +@@ -535,6 +537,9 @@ main (int argc, char *argv[]) + case 'r': + conf->force_reload = 1; + break; ++ case 'i': ++ conf->ignore_wwids = 1; ++ break; + case 't': + r = dump_config(); + goto out; +@@ -548,13 +553,13 @@ main (int argc, char *argv[]) + usage(argv[0]); + exit(0); + case 'w': +- conf->dry_run = 3; ++ conf->cmd = CMD_REMOVE_WWID; + break; + case 'W': +- conf->dry_run = 4; ++ conf->cmd = CMD_RESET_WWIDS; + break; + case 'a': +- conf->dry_run = 5; ++ conf->cmd = CMD_ADD_WWID; + break; + case ':': + fprintf(stderr, "Missing option argument\n"); +@@ -600,16 +605,16 @@ main (int argc, char *argv[]) + } + dm_init(); + +- if (conf->dry_run == 2 && ++ if (conf->cmd == CMD_VALID_PATH && + (!conf->dev || conf->dev_type == DEV_DEVMAP)) { + condlog(0, "the -c option requires a path to check"); + goto out; + } +- if (conf->dry_run == 3 && !conf->dev) { ++ if (conf->cmd == CMD_REMOVE_WWID && !conf->dev) { + condlog(0, "the -w option requires a device"); + goto out; + } +- if (conf->dry_run == 4) { ++ if (conf->cmd == CMD_RESET_WWIDS) { + struct multipath * mpp; + int i; + vector curmp; +Index: multipath-tools-130222/multipath/multipath.8 +=================================================================== +--- multipath-tools-130222.orig/multipath/multipath.8 ++++ multipath-tools-130222/multipath/multipath.8 +@@ -8,7 +8,7 @@ multipath \- Device mapper target autoco + .RB [\| \-b\ \c + .IR bindings_file \|] + .RB [\| \-d \|] +-.RB [\| \-h | \-l | \-ll | \-f | \-t | \-F | \-B | \-c | \-q | \|-r | \-a | \-A | \-w | \-W \|] ++.RB [\| \-h | \-l | \-ll | \-f | \-t | \-F | \-B | \-c | \-q | \|-r | \-r | \-a | \-A | \-w | \-W \|] + .RB [\| \-p\ \c + .BR failover | multibus | group_by_serial | group_by_prio | group_by_node_name \|] + .RB [\| device \|] +@@ -55,6 +55,9 @@ print internal hardware table to stdout + .B \-r + force devmap reload + .TP ++.B \-i ++ignore wwids file when processing devices ++.TP + .B \-B + treat the bindings file as read only + .TP +Index: multipath-tools-130222/libmultipath/configure.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/configure.c ++++ multipath-tools-130222/libmultipath/configure.c +@@ -580,7 +580,7 @@ domap (struct multipath * mpp, char * pa + /* + * last chance to quit before touching the devmaps + */ +- if (conf->dry_run && mpp->action != ACT_NOTHING) { ++ if (conf->cmd == CMD_DRY_RUN && mpp->action != ACT_NOTHING) { + print_multipath_topology(mpp, conf->verbosity); + return DOMAP_DRY; + } +Index: multipath-tools-130222/libmultipath/discovery.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/discovery.c ++++ multipath-tools-130222/libmultipath/discovery.c +@@ -54,7 +54,8 @@ store_pathinfo (vector pathvec, vector h + } + pp->udev = udev_device_ref(udevice); + err = pathinfo(pp, hwtable, +- (conf->dry_run == 3)? flag : (flag | DI_BLACKLIST)); ++ (conf->cmd == CMD_REMOVE_WWID)? flag : ++ (flag | DI_BLACKLIST)); + if (err) + goto out; + +@@ -1101,7 +1102,7 @@ get_uid (struct path * pp) + + memset(pp->wwid, 0, WWID_SIZE); + value = udev_device_get_property_value(pp->udev, pp->uid_attribute); +- if ((!value || strlen(value) == 0) && conf->dry_run == 2) ++ if ((!value || strlen(value) == 0) && conf->cmd == CMD_VALID_PATH) + value = getenv(pp->uid_attribute); + if (value && strlen(value)) { + size_t len = WWID_SIZE; diff --git a/0099-RH-add-all-devs.patch b/0099-RH-add-all-devs.patch new file mode 100644 index 0000000..aca6d4c --- /dev/null +++ b/0099-RH-add-all-devs.patch @@ -0,0 +1,170 @@ +--- + libmultipath/config.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++- + libmultipath/config.h | 1 + libmultipath/dict.c | 38 +++++++++++++++++++++++++++++ + 3 files changed, 102 insertions(+), 1 deletion(-) + +Index: multipath-tools-130222/libmultipath/config.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/config.c ++++ multipath-tools-130222/libmultipath/config.c +@@ -113,6 +113,8 @@ find_hwe (vector hwtable, char * vendor, + * continuing to the generic entries + */ + vector_foreach_slot_backwards (hwtable, tmp, i) { ++ if (tmp->all_devs == 1) ++ continue; + if (hwe_regmatch(tmp, &hwe)) + continue; + ret = tmp; +@@ -348,6 +350,62 @@ merge_hwe (struct hwentry * dst, struct + return 0; + } + ++#define overwrite_str(s) \ ++do { \ ++ if (src->s) { \ ++ if (dst->s) \ ++ FREE(dst->s); \ ++ if (!(dst->s = set_param_str(src->s))) \ ++ return 1; \ ++ } \ ++} while(0) ++ ++#define overwrite_num(s) \ ++do { \ ++ if (src->s) \ ++ dst->s = src->s; \ ++} while(0) ++ ++static int ++overwrite_hwe (struct hwentry * dst, struct hwentry * src) ++{ ++ overwrite_str(vendor); ++ overwrite_str(product); ++ overwrite_str(revision); ++ overwrite_str(uid_attribute); ++ overwrite_str(features); ++ overwrite_str(hwhandler); ++ overwrite_str(selector); ++ overwrite_str(checker_name); ++ overwrite_str(prio_name); ++ overwrite_str(prio_args); ++ overwrite_str(alias_prefix); ++ overwrite_str(bl_product); ++ overwrite_num(pgpolicy); ++ overwrite_num(pgfailback); ++ overwrite_num(rr_weight); ++ overwrite_num(no_path_retry); ++ overwrite_num(minio); ++ overwrite_num(minio_rq); ++ overwrite_num(pg_timeout); ++ overwrite_num(flush_on_last_del); ++ overwrite_num(fast_io_fail); ++ overwrite_num(dev_loss); ++ overwrite_num(user_friendly_names); ++ overwrite_num(retain_hwhandler); ++ overwrite_num(detect_prio); ++ ++ /* ++ * Make sure features is consistent with ++ * no_path_retry ++ */ ++ if (dst->no_path_retry == NO_PATH_RETRY_FAIL) ++ remove_feature(&dst->features, "queue_if_no_path"); ++ else if (dst->no_path_retry != NO_PATH_RETRY_UNDEF) ++ add_feature(&dst->features, "queue_if_no_path"); ++ return 0; ++} ++ + int + store_hwe (vector hwtable, struct hwentry * dhwe) + { +@@ -431,7 +489,11 @@ restart: + break; + j = n; + vector_foreach_slot_after(hw, hwe2, j) { +- if (conf->hw_strmatch) { ++ if (hwe2->all_devs == 1) { ++ overwrite_hwe(hwe1, hwe2); ++ continue; ++ } ++ else if (conf->hw_strmatch) { + if (hwe_strmatch(hwe2, hwe1)) + continue; + } +Index: multipath-tools-130222/libmultipath/config.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/config.h ++++ multipath-tools-130222/libmultipath/config.h +@@ -47,6 +47,7 @@ struct hwentry { + char * prio_args; + char * alias_prefix; + ++ int all_devs; + int pgpolicy; + int pgfailback; + int rr_weight; +Index: multipath-tools-130222/libmultipath/dict.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/dict.c ++++ multipath-tools-130222/libmultipath/dict.c +@@ -918,6 +918,32 @@ device_handler(vector strvec) + } + + static int ++all_devs_handler(vector strvec) ++{ ++ char * buff; ++ struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable); ++ ++ 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->all_devs = 0; ++ else if ((strlen(buff) == 3 && !strcmp(buff, "yes")) || ++ (strlen(buff) == 1 && !strcmp(buff, "1"))) ++ hwe->all_devs = 1; ++ else ++ hwe->all_devs = 0; ++ ++ FREE(buff); ++ return 0; ++} ++ ++static int + vendor_handler(vector strvec) + { + struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable); +@@ -2182,6 +2208,17 @@ snprint_hw_dev_loss(char * buff, int len + } + + static int ++snprint_hw_all_devs (char *buff, int len, void *data) ++{ ++ struct hwentry * hwe = (struct hwentry *)data; ++ ++ if (!hwe->all_devs) ++ return 0; ++ ++ return snprintf(buff, len, "yes"); ++} ++ ++static int + snprint_hw_vendor (char * buff, int len, void * data) + { + struct hwentry * hwe = (struct hwentry *)data; +@@ -2968,6 +3005,7 @@ init_keywords(void) + install_keyword_root("devices", &devices_handler); + install_keyword_multi("device", &device_handler, NULL); + install_sublevel(); ++ install_keyword("all_devs", &all_devs_handler, &snprint_hw_all_devs); + install_keyword("vendor", &vendor_handler, &snprint_hw_vendor); + install_keyword("product", &product_handler, &snprint_hw_product); + install_keyword("revision", &revision_handler, &snprint_hw_revision); diff --git a/0100-RHBZ-1067171-multipath-i-update.patch b/0100-RHBZ-1067171-multipath-i-update.patch new file mode 100644 index 0000000..9a67e7a --- /dev/null +++ b/0100-RHBZ-1067171-multipath-i-update.patch @@ -0,0 +1,54 @@ +--- + multipath/main.c | 25 ++++++++++++++++++++++++- + 1 file changed, 24 insertions(+), 1 deletion(-) + +Index: multipath-tools-130222/multipath/main.c +=================================================================== +--- multipath-tools-130222.orig/multipath/main.c ++++ multipath-tools-130222/multipath/main.c +@@ -198,6 +198,9 @@ get_dm_mpvec (vector curmp, vector pathv + continue; + } + ++ if (conf->cmd == CMD_VALID_PATH) ++ continue; ++ + dm_get_map(mpp->alias, &mpp->size, params); + condlog(3, "params = %s", params); + dm_get_status(mpp->alias, status); +@@ -308,7 +311,13 @@ configure (void) + goto out; + } + condlog(3, "scope limited to %s", refwwid); +- if (conf->cmd == CMD_VALID_PATH) { ++ /* If you are ignoring the wwids file and find_multipaths is ++ * set, you need to actually check if there are two available ++ * paths to determine if this path should be multipathed. To ++ * do this, we put off the check until after discovering all ++ * the paths */ ++ if (conf->cmd == CMD_VALID_PATH && ++ (!conf->find_multipaths || !conf->ignore_wwids)) { + if (conf->ignore_wwids || + check_wwids_file(refwwid, 0) == 0) + r = 0; +@@ -348,6 +357,20 @@ configure (void) + + filter_pathvec(pathvec, refwwid); + ++ ++ if (conf->cmd == CMD_VALID_PATH) { ++ /* This only happens if find_multipaths is and ++ * ignore_wwids is set. ++ * If there is currently a multipath device matching ++ * the refwwid, or there is more than one path matching ++ * the refwwid, then the path is valid */ ++ if (VECTOR_SIZE(curmp) != 0 || VECTOR_SIZE(pathvec) > 1) ++ r = 0; ++ printf("%s %s a valid multipath device path\n", ++ conf->dev, r == 0 ? "is" : "is not"); ++ goto out; ++ } ++ + if (conf->cmd != CMD_CREATE && conf->cmd != CMD_DRY_RUN) { + r = 0; + goto out; diff --git a/0101-RH-adapter-name-wildcard.patch b/0101-RH-adapter-name-wildcard.patch new file mode 100644 index 0000000..3c67de5 --- /dev/null +++ b/0101-RH-adapter-name-wildcard.patch @@ -0,0 +1,33 @@ +--- + libmultipath/print.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +Index: multipath-tools-130222/libmultipath/print.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/print.c ++++ multipath-tools-130222/libmultipath/print.c +@@ -510,6 +510,16 @@ snprint_tgt_wwnn (char * buff, size_t le + } + + static int ++snprint_host_adapter (char * buff, size_t len, struct path * pp) ++{ ++ char adapter[SLOT_NAME_SIZE]; ++ ++ if (sysfs_get_host_adapter_name(pp, adapter)) ++ return snprintf(buff, len, "[undef]"); ++ return snprint_str(buff, len, adapter); ++} ++ ++static int + snprint_path_checker (char * buff, size_t len, struct path * pp) + { + struct checker * c = &pp->checker; +@@ -557,6 +567,7 @@ struct path_data pd[] = { + {'n', "target WWNN", 0, snprint_tgt_wwnn}, + {'R', "host WWPN", 0, snprint_host_wwpn}, + {'r', "target WWPN", 0, snprint_tgt_wwpn}, ++ {'a', "host adapter", 0, snprint_host_adapter}, + {0, NULL, 0 , NULL} + }; + diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 43f24b8..6f17674 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,7 +1,7 @@ Summary: Tools to manage multipath devices using device-mapper Name: device-mapper-multipath Version: 0.4.9 -Release: 67%{?dist} +Release: 68%{?dist} License: GPL+ Group: System Environment/Base URL: http://christophe.varoqui.free.fr/ @@ -57,7 +57,7 @@ Patch0046: 0046-RHBZ-883981-move-udev-rules.patch Patch0047: 0047-RHBZ-980777-kpartx-read-only-loop-devs.patch Patch0048: 0048-RH-print-defaults.patch Patch0049: 0049-RH-remove-ID_FS_TYPE.patch -#Patch0050: 0050-RH-listing-speedup.patch +Patch0050: 0050-RH-listing-speedup.patch Patch0051: 0051-UP-fix-cli-resize.patch Patch0052: 0052-RH-fix-bad-derefs.patch Patch0053: 0053-UP-fix-failback.patch @@ -88,6 +88,27 @@ Patch0076: 0076-RHBZ-1056686-add-hw_str_match.patch Patch0078: 0078-RHBZ-1054044-fix-mpathconf-manpage.patch Patch0079: 0079-RHBZ-1070581-add-wwid-option.patch Patch0080: 0080-RHBZ-1075796-cmdline-wwid.patch +Patch0081: 0081-RHBZ-1066264-check-prefix-on-rename.patch +Patch0082: 0082-UPBZ-1109995-no-sync-turs-on-pthread_cancel.patch +Patch0083: 0083-RHBZ-1080055-orphan-paths-on-reload.patch +Patch0084: 0084-RHBZ-1110000-multipath-man.patch +Patch0085: 0085-UPBZ-1110006-datacore-config.patch +Patch0086: 0086-RHBZ-1110007-orphan-path-on-failed-add.patch +Patch0087: 0087-RHBZ-1110013-config-error-checking.patch +Patch0088: 0088-RHBZ-1069811-configurable-prio-timeout.patch +Patch0089: 0089-RHBZ-1110016-add-noasync-option.patch +Patch0090: 0090-UPBZ-1080038-reorder-paths-for-round-robin.patch +Patch0091: 0091-RHBZ-1069584-fix-empty-values-fast-io-fail-and-dev-loss.patch +Patch0092: 0092-UPBZ-1104605-reload-on-rename.patch +Patch0093: 0093-UPBZ-1086825-user-friendly-name-remap.patch +Patch0094: 0094-RHBZ-1086825-cleanup-remap.patch +Patch0095: 0095-RHBZ-1127944-xtremIO-config.patch +Patch0096: 0096-RHBZ-979474-new-wildcards.patch +Patch0097: 0097-RH-fix-coverity-errors.patch +Patch0098: 0098-UPBZ-1067171-mutipath-i.patch +Patch0099: 0099-RH-add-all-devs.patch +Patch0100: 0100-RHBZ-1067171-multipath-i-update.patch +Patch0101: 0101-RH-adapter-name-wildcard.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -189,7 +210,7 @@ kpartx manages partition creation and removal for device-mapper devices. %patch0047 -p1 %patch0048 -p1 %patch0049 -p1 -# %%patch0050 -p1 +%patch0050 -p1 %patch0051 -p1 %patch0052 -p1 %patch0053 -p1 @@ -219,6 +240,27 @@ kpartx manages partition creation and removal for device-mapper devices. %patch0078 -p1 %patch0079 -p1 %patch0080 -p1 +%patch0081 -p1 +%patch0082 -p1 +%patch0083 -p1 +%patch0084 -p1 +%patch0085 -p1 +%patch0086 -p1 +%patch0087 -p1 +%patch0088 -p1 +%patch0089 -p1 +%patch0090 -p1 +%patch0091 -p1 +%patch0092 -p1 +%patch0093 -p1 +%patch0094 -p1 +%patch0095 -p1 +%patch0096 -p1 +%patch0097 -p1 +%patch0098 -p1 +%patch0099 -p1 +%patch0100 -p1 +%patch0101 -p1 cp %{SOURCE1} . %build @@ -317,6 +359,58 @@ bin/systemctl --no-reload enable multipathd.service >/dev/null 2>&1 ||: %{_mandir}/man8/kpartx.8.gz %changelog +* Tue Sep 16 2014 Benjamin Marzinski 0.4.9-68 +- Modify multipath.conf + * remove getuid_callout example +- Re-add 0050-RH-listing-speedup.patch +- Add 0081-RHBZ-1066264-check-prefix-on-rename.patch + * make multipath check the prefix on kpartx partitions during rename, and + copy the existing behaviour +- Add 0082-UPBZ-1109995-no-sync-turs-on-pthread_cancel.patch + * If async tur checker fails on threads, don't retry with the sync version +- Add 0083-RHBZ-1080055-orphan-paths-on-reload.patch + * Fix case where pathlist wasn't getting updated properly +- Add 0084-RHBZ-1110000-multipath-man.patch + * fix errors in multipath man page +- Add 0085-UPBZ-1110006-datacore-config.patch + * Add support for DataCore Virtual Disk +- Add 0086-RHBZ-1110007-orphan-path-on-failed-add.patch + * If multipathd fails to add path correctly, it now fully orphans the path +- Add 0087-RHBZ-1110013-config-error-checking.patch + * Improve multipath.conf error checking. +- Add 0088-RHBZ-1069811-configurable-prio-timeout.patch + * checker_timeout now adjusts the timeouts of the prioritizers as well. +- Add 0089-RHBZ-1110016-add-noasync-option.patch + * Add a new defaults option, "force_sync", that disables the async mode + of the path checkers. This is for cases where to many parallel checkers + hog the cpu +- Add 0090-UPBZ-1080038-reorder-paths-for-round-robin.patch + * make multipathd order paths for better throughput in round-robin mode +- Add 0091-RHBZ-1069584-fix-empty-values-fast-io-fail-and-dev-loss.patch + * check for null pointers in configuration reading code. +- Add 0092-UPBZ-1104605-reload-on-rename.patch + * Reload table on rename if necessary +- Add 0093-UPBZ-1086825-user-friendly-name-remap.patch + * Keep existing user_friend_name if possible +- Add 0094-RHBZ-1086825-cleanup-remap.patch + * Cleanup issues with upstream patch +- Add 0095-RHBZ-1127944-xtremIO-config.patch + * Add support for EMC ExtremIO devices +- Add 0096-RHBZ-979474-new-wildcards.patch + * Add N, n, R, and r path wildcards to print World Wide ids +- Add 0097-RH-fix-coverity-errors.patch + * Fix a number of unterminated strings and memory leaks on failure + paths. +- Add 0098-UPBZ-1067171-mutipath-i.patch + * Add -i option to ignore wwids file when checking for valid paths +- Add 0099-RH-add-all-devs.patch + * Add new devices config option all_devs. This makes the configuration + overwrite the specified values in all builtin configs +- Add 0100-RHBZ-1067171-multipath-i-update.patch + * make -i work correctly with find_multipaths +- Add 0101-RH-adapter-name-wildcard.patch + * Add 'a' path wildcard to print adapter name + * Sat Aug 16 2014 Fedora Release Engineering - 0.4.9-67 - Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild diff --git a/multipath.conf b/multipath.conf index 401992b..c7684fe 100644 --- a/multipath.conf +++ b/multipath.conf @@ -33,7 +33,6 @@ defaults { # polling_interval 10 # selector "round-robin 0" # path_grouping_policy multibus -# getuid_callout "/lib/udev/scsi_id --whitelisted --device=/dev/%n" # prio alua # path_checker readsector0 # rr_min_io 100 @@ -79,7 +78,6 @@ defaults { # vendor "COMPAQ " # product "HSV110 (C)COMPAQ" # path_grouping_policy multibus -# getuid_callout "/lib/udev/scsi_id --whitelisted --device=/dev/%n" # path_checker readsector0 # path_selector "round-robin 0" # hardware_handler "0"