diff --git a/0000-libmultipath-remove-last-of-rbd-code.patch b/0000-libmultipath-remove-last-of-rbd-code.patch deleted file mode 100644 index 7f26eb8cafa757b9d6736d085c86b51a124cbd1d..0000000000000000000000000000000000000000 --- a/0000-libmultipath-remove-last-of-rbd-code.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 1 Jun 2018 16:30:44 -0500 -Subject: [PATCH] libmultipath: remove last of rbd code - -My previous patch to remove the rbd code missed a little bit. - -Signed-off-by: Benjamin Marzinski ---- - kpartx/del-part-nodes.rules | 2 +- - libmultipath/structs.h | 1 - - 2 files changed, 1 insertion(+), 2 deletions(-) - -diff --git a/kpartx/del-part-nodes.rules b/kpartx/del-part-nodes.rules -index 17bc505..0ceecf5 100644 ---- a/kpartx/del-part-nodes.rules -+++ b/kpartx/del-part-nodes.rules -@@ -10,7 +10,7 @@ - # or create an udev rule file that sets ENV{DONT_DEL_PART_NODES}="1". - - SUBSYSTEM!="block", GOTO="end_del_part_nodes" --KERNEL!="sd*|dasd*|rbd*", GOTO="end_del_part_nodes" -+KERNEL!="sd*|dasd*", GOTO="end_del_part_nodes" - ACTION!="add|change", GOTO="end_del_part_nodes" - ENV{DEVTYPE}=="partition", GOTO="end_del_part_nodes" - -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index e5b698b..ca14315 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -61,7 +61,6 @@ enum sysfs_buses { - SYSFS_BUS_IDE, - SYSFS_BUS_CCW, - SYSFS_BUS_CCISS, -- SYSFS_BUS_RBD, - SYSFS_BUS_NVME, - }; - --- -2.7.4 - diff --git a/0001-libmpathpersist-limit-PRIN-allocation-length-to-8192.patch b/0001-libmpathpersist-limit-PRIN-allocation-length-to-8192.patch new file mode 100644 index 0000000000000000000000000000000000000000..d40166aa771096709f7be91c9934fe184630d0cb --- /dev/null +++ b/0001-libmpathpersist-limit-PRIN-allocation-length-to-8192.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 6 Mar 2020 21:50:30 +0100 +Subject: [PATCH] libmpathpersist: limit PRIN allocation length to 8192 bytes + +Some targets (notably the qemu-pr-helper) don't support PERSISTENT +RESERVE IN commands with more than 8192 bytes allocation length. +While I have found no explicit requirement in the SCSI specs that +the allocation lengh may not exceed 8k, an 8k limit is also enforced +by sg_persist(8), and actually by mpathpersist itself for the +--allocation-length option, but not for the auto-determined length. + +Fix that. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmpathpersist/mpath_pr_ioctl.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/libmpathpersist/mpath_pr_ioctl.c b/libmpathpersist/mpath_pr_ioctl.c +index 74b26b0c..1a28cba7 100644 +--- a/libmpathpersist/mpath_pr_ioctl.c ++++ b/libmpathpersist/mpath_pr_ioctl.c +@@ -543,5 +543,7 @@ int get_prin_length(int rq_servact) + mx_resp_len = 0; + break; + } ++ if (mx_resp_len > MPATH_MAX_PARAM_LEN) ++ mx_resp_len = MPATH_MAX_PARAM_LEN; + return mx_resp_len; + } +-- +2.17.2 + diff --git a/0001-libmultipath-fix-detect-alua-corner-case.patch b/0001-libmultipath-fix-detect-alua-corner-case.patch deleted file mode 100644 index 6d6fa64bd678c375bc57dadbdc7533a92c2e6169..0000000000000000000000000000000000000000 --- a/0001-libmultipath-fix-detect-alua-corner-case.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 8 Jun 2018 17:12:37 -0500 -Subject: [PATCH] libmultipath: fix detect alua corner case - -If retain_attach_hw_handler = no, then the paths tpgs state will never -be checked, and the multipath device will always select the alua -handler, if no other handler is selected. the paths tpgs state -should be checked, regardless of the retain_hwhandler value. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/propsel.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c -index af3ed62..fdb5953 100644 ---- a/libmultipath/propsel.c -+++ b/libmultipath/propsel.c -@@ -420,9 +420,11 @@ int select_hwhandler(struct config *conf, struct multipath *mp) - bool all_tpgs = true; - - dh_state = &handler[2]; -+ -+ vector_foreach_slot(mp->paths, pp, i) -+ all_tpgs = all_tpgs && (pp->tpgs > 0); - if (mp->retain_hwhandler != RETAIN_HWHANDLER_OFF) { - vector_foreach_slot(mp->paths, pp, i) { -- all_tpgs = all_tpgs && (pp->tpgs > 0); - if (get_dh_state(pp, dh_state, sizeof(handler) - 2) > 0 - && strcmp(dh_state, "detached")) { - memcpy(handler, "1 ", 2); --- -2.7.4 - diff --git a/0002-libmpathpersist-format_transportids-avoid-PROUT-over.patch b/0002-libmpathpersist-format_transportids-avoid-PROUT-over.patch new file mode 100644 index 0000000000000000000000000000000000000000..6164b26e1bcd937e6081d4d0168a0fef4dbc2a3b --- /dev/null +++ b/0002-libmpathpersist-format_transportids-avoid-PROUT-over.patch @@ -0,0 +1,93 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 6 Mar 2020 23:33:04 +0100 +Subject: [PATCH] libmpathpersist: format_transportids(): avoid PROUT overflow + +This limits the PERSISTENT RESERVE OUT data size to max. 8192 bytes. + +Signed-off-by: Benjamin Marzinski +--- + libmpathpersist/mpath_pr_ioctl.c | 31 +++++++++++++++++++++++++++++-- + 1 file changed, 29 insertions(+), 2 deletions(-) + +diff --git a/libmpathpersist/mpath_pr_ioctl.c b/libmpathpersist/mpath_pr_ioctl.c +index 1a28cba7..c78e8000 100644 +--- a/libmpathpersist/mpath_pr_ioctl.c ++++ b/libmpathpersist/mpath_pr_ioctl.c +@@ -1,5 +1,6 @@ + #include + #include ++#include + + #include + #include +@@ -138,38 +139,64 @@ retry : + return status; + } + ++/* ++ * Helper macro to avoid overflow of prout_param_descriptor in ++ * format_transportids(). Data must not be written past ++ * MPATH_MAX_PARAM_LEN bytes from struct prout_param_descriptor. ++ */ ++#define check_overflow(ofs, n, start, label) \ ++ do { \ ++ if ((ofs) + (n) + \ ++ offsetof(struct prout_param_descriptor, private_buffer) \ ++ > MPATH_MAX_PARAM_LEN) \ ++ { \ ++ (ofs) = (start); \ ++ goto label; \ ++ } \ ++ } while(0) ++ + uint32_t format_transportids(struct prout_param_descriptor *paramp) + { + unsigned int i = 0, len; + uint32_t buff_offset = 4; +- memset(paramp->private_buffer, 0, MPATH_MAX_PARAM_LEN); ++ memset(paramp->private_buffer, 0, sizeof(paramp->private_buffer)); + for (i=0; i < paramp->num_transportid; i++ ) + { ++ uint32_t start_offset = buff_offset; ++ ++ check_overflow(buff_offset, 1, start_offset, end_loop); + paramp->private_buffer[buff_offset] = (uint8_t)((paramp->trnptid_list[i]->format_code & 0xff)| + (paramp->trnptid_list[i]->protocol_id & 0xff)); + buff_offset += 1; + switch(paramp->trnptid_list[i]->protocol_id) + { + case MPATH_PROTOCOL_ID_FC: ++ check_overflow(buff_offset, 7 + 8 + 8, ++ start_offset, end_loop); + buff_offset += 7; + memcpy(¶mp->private_buffer[buff_offset], ¶mp->trnptid_list[i]->n_port_name, 8); + buff_offset +=8 ; + buff_offset +=8 ; + break; + case MPATH_PROTOCOL_ID_SAS: ++ check_overflow(buff_offset, 3 + 12, ++ start_offset, end_loop); + buff_offset += 3; + memcpy(¶mp->private_buffer[buff_offset], ¶mp->trnptid_list[i]->sas_address, 8); + buff_offset += 12; + break; + case MPATH_PROTOCOL_ID_ISCSI: +- buff_offset += 1; + len = (paramp->trnptid_list[i]->iscsi_name[1] & 0xff)+2; ++ check_overflow(buff_offset, 1 + len, ++ start_offset, end_loop); ++ buff_offset += 1; + memcpy(¶mp->private_buffer[buff_offset], ¶mp->trnptid_list[i]->iscsi_name,len); + buff_offset += len ; + break; + } + + } ++end_loop: + buff_offset -= 4; + paramp->private_buffer[0] = (unsigned char)((buff_offset >> 24) & 0xff); + paramp->private_buffer[1] = (unsigned char)((buff_offset >> 16) & 0xff); +-- +2.17.2 + diff --git a/0002-multipath-fix-setting-conf-version.patch b/0002-multipath-fix-setting-conf-version.patch deleted file mode 100644 index 624f45efd8ec37ae8c144946154d95751fadc635..0000000000000000000000000000000000000000 --- a/0002-multipath-fix-setting-conf-version.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 8 Jun 2018 17:23:07 -0500 -Subject: [PATCH] multipath: fix setting conf->version - -Commit d3b71498 stopped multipath from setting conf->version. Instead, -it was always being set to 0.0.0. Multipathd was still setting this -correctly. - -Fixes: d3b71498 "multipath: fix rcu thread cancellation hang" -Signed-off-by: Benjamin Marzinski ---- - libmultipath/devmapper.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index f2befad..8136d15 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -245,13 +245,13 @@ void libmp_dm_init(void) - int verbosity; - unsigned int version[3]; - -+ if (dm_prereq(version)) -+ exit(1); - conf = get_multipath_config(); - verbosity = conf->verbosity; -- memcpy(version, conf->version, sizeof(version)); -+ memcpy(conf->version, version, sizeof(version)); - put_multipath_config(conf); - dm_init(verbosity); -- if (dm_prereq(version)) -- exit(1); - dm_udev_set_sync_support(libmp_dm_udev_sync); - } - --- -2.7.4 - diff --git a/0003-libmpathpersist-mpath_format_readfullstatus-use-real.patch b/0003-libmpathpersist-mpath_format_readfullstatus-use-real.patch new file mode 100644 index 0000000000000000000000000000000000000000..6d0cf1e7fd1ad60aba4896f31df11336a2b135ce --- /dev/null +++ b/0003-libmpathpersist-mpath_format_readfullstatus-use-real.patch @@ -0,0 +1,54 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 6 Mar 2020 23:46:47 +0100 +Subject: [PATCH] libmpathpersist: mpath_format_readfullstatus(): use real + buffer size + +This changes no semantics, but it will allow changing the size of +prin_readfd.private_buffer in a follow-up patch. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmpathpersist/mpath_pr_ioctl.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/libmpathpersist/mpath_pr_ioctl.c b/libmpathpersist/mpath_pr_ioctl.c +index c78e8000..fadc9e10 100644 +--- a/libmpathpersist/mpath_pr_ioctl.c ++++ b/libmpathpersist/mpath_pr_ioctl.c +@@ -238,6 +238,8 @@ static void mpath_format_readfullstatus(struct prin_resp *pr_buff) + uint32_t additional_length, k, tid_len_len = 0; + char tempbuff[MPATH_MAX_PARAM_LEN]; + struct prin_fulldescr fdesc; ++ static const int pbuf_size = ++ sizeof(pr_buff->prin_descriptor.prin_readfd.private_buffer); + + convert_be32_to_cpu(&pr_buff->prin_descriptor.prin_readfd.prgeneration); + convert_be32_to_cpu(&pr_buff->prin_descriptor.prin_readfd.number_of_descriptor); +@@ -249,16 +251,18 @@ static void mpath_format_readfullstatus(struct prin_resp *pr_buff) + } + + additional_length = pr_buff->prin_descriptor.prin_readfd.number_of_descriptor; +- if (additional_length > MPATH_MAX_PARAM_LEN) { ++ if (additional_length > pbuf_size) { + condlog(3, "PRIN length %u exceeds max length %d", additional_length, +- MPATH_MAX_PARAM_LEN); ++ pbuf_size); + return; + } + + memset(&fdesc, 0, sizeof(struct prin_fulldescr)); + +- memcpy( tempbuff, pr_buff->prin_descriptor.prin_readfd.private_buffer,MPATH_MAX_PARAM_LEN ); +- memset(&pr_buff->prin_descriptor.prin_readfd.private_buffer, 0, MPATH_MAX_PARAM_LEN); ++ memcpy( tempbuff, pr_buff->prin_descriptor.prin_readfd.private_buffer, ++ pbuf_size); ++ memset(&pr_buff->prin_descriptor.prin_readfd.private_buffer, 0, ++ pbuf_size); + + p =(unsigned char *)tempbuff; + ppbuff = (char *)pr_buff->prin_descriptor.prin_readfd.private_buffer; +-- +2.17.2 + diff --git a/0003-mpathpersist-add-param-alltgpt-option.patch b/0003-mpathpersist-add-param-alltgpt-option.patch deleted file mode 100644 index 8485d3741b4807d5a0f6a31efac139e6b8af872d..0000000000000000000000000000000000000000 --- a/0003-mpathpersist-add-param-alltgpt-option.patch +++ /dev/null @@ -1,152 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 26 Jun 2018 16:30:11 -0500 -Subject: [PATCH] mpathpersist: add --param-alltgpt option - -From the limited testing I've been able to do, commit 5b54e772 -"mpathpersist: add all_tg_pt option", does appear to enable ---param-alltgpt to work correctly on devices that accept the ALL_TG_PT -flag, so I've added the option to mpathpersist. - -Signed-off-by: Benjamin Marzinski ---- - libmpathpersist/mpath_persist.c | 10 ++++------ - mpathpersist/main.c | 11 ++++++++--- - mpathpersist/main.h | 1 + - mpathpersist/mpathpersist.8 | 4 ++++ - multipath/multipath.conf.5 | 8 +++++--- - 5 files changed, 22 insertions(+), 12 deletions(-) - -diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c -index 6e9e67f..61818e0 100644 ---- a/libmpathpersist/mpath_persist.c -+++ b/libmpathpersist/mpath_persist.c -@@ -466,11 +466,14 @@ int mpath_prout_reg(struct multipath *mpp,int rq_servact, int rq_scope, - int rc; - int count=0; - int status = MPATH_PR_SUCCESS; -+ int all_tg_pt; - uint64_t sa_key = 0; - - if (!mpp) - return MPATH_PR_DMMP_ERROR; - -+ all_tg_pt = (mpp->all_tg_pt == ALL_TG_PT_ON || -+ paramp->sa_flags & MPATH_F_ALL_TG_PT_MASK); - active_pathcount = pathcount(mpp, PATH_UP) + pathcount(mpp, PATH_GHOST); - - if (active_pathcount == 0) { -@@ -478,10 +481,6 @@ int mpath_prout_reg(struct multipath *mpp,int rq_servact, int rq_scope, - return MPATH_PR_DMMP_ERROR; - } - -- if ( paramp->sa_flags & MPATH_F_ALL_TG_PT_MASK ) { -- condlog (1, "Warning: ALL_TG_PT is set. Configuration not supported"); -- } -- - struct threadinfo thread[active_pathcount]; - int hosts[active_pathcount]; - -@@ -518,8 +517,7 @@ int mpath_prout_reg(struct multipath *mpp,int rq_servact, int rq_scope, - condlog (1, "%s: %s path not up. Skip.", mpp->wwid, pp->dev); - continue; - } -- if (mpp->all_tg_pt == ALL_TG_PT_ON && -- pp->sg_id.host_no != -1) { -+ if (all_tg_pt && pp->sg_id.host_no != -1) { - for (k = 0; k < count; k++) { - if (pp->sg_id.host_no == hosts[k]) { - condlog(3, "%s: %s host %d matches skip.", pp->wwid, pp->dev, pp->sg_id.host_no); -diff --git a/mpathpersist/main.c b/mpathpersist/main.c -index 5b37f3a..99151fe 100644 ---- a/mpathpersist/main.c -+++ b/mpathpersist/main.c -@@ -118,7 +118,7 @@ int main (int argc, char * argv[]) - { - int option_index = 0; - -- c = getopt_long (argc, argv, "v:Cd:hHioZK:S:PAT:skrGILcRX:l:", -+ c = getopt_long (argc, argv, "v:Cd:hHioYZK:S:PAT:skrGILcRX:l:", - long_options, &option_index); - if (c == -1) - break; -@@ -158,6 +158,10 @@ int main (int argc, char * argv[]) - prout_flag = 1; - break; - -+ case 'Y': -+ param_alltgpt = 1; -+ ++num_prout_param; -+ break; - case 'Z': - param_aptpl = 1; - ++num_prout_param; -@@ -443,9 +447,9 @@ int main (int argc, char * argv[]) - } - - if (param_alltgpt) -- paramp->sa_flags |= 0x4; -+ paramp->sa_flags |= MPATH_F_ALL_TG_PT_MASK; - if (param_aptpl) -- paramp->sa_flags |= 0x1; -+ paramp->sa_flags |= MPATH_F_APTPL_MASK; - - if (num_transport) - { -@@ -698,6 +702,7 @@ static void usage(void) - " --hex|-H output response in hex\n" - " --in|-i request PR In command \n" - " --out|-o request PR Out command\n" -+ " --param-alltgpt|-Y PR Out parameter 'ALL_TG_PT\n" - " --param-aptpl|-Z PR Out parameter 'APTPL'\n" - " --read-keys|-k PR In: Read Keys\n" - " --param-sark=SARK|-S SARK PR Out parameter service " -diff --git a/mpathpersist/main.h b/mpathpersist/main.h -index 5c0e089..beb8a21 100644 ---- a/mpathpersist/main.h -+++ b/mpathpersist/main.h -@@ -6,6 +6,7 @@ static struct option long_options[] = { - {"hex", 0, NULL, 'H'}, - {"in", 0, NULL, 'i'}, - {"out", 0, NULL, 'o'}, -+ {"param-alltgpt", 0, NULL, 'Y'}, - {"param-aptpl", 0, NULL, 'Z'}, - {"param-rk", 1, NULL, 'K'}, - {"param-sark", 1, NULL, 'S'}, -diff --git a/mpathpersist/mpathpersist.8 b/mpathpersist/mpathpersist.8 -index a8982e6..885491d 100644 ---- a/mpathpersist/mpathpersist.8 -+++ b/mpathpersist/mpathpersist.8 -@@ -87,6 +87,10 @@ Request PR In command. - Request PR Out command. - . - .TP -+.B \--param-alltgpt|\-Y -+PR Out parameter 'ALL_TG_PT'. -+. -+.TP - .B \--param-aptpl|\-Z - PR Out parameter 'APTPL'. - . -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index e4b25a0..fb863fd 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -756,9 +756,11 @@ The default is: \fB\fR - . - .TP - .B all_tg_pt --This must be set to \fByes\fR to successfully use mpathpersist on arrays that --automatically set and clear registration keys on all target ports from a --host, instead of per target port per host. -+Set the 'all targets ports' flag when registering keys with mpathpersist. Some -+arrays automatically set and clear registration keys on all target ports from a -+host, instead of per target port per host. The ALL_TG_PT flag must be set to -+successfully use mpathpersist on these arrays. Setting this option is identical -+to calling mpathpersist with \fI--param-alltgpt\fR - .RS - .TP - The default is: \fBno\fR --- -2.7.4 - diff --git a/0004-libmultipath-assign-variable-to-make-gcc-happy.patch b/0004-libmultipath-assign-variable-to-make-gcc-happy.patch new file mode 100644 index 0000000000000000000000000000000000000000..8db8dd992f7604e3e5d421416f2508fae78359cf --- /dev/null +++ b/0004-libmultipath-assign-variable-to-make-gcc-happy.patch @@ -0,0 +1,42 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 25 Mar 2020 23:22:46 -0500 +Subject: [PATCH] libmultipath: assign variable to make gcc happy +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +There is nothing wrong with is_queueing not being set at the start +of __set_no_path_retry(), it will always get set before it is accessed, +but gcc 8.2.1 is failing with + +structs_vec.c: In function ‘__set_no_path_retry’: +structs_vec.c:339:7: error: ‘is_queueing’ may be used uninitialized in +this function [-Werror=maybe-uninitialized] + bool is_queueing; + ^~~~~~~~~~~ + +so, assign a value to make it happy. + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/structs_vec.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c +index 3dbbaa0f..077f2e42 100644 +--- a/libmultipath/structs_vec.c ++++ b/libmultipath/structs_vec.c +@@ -336,7 +336,7 @@ static void leave_recovery_mode(struct multipath *mpp) + + void __set_no_path_retry(struct multipath *mpp, bool check_features) + { +- bool is_queueing; ++ bool is_queueing = false; /* assign a value to make gcc happy */ + + check_features = check_features && mpp->features != NULL; + if (check_features) +-- +2.17.2 + diff --git a/0004-libmutipath-remove-unused-IDE-bus-type.patch b/0004-libmutipath-remove-unused-IDE-bus-type.patch deleted file mode 100644 index 5dda5a74a7137f97a4ed24f2c1dcd872f5d60c13..0000000000000000000000000000000000000000 --- a/0004-libmutipath-remove-unused-IDE-bus-type.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 26 Jun 2018 16:45:48 -0500 -Subject: [PATCH] libmutipath: remove unused IDE bus type - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/structs.h | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index ca14315..0a2623a 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -58,7 +58,6 @@ enum failback_mode { - enum sysfs_buses { - SYSFS_BUS_UNDEF, - SYSFS_BUS_SCSI, -- SYSFS_BUS_IDE, - SYSFS_BUS_CCW, - SYSFS_BUS_CCISS, - SYSFS_BUS_NVME, --- -2.7.4 - diff --git a/0005-libmutipath-don-t-close-fd-on-dm_lib_release.patch b/0005-libmutipath-don-t-close-fd-on-dm_lib_release.patch new file mode 100644 index 0000000000000000000000000000000000000000..dd4af7ea924cf23c7387ad6f8525da0cb3d22131 --- /dev/null +++ b/0005-libmutipath-don-t-close-fd-on-dm_lib_release.patch @@ -0,0 +1,66 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 25 Mar 2020 23:22:47 -0500 +Subject: [PATCH] libmutipath: don't close fd on dm_lib_release + +If dm_hold_control_open() isn't set, when dm_lib_release() is called, it +will close the control fd. The control fd will get re-opened on the next +dm_task_run() call, but if there is a dm_task_run() call already +in progress in another thread, it can fail. Since many of the +device-mapper callouts happen with the vecs lock held, this wasn't too +noticeable, but there is code that calls dm_task_run() without the +vecs lock held, notably the dmevent waiter code. + +Since, as Martin pointed out, dm_hold_control_open() hasn't always +existed in libdevmapper, check if it's supported on compilation, +and update the version requirements if so. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/Makefile | 4 ++++ + libmultipath/devmapper.c | 7 ++++++- + 2 files changed, 10 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/Makefile b/libmultipath/Makefile +index e5651e49..ad690a49 100644 +--- a/libmultipath/Makefile ++++ b/libmultipath/Makefile +@@ -36,6 +36,10 @@ ifneq ($(call check_func,dm_task_deferred_remove,/usr/include/libdevmapper.h),0) + CFLAGS += -DLIBDM_API_DEFERRED + endif + ++ifneq ($(call check_func,dm_hold_control_dev,/usr/include/libdevmapper.h),0) ++ CFLAGS += -DLIBDM_API_HOLD_CONTROL ++endif ++ + OBJS = memory.o parser.o vector.o devmapper.o callout.o \ + hwtable.o blacklist.o util.o dmparser.o config.o \ + structs.o discovery.o propsel.o dict.o \ +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index bed8ddc6..13a1cf53 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -108,7 +108,9 @@ dm_lib_prereq (void) + { + char version[64]; + int v[3]; +-#if defined(LIBDM_API_DEFERRED) ++#if defined(LIBDM_API_HOLD_CONTROL) ++ int minv[3] = {1, 2, 111}; ++#elif defined(LIBDM_API_DEFERRED) + int minv[3] = {1, 2, 89}; + #elif defined(DM_SUBSYSTEM_UDEV_FLAG0) + int minv[3] = {1, 2, 82}; +@@ -254,6 +256,9 @@ void libmp_dm_init(void) + memcpy(conf->version, version, sizeof(version)); + put_multipath_config(conf); + dm_init(verbosity); ++#ifdef LIBDM_API_HOLD_CONTROL ++ dm_hold_control_dev(1); ++#endif + dm_udev_set_sync_support(libmp_dm_udev_sync); + } + +-- +2.17.2 + diff --git a/0005-multipathd-add-new-protocol-path-wildcard.patch b/0005-multipathd-add-new-protocol-path-wildcard.patch deleted file mode 100644 index 479788ea083e7ca15ab4e82024fbbbd76d5adb3f..0000000000000000000000000000000000000000 --- a/0005-multipathd-add-new-protocol-path-wildcard.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 26 Jun 2018 17:04:57 -0500 -Subject: [PATCH] multipathd: add new protocol path wildcard - -This patch adds a new path wildcard 'P', that will print the path's -protocol. For scsi devices, it will additionally print the transport -protocol being used. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/print.c | 43 +++++++++++++++++++++++++++++++++++++++++++ - libmultipath/print.h | 2 ++ - 2 files changed, 45 insertions(+) - -diff --git a/libmultipath/print.c b/libmultipath/print.c -index 222d270..ecfcb48 100644 ---- a/libmultipath/print.c -+++ b/libmultipath/print.c -@@ -638,6 +638,48 @@ snprint_path_failures(char * buff, size_t len, const struct path * pp) - return snprint_int(buff, len, pp->failcount); - } - -+/* if you add a protocol string bigger than "scsi:unspec" you must -+ * also change PROTOCOL_BUF_SIZE */ -+int -+snprint_path_protocol(char * buff, size_t len, const struct path * pp) -+{ -+ switch (pp->bus) { -+ case SYSFS_BUS_SCSI: -+ switch (pp->sg_id.proto_id) { -+ case SCSI_PROTOCOL_FCP: -+ return snprintf(buff, len, "scsi:fcp"); -+ case SCSI_PROTOCOL_SPI: -+ return snprintf(buff, len, "scsi:spi"); -+ case SCSI_PROTOCOL_SSA: -+ return snprintf(buff, len, "scsi:ssa"); -+ case SCSI_PROTOCOL_SBP: -+ return snprintf(buff, len, "scsi:sbp"); -+ case SCSI_PROTOCOL_SRP: -+ return snprintf(buff, len, "scsi:srp"); -+ case SCSI_PROTOCOL_ISCSI: -+ return snprintf(buff, len, "scsi:iscsi"); -+ case SCSI_PROTOCOL_SAS: -+ return snprintf(buff, len, "scsi:sas"); -+ case SCSI_PROTOCOL_ADT: -+ return snprintf(buff, len, "scsi:adt"); -+ case SCSI_PROTOCOL_ATA: -+ return snprintf(buff, len, "scsi:ata"); -+ case SCSI_PROTOCOL_UNSPEC: -+ default: -+ return snprintf(buff, len, "scsi:unspec"); -+ } -+ case SYSFS_BUS_CCW: -+ return snprintf(buff, len, "ccw"); -+ case SYSFS_BUS_CCISS: -+ return snprintf(buff, len, "cciss"); -+ case SYSFS_BUS_NVME: -+ return snprintf(buff, len, "nvme"); -+ case SYSFS_BUS_UNDEF: -+ default: -+ return snprintf(buff, len, "undef"); -+ } -+} -+ - struct multipath_data mpd[] = { - {'n', "name", 0, snprint_name}, - {'w', "uuid", 0, snprint_multipath_uuid}, -@@ -687,6 +729,7 @@ struct path_data pd[] = { - {'a', "host adapter", 0, snprint_host_adapter}, - {'G', "foreign", 0, snprint_path_foreign}, - {'0', "failures", 0, snprint_path_failures}, -+ {'P', "protocol", 0, snprint_path_protocol}, - {0, NULL, 0 , NULL} - }; - -diff --git a/libmultipath/print.h b/libmultipath/print.h -index 608b7d5..e2fb865 100644 ---- a/libmultipath/print.h -+++ b/libmultipath/print.h -@@ -133,6 +133,8 @@ int snprint_host_wwnn (char *, size_t, const struct path *); - int snprint_host_wwpn (char *, size_t, const struct path *); - int snprint_tgt_wwnn (char *, size_t, const struct path *); - int snprint_tgt_wwpn (char *, size_t, const struct path *); -+#define PROTOCOL_BUF_SIZE sizeof("scsi:unspec") -+int snprint_path_protocol(char *, size_t, const struct path *); - - void _print_multipath_topology (const struct gen_multipath * gmp, - int verbosity); --- -2.7.4 - diff --git a/0006-libmultipath-add-protocol-blacklist-option.patch b/0006-libmultipath-add-protocol-blacklist-option.patch deleted file mode 100644 index 16a1899edcff4b4f0f31b460c2f9da8addc46def..0000000000000000000000000000000000000000 --- a/0006-libmultipath-add-protocol-blacklist-option.patch +++ /dev/null @@ -1,425 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 28 Jun 2018 13:16:11 -0500 -Subject: [PATCH] libmultipath: add "protocol" blacklist option. - -Multiple users have requested an easy way to setup blacklists that do -things such as blacklisting all non FC and iSCSI devices. Currently -there is no easy way to do this, without knowing in advance what the -devices are. Looking into the udev property values, I didn't see a -consistent set of values that would worked for all the different types -of requests like this (which would have allowed us to solve this by -extending the "property" blacklist option to allow comparing values, -instead of just keywords). - -Instead I've opted to allow multipath to blacklist/whitelist devices -by the protocol strings printed by "multipathd: add new protocol path -wildcard". This check happens after multipath checks the "device" -keyword, and before it checks wwid. This gives users an easily -understandible method to set up these types of blacklists, without -needing to know the exact arrays being used. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/blacklist.c | 51 ++++++++++++++++++++++++++++++++++++++-------- - libmultipath/blacklist.h | 3 +++ - libmultipath/config.c | 15 ++++++++++++++ - libmultipath/config.h | 2 ++ - libmultipath/dict.c | 14 +++++++++++-- - libmultipath/discovery.c | 5 +++-- - libmultipath/print.c | 31 ++++++++++++++++++++++++++++ - multipath/multipath.conf.5 | 16 +++++++++++++-- - 8 files changed, 123 insertions(+), 14 deletions(-) - -diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c -index 361c603..fdd36f7 100644 ---- a/libmultipath/blacklist.c -+++ b/libmultipath/blacklist.c -@@ -12,6 +12,8 @@ - #include "structs.h" - #include "config.h" - #include "blacklist.h" -+#include "structs_vec.h" -+#include "print.h" - - int store_ble(vector blist, char * str, int origin) - { -@@ -240,12 +242,14 @@ setup_default_blist (struct config * conf) - condlog(3, "%s: %s %s %s", dev, (M), wwid, (S)); \ - else if (env) \ - condlog(3, "%s: %s %s %s", dev, (M), env, (S)); \ -+ else if (protocol) \ -+ condlog(3, "%s: %s %s %s", dev, (M), protocol, (S)); \ - else \ - condlog(3, "%s: %s %s", dev, (M), (S)) - - void - log_filter (const char *dev, char *vendor, char *product, char *wwid, -- const char *env, int r) -+ const char *env, const char *protocol, int r) - { - /* - * Try to sort from most likely to least. -@@ -265,6 +269,9 @@ log_filter (const char *dev, char *vendor, char *product, char *wwid, - case MATCH_PROPERTY_BLIST: - LOG_BLIST("udev property", "blacklisted"); - break; -+ case MATCH_PROTOCOL_BLIST: -+ LOG_BLIST("protocol", "blacklisted"); -+ break; - case MATCH_DEVICE_BLIST_EXCEPT: - LOG_BLIST("vendor/product", "whitelisted"); - break; -@@ -280,6 +287,9 @@ log_filter (const char *dev, char *vendor, char *product, char *wwid, - case MATCH_PROPERTY_BLIST_MISSING: - LOG_BLIST("blacklisted,", "udev property missing"); - break; -+ case MATCH_PROTOCOL_BLIST_EXCEPT: -+ LOG_BLIST("protocol", "whitelisted"); -+ break; - } - } - -@@ -299,7 +309,7 @@ int - filter_device (vector blist, vector elist, char * vendor, char * product) - { - int r = _filter_device(blist, elist, vendor, product); -- log_filter(NULL, vendor, product, NULL, NULL, r); -+ log_filter(NULL, vendor, product, NULL, NULL, NULL, r); - return r; - } - -@@ -319,7 +329,7 @@ int - filter_devnode (vector blist, vector elist, char * dev) - { - int r = _filter_devnode(blist, elist, dev); -- log_filter(dev, NULL, NULL, NULL, NULL, r); -+ log_filter(dev, NULL, NULL, NULL, NULL, NULL, r); - return r; - } - -@@ -339,7 +349,29 @@ int - filter_wwid (vector blist, vector elist, char * wwid, char * dev) - { - int r = _filter_wwid(blist, elist, wwid); -- log_filter(dev, NULL, NULL, wwid, NULL, r); -+ log_filter(dev, NULL, NULL, wwid, NULL, NULL, r); -+ return r; -+} -+ -+static int -+_filter_protocol (vector blist, vector elist, const char * protocol_str) -+{ -+ if (_blacklist_exceptions(elist, protocol_str)) -+ return MATCH_PROTOCOL_BLIST_EXCEPT; -+ if (_blacklist(blist, protocol_str)) -+ return MATCH_PROTOCOL_BLIST; -+ return 0; -+} -+ -+int -+filter_protocol(vector blist, vector elist, struct path * pp) -+{ -+ char buf[PROTOCOL_BUF_SIZE]; -+ int r; -+ -+ snprint_path_protocol(buf, sizeof(buf), pp); -+ r = _filter_protocol(blist, elist, buf); -+ log_filter(pp->dev, NULL, NULL, NULL, NULL, buf, r); - return r; - } - -@@ -351,7 +383,6 @@ _filter_path (struct config * conf, struct path * pp) - r = filter_property(conf, pp->udev); - if (r > 0) - return r; -- - r = _filter_devnode(conf->blist_devnode, conf->elist_devnode,pp->dev); - if (r > 0) - return r; -@@ -359,6 +390,9 @@ _filter_path (struct config * conf, struct path * pp) - pp->vendor_id, pp->product_id); - if (r > 0) - return r; -+ r = filter_protocol(conf->blist_protocol, conf->elist_protocol, pp); -+ if (r > 0) -+ return r; - r = _filter_wwid(conf->blist_wwid, conf->elist_wwid, pp->wwid); - return r; - } -@@ -367,7 +401,8 @@ int - filter_path (struct config * conf, struct path * pp) - { - int r=_filter_path(conf, pp); -- log_filter(pp->dev, pp->vendor_id, pp->product_id, pp->wwid, NULL, r); -+ log_filter(pp->dev, pp->vendor_id, pp->product_id, pp->wwid, NULL, -+ NULL, r); - return r; - } - -@@ -402,7 +437,7 @@ filter_property(struct config * conf, struct udev_device * udev) - - r = _filter_property(conf, env); - if (r) { -- log_filter(devname, NULL, NULL, NULL, env, r); -+ log_filter(devname, NULL, NULL, NULL, env, NULL, r); - return r; - } - } -@@ -411,7 +446,7 @@ filter_property(struct config * conf, struct udev_device * udev) - * This is the inverse of the 'normal' matching; - * the environment variable _has_ to match. - */ -- log_filter(devname, NULL, NULL, NULL, NULL, -+ log_filter(devname, NULL, NULL, NULL, NULL, NULL, - MATCH_PROPERTY_BLIST_MISSING); - return MATCH_PROPERTY_BLIST_MISSING; - } -diff --git a/libmultipath/blacklist.h b/libmultipath/blacklist.h -index 0b028d4..f7beef2 100644 ---- a/libmultipath/blacklist.h -+++ b/libmultipath/blacklist.h -@@ -10,10 +10,12 @@ - #define MATCH_DEVNODE_BLIST 3 - #define MATCH_PROPERTY_BLIST 4 - #define MATCH_PROPERTY_BLIST_MISSING 5 -+#define MATCH_PROTOCOL_BLIST 6 - #define MATCH_WWID_BLIST_EXCEPT -MATCH_WWID_BLIST - #define MATCH_DEVICE_BLIST_EXCEPT -MATCH_DEVICE_BLIST - #define MATCH_DEVNODE_BLIST_EXCEPT -MATCH_DEVNODE_BLIST - #define MATCH_PROPERTY_BLIST_EXCEPT -MATCH_PROPERTY_BLIST -+#define MATCH_PROTOCOL_BLIST_EXCEPT -MATCH_PROTOCOL_BLIST - - struct blentry { - char * str; -@@ -36,6 +38,7 @@ int filter_wwid (vector, vector, char *, char *); - int filter_device (vector, vector, char *, char *); - int filter_path (struct config *, struct path *); - int filter_property(struct config *, struct udev_device *); -+int filter_protocol(vector, vector, struct path *); - int store_ble (vector, char *, int); - int set_ble_device (vector, char *, char *, int); - void free_blacklist (vector); -diff --git a/libmultipath/config.c b/libmultipath/config.c -index afa309d..0aef186 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -623,11 +623,13 @@ free_config (struct config * conf) - free_blacklist(conf->blist_devnode); - free_blacklist(conf->blist_wwid); - free_blacklist(conf->blist_property); -+ free_blacklist(conf->blist_protocol); - free_blacklist_device(conf->blist_device); - - free_blacklist(conf->elist_devnode); - free_blacklist(conf->elist_wwid); - free_blacklist(conf->elist_property); -+ free_blacklist(conf->elist_protocol); - free_blacklist_device(conf->elist_device); - - free_mptable(conf->mptable); -@@ -780,6 +782,12 @@ load_config (char * file) - if (!conf->blist_property) - goto out; - } -+ if (conf->blist_protocol == NULL) { -+ conf->blist_protocol = vector_alloc(); -+ -+ if (!conf->blist_protocol) -+ goto out; -+ } - - if (conf->elist_devnode == NULL) { - conf->elist_devnode = vector_alloc(); -@@ -807,6 +815,13 @@ load_config (char * file) - if (!conf->elist_property) - goto out; - } -+ if (conf->elist_protocol == NULL) { -+ conf->elist_protocol = vector_alloc(); -+ -+ if (!conf->elist_protocol) -+ goto out; -+ } -+ - if (setup_default_blist(conf)) - goto out; - -diff --git a/libmultipath/config.h b/libmultipath/config.h -index 6bd42f0..7d0cd9a 100644 ---- a/libmultipath/config.h -+++ b/libmultipath/config.h -@@ -210,10 +210,12 @@ struct config { - vector blist_wwid; - vector blist_device; - vector blist_property; -+ vector blist_protocol; - vector elist_devnode; - vector elist_wwid; - vector elist_device; - vector elist_property; -+ vector elist_protocol; - }; - - extern struct udev * udev; -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index 15e7582..32524d5 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -1291,9 +1291,12 @@ blacklist_handler(struct config *conf, vector strvec) - conf->blist_device = vector_alloc(); - if (!conf->blist_property) - conf->blist_property = vector_alloc(); -+ if (!conf->blist_protocol) -+ conf->blist_protocol = vector_alloc(); - - if (!conf->blist_devnode || !conf->blist_wwid || -- !conf->blist_device || !conf->blist_property) -+ !conf->blist_device || !conf->blist_property || -+ !conf->blist_protocol) - return 1; - - return 0; -@@ -1310,9 +1313,12 @@ blacklist_exceptions_handler(struct config *conf, vector strvec) - conf->elist_device = vector_alloc(); - if (!conf->elist_property) - conf->elist_property = vector_alloc(); -+ if (!conf->elist_protocol) -+ conf->elist_protocol = vector_alloc(); - - if (!conf->elist_devnode || !conf->elist_wwid || -- !conf->elist_device || !conf->elist_property) -+ !conf->elist_device || !conf->elist_property || -+ !conf->elist_protocol) - return 1; - - return 0; -@@ -1356,6 +1362,8 @@ declare_ble_handler(blist_wwid) - declare_ble_handler(elist_wwid) - declare_ble_handler(blist_property) - declare_ble_handler(elist_property) -+declare_ble_handler(blist_protocol) -+declare_ble_handler(elist_protocol) - - static int - snprint_def_uxsock_timeout(struct config *conf, char * buff, int len, -@@ -1627,6 +1635,7 @@ init_keywords(vector keywords) - install_keyword_multi("devnode", &ble_blist_devnode_handler, &snprint_ble_simple); - install_keyword_multi("wwid", &ble_blist_wwid_handler, &snprint_ble_simple); - install_keyword_multi("property", &ble_blist_property_handler, &snprint_ble_simple); -+ install_keyword_multi("protocol", &ble_blist_protocol_handler, &snprint_ble_simple); - install_keyword_multi("device", &ble_device_handler, NULL); - install_sublevel(); - install_keyword("vendor", &ble_blist_device_vendor_handler, &snprint_bled_vendor); -@@ -1636,6 +1645,7 @@ init_keywords(vector keywords) - install_keyword_multi("devnode", &ble_elist_devnode_handler, &snprint_ble_simple); - install_keyword_multi("wwid", &ble_elist_wwid_handler, &snprint_ble_simple); - install_keyword_multi("property", &ble_elist_property_handler, &snprint_ble_simple); -+ install_keyword_multi("protocol", &ble_elist_protocol_handler, &snprint_ble_simple); - install_keyword_multi("device", &ble_except_device_handler, NULL); - install_sublevel(); - install_keyword("vendor", &ble_elist_device_vendor_handler, &snprint_bled_vendor); -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 573d98b..e58a3fa 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -1887,9 +1887,10 @@ int pathinfo(struct path *pp, struct config *conf, int mask) - - if (mask & DI_BLACKLIST && mask & DI_SYSFS) { - if (filter_device(conf->blist_device, conf->elist_device, -- pp->vendor_id, pp->product_id) > 0) { -+ pp->vendor_id, pp->product_id) > 0 || -+ filter_protocol(conf->blist_protocol, conf->elist_protocol, -+ pp) > 0) - return PATHINFO_SKIPPED; -- } - } - - path_state = path_offline(pp); -diff --git a/libmultipath/print.c b/libmultipath/print.c -index ecfcb48..9da6a77 100644 ---- a/libmultipath/print.c -+++ b/libmultipath/print.c -@@ -1688,6 +1688,19 @@ int snprint_blacklist_report(struct config *conf, char *buff, int len) - - if ((len - fwd - threshold) <= 0) - return len; -+ fwd += snprintf(buff + fwd, len - fwd, "protocol rules:\n" -+ "- blacklist:\n"); -+ if (!snprint_blacklist_group(buff, len, &fwd, &conf->blist_protocol)) -+ return len; -+ -+ if ((len - fwd - threshold) <= 0) -+ return len; -+ fwd += snprintf(buff + fwd, len - fwd, "- exceptions:\n"); -+ if (snprint_blacklist_group(buff, len, &fwd, &conf->elist_protocol) == 0) -+ return len; -+ -+ if ((len - fwd - threshold) <= 0) -+ return len; - fwd += snprintf(buff + fwd, len - fwd, "wwid rules:\n" - "- blacklist:\n"); - if (snprint_blacklist_group(buff, len, &fwd, &conf->blist_wwid) == 0) -@@ -1761,6 +1774,15 @@ static int snprint_blacklist(const struct config *conf, char *buff, int len) - if (fwd >= len) - return len; - } -+ vector_foreach_slot (conf->blist_protocol, ble, i) { -+ kw = find_keyword(conf->keywords, rootkw->sub, "protocol"); -+ if (!kw) -+ return 0; -+ fwd += snprint_keyword(buff + fwd, len - fwd, "\t%k %v\n", -+ kw, ble); -+ if (fwd >= len) -+ return len; -+ } - rootkw = find_keyword(conf->keywords, rootkw->sub, "device"); - if (!rootkw) - return 0; -@@ -1838,6 +1860,15 @@ static int snprint_blacklist_except(const struct config *conf, - if (fwd >= len) - return len; - } -+ vector_foreach_slot (conf->elist_protocol, ele, i) { -+ kw = find_keyword(conf->keywords, rootkw->sub, "protocol"); -+ if (!kw) -+ return 0; -+ fwd += snprint_keyword(buff + fwd, len - fwd, "\t%k %v\n", -+ kw, ele); -+ if (fwd >= len) -+ return len; -+ } - rootkw = find_keyword(conf->keywords, rootkw->sub, "device"); - if (!rootkw) - return 0; -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index fb863fd..6333366 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -1205,9 +1205,21 @@ The default \fIblacklist exception\fR is: \fB(SCSI_IDENT_|ID_WWN)\fR, causing - well-behaved SCSI devices and devices that provide a WWN (World Wide Number) - to be included, and all others to be excluded. - .RE -+.TP -+.B protocol -+Regular expression for the protocol of a device to be excluded/included. -+.RS -+.PP -+The protocol strings that multipath recognizes are \fIscsi:fcp\fR, -+\fIscsi:spi\fR, \fIscsi:ssa\fR, \fIscsi:sbp\fR, \fIscsi:srp\fR, -+\fIscsi:iscsi\fR, \fIscsi:sas\fR, \fIscsi:adt\fR, \fIscsi:ata\fR, -+\fIscsi:unspec\fR, \fIccw\fR, \fIcciss\fR, \fInvme\fR, and \fIundef\fR. -+The protocol that a path is using can be viewed by running -+\fBmultipathd show paths format "%d %P"\fR -+.RE - .LP --For every device, these 4 blacklist criteria are evaluated in the the order --"property, dev\%node, device, wwid". If a device turns out to be -+For every device, these 5 blacklist criteria are evaluated in the the order -+"property, dev\%node, device, protocol, wwid". If a device turns out to be - blacklisted by any criterion, it's excluded from handling by multipathd, and - the later criteria aren't evaluated any more. For each - criterion, the whitelist takes precedence over the blacklist if a device --- -2.7.4 - diff --git a/0006-libmultipath-allow-force-reload-with-no-active-paths.patch b/0006-libmultipath-allow-force-reload-with-no-active-paths.patch new file mode 100644 index 0000000000000000000000000000000000000000..77d54749f89265bb4e9f23cab8e89fd3a7423db6 --- /dev/null +++ b/0006-libmultipath-allow-force-reload-with-no-active-paths.patch @@ -0,0 +1,64 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 25 Mar 2020 23:22:48 -0500 +Subject: [PATCH] libmultipath: allow force reload with no active paths + +If the partition information has changed on multipath devices (say, +because it was updated on another node that has access to the same +storage), users expect that running "multipathd reconfigure" will update +that. However, if the checkers for the multipath device are pending for +too long when the the device is reconfigured, multipathd will give up +waiting for them, and refuse to reload the device, since there are no +active paths. This means that no kpartx update will be triggered. + +Multipath is fully capable of reloading a multipath device that has no +active paths. This has been possible for years. If multipath is supposed +to reload the device, it should do so, even if there are no active paths. + +Generally, when multipath is force reloaded, kpartx will be updated. +However when a device is reloaded with no paths, the udev rules won't +run kpartx. But they also weren't running kpartx when the first valid +path appeared, even though the dm activation rules get run in this case. +This changes 11-dm-mpath.rules to run kpartx when a device goes from no +usable paths to having usable paths. + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/configure.c | 6 ------ + multipath/11-dm-mpath.rules | 2 +- + 2 files changed, 1 insertion(+), 7 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index c95848a0..96c79610 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -710,12 +710,6 @@ select_action (struct multipath * mpp, vector curmp, int force_reload) + return; + } + +- if (pathcount(mpp, PATH_UP) == 0) { +- mpp->action = ACT_IMPOSSIBLE; +- condlog(3, "%s: set ACT_IMPOSSIBLE (no usable path)", +- mpp->alias); +- return; +- } + if (force_reload) { + mpp->force_udev_reload = 1; + mpp->action = ACT_RELOAD; +diff --git a/multipath/11-dm-mpath.rules b/multipath/11-dm-mpath.rules +index 07320a14..cd522e8c 100644 +--- a/multipath/11-dm-mpath.rules ++++ b/multipath/11-dm-mpath.rules +@@ -75,7 +75,7 @@ ENV{MPATH_DEVICE_READY}=="0", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1" + ENV{MPATH_DEVICE_READY}!="0", ENV{.MPATH_DEVICE_READY_OLD}=="0",\ + ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="$env{DM_DISABLE_OTHER_RULES_FLAG_OLD}",\ + ENV{DM_DISABLE_OTHER_RULES_FLAG_OLD}="",\ +- ENV{DM_ACTIVATION}="1" ++ ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0" + + # The code to check multipath state ends here. We need to set + # properties and symlinks regardless whether the map is usable or +-- +2.17.2 + diff --git a/0007-kpartx.rules-honor-DM_UDEV_DISABLE_OTHER_RULES_FLAG.patch b/0007-kpartx.rules-honor-DM_UDEV_DISABLE_OTHER_RULES_FLAG.patch new file mode 100644 index 0000000000000000000000000000000000000000..6c33439727062be3d092bb47f021187f3198870d --- /dev/null +++ b/0007-kpartx.rules-honor-DM_UDEV_DISABLE_OTHER_RULES_FLAG.patch @@ -0,0 +1,30 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 3 Apr 2020 13:03:01 +0200 +Subject: [PATCH] kpartx.rules: honor DM_UDEV_DISABLE_OTHER_RULES_FLAG + +10-dm.rules sets DM_UDEV_DISABLE_OTHER_RULES_FLAG for spurious +events that should be ignored by other layers. This means devices +with DISK_RO set, and devices that have never been set up properly +by device-mapper before. This flag should be respected by kpartx. + +Signed-off-by: Benjamin Marzinski +--- + kpartx/kpartx.rules | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules +index 8f990494..f1bf31ca 100644 +--- a/kpartx/kpartx.rules ++++ b/kpartx/kpartx.rules +@@ -7,6 +7,7 @@ + KERNEL!="dm-*", GOTO="kpartx_end" + ACTION!="add|change", GOTO="kpartx_end" + ENV{DM_UUID}!="?*", GOTO="kpartx_end" ++ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}=="1", GOTO="kpartx_end" + + # Create dm tables for partitions on multipath devices. + ENV{DM_UUID}!="mpath-?*", GOTO="mpath_kpartx_end" +-- +2.17.2 + diff --git a/0007-libmultipath-remove-_filter_-blacklist-functions.patch b/0007-libmultipath-remove-_filter_-blacklist-functions.patch deleted file mode 100644 index b8e8e07d61953a0064014e4585aa772faef0c4f9..0000000000000000000000000000000000000000 --- a/0007-libmultipath-remove-_filter_-blacklist-functions.patch +++ /dev/null @@ -1,296 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 3 Jul 2018 19:15:03 -0500 -Subject: [PATCH] libmultipath: remove _filter_* blacklist functions - -The one point of these functions was for _filter_path(), and that wasn't -improved by using them. Since filter_path() only printed one message at -the end, you could have situations where the wwid was blacklisted, but -the blacklist message included the vendor/product instead. Also, the -protocol and property messages were printed twice, and if the device was -on multiple whitelists, only the last one is printed. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/blacklist.c | 168 +++++++++++++++++++---------------------------- - libmultipath/blacklist.h | 2 +- - libmultipath/configure.c | 2 +- - libmultipath/discovery.c | 2 +- - 4 files changed, 71 insertions(+), 103 deletions(-) - -diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c -index fdd36f7..318ec03 100644 ---- a/libmultipath/blacklist.c -+++ b/libmultipath/blacklist.c -@@ -294,161 +294,129 @@ log_filter (const char *dev, char *vendor, char *product, char *wwid, - } - - int --_filter_device (vector blist, vector elist, char * vendor, char * product) -+filter_device (vector blist, vector elist, char * vendor, char * product, -+ char * dev) - { -- if (!vendor || !product) -- return 0; -- if (_blacklist_exceptions_device(elist, vendor, product)) -- return MATCH_DEVICE_BLIST_EXCEPT; -- if (_blacklist_device(blist, vendor, product)) -- return MATCH_DEVICE_BLIST; -- return 0; --} -+ int r = MATCH_NOTHING; - --int --filter_device (vector blist, vector elist, char * vendor, char * product) --{ -- int r = _filter_device(blist, elist, vendor, product); -- log_filter(NULL, vendor, product, NULL, NULL, NULL, r); -- return r; --} -+ if (vendor && product) { -+ if (_blacklist_exceptions_device(elist, vendor, product)) -+ r = MATCH_DEVICE_BLIST_EXCEPT; -+ else if (_blacklist_device(blist, vendor, product)) -+ r = MATCH_DEVICE_BLIST; -+ } - --int --_filter_devnode (vector blist, vector elist, char * dev) --{ -- if (!dev) -- return 0; -- if (_blacklist_exceptions(elist, dev)) -- return MATCH_DEVNODE_BLIST_EXCEPT; -- if (_blacklist(blist, dev)) -- return MATCH_DEVNODE_BLIST; -- return 0; -+ log_filter(dev, vendor, product, NULL, NULL, NULL, r); -+ return r; - } - - int - filter_devnode (vector blist, vector elist, char * dev) - { -- int r = _filter_devnode(blist, elist, dev); -+ int r = MATCH_NOTHING; -+ -+ if (dev) { -+ if (_blacklist_exceptions(elist, dev)) -+ r = MATCH_DEVNODE_BLIST_EXCEPT; -+ else if (_blacklist(blist, dev)) -+ r = MATCH_DEVNODE_BLIST; -+ } -+ - log_filter(dev, NULL, NULL, NULL, NULL, NULL, r); - return r; - } - - int --_filter_wwid (vector blist, vector elist, char * wwid) --{ -- if (!wwid) -- return 0; -- if (_blacklist_exceptions(elist, wwid)) -- return MATCH_WWID_BLIST_EXCEPT; -- if (_blacklist(blist, wwid)) -- return MATCH_WWID_BLIST; -- return 0; --} -- --int - filter_wwid (vector blist, vector elist, char * wwid, char * dev) - { -- int r = _filter_wwid(blist, elist, wwid); -+ int r = MATCH_NOTHING; -+ -+ if (wwid) { -+ if (_blacklist_exceptions(elist, wwid)) -+ r = MATCH_WWID_BLIST_EXCEPT; -+ else if (_blacklist(blist, wwid)) -+ r = MATCH_WWID_BLIST; -+ } -+ - log_filter(dev, NULL, NULL, wwid, NULL, NULL, r); - return r; - } - --static int --_filter_protocol (vector blist, vector elist, const char * protocol_str) --{ -- if (_blacklist_exceptions(elist, protocol_str)) -- return MATCH_PROTOCOL_BLIST_EXCEPT; -- if (_blacklist(blist, protocol_str)) -- return MATCH_PROTOCOL_BLIST; -- return 0; --} -- - int - filter_protocol(vector blist, vector elist, struct path * pp) - { - char buf[PROTOCOL_BUF_SIZE]; -- int r; -+ int r = MATCH_NOTHING; -+ -+ if (pp) { -+ snprint_path_protocol(buf, sizeof(buf), pp); -+ -+ if (_blacklist_exceptions(elist, buf)) -+ r = MATCH_PROTOCOL_BLIST_EXCEPT; -+ else if (_blacklist(blist, buf)) -+ r = MATCH_PROTOCOL_BLIST; -+ } - -- snprint_path_protocol(buf, sizeof(buf), pp); -- r = _filter_protocol(blist, elist, buf); - log_filter(pp->dev, NULL, NULL, NULL, NULL, buf, r); - return r; - } - - int --_filter_path (struct config * conf, struct path * pp) -+filter_path (struct config * conf, struct path * pp) - { - int r; - - r = filter_property(conf, pp->udev); - if (r > 0) - return r; -- r = _filter_devnode(conf->blist_devnode, conf->elist_devnode,pp->dev); -+ r = filter_devnode(conf->blist_devnode, conf->elist_devnode, pp->dev); - if (r > 0) - return r; -- r = _filter_device(conf->blist_device, conf->elist_device, -- pp->vendor_id, pp->product_id); -+ r = filter_device(conf->blist_device, conf->elist_device, -+ pp->vendor_id, pp->product_id, pp->dev); - if (r > 0) - return r; - r = filter_protocol(conf->blist_protocol, conf->elist_protocol, pp); - if (r > 0) - return r; -- r = _filter_wwid(conf->blist_wwid, conf->elist_wwid, pp->wwid); -+ r = filter_wwid(conf->blist_wwid, conf->elist_wwid, pp->wwid, pp->dev); - return r; - } - - int --filter_path (struct config * conf, struct path * pp) --{ -- int r=_filter_path(conf, pp); -- log_filter(pp->dev, pp->vendor_id, pp->product_id, pp->wwid, NULL, -- NULL, r); -- return r; --} -- --int --_filter_property (struct config *conf, const char *env) --{ -- if (_blacklist_exceptions(conf->elist_property, env)) -- return MATCH_PROPERTY_BLIST_EXCEPT; -- if (_blacklist(conf->blist_property, env)) -- return MATCH_PROPERTY_BLIST; -- -- return 0; --} -- --int - filter_property(struct config * conf, struct udev_device * udev) - { - const char *devname = udev_device_get_sysname(udev); - struct udev_list_entry *list_entry; -- int r; -- -- if (!udev) -- return 0; -- -- udev_list_entry_foreach(list_entry, -+ const char *env = NULL; -+ int r = MATCH_NOTHING; -+ -+ if (udev) { -+ /* -+ * This is the inverse of the 'normal' matching; -+ * the environment variable _has_ to match. -+ */ -+ r = MATCH_PROPERTY_BLIST_MISSING; -+ udev_list_entry_foreach(list_entry, - udev_device_get_properties_list_entry(udev)) { -- const char *env; -- -- env = udev_list_entry_get_name(list_entry); -- if (!env) -- continue; - -- r = _filter_property(conf, env); -- if (r) { -- log_filter(devname, NULL, NULL, NULL, env, NULL, r); -- return r; -+ env = udev_list_entry_get_name(list_entry); -+ if (!env) -+ continue; -+ if (_blacklist_exceptions(conf->elist_property, env)) { -+ r = MATCH_PROPERTY_BLIST_EXCEPT; -+ break; -+ } -+ if (_blacklist(conf->blist_property, env)) { -+ r = MATCH_PROPERTY_BLIST; -+ break; -+ } -+ env = NULL; - } - } - -- /* -- * This is the inverse of the 'normal' matching; -- * the environment variable _has_ to match. -- */ -- log_filter(devname, NULL, NULL, NULL, NULL, NULL, -- MATCH_PROPERTY_BLIST_MISSING); -- return MATCH_PROPERTY_BLIST_MISSING; -+ log_filter(devname, NULL, NULL, NULL, env, NULL, r); -+ return r; - } - - static void free_ble(struct blentry *ble) -diff --git a/libmultipath/blacklist.h b/libmultipath/blacklist.h -index f7beef2..18903b6 100644 ---- a/libmultipath/blacklist.h -+++ b/libmultipath/blacklist.h -@@ -35,7 +35,7 @@ int setup_default_blist (struct config *); - int alloc_ble_device (vector); - int filter_devnode (vector, vector, char *); - int filter_wwid (vector, vector, char *, char *); --int filter_device (vector, vector, char *, char *); -+int filter_device (vector, vector, char *, char *, char *); - int filter_path (struct config *, struct path *); - int filter_property(struct config *, struct udev_device *); - int filter_protocol(vector, vector, struct path *); -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 5c54f9b..09c3dcf 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -1030,7 +1030,7 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, - invalid = 1; - pthread_cleanup_pop(1); - if (invalid) { -- orphan_path(pp1, "wwid blacklisted"); -+ orphan_path(pp1, "blacklisted"); - continue; - } - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index e58a3fa..0b1855d 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -1887,7 +1887,7 @@ int pathinfo(struct path *pp, struct config *conf, int mask) - - if (mask & DI_BLACKLIST && mask & DI_SYSFS) { - if (filter_device(conf->blist_device, conf->elist_device, -- pp->vendor_id, pp->product_id) > 0 || -+ pp->vendor_id, pp->product_id, pp->dev) > 0 || - filter_protocol(conf->blist_protocol, conf->elist_protocol, - pp) > 0) - return PATHINFO_SKIPPED; --- -2.7.4 - diff --git a/0008-kpartx.rules-check-for-skip_kpartx-on-synthetic-ueve.patch b/0008-kpartx.rules-check-for-skip_kpartx-on-synthetic-ueve.patch new file mode 100644 index 0000000000000000000000000000000000000000..2a18b15696adbe077ccdedad3a49dbcb135f72e9 --- /dev/null +++ b/0008-kpartx.rules-check-for-skip_kpartx-on-synthetic-ueve.patch @@ -0,0 +1,43 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 2 Apr 2020 18:12:48 +0200 +Subject: [PATCH] kpartx.rules: check for skip_kpartx on synthetic uevents + +The current test to detect "spurious" uevents, and thus whether to +import DM_SUBSYSTEM_UDEV_FLAG1 (the flag for the "skip_kpartx" option) +from the udev db is wrong. In 10-dm.rules, DM_UDEV_PRIMARY_SOURCE_FLAG +is imported from the db if it isn't set, meaning that it's always 1 +for active maps. The only events for which DM_SUBSYSTEM_UDEV_FLAG1 +must not be loaded from the db are the real "primary" events, which +are "change" events with DM_ACTIVATION=="1". + +11-dm-mpath.rules resets DM_ACTIVATION to 0 if nothing should change in upper +layers. In this case importing DM_SUBSYSTEM_UDEV_FLAG1 is correct, too. kpartx +will not be called anyway, because 11-dm-mpath.rules also sets MPATH_UNCHANGED=1. + +Signed-off-by: Benjamin Marzinski +--- + kpartx/kpartx.rules | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules +index f1bf31ca..d7527d7d 100644 +--- a/kpartx/kpartx.rules ++++ b/kpartx/kpartx.rules +@@ -13,8 +13,11 @@ ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}=="1", GOTO="kpartx_end" + ENV{DM_UUID}!="mpath-?*", GOTO="mpath_kpartx_end" + + # DM_SUBSYSTEM_UDEV_FLAG1 is the "skip_kpartx" flag. +-# For events not generated by libdevmapper, we need to fetch it from db. +-ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}!="1", IMPORT{db}="DM_SUBSYSTEM_UDEV_FLAG1" ++# For events not generated by libdevmapper, we need to fetch it from db: ++# - "change" events with DM_ACTIVATION!="1" (e.g. partition table changes) ++# - "add" events for which rules are not disabled ("coldplug" case) ++ENV{DM_ACTIVATION}!="1", IMPORT{db}="DM_SUBSYSTEM_UDEV_FLAG1" ++ACTION=="add", IMPORT{db}="DM_SUBSYSTEM_UDEV_FLAG1" + ENV{DM_SUBSYSTEM_UDEV_FLAG1}=="1", GOTO="mpath_kpartx_end" + + # 11-dm-mpath.rules sets MPATH_UNCHANGED for events that can be ignored. +-- +2.17.2 + diff --git a/0008-multipath-tests-change-to-work-with-old-make-version.patch b/0008-multipath-tests-change-to-work-with-old-make-version.patch deleted file mode 100644 index 186015aa9fa3e2f264c8a756303d83fcae2babd5..0000000000000000000000000000000000000000 --- a/0008-multipath-tests-change-to-work-with-old-make-version.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 3 Jul 2018 19:59:33 -0500 -Subject: [PATCH] multipath tests: change to work with old make versions - -the $(file <) operation only works with make 4.2 and above. I tried -running the tests on an old machine and it failed. The $shell function -can do the same thing and multipath has been using that in its -Makefiles for a while. - -Signed-off-by: Benjamin Marzinski ---- - tests/Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/tests/Makefile b/tests/Makefile -index 78755ed..d293c87 100644 ---- a/tests/Makefile -+++ b/tests/Makefile -@@ -51,4 +51,4 @@ COLON:=: - $(multipathdir)/libmultipath.so Makefile - $(CC) $(CFLAGS) -o $@ $(LDFLAGS) $< $($@_TESTDEPS) $($@_OBJDEPS) \ - $(LIBDEPS) $($@_LIBDEPS) \ -- $(file <$<.wrap) $(foreach dep,$($@_TESTDEPS),$(file <$(dep).wrap)) -+ $(shell cat $<.wrap) $(foreach dep,$($@_TESTDEPS),$(shell cat $(dep).wrap)) --- -2.7.4 - diff --git a/0009-libmpathpersist-depend-on-libmultipath.patch b/0009-libmpathpersist-depend-on-libmultipath.patch new file mode 100644 index 0000000000000000000000000000000000000000..47aad9b80d407e9334aa8065a85e25ac2e268bd5 --- /dev/null +++ b/0009-libmpathpersist-depend-on-libmultipath.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Christian Hesse +Date: Wed, 6 May 2020 09:35:47 +0200 +Subject: [PATCH] libmpathpersist: depend on libmultipath + +Without this the build fails with: + +/usr/bin/ld: cannot find -lmultipath + +Signed-off-by: Christian Hesse +Signed-off-by: Benjamin Marzinski +--- + Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile b/Makefile +index 1dee3680..ba1d73ba 100644 +--- a/Makefile ++++ b/Makefile +@@ -28,7 +28,7 @@ all: $(BUILDDIRS) + $(BUILDDIRS): + $(MAKE) -C $@ + +-multipath multipathd mpathpersist: libmultipath ++libmpathpersist multipath multipathd mpathpersist: libmultipath + mpathpersist: libmpathpersist + + $(BUILDDIRS.clean): +-- +2.17.2 + diff --git a/0009-multipath-tests-add-blacklist-tests.patch b/0009-multipath-tests-add-blacklist-tests.patch deleted file mode 100644 index cf7eff8fbb27aa2493a9f79fbb5efbd71442f1aa..0000000000000000000000000000000000000000 --- a/0009-multipath-tests-add-blacklist-tests.patch +++ /dev/null @@ -1,559 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 12 Jul 2018 17:53:38 -0500 -Subject: [PATCH] multipath tests: add blacklist tests - -These are tests to validate the filter_* blacklist functions. They not -only verify that the device is correctly blacklisted/whitelisted, but -they also verify the log messages that are printed out. - -Signed-off-by: Benjamin Marzinski ---- - tests/Makefile | 4 +- - tests/blacklist.c | 512 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 515 insertions(+), 1 deletion(-) - create mode 100644 tests/blacklist.c - -diff --git a/tests/Makefile b/tests/Makefile -index d293c87..98b5c93 100644 ---- a/tests/Makefile -+++ b/tests/Makefile -@@ -3,7 +3,7 @@ include ../Makefile.inc - CFLAGS += $(BIN_CFLAGS) -I$(multipathdir) -I$(mpathcmddir) - LIBDEPS += -L$(multipathdir) -lmultipath -lcmocka - --TESTS := uevent parser util dmevents hwtable -+TESTS := uevent parser util dmevents hwtable blacklist - - .SILENT: $(TESTS:%=%.o) - .PRECIOUS: $(TESTS:%=%-test) -@@ -23,6 +23,8 @@ hwtable-test_TESTDEPS := test-lib.o - hwtable-test_OBJDEPS := ../libmultipath/discovery.o ../libmultipath/blacklist.o \ - ../libmultipath/prio.o ../libmultipath/callout.o ../libmultipath/structs.o - hwtable-test_LIBDEPS := -ludev -lpthread -ldl -+blacklist-test_OBJDEPS := ../libmultipath/blacklist.o -+blacklist-test_LIBDEPS := -ludev - - %.out: %-test - @echo == running $< == -diff --git a/tests/blacklist.c b/tests/blacklist.c -new file mode 100644 -index 0000000..a55c1c0 ---- /dev/null -+++ b/tests/blacklist.c -@@ -0,0 +1,512 @@ -+/* -+ * Copyright (c) 2018 Benjamin Marzinski, Redhat -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ * -+ */ -+#include -+#include -+#include -+#include -+#include "globals.c" -+#include "blacklist.h" -+#include "log.h" -+ -+struct udev_device { -+ const char *sysname; -+ char *property_list[]; -+}; -+ -+const char * -+__wrap_udev_device_get_sysname(struct udev_device *udev_device) -+{ -+ assert_non_null(udev_device); -+ assert_non_null(udev_device->sysname); -+ return udev_device->sysname; -+} -+ -+struct udev_list_entry * -+__wrap_udev_device_get_properties_list_entry(struct udev_device *udev_device) -+{ -+ assert_non_null(udev_device); -+ if (!udev_device->property_list) -+ return NULL; -+ if (!*udev_device->property_list) -+ return NULL; -+ return (struct udev_list_entry *)udev_device->property_list; -+} -+ -+struct udev_list_entry * -+__wrap_udev_list_entry_get_next(struct udev_list_entry *list_entry) -+{ -+ assert_non_null(list_entry); -+ if (!*((char **)list_entry + 1)) -+ return NULL; -+ return (struct udev_list_entry *)(((char **)list_entry) + 1); -+} -+ -+const char * -+__wrap_udev_list_entry_get_name(struct udev_list_entry *list_entry) -+{ -+ return *(const char **)list_entry; -+} -+ -+void __wrap_dlog (int sink, int prio, const char * fmt, ...) -+{ -+ char buff[MAX_MSG_SIZE]; -+ va_list ap; -+ -+ assert_int_equal(prio, mock_type(int)); -+ va_start(ap, fmt); -+ vsnprintf(buff, MAX_MSG_SIZE, fmt, ap); -+ va_end(ap); -+ assert_string_equal(buff, mock_ptr_type(char *)); -+} -+ -+void expect_condlog(int prio, char *string) -+{ -+ will_return(__wrap_dlog, prio); -+ will_return(__wrap_dlog, string); -+} -+ -+vector blist_devnode_sdb; -+vector blist_all; -+vector blist_device_foo_bar; -+vector blist_device_all; -+vector blist_wwid_xyzzy; -+vector blist_protocol_fcp; -+vector blist_property_wwn; -+ -+static int setup(void **state) -+{ -+ blist_devnode_sdb = vector_alloc(); -+ if (!blist_devnode_sdb || -+ store_ble(blist_devnode_sdb, strdup("sdb"), ORIGIN_CONFIG)) -+ return -1; -+ -+ blist_all = vector_alloc(); -+ if (!blist_all || store_ble(blist_all, strdup(".*"), ORIGIN_CONFIG)) -+ return -1; -+ -+ blist_device_foo_bar = vector_alloc(); -+ if (!blist_device_foo_bar || alloc_ble_device(blist_device_foo_bar) || -+ set_ble_device(blist_device_foo_bar, strdup("foo"), strdup("bar"), -+ ORIGIN_CONFIG)) -+ return -1; -+ -+ blist_device_all = vector_alloc(); -+ if (!blist_device_all || alloc_ble_device(blist_device_all) || -+ set_ble_device(blist_device_all, strdup(".*"), strdup(".*"), -+ ORIGIN_CONFIG)) -+ return -1; -+ -+ blist_wwid_xyzzy = vector_alloc(); -+ if (!blist_wwid_xyzzy || -+ store_ble(blist_wwid_xyzzy, strdup("xyzzy"), ORIGIN_CONFIG)) -+ return -1; -+ -+ blist_protocol_fcp = vector_alloc(); -+ if (!blist_protocol_fcp || -+ store_ble(blist_protocol_fcp, strdup("scsi:fcp"), ORIGIN_CONFIG)) -+ return -1; -+ -+ blist_property_wwn = vector_alloc(); -+ if (!blist_property_wwn || -+ store_ble(blist_property_wwn, strdup("ID_WWN"), ORIGIN_CONFIG)) -+ return -1; -+ -+ return 0; -+} -+ -+static int teardown(void **state) -+{ -+ free_blacklist(blist_devnode_sdb); -+ free_blacklist(blist_all); -+ free_blacklist_device(blist_device_foo_bar); -+ free_blacklist_device(blist_device_all); -+ free_blacklist(blist_wwid_xyzzy); -+ free_blacklist(blist_protocol_fcp); -+ free_blacklist(blist_property_wwn); -+ return 0; -+} -+ -+static int reset_blists(void **state) -+{ -+ conf.blist_devnode = NULL; -+ conf.blist_wwid = NULL; -+ conf.blist_property = NULL; -+ conf.blist_protocol = NULL; -+ conf.blist_device = NULL; -+ conf.elist_devnode = NULL; -+ conf.elist_wwid = NULL; -+ conf.elist_property = NULL; -+ conf.elist_protocol = NULL; -+ conf.elist_device = NULL; -+ return 0; -+} -+ -+static void test_devnode_blacklist(void **state) -+{ -+ expect_condlog(3, "sdb: device node name blacklisted\n"); -+ assert_int_equal(filter_devnode(blist_devnode_sdb, NULL, "sdb"), -+ MATCH_DEVNODE_BLIST); -+} -+ -+static void test_devnode_whitelist(void **state) -+{ -+ expect_condlog(3, "sdb: device node name whitelisted\n"); -+ assert_int_equal(filter_devnode(blist_all, blist_devnode_sdb, "sdb"), -+ MATCH_DEVNODE_BLIST_EXCEPT); -+ expect_condlog(3, "sdc: device node name blacklisted\n"); -+ assert_int_equal(filter_devnode(blist_all, blist_devnode_sdb, "sdc"), -+ MATCH_DEVNODE_BLIST); -+} -+ -+static void test_devnode_missing(void **state) -+{ -+ assert_int_equal(filter_devnode(blist_devnode_sdb, NULL, "sdc"), -+ MATCH_NOTHING); -+} -+ -+static void test_device_blacklist(void **state) -+{ -+ expect_condlog(3, "sdb: (foo:bar) vendor/product blacklisted\n"); -+ assert_int_equal(filter_device(blist_device_foo_bar, NULL, "foo", -+ "bar", "sdb"), -+ MATCH_DEVICE_BLIST); -+} -+ -+static void test_device_whitelist(void **state) -+{ -+ expect_condlog(3, "sdb: (foo:bar) vendor/product whitelisted\n"); -+ assert_int_equal(filter_device(blist_device_all, blist_device_foo_bar, -+ "foo", "bar", "sdb"), -+ MATCH_DEVICE_BLIST_EXCEPT); -+ expect_condlog(3, "sdb: (foo:baz) vendor/product blacklisted\n"); -+ assert_int_equal(filter_device(blist_device_all, blist_device_foo_bar, -+ "foo", "baz", "sdb"), -+ MATCH_DEVICE_BLIST); -+} -+ -+static void test_device_missing(void **state) -+{ -+ assert_int_equal(filter_device(blist_device_foo_bar, NULL, "foo", -+ "baz", "sdb"), -+ MATCH_NOTHING); -+} -+ -+static void test_wwid_blacklist(void **state) -+{ -+ expect_condlog(3, "sdb: wwid xyzzy blacklisted\n"); -+ assert_int_equal(filter_wwid(blist_wwid_xyzzy, NULL, "xyzzy", "sdb"), -+ MATCH_WWID_BLIST); -+} -+ -+static void test_wwid_whitelist(void **state) -+{ -+ expect_condlog(3, "sdb: wwid xyzzy whitelisted\n"); -+ assert_int_equal(filter_wwid(blist_all, blist_wwid_xyzzy, -+ "xyzzy", "sdb"), -+ MATCH_WWID_BLIST_EXCEPT); -+ expect_condlog(3, "sdb: wwid plugh blacklisted\n"); -+ assert_int_equal(filter_wwid(blist_all, blist_wwid_xyzzy, -+ "plugh", "sdb"), -+ MATCH_WWID_BLIST); -+} -+ -+static void test_wwid_missing(void **state) -+{ -+ assert_int_equal(filter_wwid(blist_wwid_xyzzy, NULL, "plugh", "sdb"), -+ MATCH_NOTHING); -+} -+ -+static void test_protocol_blacklist(void **state) -+{ -+ struct path pp = { .dev = "sdb", .bus = SYSFS_BUS_SCSI, -+ .sg_id.proto_id = SCSI_PROTOCOL_FCP }; -+ expect_condlog(3, "sdb: protocol scsi:fcp blacklisted\n"); -+ assert_int_equal(filter_protocol(blist_protocol_fcp, NULL, &pp), -+ MATCH_PROTOCOL_BLIST); -+} -+ -+static void test_protocol_whitelist(void **state) -+{ -+ struct path pp1 = { .dev = "sdb", .bus = SYSFS_BUS_SCSI, -+ .sg_id.proto_id = SCSI_PROTOCOL_FCP }; -+ struct path pp2 = { .dev = "sdb", .bus = SYSFS_BUS_SCSI, -+ .sg_id.proto_id = SCSI_PROTOCOL_ISCSI }; -+ expect_condlog(3, "sdb: protocol scsi:fcp whitelisted\n"); -+ assert_int_equal(filter_protocol(blist_all, blist_protocol_fcp, &pp1), -+ MATCH_PROTOCOL_BLIST_EXCEPT); -+ expect_condlog(3, "sdb: protocol scsi:iscsi blacklisted\n"); -+ assert_int_equal(filter_protocol(blist_all, blist_protocol_fcp, &pp2), -+ MATCH_PROTOCOL_BLIST); -+} -+ -+static void test_protocol_missing(void **state) -+{ -+ struct path pp = { .dev = "sdb", .bus = SYSFS_BUS_SCSI, -+ .sg_id.proto_id = SCSI_PROTOCOL_ISCSI }; -+ assert_int_equal(filter_protocol(blist_protocol_fcp, NULL, &pp), -+ MATCH_NOTHING); -+} -+ -+static void test_property_blacklist(void **state) -+{ -+ static struct udev_device udev = { "sdb", { "ID_FOO", "ID_WWN", "ID_BAR", NULL } }; -+ conf.blist_property = blist_property_wwn; -+ expect_condlog(3, "sdb: udev property ID_WWN blacklisted\n"); -+ assert_int_equal(filter_property(&conf, &udev), MATCH_PROPERTY_BLIST); -+} -+ -+/* the property check works different in that you check all the property -+ * names, so setting a blacklist value will blacklist the device if any -+ * of the property on the blacklist are found before the property names -+ * in the whitelist. This might be worth changing. although it would -+ * force multipath to go through the properties twice */ -+static void test_property_whitelist(void **state) -+{ -+ static struct udev_device udev = { "sdb", { "ID_FOO", "ID_WWN", "ID_BAR", NULL } }; -+ conf.elist_property = blist_property_wwn; -+ expect_condlog(3, "sdb: udev property ID_WWN whitelisted\n"); -+ assert_int_equal(filter_property(&conf, &udev), -+ MATCH_PROPERTY_BLIST_EXCEPT); -+} -+ -+static void test_property_missing(void **state) -+{ -+ static struct udev_device udev = { "sdb", { "ID_FOO", "ID_BAZ", "ID_BAR", NULL } }; -+ conf.blist_property = blist_property_wwn; -+ expect_condlog(3, "sdb: blacklisted, udev property missing\n"); -+ assert_int_equal(filter_property(&conf, &udev), -+ MATCH_PROPERTY_BLIST_MISSING); -+} -+ -+struct udev_device test_udev = { "sdb", { "ID_FOO", "ID_WWN", "ID_BAR", NULL } }; -+ -+struct path test_pp = { .dev = "sdb", .bus = SYSFS_BUS_SCSI, .udev = &test_udev, -+ .sg_id.proto_id = SCSI_PROTOCOL_FCP, .vendor_id = "foo", -+ .product_id = "bar", .wwid = "xyzzy" }; -+ -+static void test_filter_path_property(void **state) -+{ -+ conf.blist_property = blist_property_wwn; -+ expect_condlog(3, "sdb: udev property ID_WWN blacklisted\n"); -+ assert_int_equal(filter_path(&conf, &test_pp), MATCH_PROPERTY_BLIST); -+} -+ -+static void test_filter_path_devnode(void **state) -+{ -+ /* always must include property elist, to avoid "missing property" -+ * blacklisting */ -+ conf.elist_property = blist_property_wwn; -+ conf.blist_devnode = blist_devnode_sdb; -+ expect_condlog(3, "sdb: udev property ID_WWN whitelisted\n"); -+ expect_condlog(3, "sdb: device node name blacklisted\n"); -+ assert_int_equal(filter_path(&conf, &test_pp), MATCH_DEVNODE_BLIST); -+} -+ -+static void test_filter_path_device(void **state) -+{ -+ /* always must include property elist, to avoid "missing property" -+ * blacklisting */ -+ conf.elist_property = blist_property_wwn; -+ conf.blist_device = blist_device_foo_bar; -+ expect_condlog(3, "sdb: udev property ID_WWN whitelisted\n"); -+ expect_condlog(3, "sdb: (foo:bar) vendor/product blacklisted\n"); -+ assert_int_equal(filter_path(&conf, &test_pp), MATCH_DEVICE_BLIST); -+} -+ -+static void test_filter_path_protocol(void **state) -+{ -+ conf.elist_property = blist_property_wwn; -+ conf.blist_protocol = blist_protocol_fcp; -+ expect_condlog(3, "sdb: udev property ID_WWN whitelisted\n"); -+ expect_condlog(3, "sdb: protocol scsi:fcp blacklisted\n"); -+ assert_int_equal(filter_path(&conf, &test_pp), MATCH_PROTOCOL_BLIST); -+} -+ -+static void test_filter_path_wwid(void **state) -+{ -+ conf.elist_property = blist_property_wwn; -+ conf.blist_wwid = blist_wwid_xyzzy; -+ expect_condlog(3, "sdb: udev property ID_WWN whitelisted\n"); -+ expect_condlog(3, "sdb: wwid xyzzy blacklisted\n"); -+ assert_int_equal(filter_path(&conf, &test_pp), MATCH_WWID_BLIST); -+} -+ -+struct udev_device miss_udev = { "sdb", { "ID_FOO", "ID_BAZ", "ID_BAR", NULL } }; -+ -+struct path miss1_pp = { .dev = "sdc", .bus = SYSFS_BUS_SCSI, -+ .udev = &miss_udev, -+ .sg_id.proto_id = SCSI_PROTOCOL_ISCSI, -+ .vendor_id = "foo", .product_id = "baz", -+ .wwid = "plugh" }; -+ -+struct path miss2_pp = { .dev = "sdc", .bus = SYSFS_BUS_SCSI, -+ .udev = &test_udev, -+ .sg_id.proto_id = SCSI_PROTOCOL_ISCSI, -+ .vendor_id = "foo", .product_id = "baz", -+ .wwid = "plugh" }; -+ -+static void test_filter_path_missing1(void **state) -+{ -+ conf.blist_property = blist_property_wwn; -+ conf.blist_devnode = blist_devnode_sdb; -+ conf.blist_device = blist_device_foo_bar; -+ conf.blist_protocol = blist_protocol_fcp; -+ conf.blist_wwid = blist_wwid_xyzzy; -+ expect_condlog(3, "sdb: blacklisted, udev property missing\n"); -+ assert_int_equal(filter_path(&conf, &miss1_pp), -+ MATCH_PROPERTY_BLIST_MISSING); -+} -+ -+/* This one matches the property whitelist, to test the other missing -+ * functions */ -+static void test_filter_path_missing2(void **state) -+{ -+ conf.elist_property = blist_property_wwn; -+ conf.blist_devnode = blist_devnode_sdb; -+ conf.blist_device = blist_device_foo_bar; -+ conf.blist_protocol = blist_protocol_fcp; -+ conf.blist_wwid = blist_wwid_xyzzy; -+ expect_condlog(3, "sdb: udev property ID_WWN whitelisted\n"); -+ assert_int_equal(filter_path(&conf, &miss2_pp), -+ MATCH_NOTHING); -+} -+ -+static void test_filter_path_whitelist(void **state) -+{ -+ conf.elist_property = blist_property_wwn; -+ conf.elist_devnode = blist_devnode_sdb; -+ conf.elist_device = blist_device_foo_bar; -+ conf.elist_protocol = blist_protocol_fcp; -+ conf.elist_wwid = blist_wwid_xyzzy; -+ expect_condlog(3, "sdb: udev property ID_WWN whitelisted\n"); -+ expect_condlog(3, "sdb: device node name whitelisted\n"); -+ expect_condlog(3, "sdb: (foo:bar) vendor/product whitelisted\n"); -+ expect_condlog(3, "sdb: protocol scsi:fcp whitelisted\n"); -+ expect_condlog(3, "sdb: wwid xyzzy whitelisted\n"); -+ assert_int_equal(filter_path(&conf, &test_pp), -+ MATCH_WWID_BLIST_EXCEPT); -+} -+ -+static void test_filter_path_whitelist_property(void **state) -+{ -+ conf.blist_property = blist_property_wwn; -+ conf.elist_devnode = blist_devnode_sdb; -+ conf.elist_device = blist_device_foo_bar; -+ conf.elist_protocol = blist_protocol_fcp; -+ conf.elist_wwid = blist_wwid_xyzzy; -+ expect_condlog(3, "sdb: udev property ID_WWN blacklisted\n"); -+ assert_int_equal(filter_path(&conf, &test_pp), MATCH_PROPERTY_BLIST); -+} -+ -+static void test_filter_path_whitelist_devnode(void **state) -+{ -+ conf.elist_property = blist_property_wwn; -+ conf.blist_devnode = blist_devnode_sdb; -+ conf.elist_device = blist_device_foo_bar; -+ conf.elist_protocol = blist_protocol_fcp; -+ conf.elist_wwid = blist_wwid_xyzzy; -+ expect_condlog(3, "sdb: udev property ID_WWN whitelisted\n"); -+ expect_condlog(3, "sdb: device node name blacklisted\n"); -+ assert_int_equal(filter_path(&conf, &test_pp), MATCH_DEVNODE_BLIST); -+} -+ -+static void test_filter_path_whitelist_device(void **state) -+{ -+ conf.elist_property = blist_property_wwn; -+ conf.elist_devnode = blist_devnode_sdb; -+ conf.blist_device = blist_device_foo_bar; -+ conf.elist_protocol = blist_protocol_fcp; -+ conf.elist_wwid = blist_wwid_xyzzy; -+ expect_condlog(3, "sdb: udev property ID_WWN whitelisted\n"); -+ expect_condlog(3, "sdb: device node name whitelisted\n"); -+ expect_condlog(3, "sdb: (foo:bar) vendor/product blacklisted\n"); -+ assert_int_equal(filter_path(&conf, &test_pp), MATCH_DEVICE_BLIST); -+} -+ -+static void test_filter_path_whitelist_protocol(void **state) -+{ -+ conf.elist_property = blist_property_wwn; -+ conf.elist_devnode = blist_devnode_sdb; -+ conf.elist_device = blist_device_foo_bar; -+ conf.blist_protocol = blist_protocol_fcp; -+ conf.elist_wwid = blist_wwid_xyzzy; -+ expect_condlog(3, "sdb: udev property ID_WWN whitelisted\n"); -+ expect_condlog(3, "sdb: device node name whitelisted\n"); -+ expect_condlog(3, "sdb: (foo:bar) vendor/product whitelisted\n"); -+ expect_condlog(3, "sdb: protocol scsi:fcp blacklisted\n"); -+ assert_int_equal(filter_path(&conf, &test_pp), MATCH_PROTOCOL_BLIST); -+} -+ -+static void test_filter_path_whitelist_wwid(void **state) -+{ -+ conf.elist_property = blist_property_wwn; -+ conf.elist_devnode = blist_devnode_sdb; -+ conf.elist_device = blist_device_foo_bar; -+ conf.elist_protocol = blist_protocol_fcp; -+ conf.blist_wwid = blist_wwid_xyzzy; -+ expect_condlog(3, "sdb: udev property ID_WWN whitelisted\n"); -+ expect_condlog(3, "sdb: device node name whitelisted\n"); -+ expect_condlog(3, "sdb: (foo:bar) vendor/product whitelisted\n"); -+ expect_condlog(3, "sdb: protocol scsi:fcp whitelisted\n"); -+ expect_condlog(3, "sdb: wwid xyzzy blacklisted\n"); -+ assert_int_equal(filter_path(&conf, &test_pp), MATCH_WWID_BLIST); -+} -+ -+#define test_and_reset(x) cmocka_unit_test_teardown((x), reset_blists) -+ -+int test_blacklist(void) -+{ -+ const struct CMUnitTest tests[] = { -+ cmocka_unit_test(test_devnode_blacklist), -+ cmocka_unit_test(test_devnode_whitelist), -+ cmocka_unit_test(test_devnode_missing), -+ cmocka_unit_test(test_device_blacklist), -+ cmocka_unit_test(test_device_whitelist), -+ cmocka_unit_test(test_device_missing), -+ cmocka_unit_test(test_wwid_blacklist), -+ cmocka_unit_test(test_wwid_whitelist), -+ cmocka_unit_test(test_wwid_missing), -+ cmocka_unit_test(test_protocol_blacklist), -+ cmocka_unit_test(test_protocol_whitelist), -+ cmocka_unit_test(test_protocol_missing), -+ test_and_reset(test_property_blacklist), -+ test_and_reset(test_property_whitelist), -+ test_and_reset(test_property_missing), -+ test_and_reset(test_filter_path_property), -+ test_and_reset(test_filter_path_devnode), -+ test_and_reset(test_filter_path_device), -+ test_and_reset(test_filter_path_protocol), -+ test_and_reset(test_filter_path_wwid), -+ test_and_reset(test_filter_path_missing1), -+ test_and_reset(test_filter_path_missing2), -+ test_and_reset(test_filter_path_whitelist), -+ test_and_reset(test_filter_path_whitelist_property), -+ test_and_reset(test_filter_path_whitelist_devnode), -+ test_and_reset(test_filter_path_whitelist_device), -+ test_and_reset(test_filter_path_whitelist_protocol), -+ test_and_reset(test_filter_path_whitelist_wwid), -+ }; -+ return cmocka_run_group_tests(tests, setup, teardown); -+} -+ -+int main(void) -+{ -+ int ret = 0; -+ ret += test_blacklist(); -+ return ret; -+} --- -2.7.4 - diff --git a/0010-mpathpersist-add-missing-param-rk-usage-info.patch b/0010-mpathpersist-add-missing-param-rk-usage-info.patch deleted file mode 100644 index e05d9e68493669a3ff67ebdfbb8147eaa793ee7f..0000000000000000000000000000000000000000 --- a/0010-mpathpersist-add-missing-param-rk-usage-info.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 16 Jul 2018 16:43:57 -0500 -Subject: [PATCH] mpathpersist: add missing --param-rk usage info - -Signed-off-by: Benjamin Marzinski ---- - mpathpersist/main.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/mpathpersist/main.c b/mpathpersist/main.c -index 99151fe..0e4d3f2 100644 ---- a/mpathpersist/main.c -+++ b/mpathpersist/main.c -@@ -705,6 +705,7 @@ static void usage(void) - " --param-alltgpt|-Y PR Out parameter 'ALL_TG_PT\n" - " --param-aptpl|-Z PR Out parameter 'APTPL'\n" - " --read-keys|-k PR In: Read Keys\n" -+ " --param-rk=RK|-K RK PR Out parameter reservation key\n" - " --param-sark=SARK|-S SARK PR Out parameter service " - "action\n" - " reservation key (SARK is in " --- -2.7.4 - diff --git a/0010-multipath-tools-Makefile-more-dependency-fixes-for-p.patch b/0010-multipath-tools-Makefile-more-dependency-fixes-for-p.patch new file mode 100644 index 0000000000000000000000000000000000000000..c4f0b3e8979231f6f90da9de17df39bf5a2cc3bf --- /dev/null +++ b/0010-multipath-tools-Makefile-more-dependency-fixes-for-p.patch @@ -0,0 +1,33 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 11 May 2020 14:24:37 +0200 +Subject: [PATCH] multipath-tools: Makefile: more dependency fixes for parallel + build + +Extend the late fixes from Christian. + +Cc: Christian Hesse +Signed-off-by: Benjamin Marzinski +--- + Makefile | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/Makefile b/Makefile +index ba1d73ba..fec3b73b 100644 +--- a/Makefile ++++ b/Makefile +@@ -28,8 +28,9 @@ all: $(BUILDDIRS) + $(BUILDDIRS): + $(MAKE) -C $@ + +-libmpathpersist multipath multipathd mpathpersist: libmultipath +-mpathpersist: libmpathpersist ++libmultipath libdmmp: libmpathcmd ++libmpathpersist multipath multipathd: libmultipath ++mpathpersist multipathd: libmpathpersist + + $(BUILDDIRS.clean): + $(MAKE) -C ${@:.clean=} clean +-- +2.17.2 + diff --git a/0011-multipath-tools-Makefile.inc-separate-out-OPTFLAGS.patch b/0011-multipath-tools-Makefile.inc-separate-out-OPTFLAGS.patch new file mode 100644 index 0000000000000000000000000000000000000000..2082970bd338fa744d57a802d6298ced2fc8bd61 --- /dev/null +++ b/0011-multipath-tools-Makefile.inc-separate-out-OPTFLAGS.patch @@ -0,0 +1,44 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 11 May 2020 15:27:34 +0200 +Subject: [PATCH] multipath-tools: Makefile.inc: separate out OPTFLAGS + +OPTFLAGS is what distribution builds would typically override. That +should not include the warning flags we use. + +Moreover, in the definition of CFLAGS, put $(CFLAGS) first to make it +easier for the user to spot her input in the build logs. + +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index d4d1e0dd..7a59db85 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -93,14 +93,14 @@ STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector) + ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers,) + WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered,) + +-OPTFLAGS = -O2 -g -pipe -Werror -Wall -Wextra -Wformat=2 -Werror=implicit-int \ ++OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 ++WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 -Werror=implicit-int \ + -Werror=implicit-function-declaration -Werror=format-security \ +- $(WNOCLOBBERED) \ +- -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) \ +- $(STACKPROT) --param=ssp-buffer-size=4 ++ $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) + CPPFLAGS := -Wp,-D_FORTIFY_SOURCE=2 +-CFLAGS := $(OPTFLAGS) -DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" \ +- -MMD -MP $(CFLAGS) ++CFLAGS := $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ ++ -DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" \ ++ -MMD -MP + BIN_CFLAGS = -fPIE -DPIE + LIB_CFLAGS = -fPIC + SHARED_FLAGS = -shared +-- +2.17.2 + diff --git a/0012-multipath-tools-Makefile.inc-allow-user-settings-for.patch b/0012-multipath-tools-Makefile.inc-allow-user-settings-for.patch new file mode 100644 index 0000000000000000000000000000000000000000..ba2ec42edd619169ee804ff5aa145801f1429374 --- /dev/null +++ b/0012-multipath-tools-Makefile.inc-allow-user-settings-for.patch @@ -0,0 +1,33 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 11 May 2020 16:00:04 +0200 +Subject: [PATCH] multipath-tools: Makefile.inc: allow user settings for + LDFLAGS + +This allows e.g. setting LDFLAGS="-m32 -Wl,-b,elf32-i386" to compile +for a 32bit target on a 64bit system. + +Note that, like CFLAGS, the variable needs to be set in the environment, +not on the "make" command line. + +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 7a59db85..671dd1ca 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -104,7 +104,7 @@ CFLAGS := $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ + BIN_CFLAGS = -fPIE -DPIE + LIB_CFLAGS = -fPIC + SHARED_FLAGS = -shared +-LDFLAGS = -Wl,-z,relro -Wl,-z,now ++LDFLAGS := $(LDFLAGS) -Wl,-z,relro -Wl,-z,now + BIN_LDFLAGS = -pie + + # Check whether a function with name $1 has been declared in header file $2. +-- +2.17.2 + diff --git a/0013-multipath-tools-Makefile.inc-set-Wno-error-clobbered.patch b/0013-multipath-tools-Makefile.inc-set-Wno-error-clobbered.patch new file mode 100644 index 0000000000000000000000000000000000000000..3de6cb6045d0d254f5c4f3195d021d51dfa3131a --- /dev/null +++ b/0013-multipath-tools-Makefile.inc-set-Wno-error-clobbered.patch @@ -0,0 +1,32 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 11 May 2020 17:19:37 +0200 +Subject: [PATCH] multipath-tools: Makefile.inc: set -Wno-error=clobbered + +We need to ignore -Wclobbered because gcc has trouble dealing with glibc's +implementation of pthread_cleanup_push(). + +For some variants of gcc, -Wno-clobbered alone isn't enough if -Werror is also +set. Compilation with -Wno-error=clobbered works, though. + +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 671dd1ca..e7256e3a 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -91,7 +91,7 @@ TEST_CC_OPTION = $(shell \ + + STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector) + ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers,) +-WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered,) ++WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered -Wno-error=clobbered,) + + OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 + WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 -Werror=implicit-int \ +-- +2.17.2 + diff --git a/0014-fix-segfault-when-mount-or-umount-VIMS-with-reservation-conflict.patch b/0014-fix-segfault-when-mount-or-umount-VIMS-with-reservation-conflict.patch deleted file mode 100644 index e144e9d1f5ac764874c709efbee48269a3e08fa8..0000000000000000000000000000000000000000 --- a/0014-fix-segfault-when-mount-or-umount-VIMS-with-reservation-conflict.patch +++ /dev/null @@ -1,17 +0,0 @@ -diff -uNr a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c ---- a/libmpathpersist/mpath_persist.c 2017-05-24 11:01:39.000000000 +0800 -+++ b/libmpathpersist/mpath_persist.c 2017-05-24 11:02:22.000000000 +0800 -@@ -510,10 +510,10 @@ - if (!rollback && (thread[i].param.status == MPATH_PR_RESERV_CONFLICT)){ - rollback = 1; - sa_key = 0; -- for (i = 0; i < 8; ++i){ -- if (i > 0) -+ for (j = 0; j < 8; ++j){ -+ if (j > 0) - sa_key <<= 8; -- sa_key |= paramp->sa_key[i]; -+ sa_key |= paramp->sa_key[j]; - } - status = MPATH_PR_RESERV_CONFLICT ; - } diff --git a/0014-libmultipath-discovery.c-use-z-qualifier-for-size_t.patch b/0014-libmultipath-discovery.c-use-z-qualifier-for-size_t.patch new file mode 100644 index 0000000000000000000000000000000000000000..749bef297e4059a94cffe714614f0c07ca44cb8e --- /dev/null +++ b/0014-libmultipath-discovery.c-use-z-qualifier-for-size_t.patch @@ -0,0 +1,90 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 11 May 2020 16:02:25 +0200 +Subject: [PATCH] libmultipath: discovery.c: use %z qualifier for size_t + +Otherwise compilation for 32bit targets spits out warnings. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/discovery.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index ee3290cd..ffec5162 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -986,7 +986,7 @@ parse_vpd_pg80(const unsigned char *in, char *out, size_t out_len) + } + + if (len >= out_len) { +- condlog(2, "vpd pg80 overflow, %lu/%lu bytes required", ++ condlog(2, "vpd pg80 overflow, %zu/%zu bytes required", + len + 1, out_len); + len = out_len - 1; + } +@@ -1087,7 +1087,7 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, + + len = sprintf(out, "%d", vpd_type); + if (2 * vpd_len >= out_len - len) { +- condlog(1, "%s: WWID overflow, type %d, %lu/%lu bytes required", ++ condlog(1, "%s: WWID overflow, type %d, %zu/%zu bytes required", + __func__, vpd_type, + 2 * vpd_len + len + 1, out_len); + vpd_len = (out_len - len - 1) / 2; +@@ -1096,7 +1096,7 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, + len += sprintf(out + len, + "%02x", vpd[i]); + } else if (vpd_type == 0x8 && vpd_len < 4) { +- condlog(1, "%s: VPD length %lu too small for designator type 8", ++ condlog(1, "%s: VPD length %zu too small for designator type 8", + __func__, vpd_len); + return -EINVAL; + } else if (vpd_type == 0x8) { +@@ -1112,7 +1112,7 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, + while (len > 2 && vpd[len - 2] == '\0') + --len; + if (len > out_len - 1) { +- condlog(1, "%s: WWID overflow, type 8/%c, %lu/%lu bytes required", ++ condlog(1, "%s: WWID overflow, type 8/%c, %zu/%zu bytes required", + __func__, out[0], len + 1, out_len); + len = out_len - 1; + } +@@ -1136,7 +1136,7 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, + while ((p = memchr(vpd, ' ', vpd_len))) { + p_len = p - vpd; + if (len + p_len > out_len - 1) { +- condlog(1, "%s: WWID overflow, type 1, %lu/%lu bytes required", ++ condlog(1, "%s: WWID overflow, type 1, %zu/%zu bytes required", + __func__, len + p_len, out_len); + p_len = out_len - len - 1; + } +@@ -1162,7 +1162,7 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, + p_len = vpd_len; + if (p_len > 0 && len < out_len - 1) { + if (len + p_len > out_len - 1) { +- condlog(1, "%s: WWID overflow, type 1, %lu/%lu bytes required", ++ condlog(1, "%s: WWID overflow, type 1, %zu/%zu bytes required", + __func__, len + p_len + 1, out_len); + p_len = out_len - len - 1; + } +@@ -1186,14 +1186,14 @@ parse_vpd_c0_hp3par(const unsigned char *in, size_t in_len, + + memset(out, 0x0, out_len); + if (in_len <= 4 || (in[4] > 3 && in_len < 44)) { +- condlog(3, "HP/3PAR vendor specific VPD page length too short: %lu", in_len); ++ condlog(3, "HP/3PAR vendor specific VPD page length too short: %zu", in_len); + return -EINVAL; + } + if (in[4] <= 3) /* revision must be > 3 to have Vomlume Name */ + return -ENODATA; + len = get_unaligned_be32(&in[40]); + if (len > out_len || len + 44 > in_len) { +- condlog(3, "HP/3PAR vendor specific Volume name too long: %lu", ++ condlog(3, "HP/3PAR vendor specific Volume name too long: %zu", + len); + return -EINVAL; + } +-- +2.17.2 + diff --git a/0015-fix-multipathd-resize-when-not-all-paths-size-are-equal.patch b/0015-fix-multipathd-resize-when-not-all-paths-size-are-equal.patch deleted file mode 100644 index 955eceb265d2d604c8048ea9ea0d6f664ead73c4..0000000000000000000000000000000000000000 --- a/0015-fix-multipathd-resize-when-not-all-paths-size-are-equal.patch +++ /dev/null @@ -1,37 +0,0 @@ ---- multipath-tools-130222-patched/multipathd/cli_handlers.c 2017-10-12 19:19:08.000000000 +0800 -+++ multipath-tools-130222-patched1/multipathd/cli_handlers.c 2017-10-17 14:43:43.000000000 +0800 -@@ -593,9 +593,10 @@ - char * mapname = get_keyparam(v, MAP); - struct multipath *mpp; - int minor; -- unsigned long long size; -+ unsigned long long size, sz; - struct pathgroup *pgp; - struct path *pp; -+ int i,j; - - mapname = convert_dev(mapname, 0); - condlog(2, "%s: resize map (operator)", mapname); -@@ -627,6 +628,22 @@ - mapname); - return 1; - } -+ -+ vector_foreach_slot (mpp->pg, pgp, i) { -+ vector_foreach_slot (pgp->paths, pp, j) { -+ if (!pp->udev || sysfs_get_size(pp, &sz)) { -+ condlog(0, "%s: couldn't get size for sysfs. cannot resize", -+ mapname); -+ return 1; -+ } -+ if (size != sz) { -+ condlog(0, "%s: not all path sizes are equal, please check. cannot resize", -+ mapname); -+ return 1; -+ } -+ } -+ } -+ - if (size == mpp->size) { - condlog(0, "%s: map is still the same size (%llu)", mapname, - mpp->size); diff --git a/0015-libmultipath-eliminate-more-signed-unsigned-comparis.patch b/0015-libmultipath-eliminate-more-signed-unsigned-comparis.patch new file mode 100644 index 0000000000000000000000000000000000000000..a97c202febdeb3faffe9df31c3a57271f47ef45c --- /dev/null +++ b/0015-libmultipath-eliminate-more-signed-unsigned-comparis.patch @@ -0,0 +1,198 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 11 May 2020 16:03:58 +0200 +Subject: [PATCH] libmultipath: eliminate more signed/unsigned comparisons + +Fix some more compiler warnings about signed/unsigned comparison. +I've observed these only on 32bit builds, therefore they went unnoticed +before. + +Signed-off-by: Benjamin Marzinski +--- + libmpathpersist/mpath_pr_ioctl.c | 2 +- + libmultipath/print.c | 12 ++++++------ + libmultipath/prioritizers/alua_spc3.h | 2 +- + multipathd/cli_handlers.c | 20 ++++++++++---------- + multipathd/main.c | 2 +- + 5 files changed, 19 insertions(+), 19 deletions(-) + +diff --git a/libmpathpersist/mpath_pr_ioctl.c b/libmpathpersist/mpath_pr_ioctl.c +index fadc9e10..126601c3 100644 +--- a/libmpathpersist/mpath_pr_ioctl.c ++++ b/libmpathpersist/mpath_pr_ioctl.c +@@ -238,7 +238,7 @@ static void mpath_format_readfullstatus(struct prin_resp *pr_buff) + uint32_t additional_length, k, tid_len_len = 0; + char tempbuff[MPATH_MAX_PARAM_LEN]; + struct prin_fulldescr fdesc; +- static const int pbuf_size = ++ static const unsigned int pbuf_size = + sizeof(pr_buff->prin_descriptor.prin_readfd.private_buffer); + + convert_be32_to_cpu(&pr_buff->prin_descriptor.prin_readfd.prgeneration); +diff --git a/libmultipath/print.c b/libmultipath/print.c +index b944ef32..298b3764 100644 +--- a/libmultipath/print.c ++++ b/libmultipath/print.c +@@ -1958,25 +1958,25 @@ char *snprint_config(const struct config *conf, int *len, + } + + c = reply + snprint_defaults(conf, reply, maxlen); +- if ((c - reply) == maxlen) ++ if (c == reply + maxlen) + continue; + + c += snprint_blacklist(conf, c, reply + maxlen - c); +- if ((c - reply) == maxlen) ++ if (c == reply + maxlen) + continue; + + c += snprint_blacklist_except(conf, c, reply + maxlen - c); +- if ((c - reply) == maxlen) ++ if (c == reply + maxlen) + continue; + + c += snprint_hwtable(conf, c, reply + maxlen - c, + hwtable ? hwtable : conf->hwtable); +- if ((c - reply) == maxlen) ++ if (c == reply + maxlen) + continue; + + c += snprint_overrides(conf, c, reply + maxlen - c, + conf->overrides); +- if ((c - reply) == maxlen) ++ if (c == reply + maxlen) + continue; + + if (VECTOR_SIZE(conf->mptable) > 0 || +@@ -1984,7 +1984,7 @@ char *snprint_config(const struct config *conf, int *len, + c += snprint_mptable(conf, c, reply + maxlen - c, + mpvec); + +- if ((c - reply) < maxlen) { ++ if (c < reply + maxlen) { + if (len) + *len = c - reply; + return reply; +diff --git a/libmultipath/prioritizers/alua_spc3.h b/libmultipath/prioritizers/alua_spc3.h +index 18b495ef..7ba2cf4c 100644 +--- a/libmultipath/prioritizers/alua_spc3.h ++++ b/libmultipath/prioritizers/alua_spc3.h +@@ -284,7 +284,7 @@ struct rtpg_data { + #define RTPG_FOR_EACH_PORT_GROUP(p, g) \ + for( \ + g = &(p->data[0]); \ +- (((char *) g) - ((char *) p)) < get_unaligned_be32(p->length); \ ++ ((char *) g) < ((char *) p) + get_unaligned_be32(p->length); \ + g = (struct rtpg_tpg_dscr *) ( \ + ((char *) g) + \ + sizeof(struct rtpg_tpg_dscr) + \ +diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c +index 7d878c88..31c3d9fd 100644 +--- a/multipathd/cli_handlers.c ++++ b/multipathd/cli_handlers.c +@@ -66,7 +66,7 @@ show_paths (char ** r, int * len, struct vectors * vecs, char * style, + c += snprint_foreign_paths(c, reply + maxlen - c, + style, pretty); + +- again = ((c - reply) == (maxlen - 1)); ++ again = (c == reply + maxlen - 1); + + REALLOC_REPLY(reply, again, maxlen); + } +@@ -102,7 +102,7 @@ show_path (char ** r, int * len, struct vectors * vecs, struct path *pp, + + c += snprint_path(c, reply + maxlen - c, style, pp, 0); + +- again = ((c - reply) == (maxlen - 1)); ++ again = (c == reply + maxlen - 1); + + REALLOC_REPLY(reply, again, maxlen); + } +@@ -131,7 +131,7 @@ show_map_topology (char ** r, int * len, struct multipath * mpp, + c = reply; + + c += snprint_multipath_topology(c, reply + maxlen - c, mpp, 2); +- again = ((c - reply) == (maxlen - 1)); ++ again = (c == reply + maxlen - 1); + + REALLOC_REPLY(reply, again, maxlen); + } +@@ -171,7 +171,7 @@ show_maps_topology (char ** r, int * len, struct vectors * vecs) + } + c += snprint_foreign_topology(c, reply + maxlen - c, 2); + +- again = ((c - reply) == (maxlen - 1)); ++ again = (c == reply + maxlen - 1); + + REALLOC_REPLY(reply, again, maxlen); + } +@@ -209,7 +209,7 @@ show_maps_json (char ** r, int * len, struct vectors * vecs) + c = reply; + + c += snprint_multipath_topology_json(c, maxlen, vecs); +- again = ((c - reply) == maxlen); ++ again = (c == reply + maxlen); + + REALLOC_REPLY(reply, again, maxlen); + } +@@ -238,7 +238,7 @@ show_map_json (char ** r, int * len, struct multipath * mpp, + c = reply; + + c += snprint_multipath_map_json(c, maxlen, mpp); +- again = ((c - reply) == maxlen); ++ again = (c == reply + maxlen); + + REALLOC_REPLY(reply, again, maxlen); + } +@@ -487,7 +487,7 @@ show_map (char ** r, int *len, struct multipath * mpp, char * style, + c += snprint_multipath(c, reply + maxlen - c, style, + mpp, pretty); + +- again = ((c - reply) == (maxlen - 1)); ++ again = (c == reply + maxlen - 1); + + REALLOC_REPLY(reply, again, maxlen); + } +@@ -533,7 +533,7 @@ show_maps (char ** r, int *len, struct vectors * vecs, char * style, + } + c += snprint_foreign_multipaths(c, reply + maxlen - c, + style, pretty); +- again = ((c - reply) == (maxlen - 1)); ++ again = (c == reply + maxlen - 1); + + REALLOC_REPLY(reply, again, maxlen); + } +@@ -1297,7 +1297,7 @@ show_blacklist (char ** r, int * len) + + c = reply; + c += snprint_blacklist_report(conf, c, maxlen); +- again = ((c - reply) == maxlen); ++ again = (c == reply + maxlen); + REALLOC_REPLY(reply, again, maxlen); + } + pthread_cleanup_pop(1); +@@ -1339,7 +1339,7 @@ show_devices (char ** r, int * len, struct vectors *vecs) + + c = reply; + c += snprint_devices(conf, c, maxlen, vecs); +- again = ((c - reply) == maxlen); ++ again = (c == reply + maxlen); + REALLOC_REPLY(reply, again, maxlen); + } + pthread_cleanup_pop(1); +diff --git a/multipathd/main.c b/multipathd/main.c +index 8baf9abe..6b7db2c0 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -2374,7 +2374,7 @@ checkerloop (void *ap) + conf = get_multipath_config(); + max_checkint = conf->max_checkint; + put_multipath_config(conf); +- if (diff_time.tv_sec > max_checkint) ++ if (diff_time.tv_sec > (time_t)max_checkint) + condlog(1, "path checkers took longer " + "than %lu seconds, consider " + "increasing max_polling_interval", +-- +2.17.2 + diff --git a/0016-libmultipath-set_uint-fix-parsing-for-32bit.patch b/0016-libmultipath-set_uint-fix-parsing-for-32bit.patch new file mode 100644 index 0000000000000000000000000000000000000000..c6219375009470e7bc152e538ec89b22d94d1aad --- /dev/null +++ b/0016-libmultipath-set_uint-fix-parsing-for-32bit.patch @@ -0,0 +1,48 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 11 May 2020 22:22:25 +0200 +Subject: [PATCH] libmultipath: set_uint: fix parsing for 32bit + +On architectures where sizeof(long) == sizeof(int), the code wouldn't +work as intended. Use strtoul instead. As strtoul happily parses +negative numbers as input, require the number to begin with a digit. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/dict.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index 3e25e74f..0e9ea387 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -60,19 +60,22 @@ static int + set_uint(vector strvec, void *ptr) + { + unsigned int *uint_ptr = (unsigned int *)ptr; +- char *buff, *eptr; +- long res; ++ char *buff, *eptr, *p; ++ unsigned long res; + int rc; + + buff = set_value(strvec); + if (!buff) + return 1; + +- res = strtol(buff, &eptr, 10); ++ p = buff; ++ while (isspace(*p)) ++ p++; ++ res = strtoul(p, &eptr, 10); + if (eptr > buff) + while (isspace(*eptr)) + eptr++; +- if (*buff == '\0' || *eptr != '\0' || res < 0 || res > UINT_MAX) { ++ if (*buff == '\0' || *eptr != '\0' || !isdigit(*p) || res > UINT_MAX) { + condlog(1, "%s: invalid value for %s: \"%s\"", + __func__, (char*)VECTOR_SLOT(strvec, 0), buff); + rc = 1; +-- +2.17.2 + diff --git a/0016-multipathd-disable-queueing-for-recreated-map-in-uev.patch b/0016-multipathd-disable-queueing-for-recreated-map-in-uev.patch deleted file mode 100644 index a2cba953dab9873c0c5c1a43de76823ea835359a..0000000000000000000000000000000000000000 --- a/0016-multipathd-disable-queueing-for-recreated-map-in-uev.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 4098378d2e976c9b371ae6bf83e802fb32187f50 Mon Sep 17 00:00:00 2001 -From: sunguoshuai -Date: Tue, 22 Jan 2019 21:29:56 -0500 -Subject: [PATCH] multipathd: disable queueing for recreated map in - uev_remove_map - -reason:disable queueing for recreated map in uev_remove_map ---- - multipathd/main.c | 23 +++++++++++++++++++++-- - 1 file changed, 21 insertions(+), 2 deletions(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index cc493c1..9dd74ad 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -647,7 +647,7 @@ uev_add_map (struct uevent * uev, struct vectors * vecs) - char *alias; - int major = -1, minor = -1, rc; - -- condlog(3, "%s: add map (uevent)", uev->kernel); -+ condlog(2, "%s: add map (uevent)", uev->kernel); - alias = uevent_get_dm_name(uev); - if (!alias) { - condlog(3, "%s: No DM_NAME in uevent", uev->kernel); -@@ -766,7 +766,26 @@ uev_remove_map (struct uevent * uev, struct vectors * vecs) - mpp->alias, mpp->dmi->minor, minor); - goto out; - } -- -+ /* -+ * There may be a race window here: -+ * 1. all paths gone, causing map flushed both from multipathd and kernel -+ * 2. paths regenerated, causing multipathd creating the map again. -+ * 1 will generate a remove uevent which can be handled after 2, -+ * so we can disable queueing for the map created by 2 here temporarily -+ * and let the change uevent (generated by 2) calling uev_add_map -+ * ->setup_multipath to set queueing again. This can prevent -+ * the deadlock in this race window. -+ * -+ * The possible deadlock is: all udevd workers hangs in -+ * devices because of queue_if_no_path, so no udevd workers -+ * can handle new event and since multipathd will remove the map, -+ * the checkerloop cannot check this map's retry tick timeout -+ * and cancel the io hang which makes the udevd worker hang forever. -+ * multipathd cannot receive any uevent from udevd because all -+ * udevd workers hang there so the map cannot be recreated -+ * again which makes a deadlock. -+ */ -+ dm_queue_if_no_path(alias, 0); - orphan_paths(vecs->pathvec, mpp); - remove_map_and_stop_waiter(mpp, vecs); - out: --- -1.8.3.1 - diff --git a/0017-avoid-handling-paths-repeatedly-in-coalesce-paths.patch b/0017-avoid-handling-paths-repeatedly-in-coalesce-paths.patch deleted file mode 100644 index d60f7d980ea32b6f2a67859a6bd3fcf41db7ad03..0000000000000000000000000000000000000000 --- a/0017-avoid-handling-paths-repeatedly-in-coalesce-paths.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 6c79d35c3d351323d18b63d76450fcfbb6ef5b56 Mon Sep 17 00:00:00 2001 -From: sunguoshuai -Date: Tue, 22 Jan 2019 22:00:35 -0500 -Subject: [PATCH] Module: fix lun expansion failure when there is offline path - -reason:fix lun expansion failure when there is offline path ---- - libmultipath/configure.c | 11 +++++++++++ - libmultipath/structs.c | 1 + - libmultipath/structs.h | 1 + - libmultipath/structs_vec.c | 1 + - 4 files changed, 14 insertions(+) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 09c3dcf..1b1cc55 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -1021,6 +1021,7 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, - } - vector_foreach_slot (pathvec, pp1, k) { - int invalid = 0; -+ condlog(3, "%s %s: start coalesce", pp1->dev, pp1->dev_t); - /* skip this path for some reason */ - - /* 1. if path has no unique id or wwid blacklisted */ -@@ -1053,6 +1054,12 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, - orphan_path(pp1, "only one path"); - continue; - } -+ /* if path is handled before */ -+ if (pp1->handled) { -+ condlog(3, "%s: skip handled path.", pp1->dev_t); -+ continue; -+ } -+ - - /* - * at this point, we know we really got a new mp -@@ -1071,6 +1078,10 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, - - for (i = k + 1; i < VECTOR_SIZE(pathvec); i++) { - pp2 = VECTOR_SLOT(pathvec, i); -+ if (pp2->handled) -+ continue; -+ -+ - - if (strcmp(pp1->wwid, pp2->wwid)) - continue; -diff --git a/libmultipath/structs.c b/libmultipath/structs.c -index ae847d6..99435c1 100644 ---- a/libmultipath/structs.c -+++ b/libmultipath/structs.c -@@ -100,6 +100,7 @@ alloc_path (void) - pp->fd = -1; - pp->tpgs = TPGS_UNDEF; - pp->priority = PRIO_UNDEF; -+ pp->handled = 0; - checker_clear(&pp->checker); - dm_path_to_gen(pp)->ops = &dm_gen_path_ops; - pp->hwe = vector_alloc(); -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index 0a2623a..d667cb7 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -277,6 +277,7 @@ struct path { - struct checker checker; - struct multipath * mpp; - int fd; -+ int handled; - int initialized; - int retriggers; - int wwid_changed; -diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c -index f87d69d..fba38c0 100644 ---- a/libmultipath/structs_vec.c -+++ b/libmultipath/structs_vec.c -@@ -388,6 +388,7 @@ int verify_paths(struct multipath *mpp, struct vectors *vecs) - return 0; - - vector_foreach_slot (mpp->paths, pp, i) { -+ pp->handled = 1; - /* - * see if path is in sysfs - */ --- -1.8.3.1 - diff --git a/0017-multipath-tools-tests-Makefile-add-lmpathcmd-to-LIBD.patch b/0017-multipath-tools-tests-Makefile-add-lmpathcmd-to-LIBD.patch new file mode 100644 index 0000000000000000000000000000000000000000..282aa387be3bb0a442953702f1f7de5f9d8c7a4d --- /dev/null +++ b/0017-multipath-tools-tests-Makefile-add-lmpathcmd-to-LIBD.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 11 May 2020 18:24:19 +0200 +Subject: [PATCH] multipath-tools tests/Makefile: add -lmpathcmd to LIBDEPS + +Make sure the linker finds libmpathcmd. + +Signed-off-by: Benjamin Marzinski +--- + tests/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tests/Makefile b/tests/Makefile +index 77ff3249..028c9ea7 100644 +--- a/tests/Makefile ++++ b/tests/Makefile +@@ -10,7 +10,7 @@ W_MISSING_INITIALIZERS := $(call TEST_MISSING_INITIALIZERS) + + CFLAGS += $(BIN_CFLAGS) -I$(multipathdir) -I$(mpathcmddir) \ + -Wno-unused-parameter $(W_MISSING_INITIALIZERS) +-LIBDEPS += -L$(multipathdir) -lmultipath -lcmocka ++LIBDEPS += -L$(multipathdir) -L$(mpathcmddir) -lmultipath -lmpathcmd -lcmocka + + TESTS := uevent parser util dmevents hwtable blacklist unaligned vpd pgpolicy \ + alias directio +-- +2.17.2 + diff --git a/0018-fix-bugs-backported-from-next-branch.patch b/0018-fix-bugs-backported-from-next-branch.patch deleted file mode 100644 index dda642bb098d8ec0b4d1e96784a94c53c324cce6..0000000000000000000000000000000000000000 --- a/0018-fix-bugs-backported-from-next-branch.patch +++ /dev/null @@ -1,154 +0,0 @@ -From a9b5625e0dba3b76832b17c6fbb34840f1a91653 Mon Sep 17 00:00:00 2001 -From: sunguoshuai -Date: Wed, 23 Jan 2019 01:57:33 -0500 -Subject: [PATCH] fix bugs backported from next branch - -reason:fix bugs backported from next branch ---- - libmultipath/prioritizers/alua.c | 4 ++++ - libmultipath/prioritizers/emc.c | 2 +- - libmultipath/prioritizers/hds.c | 20 ++++++++++++-------- - libmultipath/structs_vec.c | 4 +++- - multipathd/main.c | 5 +++++ - 5 files changed, 25 insertions(+), 10 deletions(-) - -diff --git a/libmultipath/prioritizers/alua.c b/libmultipath/prioritizers/alua.c -index 03d0a0e..1400b11 100644 ---- a/libmultipath/prioritizers/alua.c -+++ b/libmultipath/prioritizers/alua.c -@@ -128,15 +128,19 @@ int getprio (struct path * pp, char * args, unsigned int timeout) - switch(-rc) { - case ALUA_PRIO_NOT_SUPPORTED: - condlog(0, "%s: alua not supported", pp->dev); -+ rc = 0; - break; - case ALUA_PRIO_RTPG_FAILED: - condlog(0, "%s: couldn't get target port group", pp->dev); -+ rc = 0; - break; - case ALUA_PRIO_GETAAS_FAILED: - condlog(0, "%s: couldn't get asymmetric access state", pp->dev); -+ rc = 0; - break; - case ALUA_PRIO_TPGS_FAILED: - condlog(3, "%s: couldn't get supported alua states", pp->dev); -+ rc = 0; - break; - } - } -diff --git a/libmultipath/prioritizers/emc.c b/libmultipath/prioritizers/emc.c -index a2f7487..c5382e0 100644 ---- a/libmultipath/prioritizers/emc.c -+++ b/libmultipath/prioritizers/emc.c -@@ -19,7 +19,7 @@ int emc_clariion_prio(const char *dev, int fd, unsigned int timeout) - unsigned char inqCmdBlk[INQUIRY_CMDLEN] = {INQUIRY_CMD, 1, 0xC0, 0, - sizeof(sense_buffer), 0}; - struct sg_io_hdr io_hdr; -- int ret = PRIO_UNDEF; -+ int ret = 0; - - memset(&io_hdr, 0, sizeof (struct sg_io_hdr)); - memset(&sense_buffer, 0, 128); -diff --git a/libmultipath/prioritizers/hds.c b/libmultipath/prioritizers/hds.c -index 70fb5d1..56d182b 100644 ---- a/libmultipath/prioritizers/hds.c -+++ b/libmultipath/prioritizers/hds.c -@@ -98,10 +98,12 @@ int hds_modular_prio (const char *dev, int fd, unsigned int timeout) - unsigned char *inqBuffp = inqBuff; - unsigned char sense_buffer[32]; - sg_io_hdr_t io_hdr; -+ int ret = 0; - - if ((ioctl (fd, SG_GET_VERSION_NUM, &k) < 0) || (k < 30000)) { - pp_hds_log(0, "can't use SG ioctl interface"); -- return -1; -+ goto out; -+ - } - - memset (&io_hdr, 0, sizeof (sg_io_hdr_t)); -@@ -118,11 +120,11 @@ int hds_modular_prio (const char *dev, int fd, unsigned int timeout) - - if (ioctl (fd, SG_IO, &io_hdr) < 0) { - pp_hds_log(0, "SG_IO error"); -- return -1; -+ goto out; - } - if ((io_hdr.info & SG_INFO_OK_MASK) != SG_INFO_OK) { - pp_hds_log(0, "SCSI error"); -- return -1; -+ goto out; - } - - snprintf (vendor, 9, "%.8s", inqBuffp + 8); -@@ -144,11 +146,11 @@ int hds_modular_prio (const char *dev, int fd, unsigned int timeout) - switch (ldev[3]) { - case '0': case '2': case '4': case '6': case '8': case 'A': case 'C': case 'E': - pp_hds_log(4, "CTRL EVEN, LDEV EVEN, PRIO 1"); -- return 1; -+ ret = 1; - break; - case '1': case '3': case '5': case '7': case '9': case 'B': case 'D': case 'F': - pp_hds_log(4, "CTRL EVEN, LDEV ODD, PRIO 0"); -- return 0; -+ ret = 0; - break; - } - break; -@@ -156,16 +158,18 @@ int hds_modular_prio (const char *dev, int fd, unsigned int timeout) - switch (ldev[3]) { - case '0': case '2': case '4': case '6': case '8': case 'A': case 'C': case 'E': - pp_hds_log(4, "CTRL ODD, LDEV EVEN, PRIO 0"); -- return 0; -+ ret = 0; - break; - case '1': case '3': case '5': case '7': case '9': case 'B': case 'D': case 'F': - pp_hds_log(4, "CTRL ODD, LDEV ODD, PRIO 1"); -- return 1; -+ ret = 1; - break; - } - break; - } -- return -1; -+ -+out: -+ return ret; - } - - int getprio (struct path * pp, char * args, unsigned int timeout) -diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c -index fba38c0..d85eb5f 100644 ---- a/libmultipath/structs_vec.c -+++ b/libmultipath/structs_vec.c -@@ -32,8 +32,10 @@ int update_mpp_paths(struct multipath *mpp, vector pathvec) - return 0; - - if (!mpp->paths && -- !(mpp->paths = vector_alloc())) -+ !(mpp->paths = vector_alloc())) { -+ condlog(2, "mpp->paths alloc failed"); - return 1; -+ } - - vector_foreach_slot (mpp->pg, pgp, i) { - vector_foreach_slot (pgp->paths, pp, j) { -diff --git a/multipathd/main.c b/multipathd/main.c -index 9dd74ad..7a80688 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -1624,6 +1624,11 @@ enable_group(struct path * pp) - - pgp = VECTOR_SLOT(pp->mpp->pg, pp->pgindex - 1); - -+ if (!pgp) { -+ condlog(2, "%s: pgp is NULL", pp->mpp->alias); -+ return; -+ } -+ - if (pgp->status == PGSTATE_DISABLED) { - condlog(2, "%s: enable group #%i", pp->mpp->alias, pp->pgindex); - dm_enablegroup(pp->mpp->alias, pp->pgindex); --- -2.19.1 - diff --git a/0018-multipath-tools-tests-Makefile-Fix-OBJDEPS-for-hwtab.patch b/0018-multipath-tools-tests-Makefile-Fix-OBJDEPS-for-hwtab.patch new file mode 100644 index 0000000000000000000000000000000000000000..5835089e2e3e78507a83fe71ee3805c3b0fabb42 --- /dev/null +++ b/0018-multipath-tools-tests-Makefile-Fix-OBJDEPS-for-hwtab.patch @@ -0,0 +1,34 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 11 May 2020 23:44:19 +0200 +Subject: [PATCH] multipath tools tests/Makefile: Fix OBJDEPS for hwtable-test + +OBJDEPS needs to list object files that _call_ functions we want +to wrap, but it should _not_ list the object files where these +functions are defined; otherwise the linker might resolve these +symbols before they can be wrapped. + +(Observed on i586 with gcc 9.3.1, ld 2.34.0, where wrapping +prio_getprio() doesn't work with prio.o in OBJDEPS). + +Signed-off-by: Benjamin Marzinski +--- + tests/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tests/Makefile b/tests/Makefile +index 028c9ea7..1b8706a7 100644 +--- a/tests/Makefile ++++ b/tests/Makefile +@@ -41,7 +41,7 @@ endif + dmevents-test_LIBDEPS = -lpthread -ldevmapper -lurcu + hwtable-test_TESTDEPS := test-lib.o + hwtable-test_OBJDEPS := ../libmultipath/discovery.o ../libmultipath/blacklist.o \ +- ../libmultipath/prio.o ../libmultipath/callout.o ../libmultipath/structs.o ++ ../libmultipath/structs.o + hwtable-test_LIBDEPS := -ludev -lpthread -ldl + blacklist-test_TESTDEPS := test-log.o + blacklist-test_OBJDEPS := ../libmultipath/blacklist.o +-- +2.17.2 + diff --git a/0019-bugfix-fix-change-reservation-key-to-uint8-for-memcmp.patch b/0019-bugfix-fix-change-reservation-key-to-uint8-for-memcmp.patch deleted file mode 100644 index af0ac0e7f325c70468a4be6f2721aaaed26c00a6..0000000000000000000000000000000000000000 --- a/0019-bugfix-fix-change-reservation-key-to-uint8-for-memcmp.patch +++ /dev/null @@ -1,46 +0,0 @@ -From aa3dbb9a4c7ba220139801533a27d99542d4e909 Mon Sep 17 00:00:00 2001 -From: sunguoshuai -Date: Wed, 23 Jan 2019 02:21:31 -0500 -Subject: [PATCH] fix change reservation key to uint8 for - memcmp - -reason:fix change reservation key to uint8 for memcmp ---- - libmpathpersist/mpath_persist.c | 14 ++++++++++++-- - 1 file changed, 12 insertions(+), 2 deletions(-) - -diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c -index 691b4e1..a2907db 100644 ---- a/libmpathpersist/mpath_persist.c -+++ b/libmpathpersist/mpath_persist.c -@@ -263,6 +263,9 @@ int mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, - int ret; - uint64_t prkey; - struct config *conf; -+ uint8_t uitmp[8] = {0}; -+ uint64_t uireservation = {0}; -+ int j; - - conf = get_multipath_config(); - conf->verbosity = verbose; -@@ -353,8 +356,15 @@ int mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, - } - } - -- if (memcmp(paramp->key, &mpp->reservation_key, 8) && -- memcmp(paramp->sa_key, &mpp->reservation_key, 8)) { -+ uireservation = get_be64(mpp->reservation_key); -+ for (j = 7; j >= 0; --j) { -+ uitmp[j] = (uireservation & 0xff); -+ uireservation >>= 8; -+ } -+ -+ if (memcmp(paramp->key, uitmp, 8) && -+ memcmp(paramp->sa_key, uitmp, 8)) { -+ - condlog(0, "%s: configured reservation key doesn't match: 0x%" PRIx64, alias, get_be64(mpp->reservation_key)); - ret = MPATH_PR_SYNTAX_ERROR; - goto out1; --- -1.8.3.1 - diff --git a/0019-multipath-tools-tests-test-lib.c-drop-__wrap_is_clai.patch b/0019-multipath-tools-tests-test-lib.c-drop-__wrap_is_clai.patch new file mode 100644 index 0000000000000000000000000000000000000000..e5882f6c696c27c1ffddeb46c30640e487e0ef9f --- /dev/null +++ b/0019-multipath-tools-tests-test-lib.c-drop-__wrap_is_clai.patch @@ -0,0 +1,33 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 11 May 2020 23:43:02 +0200 +Subject: [PATCH] multipath-tools tests/test-lib.c: drop + __wrap_is_claimed_by_foreign + +is_claimed_by_foreign() is an inline function and can't be wrapped. + +Signed-off-by: Benjamin Marzinski +--- + tests/test-lib.c | 6 ------ + 1 file changed, 6 deletions(-) + +diff --git a/tests/test-lib.c b/tests/test-lib.c +index 59275163..00bae58e 100644 +--- a/tests/test-lib.c ++++ b/tests/test-lib.c +@@ -56,12 +56,6 @@ int __wrap_execute_program(char *path, char *value, int len) + return 0; + } + +-bool __wrap_is_claimed_by_foreign(struct udev_device *ud) +-{ +- condlog(5, "%s: %p", __func__, ud); +- return false; +-} +- + struct udev_list_entry + *__wrap_udev_device_get_properties_list_entry(struct udev_device *ud) + { +-- +2.17.2 + diff --git a/0020-bugfix-ignore-for-clear-mismatch-key.patch b/0020-bugfix-ignore-for-clear-mismatch-key.patch deleted file mode 100644 index b76e188f642787b218aadc2595266a98eac0e56a..0000000000000000000000000000000000000000 --- a/0020-bugfix-ignore-for-clear-mismatch-key.patch +++ /dev/null @@ -1,49 +0,0 @@ -From de2078dd66a62ca7ba2ae6adc406311e830572fa Mon Sep 17 00:00:00 2001 -From: sunguoshuai -Date: Wed, 23 Jan 2019 02:38:00 -0500 -Subject: [PATCH] ignore for clear mismatch key - -reason:ignore for clear mismatch key ---- - libmpathpersist/mpath_persist.c | 17 +++++++++++------ - 1 file changed, 11 insertions(+), 6 deletions(-) - -diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c -index a2907db..27c848c 100644 ---- a/libmpathpersist/mpath_persist.c -+++ b/libmpathpersist/mpath_persist.c -@@ -345,7 +345,8 @@ int mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, - if (mpp->prkey_source == PRKEY_SOURCE_FILE && prkey && - ((!get_be64(mpp->reservation_key) && - rq_servact == MPATH_PROUT_REG_SA) || -- rq_servact == MPATH_PROUT_REG_IGN_SA)) { -+ rq_servact == MPATH_PROUT_REG_IGN_SA || -+ (!memcmp(paramp->key, &mpp->reservation_key, 8) && rq_servact == MPATH_PROUT_REG_SA))) { - memcpy(&mpp->reservation_key, paramp->sa_key, 8); - if (update_prkey_flags(alias, get_be64(mpp->reservation_key), - paramp->sa_flags)) { -@@ -362,12 +363,16 @@ int mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, - uireservation >>= 8; - } - -- if (memcmp(paramp->key, uitmp, 8) && -- memcmp(paramp->sa_key, uitmp, 8)) { -+ /* pass -I option */ -+ if (rq_servact != MPATH_PROUT_REG_IGN_SA) { -+ if (memcmp(paramp->key, uitmp, 8) && -+ memcmp(paramp->sa_key, uitmp, 8)) { -+ condlog(0, "%s: configured reservation key doesn't match: 0x%" PRIx64, alias, get_be64(mpp->reservation_key)); -+ ret = MPATH_PR_SYNTAX_ERROR; -+ goto out1; -+ } -+ - -- condlog(0, "%s: configured reservation key doesn't match: 0x%" PRIx64, alias, get_be64(mpp->reservation_key)); -- ret = MPATH_PR_SYNTAX_ERROR; -- goto out1; - } - - switch(rq_servact) --- -1.8.3.1 - diff --git a/0020-multipath-tools-tests-directio-fix-Wmaybe-uninitaliz.patch b/0020-multipath-tools-tests-directio-fix-Wmaybe-uninitaliz.patch new file mode 100644 index 0000000000000000000000000000000000000000..3bf6f75ef9717c0a310d3f9e20db35c8a8d51529 --- /dev/null +++ b/0020-multipath-tools-tests-directio-fix-Wmaybe-uninitaliz.patch @@ -0,0 +1,29 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 12 May 2020 00:11:39 +0200 +Subject: [PATCH] multipath-tools tests/directio: fix -Wmaybe-uninitalized + warning + +Initialize aio_grp to satisfy gcc. + +Signed-off-by: Benjamin Marzinski +--- + tests/directio.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tests/directio.c b/tests/directio.c +index 3cd7a520..66aaf0eb 100644 +--- a/tests/directio.c ++++ b/tests/directio.c +@@ -316,7 +316,7 @@ static void test_init_free(void **state) + { + int i, count = 0; + struct checker c[4096] = {0}; +- struct aio_group *aio_grp; ++ struct aio_group *aio_grp = NULL; + + assert_true(list_empty(&aio_grp_list)); + will_return(__wrap_io_setup, 0); +-- +2.17.2 + diff --git a/0021-bugfix-flush-and-sync-before-reboot.patch b/0021-bugfix-flush-and-sync-before-reboot.patch deleted file mode 100644 index dd411848cfe4e7fe87e32da3645fae1da5bba46a..0000000000000000000000000000000000000000 --- a/0021-bugfix-flush-and-sync-before-reboot.patch +++ /dev/null @@ -1,17 +0,0 @@ -diff --git a/libmultipath/util.c b/libmultipath/util.c -index 8d8fcc8..3c284b7 100644 ---- a/libmultipath/util.c -+++ b/libmultipath/util.c -@@ -463,5 +463,12 @@ int safe_write(int fd, const void *buf, size_t count) - count -= r; - buf = (const char *)buf + r; - } -+ -+ /* sync->disk */ -+ if (fsync(fd) < 0) { -+ condlog(0, "failed to fsync fd :%d", fd); -+ return -errno; -+ } -+ - return 0; - } diff --git a/0021-libmultipath-move-libsg-into-libmultipath.patch b/0021-libmultipath-move-libsg-into-libmultipath.patch new file mode 100644 index 0000000000000000000000000000000000000000..e7cf278ee0a4b7b692b1e90ff1c48252c80b6d86 --- /dev/null +++ b/0021-libmultipath-move-libsg-into-libmultipath.patch @@ -0,0 +1,83 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 12 May 2020 16:46:15 +0200 +Subject: [PATCH] libmultipath: move libsg into libmultipath + +sg_read() is called from readsector0 and emc_clariion. Move it +to libmultipath/, where all common code resides. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/Makefile | 3 ++- + libmultipath/checkers/Makefile | 6 +++--- + libmultipath/{checkers => }/libsg.c | 0 + libmultipath/{checkers => }/libsg.h | 0 + libmultipath/prioritizers/Makefile | 2 +- + 5 files changed, 6 insertions(+), 5 deletions(-) + rename libmultipath/{checkers => }/libsg.c (100%) + rename libmultipath/{checkers => }/libsg.h (100%) + +diff --git a/libmultipath/Makefile b/libmultipath/Makefile +index ad690a49..f19b7ad2 100644 +--- a/libmultipath/Makefile ++++ b/libmultipath/Makefile +@@ -47,7 +47,8 @@ OBJS = memory.o parser.o vector.o devmapper.o callout.o \ + switchgroup.o uxsock.o print.o alias.o log_pthread.o \ + log.o configure.o structs_vec.o sysfs.o prio.o checkers.o \ + lock.o file.o wwids.o prioritizers/alua_rtpg.o prkey.o \ +- io_err_stat.o dm-generic.o generic.o foreign.o nvme-lib.o ++ io_err_stat.o dm-generic.o generic.o foreign.o nvme-lib.o \ ++ libsg.o + + all: $(LIBS) + +diff --git a/libmultipath/checkers/Makefile b/libmultipath/checkers/Makefile +index 02caea64..01c04510 100644 +--- a/libmultipath/checkers/Makefile ++++ b/libmultipath/checkers/Makefile +@@ -17,10 +17,10 @@ LIBS= \ + + all: $(LIBS) + +-libcheckdirectio.so: libsg.o directio.o ++libcheckdirectio.so: directio.o + $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ -laio + +-libcheck%.so: libsg.o %.o ++libcheck%.so: %.o + $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ + + install: +@@ -32,7 +32,7 @@ uninstall: + clean: dep_clean + $(RM) core *.a *.o *.gz *.so + +-OBJS := $(LIBS:libcheck%.so=%.o) libsg.o directio.o ++OBJS := $(LIBS:libcheck%.so=%.o) + .SECONDARY: $(OBJS) + + include $(wildcard $(OBJS:.o=.d)) +diff --git a/libmultipath/checkers/libsg.c b/libmultipath/libsg.c +similarity index 100% +rename from libmultipath/checkers/libsg.c +rename to libmultipath/libsg.c +diff --git a/libmultipath/checkers/libsg.h b/libmultipath/libsg.h +similarity index 100% +rename from libmultipath/checkers/libsg.h +rename to libmultipath/libsg.h +diff --git a/libmultipath/prioritizers/Makefile b/libmultipath/prioritizers/Makefile +index 9d0fe03c..fc6e0e0c 100644 +--- a/libmultipath/prioritizers/Makefile ++++ b/libmultipath/prioritizers/Makefile +@@ -28,7 +28,7 @@ endif + + all: $(LIBS) + +-libpriopath_latency.so: path_latency.o ../checkers/libsg.o ++libpriopath_latency.so: path_latency.o + $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ -lm + + libprio%.so: %.o +-- +2.17.2 + diff --git a/0022-bugfix-RH-remove-local-disk-from-pathvec.patch b/0022-bugfix-RH-remove-local-disk-from-pathvec.patch deleted file mode 100644 index 3aa00c45c0ba489aebca16c042ca45a89e884bc8..0000000000000000000000000000000000000000 --- a/0022-bugfix-RH-remove-local-disk-from-pathvec.patch +++ /dev/null @@ -1,206 +0,0 @@ -From f637f15dacc660f663a6cf36e3fe8f7a0cc9f9e4 Mon Sep 17 00:00:00 2001 -From: chenminhua -Date: Mon, 2 Apr 2018 04:01:04 -0400 -Subject: [PATCH] 1hostos-patch-upgrade:0330 hotpatch modify - -[Changelog]:add upgrade path -[Author]:chenminhua - ---- - libmultipath/discovery.c | 129 +++++++++++++++++++++++++++++++++++++-- - libmultipath/discovery.h | 1 + - multipathd/main.c | 4 ++ - 3 files changed, 128 insertions(+), 6 deletions(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 0b1855d..95eb3a0 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -34,6 +34,103 @@ - #include "prioritizers/alua_rtpg.h" - #include "foreign.h" - -+const char *conf_file = "/etc/multipath_private.conf"; -+static int conf_file_parsed = 0; -+static int should_remove_local_disk = 0; -+ -+static void parse_config() -+{ -+ FILE *fp = NULL; -+ char buffer[256] = {0}; -+ char *str = NULL; -+ char *p = NULL; -+ -+ fp = fopen(conf_file, "r"); -+ if (fp) { -+ while (fgets(buffer, sizeof(buffer), fp)) { -+ str = buffer; -+ /* skip the space */ -+ while (isspace(*str)) -+ str++; -+ /* skip the comment line */ -+ if (strncmp(str, "#", 1) == 0) -+ continue; -+ /* skip line feed */ -+ if((p = strchr(str, '\n')) != NULL) -+ *p = '\0'; -+ if (strstr(str, "remove_local_disk") != NULL && (p = strstr(str, "=")) != NULL){ -+ str = p + 1; -+ /* skip the space */ -+ while (isspace(*str)) -+ str++; -+ if (strcmp(str, "1") == 0){ -+ should_remove_local_disk = 1; -+ } -+ break; -+ } -+ } -+ fclose(fp); -+ fp = NULL; -+ } -+ conf_file_parsed = 1; -+} -+ -+static int get_should_remove_local_disk() -+{ -+ if (!conf_file_parsed) -+ parse_config(); -+ return should_remove_local_disk; -+} -+ -+/* Filter the local disks and remove them from pathvec */ -+static int -+transport (int h) -+{ -+ char buff[PATH_SIZE]; -+ int len, off; -+ struct stat a_stat; -+ -+ /* FC host */ -+ strcpy(buff, "/sys"); -+ strcat(buff, "/class/fc_host/"); -+ len = strlen(buff); -+ snprintf(buff + len, PATH_SIZE - len, "host%d", h); -+ if ((stat(buff, &a_stat) >= 0) && S_ISDIR(a_stat.st_mode)) { -+ return 0; -+ } -+ memset(buff, 0, PATH_SIZE); -+ -+ /* iSCSI device */ -+ strcpy(buff, "/sys"); -+ strcat(buff, "/class/iscsi_host/"); -+ off = strlen(buff); -+ snprintf(buff + off, PATH_SIZE - off, "host%d", h); -+ if ((stat(buff, &a_stat) >= 0) && S_ISDIR(a_stat.st_mode)) { -+ return 0; -+ } -+ return 1; -+} -+ -+int -+remove_local_path (vector pathvec, struct path *pp) -+{ -+ int i = -1; -+ -+ if(!get_should_remove_local_disk()){ -+ return 1; -+ } -+ -+ if (transport(pp->sg_id.host_no) == 0) { -+ return 1; -+ } -+ -+ if ((i = find_slot(pathvec, (void *)pp)) != -1) { -+ vector_del_slot(pathvec, i); -+ } -+ free_path(pp); -+ return 0; -+} -+ - int - alloc_path_with_pathinfo (struct config *conf, struct udev_device *udevice, - const char *wwid, int flag, struct path **pp_ptr) -@@ -118,6 +215,7 @@ path_discover (vector pathvec, struct config * conf, - { - struct path * pp; - const char * devname; -+ int err = 1; - - devname = udev_device_get_sysname(udevice); - if (!devname) -@@ -131,11 +229,22 @@ path_discover (vector pathvec, struct config * conf, - snprintf(devt, BLK_DEV_SIZE, "%d:%d", - major(devnum), minor(devnum)); - pp = find_path_by_devt(pathvec, devt); -- if (!pp) -- return store_pathinfo(pathvec, conf, -- udevice, flag, NULL); -+ if (!pp) { -+ err = store_pathinfo(pathvec, conf, -+ udevice, flag, &pp); -+ if (err == 1) -+ return 1; -+ if (err == 0) -+ remove_local_path(pathvec, pp); -+ return 0; -+ } - } -- return pathinfo(pp, conf, flag); -+ err = pathinfo(pp, conf, flag); -+ if (err) -+ return err; -+ -+ remove_local_path(pathvec, pp); -+ return err; - } - - int -@@ -1882,8 +1991,16 @@ int pathinfo(struct path *pp, struct config *conf, int mask) - /* - * fetch info available in sysfs - */ -- if (mask & DI_SYSFS && sysfs_pathinfo(pp, conf->hwtable)) -- return PATHINFO_FAILED; -+ if (mask & DI_SYSFS) { -+ if (sysfs_pathinfo(pp, conf->hwtable)) -+ return 1; -+ -+ /* free local device */ -+ if (transport(pp->sg_id.host_no)) { -+ condlog(3, "%s is a local device", pp->dev); -+ return 0; -+ } -+ } - - if (mask & DI_BLACKLIST && mask & DI_SYSFS) { - if (filter_device(conf->blist_device, conf->elist_device, -diff --git a/libmultipath/discovery.h b/libmultipath/discovery.h -index 9aacf75..c4b1d25 100644 ---- a/libmultipath/discovery.h -+++ b/libmultipath/discovery.h -@@ -53,6 +53,7 @@ ssize_t sysfs_get_vpd (struct udev_device * udev, int pg, unsigned char * buff, - int sysfs_get_asymmetric_access_state(struct path *pp, - char *buff, int buflen); - int get_uid(struct path * pp, int path_state, struct udev_device *udev); -+int remove_local_path(vector pathvec, struct path *pp); - - /* - * discovery bitmask -diff --git a/multipathd/main.c b/multipathd/main.c -index 7a80688..c2757c4 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -917,6 +917,10 @@ ev_add_path (struct path * pp, struct vectors * vecs, int need_do_map) - int start_waiter = 0; - int ret; - -+ /* if pp is local path,remove it and return 0. */ -+ if (!remove_local_path(vecs->pathvec, pp)) -+ return 0; -+ - /* - * need path UID to go any further - */ --- -2.19.1 - diff --git a/0022-multipath-tools-Makefile-add-install-dependency.patch b/0022-multipath-tools-Makefile-add-install-dependency.patch new file mode 100644 index 0000000000000000000000000000000000000000..95c80fdd0cff9062a5ba5533d0ea35fe3f4333ae --- /dev/null +++ b/0022-multipath-tools-Makefile-add-install-dependency.patch @@ -0,0 +1,32 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 12 May 2020 22:13:51 +0200 +Subject: [PATCH] multipath-tools Makefile: add install dependency + +$(libdir) must exist before running "make install" on prioritizer, checker, +and foreign libraries. + +Cc: Christian Hesse +Signed-off-by: Benjamin Marzinski +--- + Makefile | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/Makefile b/Makefile +index fec3b73b..8bcaba66 100644 +--- a/Makefile ++++ b/Makefile +@@ -32,6 +32,10 @@ libmultipath libdmmp: libmpathcmd + libmpathpersist multipath multipathd: libmultipath + mpathpersist multipathd: libmpathpersist + ++libmultipath/checkers.install \ ++ libmultipath/prioritizers.install \ ++ libmultipath/foreign.install: libmultipath.install ++ + $(BUILDDIRS.clean): + $(MAKE) -C ${@:.clean=} clean + +-- +2.17.2 + diff --git a/0023-bugfix-lun-expansion-failure-when-there-is-offline-path.patch b/0023-bugfix-lun-expansion-failure-when-there-is-offline-path.patch deleted file mode 100644 index 8586f3d916af212f0ab977e65e44a2bacd442830..0000000000000000000000000000000000000000 --- a/0023-bugfix-lun-expansion-failure-when-there-is-offline-path.patch +++ /dev/null @@ -1,54 +0,0 @@ -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 1b1cc55..f66bd5b 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -1054,11 +1054,18 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, - orphan_path(pp1, "only one path"); - continue; - } -- /* if path is handled before */ -- if (pp1->handled) { -- condlog(3, "%s: skip handled path.", pp1->dev_t); -- continue; -- } -+ -+ /* if path is offline */ -+ if (pp1->state == PATH_DOWN) { -+ orphan_path(pp1, "skip offline path"); -+ continue; -+ } -+ -+ /* if path is handled before */ -+ if (pp1->handled) { -+ condlog(3, "%s: skip handled path.", pp1->dev_t); -+ continue; -+ } - - - /* -@@ -1086,6 +1093,9 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, - if (strcmp(pp1->wwid, pp2->wwid)) - continue; - -+ if (!pp2->size || pp2->state == PATH_DOWN) -+ continue; -+ - if (!mpp->size && pp2->size) - mpp->size = pp2->size; - -diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c -index d85eb5f..6c42824 100644 ---- a/libmultipath/structs_vec.c -+++ b/libmultipath/structs_vec.c -@@ -394,8 +394,9 @@ int verify_paths(struct multipath *mpp, struct vectors *vecs) - /* - * see if path is in sysfs - */ -- if (sysfs_attr_get_value(pp->udev, "dev", -- pp->dev_t, BLK_DEV_SIZE) < 0) { -+ if ((sysfs_attr_get_value(pp->udev, "dev", -+ pp->dev_t, BLK_DEV_SIZE) < 0) || -+ (pp->state == PATH_DOWN && pp->size != mpp->size)) { - if (pp->state != PATH_DOWN) { - condlog(1, "%s: removing valid path %s in state %d", - mpp->alias, pp->dev, pp->state); diff --git a/0023-libmultipath-make-libmp_dm_init-optional.patch b/0023-libmultipath-make-libmp_dm_init-optional.patch new file mode 100644 index 0000000000000000000000000000000000000000..588fd875618c8a8c2f5891e3ad06ea35ad8131a7 --- /dev/null +++ b/0023-libmultipath-make-libmp_dm_init-optional.patch @@ -0,0 +1,89 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 19 May 2020 12:08:40 -0500 +Subject: [PATCH] libmultipath: make libmp_dm_init optional + +Move dm_initialized out of libmp_dm_task_create(), and add +a function skip_libmp_dm_init() so that users of libmultipath can skip +initializing device-mapper. This is needed for other programs that +use libmultipath (or a library that depends on it) but want to control +how device-mapper is set up. + +Also make dm_prereq a global function. + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/devmapper.c | 17 +++++++++++++---- + libmultipath/devmapper.h | 3 ++- + 2 files changed, 15 insertions(+), 5 deletions(-) + +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index 13a1cf53..7ed494a1 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -33,6 +33,8 @@ + #define MAX_WAIT 5 + #define LOOPS_PER_SEC 5 + ++static pthread_once_t dm_initialized = PTHREAD_ONCE_INIT; ++ + static int dm_conf_verbosity; + + #ifdef LIBDM_API_DEFERRED +@@ -229,7 +231,7 @@ dm_tgt_prereq (unsigned int *ver) + return 1; + } + +-static int dm_prereq(unsigned int *v) ++int dm_prereq(unsigned int *v) + { + if (dm_lib_prereq()) + return 1; +@@ -243,7 +245,7 @@ void libmp_udev_set_sync_support(int on) + libmp_dm_udev_sync = !!on; + } + +-void libmp_dm_init(void) ++static void libmp_dm_init(void) + { + struct config *conf; + int verbosity; +@@ -262,11 +264,18 @@ void libmp_dm_init(void) + dm_udev_set_sync_support(libmp_dm_udev_sync); + } + ++static void _do_skip_libmp_dm_init(void) ++{ ++} ++ ++void skip_libmp_dm_init(void) ++{ ++ pthread_once(&dm_initialized, _do_skip_libmp_dm_init); ++} ++ + struct dm_task* + libmp_dm_task_create(int task) + { +- static pthread_once_t dm_initialized = PTHREAD_ONCE_INIT; +- + pthread_once(&dm_initialized, libmp_dm_init); + return dm_task_create(task); + } +diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h +index 7557a86b..17fc9faf 100644 +--- a/libmultipath/devmapper.h ++++ b/libmultipath/devmapper.h +@@ -28,7 +28,8 @@ + #define UUID_PREFIX_LEN (sizeof(UUID_PREFIX) - 1) + + void dm_init(int verbosity); +-void libmp_dm_init(void); ++int dm_prereq(unsigned int *v); ++void skip_libmp_dm_init(void); + void libmp_udev_set_sync_support(int on); + struct dm_task *libmp_dm_task_create(int task); + int dm_drv_version (unsigned int * version); +-- +2.17.2 + diff --git a/0024-bugfix-some-memory-leaks-issues-in-libmpathpersist.patch b/0024-bugfix-some-memory-leaks-issues-in-libmpathpersist.patch deleted file mode 100644 index 1b61be236cd49f705a4be538d326d101730fa477..0000000000000000000000000000000000000000 --- a/0024-bugfix-some-memory-leaks-issues-in-libmpathpersist.patch +++ /dev/null @@ -1,162 +0,0 @@ -diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c -index 27c848c..1e6a172 100644 ---- a/libmpathpersist/mpath_persist.c -+++ b/libmpathpersist/mpath_persist.c -@@ -199,6 +199,11 @@ int mpath_persistent_reserve_in (int fd, int rq_servact, - if (map_present && !dm_is_mpath(alias)){ - condlog( 0, "%s: not a multipath device.", alias); - ret = MPATH_PR_DMMP_ERROR; -+ if (curmp) -+ vector_free(curmp); -+ if (pathvec) -+ vector_free(pathvec); -+ - goto out; - } - -@@ -297,6 +302,10 @@ int mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, - if (map_present && !dm_is_mpath(alias)){ - condlog(3, "%s: not a multipath device.", alias); - ret = MPATH_PR_DMMP_ERROR; -+ if (curmp) -+ vector_free(curmp); -+ if (pathvec) -+ vector_free(pathvec); - goto out; - } - -@@ -321,7 +330,7 @@ int mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, - goto out1; - } - -- /* get info of all paths from the dm device */ -+ /* get info of all paths from the dm device */ - if (get_mpvec(curmp, pathvec, alias)){ - condlog(0, "%s: failed to get device info.", alias); - ret = MPATH_PR_DMMP_ERROR; -@@ -882,7 +891,7 @@ out: - return (status); - } - --void * mpath_alloc_prin_response(int prin_sa) -+void *mpath_alloc_prin_response(int prin_sa) - { - void * ptr = NULL; - int size=0; -@@ -905,6 +914,10 @@ void * mpath_alloc_prin_response(int prin_sa) - if (size > 0) - { - ptr = calloc(size, 1); -+ if (!ptr) { -+ condlog (0, "failed to allocate MPATH_PRIN_RFSTAT_SA buffer"); -+ return NULL; -+ } - } - return ptr; - } -diff --git a/libmpathpersist/mpath_pr_ioctl.c b/libmpathpersist/mpath_pr_ioctl.c -index 6dd7403..b317b4e 100644 ---- a/libmpathpersist/mpath_pr_ioctl.c -+++ b/libmpathpersist/mpath_pr_ioctl.c -@@ -25,8 +25,8 @@ - int prin_do_scsi_ioctl(char * dev, int rq_servact, struct prin_resp *resp, int noisy); - void mpath_format_readkeys(struct prin_resp *pr_buff, int len , int noisy); - void mpath_format_readfullstatus(struct prin_resp *pr_buff, int len, int noisy); --int mpath_translate_response (char * dev, struct sg_io_hdr io_hdr, -- SenseData_t *Sensedata, int noisy); -+int mpath_translate_response (const char *dev, struct sg_io_hdr *io_hdr, -+ const SenseData_t *Sensedata, int noisy); - void dumpHex(const char* str, int len, int no_ascii); - int prout_do_scsi_ioctl( char * dev, int rq_servact, int rq_scope, - unsigned int rq_type, struct prout_param_descriptor *paramp, int noisy); -@@ -115,7 +115,7 @@ retry : - - condlog(4, "%s: Duration=%u (ms)", dev, io_hdr.duration); - -- status = mpath_translate_response(dev, io_hdr, &Sensedata, noisy); -+ status = mpath_translate_response(dev, &io_hdr, &Sensedata, noisy); - condlog(3, "%s: status = %d", dev, status); - - if (status == MPATH_PR_SENSE_UNIT_ATTENTION && (retry > 0)) -@@ -354,7 +354,7 @@ retry : - condlog(3, "%s: duration = %u (ms)", dev, io_hdr.duration); - condlog(4, "%s: persistent reservation in: requested %d bytes but got %d bytes)", dev, mx_resp_len, got); - -- status = mpath_translate_response(dev, io_hdr, &Sensedata, noisy); -+ status = mpath_translate_response(dev, &io_hdr, &Sensedata, noisy); - - if (status == MPATH_PR_SENSE_UNIT_ATTENTION && (retry > 0)) - { -@@ -399,18 +399,18 @@ out: - return status; - } - --int mpath_translate_response (char * dev, struct sg_io_hdr io_hdr, -- SenseData_t *Sensedata, int noisy) -+int mpath_translate_response (const char *dev, struct sg_io_hdr *io_hdr, -+ const SenseData_t *Sensedata, int noisy) - { - condlog(3, "%s: status driver:%02x host:%02x scsi:%02x", dev, -- io_hdr.driver_status, io_hdr.host_status ,io_hdr.status); -- io_hdr.status &= 0x7e; -- if ((0 == io_hdr.status) && -- (0 == io_hdr.host_status) && -- (0 == io_hdr.driver_status)) -+ io_hdr->driver_status, io_hdr->host_status ,io_hdr->status); -+ io_hdr->status &= 0x7e; -+ if ((0 == io_hdr->status) && -+ (0 == io_hdr->host_status) && -+ (0 == io_hdr->driver_status)) - return MPATH_PR_SUCCESS; - -- switch(io_hdr.status) { -+ switch(io_hdr->status) { - case SAM_STAT_GOOD: - break; - case SAM_STAT_CHECK_CONDITION: -@@ -450,13 +450,13 @@ int mpath_translate_response (char * dev, struct sg_io_hdr io_hdr, - return MPATH_PR_OTHER; - } - -- switch(io_hdr.host_status) { -+ switch(io_hdr->host_status) { - case DID_OK : - break; - default : - return MPATH_PR_OTHER; - } -- switch(io_hdr.driver_status) -+ switch(io_hdr->driver_status) - { - case DRIVER_OK: - break; -diff --git a/mpathpersist/main.c b/mpathpersist/main.c -index 0e4d3f2..4db07b2 100644 ---- a/mpathpersist/main.c -+++ b/mpathpersist/main.c -@@ -61,7 +61,7 @@ struct udev *udev; - - int main (int argc, char * argv[]) - { -- int fd, c, res; -+ int c, res, fd = -1; - const char *device_name = NULL; - int num_prin_sa = 0; - int num_prout_sa = 0; -@@ -488,6 +488,7 @@ int main (int argc, char * argv[]) - } - - res = close (fd); -+ fd = -1; - if (res < 0) - { - mpath_lib_exit(conf); -@@ -496,6 +497,8 @@ int main (int argc, char * argv[]) - } - - out : -+ if (fd >= 0) -+ close(fd); - mpath_lib_exit(conf); - udev_unref(udev); - return (ret >= 0) ? ret : MPATH_PR_OTHER; diff --git a/0024-libmultipath-make-sysfs_is_multipathed-able-to-retur.patch b/0024-libmultipath-make-sysfs_is_multipathed-able-to-retur.patch new file mode 100644 index 0000000000000000000000000000000000000000..47c7a809b3fcf347a956de118f60be1a8a93b86e --- /dev/null +++ b/0024-libmultipath-make-sysfs_is_multipathed-able-to-retur.patch @@ -0,0 +1,108 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 19 May 2020 12:08:41 -0500 +Subject: [PATCH] libmultipath: make sysfs_is_multipathed able to return wwid + +sysfs_is_multipathed reads the wwid of the dm device holding a path to +check if its a multipath device. Add code to optinally set pp->wwid to +that wwid. This will be used by a future patch. + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/sysfs.c | 24 +++++++++++++++++++----- + libmultipath/sysfs.h | 2 +- + multipath/main.c | 7 ++++--- + 3 files changed, 24 insertions(+), 9 deletions(-) + +diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c +index 62ec2ed7..12a82d95 100644 +--- a/libmultipath/sysfs.c ++++ b/libmultipath/sysfs.c +@@ -295,7 +295,7 @@ static int select_dm_devs(const struct dirent *di) + return fnmatch("dm-*", di->d_name, FNM_FILE_NAME) == 0; + } + +-bool sysfs_is_multipathed(const struct path *pp) ++bool sysfs_is_multipathed(struct path *pp, bool set_wwid) + { + char pathbuf[PATH_MAX]; + struct scandir_result sr; +@@ -325,7 +325,7 @@ bool sysfs_is_multipathed(const struct path *pp) + for (i = 0; i < r && !found; i++) { + long fd; + int nr; +- char uuid[6]; ++ char uuid[WWID_SIZE + UUID_PREFIX_LEN]; + + if (safe_snprintf(pathbuf + n, sizeof(pathbuf) - n, + "/%s/dm/uuid", di[i]->d_name)) +@@ -339,12 +339,26 @@ bool sysfs_is_multipathed(const struct path *pp) + + pthread_cleanup_push(close_fd, (void *)fd); + nr = read(fd, uuid, sizeof(uuid)); +- if (nr == sizeof(uuid) && !memcmp(uuid, "mpath-", sizeof(uuid))) ++ if (nr > (int)UUID_PREFIX_LEN && ++ !memcmp(uuid, UUID_PREFIX, UUID_PREFIX_LEN)) + found = true; + else if (nr < 0) { +- condlog(1, "%s: error reading from %s: %s", +- __func__, pathbuf, strerror(errno)); ++ condlog(1, "%s: error reading from %s: %m", ++ __func__, pathbuf); + } ++ if (found && set_wwid) { ++ nr -= UUID_PREFIX_LEN; ++ memcpy(pp->wwid, uuid + UUID_PREFIX_LEN, nr); ++ if (nr == WWID_SIZE) { ++ condlog(4, "%s: overflow while reading from %s", ++ __func__, pathbuf); ++ pp->wwid[0] = '\0'; ++ } else { ++ pp->wwid[nr] = '\0'; ++ strchop(pp->wwid); ++ } ++ } ++ + pthread_cleanup_pop(1); + } + pthread_cleanup_pop(1); +diff --git a/libmultipath/sysfs.h b/libmultipath/sysfs.h +index 9ae30b39..72b39ab2 100644 +--- a/libmultipath/sysfs.h ++++ b/libmultipath/sysfs.h +@@ -14,5 +14,5 @@ ssize_t sysfs_bin_attr_get_value(struct udev_device *dev, const char *attr_name, + unsigned char * value, size_t value_len); + int sysfs_get_size (struct path *pp, unsigned long long * size); + int sysfs_check_holders(char * check_devt, char * new_devt); +-bool sysfs_is_multipathed(const struct path *pp); ++bool sysfs_is_multipathed(struct path *pp, bool set_wwid); + #endif +diff --git a/multipath/main.c b/multipath/main.c +index cf9d2a28..545ead87 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -638,7 +638,8 @@ configure (struct config *conf, enum mpath_cmds cmd, + * Shortcut for find_multipaths smart: + * Quick check if path is already multipathed. + */ +- if (sysfs_is_multipathed(VECTOR_SLOT(pathvec, 0))) { ++ if (sysfs_is_multipathed(VECTOR_SLOT(pathvec, 0), ++ false)) { + r = RTVL_YES; + goto print_valid; + } +@@ -747,8 +748,8 @@ configure (struct config *conf, enum mpath_cmds cmd, + /* + * Check if we raced with multipathd + */ +- r = sysfs_is_multipathed(VECTOR_SLOT(pathvec, 0)) ? +- RTVL_YES : RTVL_NO; ++ r = sysfs_is_multipathed(VECTOR_SLOT(pathvec, 0), ++ false) ? RTVL_YES : RTVL_NO; + } + goto print_valid; + } +-- +2.17.2 + diff --git a/0025-libmultipath-fix-set_int-error-path.patch b/0025-libmultipath-fix-set_int-error-path.patch deleted file mode 100644 index 0cdcfbd812b5588613450aaa6b4301b34cdfffa9..0000000000000000000000000000000000000000 --- a/0025-libmultipath-fix-set_int-error-path.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 8f9ac30dcb144d4ce79f88e8a01fba0968da3a07 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 9 Oct 2018 18:03:03 -0500 -Subject: [PATCH] libmultipath: fix set_int error path - -set_int() wasn't checking if the line actually had a value before -converting it to an integer. Found by coverity. Also, it should -be using set_value(). - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/dict.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index 32524d5f..bf4701ee 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -33,7 +33,10 @@ set_int(vector strvec, void *ptr) - int *int_ptr = (int *)ptr; - char * buff; - -- buff = VECTOR_SLOT(strvec, 1); -+ buff = set_value(strvec); -+ if (!buff) -+ return 1; -+ - *int_ptr = atoi(buff); - - return 0; --- -2.11.0 - diff --git a/0025-multipath-centralize-validation-code.patch b/0025-multipath-centralize-validation-code.patch new file mode 100644 index 0000000000000000000000000000000000000000..c8f862c70d91eea41a7ca2eeb42f0f79a7e4c905 --- /dev/null +++ b/0025-multipath-centralize-validation-code.patch @@ -0,0 +1,777 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 19 May 2020 12:08:42 -0500 +Subject: [PATCH] multipath: centralize validation code + +This code pulls the multipath path validation code out of configure(), +and puts it into its own function, check_path_valid(). This function +calls a new libmultipath function, is_path_valid() to check just path +requested. This seperation exists so that is_path_valid() can be reused +by future code. This code will give almost the same answer as the +existing code, with the exception that now, if a device is currently +multipathed, it will always be a valid multipath path. + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/Makefile | 2 +- + libmultipath/devmapper.c | 45 ++++++ + libmultipath/devmapper.h | 1 + + libmultipath/structs.h | 24 +--- + libmultipath/valid.c | 118 ++++++++++++++++ + libmultipath/valid.h | 42 ++++++ + libmultipath/wwids.c | 10 +- + multipath/main.c | 296 +++++++++++++++++---------------------- + 8 files changed, 343 insertions(+), 195 deletions(-) + create mode 100644 libmultipath/valid.c + create mode 100644 libmultipath/valid.h + +diff --git a/libmultipath/Makefile b/libmultipath/Makefile +index f19b7ad2..e5dac5ea 100644 +--- a/libmultipath/Makefile ++++ b/libmultipath/Makefile +@@ -48,7 +48,7 @@ OBJS = memory.o parser.o vector.o devmapper.o callout.o \ + log.o configure.o structs_vec.o sysfs.o prio.o checkers.o \ + lock.o file.o wwids.o prioritizers/alua_rtpg.o prkey.o \ + io_err_stat.o dm-generic.o generic.o foreign.o nvme-lib.o \ +- libsg.o ++ libsg.o valid.o + + all: $(LIBS) + +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index 7ed494a1..27d52398 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -770,6 +770,51 @@ out: + return r; + } + ++/* ++ * Return ++ * 1 : map with uuid exists ++ * 0 : map with uuid doesn't exist ++ * -1 : error ++ */ ++int ++dm_map_present_by_uuid(const char *uuid) ++{ ++ struct dm_task *dmt; ++ struct dm_info info; ++ char prefixed_uuid[WWID_SIZE + UUID_PREFIX_LEN]; ++ int r = -1; ++ ++ if (!uuid || uuid[0] == '\0') ++ return 0; ++ ++ if (safe_sprintf(prefixed_uuid, UUID_PREFIX "%s", uuid)) ++ goto out; ++ ++ if (!(dmt = dm_task_create(DM_DEVICE_INFO))) ++ goto out; ++ ++ dm_task_no_open_count(dmt); ++ ++ if (!dm_task_set_uuid(dmt, prefixed_uuid)) ++ goto out_task; ++ ++ if (!dm_task_run(dmt)) ++ goto out_task; ++ ++ if (!dm_task_get_info(dmt, &info)) ++ goto out_task; ++ ++ r = !!info.exists; ++ ++out_task: ++ dm_task_destroy(dmt); ++out: ++ if (r < 0) ++ condlog(3, "%s: dm command failed in %s: %s", uuid, ++ __FUNCTION__, strerror(errno)); ++ return r; ++} ++ + static int + dm_dev_t (const char * mapname, char * dev_t, int len) + { +diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h +index 17fc9faf..5ed7edc5 100644 +--- a/libmultipath/devmapper.h ++++ b/libmultipath/devmapper.h +@@ -39,6 +39,7 @@ int dm_simplecmd_noflush (int, const char *, uint16_t); + int dm_addmap_create (struct multipath *mpp, char *params); + int dm_addmap_reload (struct multipath *mpp, char *params, int flush); + int dm_map_present (const char *); ++int dm_map_present_by_uuid(const char *uuid); + int dm_get_map(const char *, unsigned long long *, char *); + int dm_get_status(const char *, char *); + int dm_type(const char *, char *); +diff --git a/libmultipath/structs.h b/libmultipath/structs.h +index 9bd39eb1..d69bc2e9 100644 +--- a/libmultipath/structs.h ++++ b/libmultipath/structs.h +@@ -101,29 +101,13 @@ enum yes_no_undef_states { + YNU_YES, + }; + +-#define _FIND_MULTIPATHS_F (1 << 1) +-#define _FIND_MULTIPATHS_I (1 << 2) +-#define _FIND_MULTIPATHS_N (1 << 3) +-/* +- * _FIND_MULTIPATHS_F must have the same value as YNU_YES. +- * Generate a compile time error if that isn't the case. +- */ +-extern char ___error1___[-(_FIND_MULTIPATHS_F != YNU_YES)]; +- +-#define find_multipaths_on(conf) \ +- (!!((conf)->find_multipaths & _FIND_MULTIPATHS_F)) +-#define ignore_wwids_on(conf) \ +- (!!((conf)->find_multipaths & _FIND_MULTIPATHS_I)) +-#define ignore_new_devs_on(conf) \ +- (!!((conf)->find_multipaths & _FIND_MULTIPATHS_N)) +- + enum find_multipaths_states { + FIND_MULTIPATHS_UNDEF = YNU_UNDEF, + FIND_MULTIPATHS_OFF = YNU_NO, +- FIND_MULTIPATHS_ON = _FIND_MULTIPATHS_F, +- FIND_MULTIPATHS_GREEDY = _FIND_MULTIPATHS_I, +- FIND_MULTIPATHS_SMART = _FIND_MULTIPATHS_F|_FIND_MULTIPATHS_I, +- FIND_MULTIPATHS_STRICT = _FIND_MULTIPATHS_F|_FIND_MULTIPATHS_N, ++ FIND_MULTIPATHS_ON = YNU_YES, ++ FIND_MULTIPATHS_GREEDY, ++ FIND_MULTIPATHS_SMART, ++ FIND_MULTIPATHS_STRICT, + __FIND_MULTIPATHS_LAST, + }; + +diff --git a/libmultipath/valid.c b/libmultipath/valid.c +new file mode 100644 +index 00000000..456b1f6e +--- /dev/null ++++ b/libmultipath/valid.c +@@ -0,0 +1,118 @@ ++/* ++ Copyright (c) 2020 Benjamin Marzinski, IBM ++ ++ This program is free software; you can redistribute it and/or ++ modify it under the terms of the GNU General Public License ++ as published by the Free Software Foundation; either version 2 ++ of the License, or (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . ++ */ ++#include ++#include ++#include ++ ++#include "vector.h" ++#include "config.h" ++#include "debug.h" ++#include "util.h" ++#include "devmapper.h" ++#include "discovery.h" ++#include "wwids.h" ++#include "sysfs.h" ++#include "blacklist.h" ++#include "mpath_cmd.h" ++#include "valid.h" ++ ++int ++is_path_valid(const char *name, struct config *conf, struct path *pp, ++ bool check_multipathd) ++{ ++ int r; ++ int fd; ++ ++ if (!pp || !name || !conf) ++ return PATH_IS_ERROR; ++ ++ if (conf->find_multipaths <= FIND_MULTIPATHS_UNDEF || ++ conf->find_multipaths >= __FIND_MULTIPATHS_LAST) ++ return PATH_IS_ERROR; ++ ++ if (safe_sprintf(pp->dev, "%s", name)) ++ return PATH_IS_ERROR; ++ ++ if (sysfs_is_multipathed(pp, true)) { ++ if (pp->wwid[0] == '\0') ++ return PATH_IS_ERROR; ++ return PATH_IS_VALID_NO_CHECK; ++ } ++ ++ /* ++ * "multipath -u" may be run before the daemon is started. In this ++ * case, systemd might own the socket but might delay multipathd ++ * startup until some other unit (udev settle!) has finished ++ * starting. With many LUNs, the listen backlog may be exceeded, which ++ * would cause connect() to block. This causes udev workers calling ++ * "multipath -u" to hang, and thus creates a deadlock, until "udev ++ * settle" times out. To avoid this, call connect() in non-blocking ++ * mode here, and take EAGAIN as indication for a filled-up systemd ++ * backlog. ++ */ ++ ++ if (check_multipathd) { ++ fd = __mpath_connect(1); ++ if (fd < 0) { ++ if (errno != EAGAIN && !systemd_service_enabled(name)) { ++ condlog(3, "multipathd not running or enabled"); ++ return PATH_IS_NOT_VALID; ++ } ++ } else ++ mpath_disconnect(fd); ++ } ++ ++ pp->udev = udev_device_new_from_subsystem_sysname(udev, "block", name); ++ if (!pp->udev) ++ return PATH_IS_ERROR; ++ ++ r = pathinfo(pp, conf, DI_SYSFS | DI_WWID | DI_BLACKLIST); ++ if (r == PATHINFO_SKIPPED) ++ return PATH_IS_NOT_VALID; ++ else if (r) ++ return PATH_IS_ERROR; ++ ++ if (pp->wwid[0] == '\0') ++ return PATH_IS_NOT_VALID; ++ ++ if (pp->udev && pp->uid_attribute && ++ filter_property(conf, pp->udev, 3, pp->uid_attribute) > 0) ++ return PATH_IS_NOT_VALID; ++ ++ r = is_failed_wwid(pp->wwid); ++ if (r != WWID_IS_NOT_FAILED) { ++ if (r == WWID_IS_FAILED) ++ return PATH_IS_NOT_VALID; ++ return PATH_IS_ERROR; ++ } ++ ++ if (conf->find_multipaths == FIND_MULTIPATHS_GREEDY) ++ return PATH_IS_VALID; ++ ++ if (check_wwids_file(pp->wwid, 0) == 0) ++ return PATH_IS_VALID_NO_CHECK; ++ ++ if (dm_map_present_by_uuid(pp->wwid) == 1) ++ return PATH_IS_VALID; ++ ++ /* all these act like FIND_MULTIPATHS_STRICT for finding if a ++ * path is valid */ ++ if (conf->find_multipaths != FIND_MULTIPATHS_SMART) ++ return PATH_IS_NOT_VALID; ++ ++ return PATH_IS_MAYBE_VALID; ++} +diff --git a/libmultipath/valid.h b/libmultipath/valid.h +new file mode 100644 +index 00000000..ce1c7cbf +--- /dev/null ++++ b/libmultipath/valid.h +@@ -0,0 +1,42 @@ ++/* ++ Copyright (c) 2020 Benjamin Marzinski, IBM ++ ++ This program is free software; you can redistribute it and/or ++ modify it under the terms of the GNU General Public License ++ as published by the Free Software Foundation; either version 2 ++ of the License, or (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . ++ */ ++#ifndef _VALID_H ++#define _VALID_H ++ ++/* ++ * PATH_IS_VALID_NO_CHECK is returned when multipath should claim ++ * the path, regardless of whether is has been released to systemd ++ * already. ++ * PATH_IS_VALID is returned by is_path_valid, when the path is ++ * valid only if it hasn't been released to systemd already. ++ * PATH_IS_MAYBE_VALID is returned when the the path would be valid ++ * if other paths with the same wwid existed. It is up to the caller ++ * to check for these other paths. ++ */ ++enum is_path_valid_result { ++ PATH_IS_ERROR = -1, ++ PATH_IS_NOT_VALID, ++ PATH_IS_VALID, ++ PATH_IS_VALID_NO_CHECK, ++ PATH_IS_MAYBE_VALID, ++ PATH_MAX_VALID_RESULT, /* only for bounds checking */ ++}; ++ ++int is_path_valid(const char *name, struct config *conf, struct path *pp, ++ bool check_multipathd); ++ ++#endif /* _VALID_D */ +diff --git a/libmultipath/wwids.c b/libmultipath/wwids.c +index 28a2150d..637cb0ab 100644 +--- a/libmultipath/wwids.c ++++ b/libmultipath/wwids.c +@@ -289,19 +289,19 @@ out: + int + should_multipath(struct path *pp1, vector pathvec, vector mpvec) + { +- int i, ignore_new_devs, find_multipaths; ++ int i, find_multipaths; + struct path *pp2; + struct config *conf; + + conf = get_multipath_config(); +- ignore_new_devs = ignore_new_devs_on(conf); +- find_multipaths = find_multipaths_on(conf); ++ find_multipaths = conf->find_multipaths; + put_multipath_config(conf); +- if (!find_multipaths && !ignore_new_devs) ++ if (find_multipaths == FIND_MULTIPATHS_OFF || ++ find_multipaths == FIND_MULTIPATHS_GREEDY) + return 1; + + condlog(4, "checking if %s should be multipathed", pp1->dev); +- if (!ignore_new_devs) { ++ if (find_multipaths != FIND_MULTIPATHS_STRICT) { + char tmp_wwid[WWID_SIZE]; + struct multipath *mp = find_mp_by_wwid(mpvec, pp1->wwid); + +diff --git a/multipath/main.c b/multipath/main.c +index 545ead87..953fab27 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -63,21 +63,18 @@ + #include "propsel.h" + #include "time-util.h" + #include "file.h" ++#include "valid.h" + + int logsink; + struct udev *udev; + struct config *multipath_conf; + + /* +- * Return values of configure(), print_cmd_valid(), and main(). +- * RTVL_{YES,NO} are synonyms for RTVL_{OK,FAIL} for the CMD_VALID_PATH case. ++ * Return values of configure(), check_path_valid(), and main(). + */ + enum { + RTVL_OK = 0, +- RTVL_YES = RTVL_OK, + RTVL_FAIL = 1, +- RTVL_NO = RTVL_FAIL, +- RTVL_MAYBE, /* only used internally, never returned */ + RTVL_RETRY, /* returned by configure(), not by main() */ + }; + +@@ -269,9 +266,6 @@ get_dm_mpvec (enum mpath_cmds cmd, vector curmp, vector pathvec, char * refwwid) + continue; + } + +- if (cmd == CMD_VALID_PATH) +- continue; +- + dm_get_map(mpp->alias, &mpp->size, params); + condlog(3, "params = %s", params); + dm_get_status(mpp->alias, status); +@@ -491,10 +485,11 @@ static int print_cmd_valid(int k, const vector pathvec, + struct timespec until; + struct path *pp; + +- if (k != RTVL_YES && k != RTVL_NO && k != RTVL_MAYBE) +- return RTVL_NO; ++ if (k != PATH_IS_VALID && k != PATH_IS_NOT_VALID && ++ k != PATH_IS_MAYBE_VALID) ++ return PATH_IS_NOT_VALID; + +- if (k == RTVL_MAYBE) { ++ if (k == PATH_IS_MAYBE_VALID) { + /* + * Caller ensures that pathvec[0] is the path to + * examine. +@@ -504,7 +499,7 @@ static int print_cmd_valid(int k, const vector pathvec, + wait = find_multipaths_check_timeout( + pp, pp->find_multipaths_timeout, &until); + if (wait != FIND_MULTIPATHS_WAITING) +- k = RTVL_NO; ++ k = PATH_IS_NOT_VALID; + } else if (pathvec != NULL && (pp = VECTOR_SLOT(pathvec, 0))) + wait = find_multipaths_check_timeout(pp, 0, &until); + if (wait == FIND_MULTIPATHS_WAITING) +@@ -513,9 +508,9 @@ static int print_cmd_valid(int k, const vector pathvec, + else if (wait == FIND_MULTIPATHS_WAIT_DONE) + printf("FIND_MULTIPATHS_WAIT_UNTIL=\"0\"\n"); + printf("DM_MULTIPATH_DEVICE_PATH=\"%d\"\n", +- k == RTVL_MAYBE ? 2 : k == RTVL_YES ? 1 : 0); ++ k == PATH_IS_MAYBE_VALID ? 2 : k == PATH_IS_VALID ? 1 : 0); + /* Never return RTVL_MAYBE */ +- return k == RTVL_NO ? RTVL_NO : RTVL_YES; ++ return k == PATH_IS_NOT_VALID ? PATH_IS_NOT_VALID : PATH_IS_VALID; + } + + /* +@@ -548,7 +543,6 @@ configure (struct config *conf, enum mpath_cmds cmd, + int di_flag = 0; + char * refwwid = NULL; + char * dev = NULL; +- bool released = released_to_systemd(); + + /* + * allocate core vectors to store paths and multipaths +@@ -573,7 +567,7 @@ configure (struct config *conf, enum mpath_cmds cmd, + cmd != CMD_REMOVE_WWID && + (filter_devnode(conf->blist_devnode, + conf->elist_devnode, dev) > 0)) { +- goto print_valid; ++ goto out; + } + + /* +@@ -581,14 +575,10 @@ configure (struct config *conf, enum mpath_cmds cmd, + * failing the translation is fatal (by policy) + */ + if (devpath) { +- int failed = get_refwwid(cmd, devpath, dev_type, +- pathvec, &refwwid); ++ get_refwwid(cmd, devpath, dev_type, pathvec, &refwwid); + if (!refwwid) { + condlog(4, "%s: failed to get wwid", devpath); +- if (failed == 2 && cmd == CMD_VALID_PATH) +- goto print_valid; +- else +- condlog(3, "scope is null"); ++ condlog(3, "scope is null"); + goto out; + } + if (cmd == CMD_REMOVE_WWID) { +@@ -614,53 +604,6 @@ configure (struct config *conf, enum mpath_cmds cmd, + goto out; + } + condlog(3, "scope limited to %s", refwwid); +- /* 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. +- * Paths listed in the wwids file are always considered valid. +- */ +- if (cmd == CMD_VALID_PATH) { +- if (is_failed_wwid(refwwid) == WWID_IS_FAILED) { +- r = RTVL_NO; +- goto print_valid; +- } +- if ((!find_multipaths_on(conf) && +- ignore_wwids_on(conf)) || +- check_wwids_file(refwwid, 0) == 0) +- r = RTVL_YES; +- if (!ignore_wwids_on(conf)) +- goto print_valid; +- /* At this point, either r==0 or find_multipaths_on. */ +- +- /* +- * Shortcut for find_multipaths smart: +- * Quick check if path is already multipathed. +- */ +- if (sysfs_is_multipathed(VECTOR_SLOT(pathvec, 0), +- false)) { +- r = RTVL_YES; +- goto print_valid; +- } +- +- /* +- * DM_MULTIPATH_DEVICE_PATH=="0" means that we have +- * been called for this device already, and have +- * released it to systemd. Unless the device is now +- * already multipathed (see above), we can't try to +- * grab it, because setting SYSTEMD_READY=0 would +- * cause file systems to be unmounted. +- * Leave DM_MULTIPATH_DEVICE_PATH="0". +- */ +- if (released) { +- r = RTVL_NO; +- goto print_valid; +- } +- if (r == RTVL_YES) +- goto print_valid; +- /* find_multipaths_on: Fall through to path detection */ +- } + } + + /* +@@ -701,59 +644,6 @@ configure (struct config *conf, enum mpath_cmds cmd, + goto out; + } + +- if (cmd == CMD_VALID_PATH) { +- struct path *pp; +- int fd; +- +- /* This only happens if find_multipaths and +- * ignore_wwids is set, and the path is not in WWIDs +- * file, not currently multipathed, and has +- * never been released to systemd. +- * 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) { +- r = RTVL_YES; +- goto print_valid; +- } else if (VECTOR_SIZE(pathvec) > 1) +- r = RTVL_YES; +- else +- r = RTVL_MAYBE; +- +- /* +- * If opening the path with O_EXCL fails, the path +- * is in use (e.g. mounted during initramfs processing). +- * We know that it's not used by dm-multipath. +- * We may not set SYSTEMD_READY=0 on such devices, it +- * might cause systemd to umount the device. +- * Use O_RDONLY, because udevd would trigger another +- * uevent for close-after-write. +- * +- * The O_EXCL check is potentially dangerous, because it may +- * race with other tasks trying to access the device. Therefore +- * this code is only executed if the path hasn't been released +- * to systemd earlier (see above). +- * +- * get_refwwid() above stores the path we examine in slot 0. +- */ +- pp = VECTOR_SLOT(pathvec, 0); +- fd = open(udev_device_get_devnode(pp->udev), +- O_RDONLY|O_EXCL); +- if (fd >= 0) +- close(fd); +- else { +- condlog(3, "%s: path %s is in use: %s", +- __func__, pp->dev, +- strerror(errno)); +- /* +- * Check if we raced with multipathd +- */ +- r = sysfs_is_multipathed(VECTOR_SLOT(pathvec, 0), +- false) ? RTVL_YES : RTVL_NO; +- } +- goto print_valid; +- } +- + if (cmd != CMD_CREATE && cmd != CMD_DRY_RUN) { + r = RTVL_OK; + goto out; +@@ -766,10 +656,6 @@ configure (struct config *conf, enum mpath_cmds cmd, + conf->force_reload, cmd); + r = rc == CP_RETRY ? RTVL_RETRY : rc == CP_OK ? RTVL_OK : RTVL_FAIL; + +-print_valid: +- if (cmd == CMD_VALID_PATH) +- r = print_cmd_valid(r, pathvec, conf); +- + out: + if (refwwid) + FREE(refwwid); +@@ -780,6 +666,112 @@ out: + return r; + } + ++static int ++check_path_valid(const char *name, struct config *conf, bool is_uevent) ++{ ++ int fd, r = PATH_IS_ERROR; ++ struct path *pp = NULL; ++ vector pathvec = NULL; ++ ++ pp = alloc_path(); ++ if (!pp) ++ return RTVL_FAIL; ++ ++ r = is_path_valid(name, conf, pp, is_uevent); ++ if (r <= PATH_IS_ERROR || r >= PATH_MAX_VALID_RESULT) ++ goto fail; ++ ++ /* set path values if is_path_valid() didn't */ ++ if (!pp->udev) ++ pp->udev = udev_device_new_from_subsystem_sysname(udev, "block", ++ name); ++ if (!pp->udev) ++ goto fail; ++ ++ if (!strlen(pp->dev_t)) { ++ dev_t devt = udev_device_get_devnum(pp->udev); ++ if (major(devt) == 0 && minor(devt) == 0) ++ goto fail; ++ snprintf(pp->dev_t, BLK_DEV_SIZE, "%d:%d", major(devt), ++ minor(devt)); ++ } ++ ++ pathvec = vector_alloc(); ++ if (!pathvec) ++ goto fail; ++ ++ if (store_path(pathvec, pp) != 0) { ++ free_path(pp); ++ goto fail; ++ } ++ ++ if ((r == PATH_IS_VALID || r == PATH_IS_MAYBE_VALID) && ++ released_to_systemd()) ++ r = PATH_IS_NOT_VALID; ++ ++ /* This state is only used to skip the released_to_systemd() check */ ++ if (r == PATH_IS_VALID_NO_CHECK) ++ r = PATH_IS_VALID; ++ ++ if (r != PATH_IS_MAYBE_VALID) ++ goto out; ++ ++ /* ++ * If opening the path with O_EXCL fails, the path ++ * is in use (e.g. mounted during initramfs processing). ++ * We know that it's not used by dm-multipath. ++ * We may not set SYSTEMD_READY=0 on such devices, it ++ * might cause systemd to umount the device. ++ * Use O_RDONLY, because udevd would trigger another ++ * uevent for close-after-write. ++ * ++ * The O_EXCL check is potentially dangerous, because it may ++ * race with other tasks trying to access the device. Therefore ++ * this code is only executed if the path hasn't been released ++ * to systemd earlier (see above). ++ */ ++ fd = open(udev_device_get_devnode(pp->udev), O_RDONLY|O_EXCL); ++ if (fd >= 0) ++ close(fd); ++ else { ++ condlog(3, "%s: path %s is in use: %m", __func__, pp->dev); ++ /* Check if we raced with multipathd */ ++ if (sysfs_is_multipathed(pp, false)) ++ r = PATH_IS_VALID; ++ else ++ r = PATH_IS_NOT_VALID; ++ goto out; ++ } ++ ++ /* For find_multipaths = SMART, if there is more than one path ++ * matching the refwwid, then the path is valid */ ++ if (path_discovery(pathvec, DI_SYSFS | DI_WWID) < 0) ++ goto fail; ++ filter_pathvec(pathvec, pp->wwid); ++ if (VECTOR_SIZE(pathvec) > 1) ++ r = PATH_IS_VALID; ++ else ++ r = PATH_IS_MAYBE_VALID; ++ ++out: ++ r = print_cmd_valid(r, pathvec, conf); ++ free_pathvec(pathvec, FREE_PATHS); ++ /* ++ * multipath -u must exit with status 0, otherwise udev won't ++ * import its output. ++ */ ++ if (!is_uevent && r == PATH_IS_NOT_VALID) ++ return RTVL_FAIL; ++ return RTVL_OK; ++ ++fail: ++ if (pathvec) ++ free_pathvec(pathvec, FREE_PATHS); ++ else ++ free_path(pp); ++ return RTVL_FAIL; ++} ++ + static int + get_dev_type(char *dev) { + struct stat buf; +@@ -861,32 +853,6 @@ out: + return r; + } + +-static int test_multipathd_socket(void) +-{ +- int fd; +- /* +- * "multipath -u" may be run before the daemon is started. In this +- * case, systemd might own the socket but might delay multipathd +- * startup until some other unit (udev settle!) has finished +- * starting. With many LUNs, the listen backlog may be exceeded, which +- * would cause connect() to block. This causes udev workers calling +- * "multipath -u" to hang, and thus creates a deadlock, until "udev +- * settle" times out. To avoid this, call connect() in non-blocking +- * mode here, and take EAGAIN as indication for a filled-up systemd +- * backlog. +- */ +- +- fd = __mpath_connect(1); +- if (fd == -1) { +- if (errno == EAGAIN) +- condlog(3, "daemon backlog exceeded"); +- else +- return 0; +- } else +- close(fd); +- return 1; +-} +- + int + main (int argc, char *argv[]) + { +@@ -970,7 +936,11 @@ main (int argc, char *argv[]) + conf->force_reload = FORCE_RELOAD_YES; + break; + case 'i': +- conf->find_multipaths |= _FIND_MULTIPATHS_I; ++ if (conf->find_multipaths == FIND_MULTIPATHS_ON || ++ conf->find_multipaths == FIND_MULTIPATHS_STRICT) ++ conf->find_multipaths = FIND_MULTIPATHS_SMART; ++ else if (conf->find_multipaths == FIND_MULTIPATHS_OFF) ++ conf->find_multipaths = FIND_MULTIPATHS_GREEDY; + break; + case 't': + r = dump_config(conf, NULL, NULL) ? RTVL_FAIL : RTVL_OK; +@@ -1064,15 +1034,10 @@ main (int argc, char *argv[]) + condlog(0, "the -c option requires a path to check"); + goto out; + } +- if (cmd == CMD_VALID_PATH && +- dev_type == DEV_UEVENT) { +- if (!test_multipathd_socket()) { +- condlog(3, "%s: daemon is not running", dev); +- if (!systemd_service_enabled(dev)) { +- r = print_cmd_valid(RTVL_NO, NULL, conf); +- goto out; +- } +- } ++ if (cmd == CMD_VALID_PATH) { ++ char * name = convert_dev(dev, (dev_type == DEV_DEVNODE)); ++ r = check_path_valid(name, conf, dev_type == DEV_UEVENT); ++ goto out; + } + + if (cmd == CMD_REMOVE_WWID && !dev) { +@@ -1136,13 +1101,6 @@ out: + cleanup_prio(); + cleanup_checkers(); + +- /* +- * multipath -u must exit with status 0, otherwise udev won't +- * import its output. +- */ +- if (cmd == CMD_VALID_PATH && dev_type == DEV_UEVENT && r == RTVL_NO) +- r = RTVL_OK; +- + if (dev_type == DEV_UEVENT) + closelog(); + +-- +2.17.2 + diff --git a/0026-Unit-tests-for-is_path_valid.patch b/0026-Unit-tests-for-is_path_valid.patch new file mode 100644 index 0000000000000000000000000000000000000000..9ada3686a1c1653937f17589b786cf045409eecd --- /dev/null +++ b/0026-Unit-tests-for-is_path_valid.patch @@ -0,0 +1,530 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 19 May 2020 12:08:43 -0500 +Subject: [PATCH] Unit tests for is_path_valid() + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + tests/Makefile | 4 +- + tests/valid.c | 486 +++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 489 insertions(+), 1 deletion(-) + create mode 100644 tests/valid.c + +diff --git a/tests/Makefile b/tests/Makefile +index 1b8706a7..125553b8 100644 +--- a/tests/Makefile ++++ b/tests/Makefile +@@ -13,7 +13,7 @@ CFLAGS += $(BIN_CFLAGS) -I$(multipathdir) -I$(mpathcmddir) \ + LIBDEPS += -L$(multipathdir) -L$(mpathcmddir) -lmultipath -lmpathcmd -lcmocka + + TESTS := uevent parser util dmevents hwtable blacklist unaligned vpd pgpolicy \ +- alias directio ++ alias directio valid + + .SILENT: $(TESTS:%=%.o) + .PRECIOUS: $(TESTS:%=%-test) +@@ -50,6 +50,8 @@ vpd-test_OBJDEPS := ../libmultipath/discovery.o + vpd-test_LIBDEPS := -ludev -lpthread -ldl + alias-test_TESTDEPS := test-log.o + alias-test_LIBDEPS := -lpthread -ldl ++valid-test_OBJDEPS := ../libmultipath/valid.o ++valid-test_LIBDEPS := -ludev -lpthread -ldl + ifneq ($(DIO_TEST_DEV),) + directio-test_LIBDEPS := -laio + endif +diff --git a/tests/valid.c b/tests/valid.c +new file mode 100644 +index 00000000..693c72c5 +--- /dev/null ++++ b/tests/valid.c +@@ -0,0 +1,486 @@ ++/* ++ * Copyright (c) 2020 Benjamin Marzinski, Redhat ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2 ++ * of the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see . ++ * ++ */ ++ ++#define _GNU_SOURCE ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "globals.c" ++#include "util.h" ++#include "discovery.h" ++#include "wwids.h" ++#include "blacklist.h" ++#include "valid.h" ++ ++int test_fd; ++struct udev_device { ++ int unused; ++} test_udev; ++ ++bool __wrap_sysfs_is_multipathed(struct path *pp, bool set_wwid) ++{ ++ bool is_multipathed = mock_type(bool); ++ assert_non_null(pp); ++ assert_int_not_equal(strlen(pp->dev), 0); ++ if (is_multipathed && set_wwid) ++ strlcpy(pp->wwid, mock_ptr_type(char *), WWID_SIZE); ++ return is_multipathed; ++} ++ ++int __wrap___mpath_connect(int nonblocking) ++{ ++ bool connected = mock_type(bool); ++ assert_int_equal(nonblocking, 1); ++ if (connected) ++ return test_fd; ++ errno = mock_type(int); ++ return -1; ++} ++ ++int __wrap_systemd_service_enabled(const char *dev) ++{ ++ return (int)mock_type(bool); ++} ++ ++/* There's no point in checking the return value here */ ++int __wrap_mpath_disconnect(int fd) ++{ ++ assert_int_equal(fd, test_fd); ++ return 0; ++} ++ ++struct udev_device *__wrap_udev_device_new_from_subsystem_sysname(struct udev *udev, const char *subsystem, const char *sysname) ++{ ++ bool passed = mock_type(bool); ++ assert_string_equal(sysname, mock_ptr_type(char *)); ++ if (passed) ++ return &test_udev; ++ return NULL; ++} ++ ++int __wrap_pathinfo(struct path *pp, struct config *conf, int mask) ++{ ++ int ret = mock_type(int); ++ assert_string_equal(pp->dev, mock_ptr_type(char *)); ++ assert_int_equal(mask, DI_SYSFS | DI_WWID | DI_BLACKLIST); ++ if (ret == PATHINFO_OK) { ++ pp->uid_attribute = "ID_TEST"; ++ strlcpy(pp->wwid, mock_ptr_type(char *), WWID_SIZE); ++ } else ++ memset(pp->wwid, 0, WWID_SIZE); ++ return ret; ++} ++ ++int __wrap_filter_property(struct config *conf, struct udev_device *udev, ++ int lvl, const char *uid_attribute) ++{ ++ int ret = mock_type(int); ++ assert_string_equal(uid_attribute, "ID_TEST"); ++ return ret; ++} ++ ++int __wrap_is_failed_wwid(const char *wwid) ++{ ++ int ret = mock_type(int); ++ assert_string_equal(wwid, mock_ptr_type(char *)); ++ return ret; ++} ++ ++int __wrap_check_wwids_file(char *wwid, int write_wwid) ++{ ++ bool passed = mock_type(bool); ++ assert_int_equal(write_wwid, 0); ++ assert_string_equal(wwid, mock_ptr_type(char *)); ++ if (passed) ++ return 0; ++ else ++ return -1; ++} ++ ++int __wrap_dm_map_present_by_uuid(const char *uuid) ++{ ++ int ret = mock_type(int); ++ assert_string_equal(uuid, mock_ptr_type(char *)); ++ return ret; ++} ++ ++enum { ++ STAGE_IS_MULTIPATHED, ++ STAGE_CHECK_MULTIPATHD, ++ STAGE_GET_UDEV_DEVICE, ++ STAGE_PATHINFO, ++ STAGE_FILTER_PROPERTY, ++ STAGE_IS_FAILED, ++ STAGE_CHECK_WWIDS, ++ STAGE_UUID_PRESENT, ++}; ++ ++enum { ++ CHECK_MPATHD_RUNNING, ++ CHECK_MPATHD_EAGAIN, ++ CHECK_MPATHD_ENABLED, ++ CHECK_MPATHD_SKIP, ++}; ++ ++/* setup the test to continue past the given stage in is_path_valid() */ ++static void setup_passing(char *name, char *wwid, unsigned int check_multipathd, ++ unsigned int stage) ++{ ++ will_return(__wrap_sysfs_is_multipathed, false); ++ if (stage == STAGE_IS_MULTIPATHED) ++ return; ++ if (check_multipathd == CHECK_MPATHD_RUNNING) ++ will_return(__wrap___mpath_connect, true); ++ else if (check_multipathd == CHECK_MPATHD_EAGAIN) { ++ will_return(__wrap___mpath_connect, false); ++ will_return(__wrap___mpath_connect, EAGAIN); ++ } else if (check_multipathd == CHECK_MPATHD_ENABLED) { ++ will_return(__wrap___mpath_connect, false); ++ will_return(__wrap___mpath_connect, ECONNREFUSED); ++ will_return(__wrap_systemd_service_enabled, true); ++ } ++ /* nothing for CHECK_MPATHD_SKIP */ ++ if (stage == STAGE_CHECK_MULTIPATHD) ++ return; ++ will_return(__wrap_udev_device_new_from_subsystem_sysname, true); ++ will_return(__wrap_udev_device_new_from_subsystem_sysname, ++ name); ++ if (stage == STAGE_GET_UDEV_DEVICE) ++ return; ++ will_return(__wrap_pathinfo, PATHINFO_OK); ++ will_return(__wrap_pathinfo, name); ++ will_return(__wrap_pathinfo, wwid); ++ if (stage == STAGE_PATHINFO) ++ return; ++ will_return(__wrap_filter_property, MATCH_PROPERTY_BLIST_EXCEPT); ++ if (stage == STAGE_FILTER_PROPERTY) ++ return; ++ will_return(__wrap_is_failed_wwid, WWID_IS_NOT_FAILED); ++ will_return(__wrap_is_failed_wwid, wwid); ++ if (stage == STAGE_IS_FAILED) ++ return; ++ will_return(__wrap_check_wwids_file, false); ++ will_return(__wrap_check_wwids_file, wwid); ++ if (stage == STAGE_CHECK_WWIDS) ++ return; ++ will_return(__wrap_dm_map_present_by_uuid, 0); ++ will_return(__wrap_dm_map_present_by_uuid, wwid); ++} ++ ++static void test_bad_arguments(void **state) ++{ ++ struct path pp; ++ char too_long[FILE_NAME_SIZE + 1]; ++ ++ memset(&pp, 0, sizeof(pp)); ++ /* test NULL pointers */ ++ assert_int_equal(is_path_valid("test", &conf, NULL, true), ++ PATH_IS_ERROR); ++ assert_int_equal(is_path_valid("test", NULL, &pp, true), ++ PATH_IS_ERROR); ++ assert_int_equal(is_path_valid(NULL, &conf, &pp, true), ++ PATH_IS_ERROR); ++ /* test undefined find_multipaths */ ++ conf.find_multipaths = FIND_MULTIPATHS_UNDEF; ++ assert_int_equal(is_path_valid("test", &conf, &pp, true), ++ PATH_IS_ERROR); ++ /* test name too long */ ++ memset(too_long, 'x', sizeof(too_long)); ++ too_long[sizeof(too_long) - 1] = '\0'; ++ conf.find_multipaths = FIND_MULTIPATHS_STRICT; ++ assert_int_equal(is_path_valid(too_long, &conf, &pp, true), ++ PATH_IS_ERROR); ++} ++ ++static void test_sysfs_is_multipathed(void **state) ++{ ++ struct path pp; ++ char *name = "test"; ++ char *wwid = "test_wwid"; ++ ++ memset(&pp, 0, sizeof(pp)); ++ conf.find_multipaths = FIND_MULTIPATHS_STRICT; ++ /* test for already existing multiapthed device */ ++ will_return(__wrap_sysfs_is_multipathed, true); ++ will_return(__wrap_sysfs_is_multipathed, wwid); ++ assert_int_equal(is_path_valid(name, &conf, &pp, true), ++ PATH_IS_VALID_NO_CHECK); ++ assert_string_equal(pp.dev, name); ++ assert_string_equal(pp.wwid, wwid); ++ /* test for wwid device with empty wwid */ ++ will_return(__wrap_sysfs_is_multipathed, true); ++ will_return(__wrap_sysfs_is_multipathed, ""); ++ assert_int_equal(is_path_valid(name, &conf, &pp, true), ++ PATH_IS_ERROR); ++} ++ ++static void test_check_multipathd(void **state) ++{ ++ struct path pp; ++ char *name = "test"; ++ ++ memset(&pp, 0, sizeof(pp)); ++ conf.find_multipaths = FIND_MULTIPATHS_STRICT; ++ /* test failed check to see if multipathd is active */ ++ will_return(__wrap_sysfs_is_multipathed, false); ++ will_return(__wrap___mpath_connect, false); ++ will_return(__wrap___mpath_connect, ECONNREFUSED); ++ will_return(__wrap_systemd_service_enabled, false); ++ assert_int_equal(is_path_valid(name, &conf, &pp, true), ++ PATH_IS_NOT_VALID); ++ assert_string_equal(pp.dev, name); ++ /* test pass because service is enabled. fail getting udev */ ++ memset(&pp, 0, sizeof(pp)); ++ setup_passing(name, NULL, CHECK_MPATHD_ENABLED, STAGE_CHECK_MULTIPATHD); ++ will_return(__wrap_udev_device_new_from_subsystem_sysname, false); ++ will_return(__wrap_udev_device_new_from_subsystem_sysname, ++ name); ++ assert_int_equal(is_path_valid(name, &conf, &pp, true), ++ PATH_IS_ERROR); ++ assert_string_equal(pp.dev, name); ++ /* test pass because connect returned EAGAIN. fail getting udev */ ++ setup_passing(name, NULL, CHECK_MPATHD_EAGAIN, STAGE_CHECK_MULTIPATHD); ++ will_return(__wrap_udev_device_new_from_subsystem_sysname, false); ++ will_return(__wrap_udev_device_new_from_subsystem_sysname, ++ name); ++ assert_int_equal(is_path_valid(name, &conf, &pp, true), ++ PATH_IS_ERROR); ++ /* test pass because connect succeeded. fail getting udev */ ++ memset(&pp, 0, sizeof(pp)); ++ setup_passing(name, NULL, CHECK_MPATHD_RUNNING, STAGE_CHECK_MULTIPATHD); ++ will_return(__wrap_udev_device_new_from_subsystem_sysname, false); ++ will_return(__wrap_udev_device_new_from_subsystem_sysname, ++ name); ++ assert_int_equal(is_path_valid(name, &conf, &pp, true), ++ PATH_IS_ERROR); ++ assert_string_equal(pp.dev, name); ++} ++ ++static void test_pathinfo(void **state) ++{ ++ struct path pp; ++ char *name = "test"; ++ ++ memset(&pp, 0, sizeof(pp)); ++ conf.find_multipaths = FIND_MULTIPATHS_STRICT; ++ /* Test pathinfo blacklisting device */ ++ setup_passing(name, NULL, CHECK_MPATHD_SKIP, STAGE_GET_UDEV_DEVICE); ++ will_return(__wrap_pathinfo, PATHINFO_SKIPPED); ++ will_return(__wrap_pathinfo, name); ++ assert_int_equal(is_path_valid(name, &conf, &pp, false), ++ PATH_IS_NOT_VALID); ++ assert_string_equal(pp.dev, name); ++ assert_ptr_equal(pp.udev, &test_udev); ++ /* Test pathinfo failing */ ++ memset(&pp, 0, sizeof(pp)); ++ setup_passing(name, NULL, CHECK_MPATHD_SKIP, STAGE_GET_UDEV_DEVICE); ++ will_return(__wrap_pathinfo, PATHINFO_FAILED); ++ will_return(__wrap_pathinfo, name); ++ assert_int_equal(is_path_valid(name, &conf, &pp, false), ++ PATH_IS_ERROR); ++ /* Test blank wwid */ ++ memset(&pp, 0, sizeof(pp)); ++ setup_passing(name, NULL, CHECK_MPATHD_SKIP, STAGE_GET_UDEV_DEVICE); ++ will_return(__wrap_pathinfo, PATHINFO_OK); ++ will_return(__wrap_pathinfo, name); ++ will_return(__wrap_pathinfo, ""); ++ assert_int_equal(is_path_valid(name, &conf, &pp, false), ++ PATH_IS_NOT_VALID); ++} ++ ++static void test_filter_property(void **state) ++{ ++ struct path pp; ++ char *name = "test"; ++ char *wwid = "test-wwid"; ++ ++ /* test blacklist property */ ++ memset(&pp, 0, sizeof(pp)); ++ conf.find_multipaths = FIND_MULTIPATHS_STRICT; ++ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_PATHINFO); ++ will_return(__wrap_filter_property, MATCH_PROPERTY_BLIST); ++ assert_int_equal(is_path_valid(name, &conf, &pp, false), ++ PATH_IS_NOT_VALID); ++ assert_ptr_equal(pp.udev, &test_udev); ++ assert_string_equal(pp.wwid, wwid); ++ /* test missing property */ ++ memset(&pp, 0, sizeof(pp)); ++ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_PATHINFO); ++ will_return(__wrap_filter_property, MATCH_PROPERTY_BLIST_MISSING); ++ assert_int_equal(is_path_valid(name, &conf, &pp, false), ++ PATH_IS_NOT_VALID); ++ /* test MATCH_NOTHING fail on is_failed_wwid */ ++ memset(&pp, 0, sizeof(pp)); ++ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_PATHINFO); ++ will_return(__wrap_filter_property, MATCH_NOTHING); ++ will_return(__wrap_is_failed_wwid, WWID_IS_FAILED); ++ will_return(__wrap_is_failed_wwid, wwid); ++ assert_int_equal(is_path_valid(name, &conf, &pp, false), ++ PATH_IS_NOT_VALID); ++} ++ ++static void test_is_failed_wwid(void **state) ++{ ++ struct path pp; ++ char *name = "test"; ++ char *wwid = "test-wwid"; ++ ++ memset(&pp, 0, sizeof(pp)); ++ conf.find_multipaths = FIND_MULTIPATHS_STRICT; ++ /* Test wwid failed */ ++ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_FILTER_PROPERTY); ++ will_return(__wrap_is_failed_wwid, WWID_IS_FAILED); ++ will_return(__wrap_is_failed_wwid, wwid); ++ assert_int_equal(is_path_valid(name, &conf, &pp, false), ++ PATH_IS_NOT_VALID); ++ assert_string_equal(pp.dev, name); ++ assert_ptr_equal(pp.udev, &test_udev); ++ assert_string_equal(pp.wwid, wwid); ++ /* test is_failed_wwid error */ ++ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_FILTER_PROPERTY); ++ will_return(__wrap_is_failed_wwid, WWID_FAILED_ERROR); ++ will_return(__wrap_is_failed_wwid, wwid); ++ assert_int_equal(is_path_valid(name, &conf, &pp, false), ++ PATH_IS_ERROR); ++} ++ ++static void test_greedy(void **state) ++{ ++ struct path pp; ++ char *name = "test"; ++ char *wwid = "test-wwid"; ++ ++ /* test greedy success with checking multipathd */ ++ memset(&pp, 0, sizeof(pp)); ++ conf.find_multipaths = FIND_MULTIPATHS_GREEDY; ++ setup_passing(name, wwid, CHECK_MPATHD_RUNNING, STAGE_IS_FAILED); ++ assert_int_equal(is_path_valid(name, &conf, &pp, true), ++ PATH_IS_VALID); ++ assert_string_equal(pp.dev, name); ++ assert_ptr_equal(pp.udev, &test_udev); ++ assert_string_equal(pp.wwid, wwid); ++ /* test greedy success without checking multiapthd */ ++ memset(&pp, 0, sizeof(pp)); ++ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_IS_FAILED); ++ assert_int_equal(is_path_valid(name, &conf, &pp, false), ++ PATH_IS_VALID); ++} ++ ++static void test_check_wwids(void **state) ++{ ++ struct path pp; ++ char *name = "test"; ++ char *wwid = "test-wwid"; ++ ++ memset(&pp, 0, sizeof(pp)); ++ conf.find_multipaths = FIND_MULTIPATHS_STRICT; ++ setup_passing(name, wwid, CHECK_MPATHD_EAGAIN, STAGE_IS_FAILED); ++ will_return(__wrap_check_wwids_file, true); ++ will_return(__wrap_check_wwids_file, wwid); ++ assert_int_equal(is_path_valid(name, &conf, &pp, true), ++ PATH_IS_VALID_NO_CHECK); ++ assert_string_equal(pp.dev, name); ++ assert_ptr_equal(pp.udev, &test_udev); ++ assert_string_equal(pp.wwid, wwid); ++} ++ ++static void test_check_uuid_present(void **state) ++{ ++ struct path pp; ++ char *name = "test"; ++ char *wwid = "test-wwid"; ++ ++ memset(&pp, 0, sizeof(pp)); ++ conf.find_multipaths = FIND_MULTIPATHS_STRICT; ++ setup_passing(name, wwid, CHECK_MPATHD_ENABLED, STAGE_CHECK_WWIDS); ++ will_return(__wrap_dm_map_present_by_uuid, 1); ++ will_return(__wrap_dm_map_present_by_uuid, wwid); ++ assert_int_equal(is_path_valid(name, &conf, &pp, true), ++ PATH_IS_VALID); ++ assert_string_equal(pp.dev, name); ++ assert_ptr_equal(pp.udev, &test_udev); ++ assert_string_equal(pp.wwid, wwid); ++} ++ ++ ++static void test_find_multipaths(void **state) ++{ ++ struct path pp; ++ char *name = "test"; ++ char *wwid = "test-wwid"; ++ ++ /* test find_multipaths = FIND_MULTIPATHS_STRICT */ ++ memset(&pp, 0, sizeof(pp)); ++ conf.find_multipaths = FIND_MULTIPATHS_STRICT; ++ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_UUID_PRESENT); ++ assert_int_equal(is_path_valid(name, &conf, &pp, false), ++ PATH_IS_NOT_VALID); ++ assert_string_equal(pp.dev, name); ++ assert_ptr_equal(pp.udev, &test_udev); ++ assert_string_equal(pp.wwid, wwid); ++ /* test find_multipaths = FIND_MULTIPATHS_OFF */ ++ memset(&pp, 0, sizeof(pp)); ++ conf.find_multipaths = FIND_MULTIPATHS_OFF; ++ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_UUID_PRESENT); ++ assert_int_equal(is_path_valid(name, &conf, &pp, false), ++ PATH_IS_NOT_VALID); ++ /* test find_multipaths = FIND_MULTIPATHS_ON */ ++ memset(&pp, 0, sizeof(pp)); ++ conf.find_multipaths = FIND_MULTIPATHS_ON; ++ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_UUID_PRESENT); ++ assert_int_equal(is_path_valid(name, &conf, &pp, false), ++ PATH_IS_NOT_VALID); ++ /* test find_multipaths = FIND_MULTIPATHS_SMART */ ++ memset(&pp, 0, sizeof(pp)); ++ conf.find_multipaths = FIND_MULTIPATHS_SMART; ++ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_UUID_PRESENT); ++ assert_int_equal(is_path_valid(name, &conf, &pp, false), ++ PATH_IS_MAYBE_VALID); ++ assert_string_equal(pp.dev, name); ++ assert_ptr_equal(pp.udev, &test_udev); ++ assert_string_equal(pp.wwid, wwid); ++} ++ ++int test_valid(void) ++{ ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test(test_bad_arguments), ++ cmocka_unit_test(test_sysfs_is_multipathed), ++ cmocka_unit_test(test_check_multipathd), ++ cmocka_unit_test(test_pathinfo), ++ cmocka_unit_test(test_filter_property), ++ cmocka_unit_test(test_is_failed_wwid), ++ cmocka_unit_test(test_greedy), ++ cmocka_unit_test(test_check_wwids), ++ cmocka_unit_test(test_check_uuid_present), ++ cmocka_unit_test(test_find_multipaths), ++ }; ++ return cmocka_run_group_tests(tests, NULL, NULL); ++} ++ ++int main(void) ++{ ++ int ret = 0; ++ ret += test_valid(); ++ return ret; ++} +-- +2.17.2 + diff --git a/0026-libmultipath-free-allocated-value-in-set_int.patch b/0026-libmultipath-free-allocated-value-in-set_int.patch deleted file mode 100644 index 5dfa3c745e60b231e6e4303d153e1d212ed5c5f5..0000000000000000000000000000000000000000 --- a/0026-libmultipath-free-allocated-value-in-set_int.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 5e71f6eb17cbb119f0f995f234bf1887a4f77058 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 11 Oct 2018 15:43:47 -0500 -Subject: [PATCH] libmultipath: free allocated value in set_int - -set_int() needs to free the buffer it got back from set_value() - -Fixes: 8f9ac30d ("libmultipath: fix set_int error path") -Signed-off-by: Benjamin Marzinski ---- - libmultipath/dict.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index bf4701ee..c3f5a6e6 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -39,6 +39,7 @@ set_int(vector strvec, void *ptr) - - *int_ptr = atoi(buff); - -+ FREE(buff); - return 0; - } - --- -2.11.0 - diff --git a/0027-libmultipath-fix-memory-issue-in-path_latency-prio.patch b/0027-libmultipath-fix-memory-issue-in-path_latency-prio.patch deleted file mode 100644 index e490a8a04359ed44922c760ed8092ec7b757381c..0000000000000000000000000000000000000000 --- a/0027-libmultipath-fix-memory-issue-in-path_latency-prio.patch +++ /dev/null @@ -1,32 +0,0 @@ -From c3b739527258dae7ebe4b5d083a33ce527675082 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 9 Oct 2018 18:03:07 -0500 -Subject: [PATCH] libmultipath: fix memory issue in path_latency prio - -The path_latency prioriziter was assuming that prepare_directio_read() -always succeeds. However, it doesn't, and when it fails, the prioritizer -used buf without it pointing to alloced memory. Found by coverity. - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/prioritizers/path_latency.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/prioritizers/path_latency.c b/libmultipath/prioritizers/path_latency.c -index 765265c0..eeee01e1 100644 ---- a/libmultipath/prioritizers/path_latency.c -+++ b/libmultipath/prioritizers/path_latency.c -@@ -237,7 +237,8 @@ int getprio(struct path *pp, char *args, unsigned int timeout) - lg_maxavglatency = log(MAX_AVG_LATENCY) / lg_base; - lg_minavglatency = log(MIN_AVG_LATENCY) / lg_base; - -- prepare_directio_read(pp->fd, &blksize, &buf, &restore_flags); -+ if (prepare_directio_read(pp->fd, &blksize, &buf, &restore_flags) < 0) -+ return PRIO_UNDEF; - - temp = io_num; - while (temp-- > 0) { --- -2.11.0 - diff --git a/0027-libmultipath-simplify-failed-wwid-code.patch b/0027-libmultipath-simplify-failed-wwid-code.patch new file mode 100644 index 0000000000000000000000000000000000000000..bb60d21db954ee9b6b8600e8560528cc1c09a391 --- /dev/null +++ b/0027-libmultipath-simplify-failed-wwid-code.patch @@ -0,0 +1,205 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 19 May 2020 12:08:44 -0500 +Subject: [PATCH] libmultipath: simplify failed wwid code + +The (is|mark|unmark)_failed_wwid code is needlessly complicated. +Locking a file is necssary if multiple processes could otherwise be +writing to it at the same time. That is not the case with the +failed_wwids files. They can simply be empty files in a directory. Even +with all the locking in place, two processes accessing or modifying a +file at the same time will still race. And even without the locking, if +two processes try to access or modify a file at the same time, they will +both see a reasonable result, and will leave the files in a valid state +afterwards. + +Instead of doing all the locking work (which made it necessary to write +a file, even just to check if a file existed), simply check for files +with lstat(), create them with open(), and remove them with unlink(). + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/wwids.c | 131 ++++++++++++++++++------------------------- + 1 file changed, 56 insertions(+), 75 deletions(-) + +diff --git a/libmultipath/wwids.c b/libmultipath/wwids.c +index 637cb0ab..aab5da8a 100644 +--- a/libmultipath/wwids.c ++++ b/libmultipath/wwids.c +@@ -6,6 +6,7 @@ + #include + #include + #include ++#include + + #include "util.h" + #include "checkers.h" +@@ -348,109 +349,89 @@ remember_wwid(char *wwid) + } + + static const char shm_dir[] = MULTIPATH_SHM_BASE "failed_wwids"; +-static const char shm_lock[] = ".lock"; +-static const char shm_header[] = "multipath shm lock file, don't edit"; +-static char _shm_lock_path[sizeof(shm_dir)+sizeof(shm_lock)]; +-static const char *shm_lock_path = &_shm_lock_path[0]; + +-static void init_shm_paths(void) ++static void print_failed_wwid_result(const char * msg, const char *wwid, int r) + { +- snprintf(_shm_lock_path, sizeof(_shm_lock_path), +- "%s/%s", shm_dir, shm_lock); ++ switch(r) { ++ case WWID_FAILED_ERROR: ++ condlog(1, "%s: %s: %m", msg, wwid); ++ return; ++ case WWID_IS_FAILED: ++ case WWID_IS_NOT_FAILED: ++ condlog(4, "%s: %s is %s", msg, wwid, ++ r == WWID_IS_FAILED ? "failed" : "good"); ++ return; ++ case WWID_FAILED_CHANGED: ++ condlog(3, "%s: %s", msg, wwid); ++ } + } + +-static pthread_once_t shm_path_once = PTHREAD_ONCE_INIT; +- +-static int multipath_shm_open(bool rw) ++int is_failed_wwid(const char *wwid) + { +- int fd; +- int can_write; +- +- pthread_once(&shm_path_once, init_shm_paths); +- fd = open_file(shm_lock_path, &can_write, shm_header); ++ struct stat st; ++ char path[PATH_MAX]; ++ int r; + +- if (fd >= 0 && rw && !can_write) { +- close(fd); +- condlog(1, "failed to open %s for writing", shm_dir); ++ if (safe_sprintf(path, "%s/%s", shm_dir, wwid)) { ++ condlog(1, "%s: path name overflow", __func__); + return -1; + } + +- return fd; +-} +- +-static void multipath_shm_close(void *arg) +-{ +- long fd = (long)arg; ++ if (lstat(path, &st) == 0) ++ r = WWID_IS_FAILED; ++ else if (errno == ENOENT) ++ r = WWID_IS_NOT_FAILED; ++ else ++ r = WWID_FAILED_ERROR; + +- close(fd); +- unlink(shm_lock_path); ++ print_failed_wwid_result("is_failed", wwid, r); ++ return r; + } + +-static int _failed_wwid_op(const char *wwid, bool rw, +- int (*func)(const char *), const char *msg) ++int mark_failed_wwid(const char *wwid) + { + char path[PATH_MAX]; +- long lockfd; +- int r = -1; ++ int r, fd; + + if (safe_sprintf(path, "%s/%s", shm_dir, wwid)) { + condlog(1, "%s: path name overflow", __func__); + return -1; + } +- +- lockfd = multipath_shm_open(rw); +- if (lockfd == -1) ++ if (ensure_directories_exist(path, 0700) < 0) { ++ condlog(1, "%s: can't setup directories", __func__); + return -1; ++ } + +- pthread_cleanup_push(multipath_shm_close, (void *)lockfd); +- r = func(path); +- pthread_cleanup_pop(1); +- +- if (r == WWID_FAILED_ERROR) +- condlog(1, "%s: %s: %s", msg, wwid, strerror(errno)); +- else if (r == WWID_FAILED_CHANGED) +- condlog(3, "%s: %s", msg, wwid); +- else if (!rw) +- condlog(4, "%s: %s is %s", msg, wwid, +- r == WWID_IS_FAILED ? "failed" : "good"); ++ fd = open(path, O_RDONLY | O_CREAT | O_EXCL, S_IRUSR); ++ if (fd >= 0) { ++ close(fd); ++ r = WWID_FAILED_CHANGED; ++ } else if (errno == EEXIST) ++ r = WWID_FAILED_UNCHANGED; ++ else ++ r = WWID_FAILED_ERROR; + ++ print_failed_wwid_result("mark_failed", wwid, r); + return r; + } + +-static int _is_failed(const char *path) ++int unmark_failed_wwid(const char *wwid) + { +- struct stat st; ++ char path[PATH_MAX]; ++ int r; + +- if (lstat(path, &st) == 0) +- return WWID_IS_FAILED; ++ if (safe_sprintf(path, "%s/%s", shm_dir, wwid)) { ++ condlog(1, "%s: path name overflow", __func__); ++ return -1; ++ } ++ ++ if (unlink(path) == 0) ++ r = WWID_FAILED_CHANGED; + else if (errno == ENOENT) +- return WWID_IS_NOT_FAILED; ++ r = WWID_FAILED_UNCHANGED; + else +- return WWID_FAILED_ERROR; +-} +- +-static int _mark_failed(const char *path) +-{ +- /* Called from _failed_wwid_op: we know that shm_lock_path exists */ +- if (_is_failed(path) == WWID_IS_FAILED) +- return WWID_FAILED_UNCHANGED; +- return (link(shm_lock_path, path) == 0 ? WWID_FAILED_CHANGED : +- WWID_FAILED_ERROR); +-} ++ r = WWID_FAILED_ERROR; + +-static int _unmark_failed(const char *path) +-{ +- if (_is_failed(path) == WWID_IS_NOT_FAILED) +- return WWID_FAILED_UNCHANGED; +- return (unlink(path) == 0 ? WWID_FAILED_CHANGED : WWID_FAILED_ERROR); +-} +- +-#define declare_failed_wwid_op(op, rw) \ +-int op ## _wwid(const char *wwid) \ +-{ \ +- return _failed_wwid_op(wwid, (rw), _ ## op, #op); \ ++ print_failed_wwid_result("unmark_failed", wwid, r); ++ return r; + } +- +-declare_failed_wwid_op(is_failed, false) +-declare_failed_wwid_op(mark_failed, true) +-declare_failed_wwid_op(unmark_failed, true) +-- +2.17.2 + diff --git a/0028-libmultipath-fix-null-dereference-int-alloc_path_group.patch b/0028-libmultipath-fix-null-dereference-int-alloc_path_group.patch deleted file mode 100644 index 50e5ac1f137026e51453357bc69ef9bac2c87dd0..0000000000000000000000000000000000000000 --- a/0028-libmultipath-fix-null-dereference-int-alloc_path_group.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 156b75082c7c5d5aa832e500cf4175c3f943fa22 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 9 Oct 2018 18:03:08 -0500 -Subject: [PATCH] libmultipath: fix null dereference int alloc_path_group - -If all_pathgroup failed to allocate a vector for pgp->paths, instead of -failing after it freed pgp, it would set pgp to NULL and then -dereference it. This patch fixes that. Found by coverity. - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/structs.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/structs.c b/libmultipath/structs.c -index ae847d61..caa178a6 100644 ---- a/libmultipath/structs.c -+++ b/libmultipath/structs.c -@@ -165,7 +165,7 @@ alloc_pathgroup (void) - - if (!pgp->paths) { - FREE(pgp); -- pgp = NULL; -+ return NULL; - } - - dm_pathgroup_to_gen(pgp)->ops = &dm_gen_pathgroup_ops; --- -2.11.0 - diff --git a/0028-libmultipath-use-atomic-linkat-in-mark_failed_wwid.patch b/0028-libmultipath-use-atomic-linkat-in-mark_failed_wwid.patch new file mode 100644 index 0000000000000000000000000000000000000000..6b9941a10d2e89dd8a738d33b48e6c2a6145a7f9 --- /dev/null +++ b/0028-libmultipath-use-atomic-linkat-in-mark_failed_wwid.patch @@ -0,0 +1,96 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 19 May 2020 12:08:45 -0500 +Subject: [PATCH] libmultipath: use atomic linkat() in mark_failed_wwid() + +This keeps (almost) the simplicity of the previous patch, while +making sure that the return value of mark_failed_wwid() +(WWID_FAILED_CHANGED vs. WWID_FAILED_UNCHANGED) is correct, even +if several processes access this WWID at the same time. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/wwids.c | 42 +++++++++++++++++++++++++++++------------- + 1 file changed, 29 insertions(+), 13 deletions(-) + +diff --git a/libmultipath/wwids.c b/libmultipath/wwids.c +index aab5da8a..61d9c39e 100644 +--- a/libmultipath/wwids.c ++++ b/libmultipath/wwids.c +@@ -374,7 +374,7 @@ int is_failed_wwid(const char *wwid) + + if (safe_sprintf(path, "%s/%s", shm_dir, wwid)) { + condlog(1, "%s: path name overflow", __func__); +- return -1; ++ return WWID_FAILED_ERROR; + } + + if (lstat(path, &st) == 0) +@@ -390,27 +390,43 @@ int is_failed_wwid(const char *wwid) + + int mark_failed_wwid(const char *wwid) + { +- char path[PATH_MAX]; +- int r, fd; ++ char tmpfile[WWID_SIZE + 2 * sizeof(long) + 1]; ++ int r = WWID_FAILED_ERROR, fd, dfd; + +- if (safe_sprintf(path, "%s/%s", shm_dir, wwid)) { +- condlog(1, "%s: path name overflow", __func__); +- return -1; ++ dfd = open(shm_dir, O_RDONLY|O_DIRECTORY); ++ if (dfd == -1 && errno == ENOENT) { ++ char path[sizeof(shm_dir) + 2]; ++ ++ /* arg for ensure_directories_exist() must not end with "/" */ ++ safe_sprintf(path, "%s/_", shm_dir); ++ ensure_directories_exist(path, 0700); ++ dfd = open(shm_dir, O_RDONLY|O_DIRECTORY); + } +- if (ensure_directories_exist(path, 0700) < 0) { +- condlog(1, "%s: can't setup directories", __func__); +- return -1; ++ if (dfd == -1) { ++ condlog(1, "%s: can't setup %s: %m", __func__, shm_dir); ++ return WWID_FAILED_ERROR; + } + +- fd = open(path, O_RDONLY | O_CREAT | O_EXCL, S_IRUSR); +- if (fd >= 0) { ++ safe_sprintf(tmpfile, "%s.%lx", wwid, (long)getpid()); ++ fd = openat(dfd, tmpfile, O_RDONLY | O_CREAT | O_EXCL, S_IRUSR); ++ if (fd >= 0) + close(fd); ++ else ++ goto out_closedir; ++ ++ if (linkat(dfd, tmpfile, dfd, wwid, 0) == 0) + r = WWID_FAILED_CHANGED; +- } else if (errno == EEXIST) ++ else if (errno == EEXIST) + r = WWID_FAILED_UNCHANGED; + else + r = WWID_FAILED_ERROR; + ++ if (unlinkat(dfd, tmpfile, 0) == -1) ++ condlog(2, "%s: failed to unlink %s/%s: %m", ++ __func__, shm_dir, tmpfile); ++ ++out_closedir: ++ close(dfd); + print_failed_wwid_result("mark_failed", wwid, r); + return r; + } +@@ -422,7 +438,7 @@ int unmark_failed_wwid(const char *wwid) + + if (safe_sprintf(path, "%s/%s", shm_dir, wwid)) { + condlog(1, "%s: path name overflow", __func__); +- return -1; ++ return WWID_FAILED_ERROR; + } + + if (unlink(path) == 0) +-- +2.17.2 + diff --git a/0029-fix-boolean-value-with-json-c-0.14.patch b/0029-fix-boolean-value-with-json-c-0.14.patch new file mode 100644 index 0000000000000000000000000000000000000000..29bb90b9ae1599b659280033beeafc23530f6943 --- /dev/null +++ b/0029-fix-boolean-value-with-json-c-0.14.patch @@ -0,0 +1,41 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: "mail@eworm.de" +Date: Sat, 25 Apr 2020 21:11:13 +0200 +Subject: [PATCH] fix boolean value with json-c 0.14 + +Upstream json-c removed the TRUE and FALSE defines in commit +0992aac61f8b087efd7094e9ac2b84fa9c040fcd. + +[mwilck]: Use stdbool.h, and keep the log message unchanged. + +Signed-off-by: Christian Hesse +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libdmmp/libdmmp_private.h | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/libdmmp/libdmmp_private.h b/libdmmp/libdmmp_private.h +index ac85b63f..b1a6ddea 100644 +--- a/libdmmp/libdmmp_private.h ++++ b/libdmmp/libdmmp_private.h +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include + #include + + #include "libdmmp/libdmmp.h" +@@ -82,7 +83,7 @@ static out_type func_name(struct dmmp_context *ctx, const char *var_name) { \ + do { \ + json_type j_type = json_type_null; \ + json_object *j_obj_tmp = NULL; \ +- if (json_object_object_get_ex(j_obj, key, &j_obj_tmp) != TRUE) { \ ++ if (json_object_object_get_ex(j_obj, key, &j_obj_tmp) != true) { \ + _error(ctx, "Invalid JSON output from multipathd IPC: " \ + "key '%s' not found", key); \ + rc = DMMP_ERR_IPC_ERROR; \ +-- +2.17.2 + diff --git a/0029-multipath-fix-max-array-size-in-print_cmd_valid.patch b/0029-multipath-fix-max-array-size-in-print_cmd_valid.patch deleted file mode 100644 index 4f08d488c24129615ba0b60b36edec5633f98006..0000000000000000000000000000000000000000 --- a/0029-multipath-fix-max-array-size-in-print_cmd_valid.patch +++ /dev/null @@ -1,31 +0,0 @@ -From b25493d8fa13c2d7a346e0b18ad4756aa733ff8d Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 9 Oct 2018 18:03:10 -0500 -Subject: [PATCH] multipath: fix max array size in print_cmd_valid - -The code is attempting to verify that 0 <= k < 3 -However, sizeof(val) is 12, assuming 4 byte integers. The check needs to -take integer size into account. Found by coverity. - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - multipath/main.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/multipath/main.c b/multipath/main.c -index fc5bf169..d5aad952 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -482,7 +482,7 @@ static int print_cmd_valid(int k, const vector pathvec, - struct timespec until; - struct path *pp; - -- if (k < 0 || k >= sizeof(vals)) -+ if (k < 0 || k >= (sizeof(vals) / sizeof(int))) - return 1; - - if (k == 2) { --- -2.11.0 - diff --git a/0030-libmultipath-fix-condlog-NULL-argument-in-uevent_get.patch b/0030-libmultipath-fix-condlog-NULL-argument-in-uevent_get.patch new file mode 100644 index 0000000000000000000000000000000000000000..d8ae27de3c889edc6703e10544491ce1dc7878c3 --- /dev/null +++ b/0030-libmultipath-fix-condlog-NULL-argument-in-uevent_get.patch @@ -0,0 +1,46 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 4 Jun 2020 18:20:06 -0500 +Subject: [PATCH] libmultipath: fix condlog NULL argument in uevent_get_env_var + +uevent_get_env_var() could call condlog with p == NULL. On gcc 10, +this triggers warnings like: + +In file included from uevent.c:47: +In function 'uevent_get_env_var', + inlined from 'uevent_get_wwid' at uevent.c:170:8: +debug.h:13:2: error: '%s' directive argument is null +[-Werror=format-overflow=] + 13 | dlog(logsink, prio, fmt "\n", ##args) + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +uevent.c:132:2: note: in expansion of macro 'condlog' + 132 | condlog(4, "%s: %s -> '%s'", __func__, attr, p); + | ^~~~~~~ +uevent.c: In function 'uevent_get_wwid': +uevent.c:132:25: note: format string is defined here + 132 | condlog(4, "%s: %s -> '%s'", __func__, attr, p); + | ^~ + +If p is NULL, use "(null)" instead. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/uevent.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmultipath/uevent.c b/libmultipath/uevent.c +index d38e8a7f..e0d13b11 100644 +--- a/libmultipath/uevent.c ++++ b/libmultipath/uevent.c +@@ -129,7 +129,7 @@ static const char* uevent_get_env_var(const struct uevent *uev, + } + } + +- condlog(4, "%s: %s -> '%s'", __func__, attr, p); ++ condlog(4, "%s: %s -> '%s'", __func__, attr, p ?: "(null)"); + return p; + + invalid: +-- +2.17.2 + diff --git a/0030-multipathd-minor-fixes.patch b/0030-multipathd-minor-fixes.patch deleted file mode 100644 index 844810e1bc8b387676df1b614172d07a6db6dcc3..0000000000000000000000000000000000000000 --- a/0030-multipathd-minor-fixes.patch +++ /dev/null @@ -1,41 +0,0 @@ -From b31f8f5a21a90fb9087c02e00b6b69934a5bbdd5 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 9 Oct 2018 18:03:12 -0500 -Subject: [PATCH] multipathd: minor fixes - -In update_multipath(), conf is set again in a couple of lines, and -nothing uses it before then, so there's no point in setting it twice. -Also, in ev_remove_path(), strncpy() could end up unterminated, so -use strlcpy() instead. - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index ba796ab1..cd963043 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -429,7 +429,7 @@ int update_multipath (struct vectors *vecs, char *mapname, int reset) - continue; - - if (pp->state != PATH_DOWN) { -- struct config *conf = get_multipath_config(); -+ struct config *conf; - int oldstate = pp->state; - int checkint; - -@@ -1097,7 +1097,7 @@ ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map) - /* - * flush_map will fail if the device is open - */ -- strncpy(alias, mpp->alias, WWID_SIZE); -+ strlcpy(alias, mpp->alias, WWID_SIZE); - if (mpp->flush_on_last_del == FLUSH_ENABLED) { - condlog(2, "%s Last path deleted, disabling queueing", mpp->alias); - mpp->retry_tick = 0; --- -2.11.0 - diff --git a/0031-libmultipath-set-enable_foreign-to-NONE-by-default.patch b/0031-libmultipath-set-enable_foreign-to-NONE-by-default.patch new file mode 100644 index 0000000000000000000000000000000000000000..7d2b8867beaf4883072cdf543557ac8426c6ac3d --- /dev/null +++ b/0031-libmultipath-set-enable_foreign-to-NONE-by-default.patch @@ -0,0 +1,49 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 21 Aug 2019 16:07:12 +0200 +Subject: [PATCH] libmultipath: set "enable_foreign" to NONE by default + +This has been requested by NetApp. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/defaults.h | 4 ++-- + multipath/multipath.conf.5 | 5 +++-- + 2 files changed, 5 insertions(+), 4 deletions(-) + +diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h +index e5ee6afe..01a501bd 100644 +--- a/libmultipath/defaults.h ++++ b/libmultipath/defaults.h +@@ -50,8 +50,8 @@ + #define DEFAULT_FIND_MULTIPATHS_TIMEOUT -10 + #define DEFAULT_UNKNOWN_FIND_MULTIPATHS_TIMEOUT 1 + #define DEFAULT_ALL_TG_PT ALL_TG_PT_OFF +-/* Enable all foreign libraries by default */ +-#define DEFAULT_ENABLE_FOREIGN "" ++/* Enable no foreign libraries by default */ ++#define DEFAULT_ENABLE_FOREIGN "NONE" + + #define CHECKINT_UNDEF UINT_MAX + #define DEFAULT_CHECKINT 5 +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 +index 05a5e8ff..28cea88c 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5 +@@ -1228,10 +1228,11 @@ Enables or disables foreign libraries (see section + .I FOREIGN MULTIPATH SUPPORT + below). The value is a regular expression; foreign libraries are loaded + if their name (e.g. \(dqnvme\(dq) matches the expression. By default, +-all foreign libraries are enabled. ++no foreign libraries are enabled. Set this to \(dqnvme\(dq to enable NVMe native ++multipath support, or \(dq.*\(dq to enable all foreign libraries. + .RS + .TP +-The default is: \fB\(dq\(dq\fR (the empty regular expression) ++The default is: \fB\(dqNONE\(dq\fR + .RE + . + . +-- +2.17.2 + diff --git a/0031-multipathd-fix-memory-leak-on-error-in-configure.patch b/0031-multipathd-fix-memory-leak-on-error-in-configure.patch deleted file mode 100644 index cb94629d5b6f9d35115815dd1fab5d9667377fdb..0000000000000000000000000000000000000000 --- a/0031-multipathd-fix-memory-leak-on-error-in-configure.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 3b8da487d534eb49c8c59d1a9c2d6199c0716572 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 9 Oct 2018 18:03:14 -0500 -Subject: [PATCH] multipathd: fix memory leak on error in configure - -If configure fails after allocing mpvec, it must free it. Found by -coverity. - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 12 ++++++++---- - 1 file changed, 8 insertions(+), 4 deletions(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 463b1b82..04dce04c 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -2278,7 +2278,7 @@ configure (struct vectors * vecs) - ret = path_discovery(vecs->pathvec, DI_ALL); - if (ret < 0) { - condlog(0, "configure failed at path discovery"); -- return 1; -+ goto fail; - } - - vector_foreach_slot (vecs->pathvec, pp, i){ -@@ -2295,7 +2295,7 @@ configure (struct vectors * vecs) - } - if (map_discovery(vecs)) { - condlog(0, "configure failed at map discovery"); -- return 1; -+ goto fail; - } - - /* -@@ -2309,7 +2309,7 @@ configure (struct vectors * vecs) - force_reload = FORCE_RELOAD_YES; - if (ret) { - condlog(0, "configure failed while coalescing paths"); -- return 1; -+ goto fail; - } - - /* -@@ -2318,7 +2318,7 @@ configure (struct vectors * vecs) - */ - if (coalesce_maps(vecs, mpvec)) { - condlog(0, "configure failed while coalescing maps"); -- return 1; -+ goto fail; - } - - dm_lib_release(); -@@ -2354,6 +2354,10 @@ configure (struct vectors * vecs) - i--; - } - return 0; -+ -+fail: -+ vector_free(mpvec); -+ return 1; - } - - int --- -2.11.0 - diff --git a/0032-multipath-add-e-option-to-enable-foreign-libraries.patch b/0032-multipath-add-e-option-to-enable-foreign-libraries.patch new file mode 100644 index 0000000000000000000000000000000000000000..6e07152d073f5c41bfbca60c14e0b37681801399 --- /dev/null +++ b/0032-multipath-add-e-option-to-enable-foreign-libraries.patch @@ -0,0 +1,89 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 2 Mar 2020 22:43:27 +0100 +Subject: [PATCH] multipath: add "-e" option to enable foreign libraries + +As we have set "enable_foreign" to "NONE" now by default, users +may find it useful to be able to switch on foreign multipath display +with an extra command line option even if foreign libraries are +not enabled in multipath.conf. Currently this makes only sense +with "multipath -ll", as the nvme library (and foreign libraries +in general) support only the display of status information. + +Suggested-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/main.c | 11 ++++++++++- + multipath/multipath.8 | 6 ++++++ + 2 files changed, 16 insertions(+), 1 deletion(-) + +diff --git a/multipath/main.c b/multipath/main.c +index 953fab27..c4740fab 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -145,6 +145,7 @@ usage (char * progname) + " -h print this usage text\n" + " -l show multipath topology (sysfs and DM info)\n" + " -ll show multipath topology (maximum info)\n" ++ " -e enable foreign libraries with -l/-ll\n" + " -f flush a multipath device map\n" + " -F flush all multipath device maps\n" + " -a add a device wwid to the wwids file\n" +@@ -865,6 +866,7 @@ main (int argc, char *argv[]) + char *dev = NULL; + struct config *conf; + int retries = -1; ++ bool enable_foreign = false; + + udev = udev_new(); + logsink = 0; +@@ -874,7 +876,7 @@ main (int argc, char *argv[]) + multipath_conf = conf; + conf->retrigger_tries = 0; + conf->force_sync = 1; +- while ((arg = getopt(argc, argv, ":adcChl::FfM:v:p:b:BrR:itTquUwW")) != EOF ) { ++ while ((arg = getopt(argc, argv, ":adcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { + switch(arg) { + case 1: printf("optarg : %s\n",optarg); + break; +@@ -971,6 +973,9 @@ main (int argc, char *argv[]) + case 'R': + retries = atoi(optarg); + break; ++ case 'e': ++ enable_foreign = true; ++ break; + case ':': + fprintf(stderr, "Missing option argument\n"); + usage(argv[0]); +@@ -1022,6 +1027,10 @@ main (int argc, char *argv[]) + condlog(0, "failed to initialize prioritizers"); + goto out; + } ++ ++ if ((cmd == CMD_LIST_SHORT || cmd == CMD_LIST_LONG) && enable_foreign) ++ conf->enable_foreign = ""; ++ + /* Failing here is non-fatal */ + init_foreign(conf->multipath_dir, conf->enable_foreign); + if (cmd == CMD_USABLE_PATHS) { +diff --git a/multipath/multipath.8 b/multipath/multipath.8 +index 9cdd05a3..6fb8645a 100644 +--- a/multipath/multipath.8 ++++ b/multipath/multipath.8 +@@ -223,6 +223,12 @@ The verbosity level also controls the level of log and debug messages printed to + Dry run, do not create or update devmaps. + . + .TP ++.B \-e ++Enable all foreign libraries. This overrides the ++.I enable_foreign ++option from \fBmultipath.conf(5)\fR. ++. ++.TP + .B \-i + Ignore WWIDs file when processing devices. If + \fIfind_multipaths strict\fR or \fIfind_multipaths no\fR is set in +-- +2.17.2 + diff --git a/0032-multipathd-check-for-NULL-udevice-in-cli_add_path.patch b/0032-multipathd-check-for-NULL-udevice-in-cli_add_path.patch deleted file mode 100644 index 801cbaeca97bfc365e2190b0d2e56ed82077d352..0000000000000000000000000000000000000000 --- a/0032-multipathd-check-for-NULL-udevice-in-cli_add_path.patch +++ /dev/null @@ -1,32 +0,0 @@ -From e7a3324274578d63cdef23bb08410df20e0de862 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 10 Oct 2018 13:01:09 -0500 -Subject: [PATCH] multipathd: check for NULL udevice in cli_add_path - -If cli_add_path can't get a udevice for the path, it should fail -immediately, instead of continuing with a NULL udevice, since it will -fail in store_pathinfo() anyway. - -Signed-off-by: Benjamin Marzinski ---- - multipathd/cli_handlers.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c -index bb164726..75000807 100644 ---- a/multipathd/cli_handlers.c -+++ b/multipathd/cli_handlers.c -@@ -720,6 +720,10 @@ cli_add_path (void * v, char ** reply, int * len, void * data) - udevice = udev_device_new_from_subsystem_sysname(udev, - "block", - param); -+ if (!udevice) { -+ condlog(0, "%s: can't find path", param); -+ return 1; -+ } - conf = get_multipath_config(); - pthread_cleanup_push(put_multipath_config, conf); - r = store_pathinfo(vecs->pathvec, conf, --- -2.11.0 - diff --git a/0033-kpartx-fix-apparent-out-of-bounds-access.patch b/0033-kpartx-fix-apparent-out-of-bounds-access.patch deleted file mode 100644 index f0f5db9c8040951c49a8dde673e5d3fcacb58ba4..0000000000000000000000000000000000000000 --- a/0033-kpartx-fix-apparent-out-of-bounds-access.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 2578838d077ecd7f4555e90df019053e7131e151 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 8 Jan 2019 23:54:00 +0100 -Subject: [PATCH] kpartx(coverity): fix apparent out-of-bounds access - -This was a false positive. - -Signed-off-by: Martin Wilck ---- - kpartx/dasd.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/kpartx/dasd.c b/kpartx/dasd.c -index fb358add..61b609a5 100644 ---- a/kpartx/dasd.c -+++ b/kpartx/dasd.c -@@ -190,7 +190,7 @@ read_dasd_pt(int fd, struct slice all, struct slice *sp, int ns) - memcpy (&vlabel, data, sizeof(vlabel)); - else { - bzero(&vlabel,4); -- memcpy (&vlabel.vollbl, data, sizeof(vlabel) - 4); -+ memcpy ((char *)&vlabel + 4, data, sizeof(vlabel) - 4); - } - vtoc_ebcdic_dec(vlabel.vollbl, type, 4); - --- -2.11.0 - diff --git a/0033-libmultipath-remove-_blacklist_exceptions-functions.patch b/0033-libmultipath-remove-_blacklist_exceptions-functions.patch new file mode 100644 index 0000000000000000000000000000000000000000..5fa6539c4c5168d5436ff2edb2bfaa08ead75cbd --- /dev/null +++ b/0033-libmultipath-remove-_blacklist_exceptions-functions.patch @@ -0,0 +1,139 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 9 Jun 2020 16:35:27 -0500 +Subject: [PATCH] libmultipath: remove _blacklist_exceptions functions + +_blacklist_exceptions() and _blacklist_exceptions_device() are exactly +the same as _blacklist() and _blacklist_device(), so remove them, and +give the remaining functions to a more general name. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/blacklist.c | 62 ++++++++++------------------------------ + 1 file changed, 15 insertions(+), 47 deletions(-) + +diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c +index 00e8dbdb..c21a0e27 100644 +--- a/libmultipath/blacklist.c ++++ b/libmultipath/blacklist.c +@@ -101,21 +101,8 @@ int set_ble_device(vector blist, char * vendor, char * product, int origin) + return 0; + } + +-int +-_blacklist_exceptions (vector elist, const char * str) +-{ +- int i; +- struct blentry * ele; +- +- vector_foreach_slot (elist, ele, i) { +- if (!regexec(&ele->regex, str, 0, NULL, 0)) +- return 1; +- } +- return 0; +-} +- +-int +-_blacklist (vector blist, const char * str) ++static int ++match_reglist (vector blist, const char * str) + { + int i; + struct blentry * ble; +@@ -127,28 +114,9 @@ _blacklist (vector blist, const char * str) + return 0; + } + +-int +-_blacklist_exceptions_device(const struct _vector *elist, const char * vendor, +- const char * product) +-{ +- int i; +- struct blentry_device * ble; +- +- vector_foreach_slot (elist, ble, i) { +- if (!ble->vendor && !ble->product) +- continue; +- if ((!ble->vendor || +- !regexec(&ble->vendor_reg, vendor, 0, NULL, 0)) && +- (!ble->product || +- !regexec(&ble->product_reg, product, 0, NULL, 0))) +- return 1; +- } +- return 0; +-} +- +-int +-_blacklist_device (const struct _vector *blist, const char * vendor, +- const char * product) ++static int ++match_reglist_device (const struct _vector *blist, const char * vendor, ++ const char * product) + { + int i; + struct blentry_device * ble; +@@ -300,9 +268,9 @@ filter_device (vector blist, vector elist, char * vendor, char * product, + int r = MATCH_NOTHING; + + if (vendor && product) { +- if (_blacklist_exceptions_device(elist, vendor, product)) ++ if (match_reglist_device(elist, vendor, product)) + r = MATCH_DEVICE_BLIST_EXCEPT; +- else if (_blacklist_device(blist, vendor, product)) ++ else if (match_reglist_device(blist, vendor, product)) + r = MATCH_DEVICE_BLIST; + } + +@@ -316,9 +284,9 @@ filter_devnode (vector blist, vector elist, char * dev) + int r = MATCH_NOTHING; + + if (dev) { +- if (_blacklist_exceptions(elist, dev)) ++ if (match_reglist(elist, dev)) + r = MATCH_DEVNODE_BLIST_EXCEPT; +- else if (_blacklist(blist, dev)) ++ else if (match_reglist(blist, dev)) + r = MATCH_DEVNODE_BLIST; + } + +@@ -332,9 +300,9 @@ filter_wwid (vector blist, vector elist, char * wwid, char * dev) + int r = MATCH_NOTHING; + + if (wwid) { +- if (_blacklist_exceptions(elist, wwid)) ++ if (match_reglist(elist, wwid)) + r = MATCH_WWID_BLIST_EXCEPT; +- else if (_blacklist(blist, wwid)) ++ else if (match_reglist(blist, wwid)) + r = MATCH_WWID_BLIST; + } + +@@ -351,9 +319,9 @@ filter_protocol(vector blist, vector elist, struct path * pp) + if (pp) { + snprint_path_protocol(buf, sizeof(buf), pp); + +- if (_blacklist_exceptions(elist, buf)) ++ if (match_reglist(elist, buf)) + r = MATCH_PROTOCOL_BLIST_EXCEPT; +- else if (_blacklist(blist, buf)) ++ else if (match_reglist(blist, buf)) + r = MATCH_PROTOCOL_BLIST; + } + +@@ -422,11 +390,11 @@ filter_property(struct config *conf, struct udev_device *udev, int lvl, + if (check_missing_prop && !strcmp(env, uid_attribute)) + uid_attr_seen = true; + +- if (_blacklist_exceptions(conf->elist_property, env)) { ++ if (match_reglist(conf->elist_property, env)) { + r = MATCH_PROPERTY_BLIST_EXCEPT; + break; + } +- if (_blacklist(conf->blist_property, env)) { ++ if (match_reglist(conf->blist_property, env)) { + r = MATCH_PROPERTY_BLIST; + break; + } +-- +2.17.2 + diff --git a/0034-libmultipath-fix-apparent-overflow.patch b/0034-libmultipath-fix-apparent-overflow.patch deleted file mode 100644 index 921cea9e12fae4ca8585047c663796e21195a3e8..0000000000000000000000000000000000000000 --- a/0034-libmultipath-fix-apparent-overflow.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 7d30130a5d53629e7c3420aa58018c75fa9dbeef Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 8 Jan 2019 23:54:02 +0100 -Subject: [PATCH] libmultipath(coverity): fix apparent overflow - -"preferred_path" contains always "0" or "1". - -Signed-off-by: Martin Wilck ---- - libmultipath/discovery.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 7f983a63..3fd79a36 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -520,7 +520,7 @@ sysfs_get_asymmetric_access_state(struct path *pp, char *buff, int buflen) - /* Parse error, ignore */ - return 0; - } -- return preferred; -+ return !!preferred; - } - - static void --- -2.11.0 - diff --git a/0034-libmultipath-fix-parser-issue-with-comments-in-strin.patch b/0034-libmultipath-fix-parser-issue-with-comments-in-strin.patch new file mode 100644 index 0000000000000000000000000000000000000000..22cc22cdb250bb6a098e0891cd2f4e3febe2bd2b --- /dev/null +++ b/0034-libmultipath-fix-parser-issue-with-comments-in-strin.patch @@ -0,0 +1,95 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 9 Jun 2020 16:35:28 -0500 +Subject: [PATCH] libmultipath: fix parser issue with comments in strings + +If a quoted string starts with '#' or '!', the parser will stop +parsing the line, thinking that it's a comment. It should only +be checking for comments outside of quoted strings. Fixed this and +added unit tests to verify it. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/parser.c | 4 +++- + tests/parser.c | 42 ++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 45 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/parser.c b/libmultipath/parser.c +index d478b177..11a6168c 100644 +--- a/libmultipath/parser.c ++++ b/libmultipath/parser.c +@@ -300,8 +300,10 @@ alloc_strvec(char *string) + (isspace((int) *cp) || !isascii((int) *cp))) + && *cp != '\0') + cp++; +- if (*cp == '\0' || *cp == '!' || *cp == '#') ++ if (*cp == '\0' || ++ (!in_string && (*cp == '!' || *cp == '#'))) { + return strvec; ++ } + } + out: + vector_free(strvec); +diff --git a/tests/parser.c b/tests/parser.c +index 29859dac..5772391e 100644 +--- a/tests/parser.c ++++ b/tests/parser.c +@@ -440,6 +440,46 @@ static void test18(void **state) + free_strvec(v); + } + ++static void test19(void **state) ++{ ++#define QUOTED19 "!value" ++ vector v = alloc_strvec("key \"" QUOTED19 "\""); ++ char *val; ++ ++ assert_int_equal(VECTOR_SIZE(v), 4); ++ assert_string_equal(VECTOR_SLOT(v, 0), "key"); ++ assert_true(is_quote(VECTOR_SLOT(v, 1))); ++ assert_string_equal(VECTOR_SLOT(v, 2), QUOTED19); ++ assert_true(is_quote(VECTOR_SLOT(v, 3))); ++ assert_int_equal(validate_config_strvec(v, test_file), 0); ++ ++ val = set_value(v); ++ assert_string_equal(val, QUOTED19); ++ ++ free(val); ++ free_strvec(v); ++} ++ ++static void test20(void **state) ++{ ++#define QUOTED20 "#value" ++ vector v = alloc_strvec("key \"" QUOTED20 "\""); ++ char *val; ++ ++ assert_int_equal(VECTOR_SIZE(v), 4); ++ assert_string_equal(VECTOR_SLOT(v, 0), "key"); ++ assert_true(is_quote(VECTOR_SLOT(v, 1))); ++ assert_string_equal(VECTOR_SLOT(v, 2), QUOTED20); ++ assert_true(is_quote(VECTOR_SLOT(v, 3))); ++ assert_int_equal(validate_config_strvec(v, test_file), 0); ++ ++ val = set_value(v); ++ assert_string_equal(val, QUOTED20); ++ ++ free(val); ++ free_strvec(v); ++} ++ + int test_config_parser(void) + { + const struct CMUnitTest tests[] = { +@@ -461,6 +501,8 @@ int test_config_parser(void) + cmocka_unit_test(test16), + cmocka_unit_test(test17), + cmocka_unit_test(test18), ++ cmocka_unit_test(test19), ++ cmocka_unit_test(test20), + }; + return cmocka_run_group_tests(tests, setup, teardown); + } +-- +2.17.2 + diff --git a/0035-libmultipath-fix-int-overflow-in-sysfs_set_scsi_tmo.patch b/0035-libmultipath-fix-int-overflow-in-sysfs_set_scsi_tmo.patch deleted file mode 100644 index 428427114f4d99f4c2dc3a513e6238d18a3576de..0000000000000000000000000000000000000000 --- a/0035-libmultipath-fix-int-overflow-in-sysfs_set_scsi_tmo.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 3044fc0bd953faf71bfa6ebd98f2084f6ae1772b Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 8 Jan 2019 23:54:04 +0100 -Subject: [PATCH] libmultipath(coverity): fix int overflow in - sysfs_set_scsi_tmo - -Signed-off-by: Martin Wilck ---- - libmultipath/discovery.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 3fd79a36..1748eebb 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -711,7 +711,7 @@ sysfs_set_scsi_tmo (struct multipath *mpp, int checkint) - int dev_loss_tmo = mpp->dev_loss; - - if (mpp->no_path_retry > 0) { -- uint64_t no_path_retry_tmo = mpp->no_path_retry * checkint; -+ uint64_t no_path_retry_tmo = (uint64_t)mpp->no_path_retry * checkint; - - if (no_path_retry_tmo > MAX_DEV_LOSS_TMO) - no_path_retry_tmo = MAX_DEV_LOSS_TMO; --- -2.11.0 - diff --git a/0035-libmultipath-invert-regexes-that-start-with-exclamat.patch b/0035-libmultipath-invert-regexes-that-start-with-exclamat.patch new file mode 100644 index 0000000000000000000000000000000000000000..ff1331d92bb2946c4f413c998088e86ac5da9265 --- /dev/null +++ b/0035-libmultipath-invert-regexes-that-start-with-exclamat.patch @@ -0,0 +1,435 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 9 Jun 2020 16:35:29 -0500 +Subject: [PATCH] libmultipath: invert regexes that start with exclamation + point + +The number of devices that multipath needs to blacklist keeps growing, +and the udev rules already have + +KERNEL!="sd*|dasd*|nvme*", GOTO="end_mpath" + +so they only work correctly with these device types. Instead of +individually blacklisting every type of device that can't be +multipathed, multipath's default blacklist should work like the udev +rule, and blacklist all devices that aren't scsi, dasd, or nvme. +Unfortunately, the c regex library doesn't support negative lookahead. +Instead, multipath should treat "!" at the beginning of +blacklist/exceptions regexes as inverse matching the rest of the regex. +If users need to match a literal '!' as the first character of their +regex, they can use "\!" instead. This allows multipath to change the +default devnode blacklist regex to "!^(sd[a-z]|dasd[a-z]|nvme[0-9])". + +Extra tests have been added to the blacklist unit tests to verify the +inverse matching code and the new default blacklist. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/blacklist.c | 41 +++++++++----- + libmultipath/blacklist.h | 3 + + multipath/multipath.conf.5 | 17 ++++-- + tests/blacklist.c | 110 +++++++++++++++++++++++++++++++++++++ + tests/test-lib.c | 2 +- + 5 files changed, 155 insertions(+), 18 deletions(-) + +diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c +index c21a0e27..db58ccca 100644 +--- a/libmultipath/blacklist.c ++++ b/libmultipath/blacklist.c +@@ -15,9 +15,24 @@ + #include "structs_vec.h" + #include "print.h" + ++char *check_invert(char *str, bool *invert) ++{ ++ if (str[0] == '!') { ++ *invert = true; ++ return str + 1; ++ } ++ if (str[0] == '\\' && str[1] == '!') { ++ *invert = false; ++ return str + 1; ++ } ++ *invert = false; ++ return str; ++} ++ + int store_ble(vector blist, char * str, int origin) + { + struct blentry * ble; ++ char *regex_str; + + if (!str) + return 0; +@@ -30,7 +45,8 @@ int store_ble(vector blist, char * str, int origin) + if (!ble) + goto out; + +- if (regcomp(&ble->regex, str, REG_EXTENDED|REG_NOSUB)) ++ regex_str = check_invert(str, &ble->invert); ++ if (regcomp(&ble->regex, regex_str, REG_EXTENDED|REG_NOSUB)) + goto out1; + + if (!vector_alloc_slot(blist)) +@@ -66,6 +82,7 @@ int alloc_ble_device(vector blist) + int set_ble_device(vector blist, char * vendor, char * product, int origin) + { + struct blentry_device * ble; ++ char *regex_str; + + if (!blist) + return 1; +@@ -76,7 +93,8 @@ int set_ble_device(vector blist, char * vendor, char * product, int origin) + return 1; + + if (vendor) { +- if (regcomp(&ble->vendor_reg, vendor, ++ regex_str = check_invert(vendor, &ble->vendor_invert); ++ if (regcomp(&ble->vendor_reg, regex_str, + REG_EXTENDED|REG_NOSUB)) { + FREE(vendor); + if (product) +@@ -86,7 +104,8 @@ int set_ble_device(vector blist, char * vendor, char * product, int origin) + ble->vendor = vendor; + } + if (product) { +- if (regcomp(&ble->product_reg, product, ++ regex_str = check_invert(product, &ble->product_invert); ++ if (regcomp(&ble->product_reg, regex_str, + REG_EXTENDED|REG_NOSUB)) { + FREE(product); + if (vendor) { +@@ -108,7 +127,7 @@ match_reglist (vector blist, const char * str) + struct blentry * ble; + + vector_foreach_slot (blist, ble, i) { +- if (!regexec(&ble->regex, str, 0, NULL, 0)) ++ if (!!regexec(&ble->regex, str, 0, NULL, 0) == ble->invert) + return 1; + } + return 0; +@@ -125,9 +144,11 @@ match_reglist_device (const struct _vector *blist, const char * vendor, + if (!ble->vendor && !ble->product) + continue; + if ((!ble->vendor || +- !regexec(&ble->vendor_reg, vendor, 0, NULL, 0)) && ++ !!regexec(&ble->vendor_reg, vendor, 0, NULL, 0) == ++ ble->vendor_invert) && + (!ble->product || +- !regexec(&ble->product_reg, product, 0, NULL, 0))) ++ !!regexec(&ble->product_reg, product, 0, NULL, 0) == ++ ble->product_invert)) + return 1; + } + return 0; +@@ -160,13 +181,7 @@ setup_default_blist (struct config * conf) + char * str; + int i; + +- str = STRDUP("^(ram|zram|raw|loop|fd|md|dm-|sr|scd|st|dcssblk)[0-9]"); +- if (!str) +- return 1; +- if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT)) +- return 1; +- +- str = STRDUP("^(td|hd|vd)[a-z]"); ++ str = STRDUP("!^(sd[a-z]|dasd[a-z]|nvme[0-9])"); + if (!str) + return 1; + if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT)) +diff --git a/libmultipath/blacklist.h b/libmultipath/blacklist.h +index 2d721f60..4305857d 100644 +--- a/libmultipath/blacklist.h ++++ b/libmultipath/blacklist.h +@@ -20,6 +20,7 @@ + struct blentry { + char * str; + regex_t regex; ++ bool invert; + int origin; + }; + +@@ -28,6 +29,8 @@ struct blentry_device { + char * product; + regex_t vendor_reg; + regex_t product_reg; ++ bool vendor_invert; ++ bool product_invert; + int origin; + }; + +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 +index 28cea88c..5adaced6 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5 +@@ -1249,6 +1249,16 @@ being handled by multipath-tools. + .LP + . + . ++In the \fIblacklist\fR and \fIblacklist_exceptions\fR sections, starting a ++quoted value with an exclamation mark \fB"!"\fR will invert the matching ++of the rest of the regular expression. For instance, \fB"!^sd[a-z]"\fR will ++match all values that do not start with \fB"sd[a-z]"\fR. The exclamation mark ++can be escaped \fB"\\!"\fR to match a literal \fB!\fR at the start of a ++regular expression. \fBNote:\fR The exclamation mark must be inside quotes, ++otherwise it will be treated as starting a comment. ++.LP ++. ++. + The \fIblacklist_exceptions\fR section is used to revert the actions of the + \fIblacklist\fR section. This allows one to selectively include ("whitelist") devices which + would normally be excluded via the \fIblacklist\fR section. A common usage is +@@ -1265,10 +1275,9 @@ unless explicitly stated. + Regular expression matching the device nodes to be excluded/included. + .RS + .PP +-The default \fIblacklist\fR consists of the regular expressions +-"^(ram|zram|raw|loop|fd|md|dm-|sr|scd|st|dcssblk)[0-9]" and +-"^(td|hd|vd)[a-z]". This causes virtual devices, non-disk devices, and some other +-device types to be excluded from multipath handling by default. ++The default \fIblacklist\fR consists of the regular expression ++\fB"!^(sd[a-z]|dasd[a-z]|nvme[0-9])"\fR. This causes all device types other ++than scsi, dasd, and nvme to be excluded from multipath handling by default. + .RE + .TP + .B wwid +diff --git a/tests/blacklist.c b/tests/blacklist.c +index 6e7c1864..d5c40898 100644 +--- a/tests/blacklist.c ++++ b/tests/blacklist.c +@@ -60,20 +60,46 @@ __wrap_udev_list_entry_get_name(struct udev_list_entry *list_entry) + return *(const char **)list_entry; + } + ++vector elist_property_default; ++vector blist_devnode_default; + vector blist_devnode_sdb; ++vector blist_devnode_sdb_inv; + vector blist_all; + vector blist_device_foo_bar; ++vector blist_device_foo_inv_bar; ++vector blist_device_foo_bar_inv; + vector blist_device_all; + vector blist_wwid_xyzzy; ++vector blist_wwid_xyzzy_inv; + vector blist_protocol_fcp; ++vector blist_protocol_fcp_inv; + vector blist_property_wwn; ++vector blist_property_wwn_inv; + + static int setup(void **state) + { ++ struct config conf; ++ ++ memset(&conf, 0, sizeof(conf)); ++ conf.blist_devnode = vector_alloc(); ++ if (!conf.blist_devnode) ++ return -1; ++ conf.elist_property = vector_alloc(); ++ if (!conf.elist_property) ++ return -1; ++ if (setup_default_blist(&conf) != 0) ++ return -1; ++ elist_property_default = conf.elist_property; ++ blist_devnode_default = conf.blist_devnode; ++ + blist_devnode_sdb = vector_alloc(); + if (!blist_devnode_sdb || + store_ble(blist_devnode_sdb, strdup("sdb"), ORIGIN_CONFIG)) + return -1; ++ blist_devnode_sdb_inv = vector_alloc(); ++ if (!blist_devnode_sdb_inv || ++ store_ble(blist_devnode_sdb_inv, strdup("!sdb"), ORIGIN_CONFIG)) ++ return -1; + + blist_all = vector_alloc(); + if (!blist_all || store_ble(blist_all, strdup(".*"), ORIGIN_CONFIG)) +@@ -84,6 +110,18 @@ static int setup(void **state) + set_ble_device(blist_device_foo_bar, strdup("foo"), strdup("bar"), + ORIGIN_CONFIG)) + return -1; ++ blist_device_foo_inv_bar = vector_alloc(); ++ if (!blist_device_foo_inv_bar || ++ alloc_ble_device(blist_device_foo_inv_bar) || ++ set_ble_device(blist_device_foo_inv_bar, strdup("!foo"), ++ strdup("bar"), ORIGIN_CONFIG)) ++ return -1; ++ blist_device_foo_bar_inv = vector_alloc(); ++ if (!blist_device_foo_bar_inv || ++ alloc_ble_device(blist_device_foo_bar_inv) || ++ set_ble_device(blist_device_foo_bar_inv, strdup("foo"), ++ strdup("!bar"), ORIGIN_CONFIG)) ++ return -1; + + blist_device_all = vector_alloc(); + if (!blist_device_all || alloc_ble_device(blist_device_all) || +@@ -95,29 +133,50 @@ static int setup(void **state) + if (!blist_wwid_xyzzy || + store_ble(blist_wwid_xyzzy, strdup("xyzzy"), ORIGIN_CONFIG)) + return -1; ++ blist_wwid_xyzzy_inv = vector_alloc(); ++ if (!blist_wwid_xyzzy_inv || ++ store_ble(blist_wwid_xyzzy_inv, strdup("!xyzzy"), ORIGIN_CONFIG)) ++ return -1; + + blist_protocol_fcp = vector_alloc(); + if (!blist_protocol_fcp || + store_ble(blist_protocol_fcp, strdup("scsi:fcp"), ORIGIN_CONFIG)) + return -1; ++ blist_protocol_fcp_inv = vector_alloc(); ++ if (!blist_protocol_fcp_inv || ++ store_ble(blist_protocol_fcp_inv, strdup("!scsi:fcp"), ++ ORIGIN_CONFIG)) ++ return -1; + + blist_property_wwn = vector_alloc(); + if (!blist_property_wwn || + store_ble(blist_property_wwn, strdup("ID_WWN"), ORIGIN_CONFIG)) + return -1; ++ blist_property_wwn_inv = vector_alloc(); ++ if (!blist_property_wwn_inv || ++ store_ble(blist_property_wwn_inv, strdup("!ID_WWN"), ORIGIN_CONFIG)) ++ return -1; + + return 0; + } + + static int teardown(void **state) + { ++ free_blacklist(elist_property_default); ++ free_blacklist(blist_devnode_default); + free_blacklist(blist_devnode_sdb); ++ free_blacklist(blist_devnode_sdb_inv); + free_blacklist(blist_all); + free_blacklist_device(blist_device_foo_bar); ++ free_blacklist_device(blist_device_foo_inv_bar); ++ free_blacklist_device(blist_device_foo_bar_inv); + free_blacklist_device(blist_device_all); + free_blacklist(blist_wwid_xyzzy); ++ free_blacklist(blist_wwid_xyzzy_inv); + free_blacklist(blist_protocol_fcp); ++ free_blacklist(blist_protocol_fcp_inv); + free_blacklist(blist_property_wwn); ++ free_blacklist(blist_property_wwn_inv); + return 0; + } + +@@ -141,6 +200,11 @@ static void test_devnode_blacklist(void **state) + expect_condlog(3, "sdb: device node name blacklisted\n"); + assert_int_equal(filter_devnode(blist_devnode_sdb, NULL, "sdb"), + MATCH_DEVNODE_BLIST); ++ assert_int_equal(filter_devnode(blist_devnode_sdb_inv, NULL, "sdb"), ++ MATCH_NOTHING); ++ expect_condlog(3, "sdc: device node name blacklisted\n"); ++ assert_int_equal(filter_devnode(blist_devnode_sdb_inv, NULL, "sdc"), ++ MATCH_DEVNODE_BLIST); + } + + static void test_devnode_whitelist(void **state) +@@ -159,12 +223,39 @@ static void test_devnode_missing(void **state) + MATCH_NOTHING); + } + ++static void test_devnode_default(void **state) ++{ ++ assert_int_equal(filter_devnode(blist_devnode_default, NULL, "sdaa"), ++ MATCH_NOTHING); ++ assert_int_equal(filter_devnode(blist_devnode_default, NULL, "nvme0n1"), ++ MATCH_NOTHING); ++ assert_int_equal(filter_devnode(blist_devnode_default, NULL, "dasda"), ++ MATCH_NOTHING); ++ expect_condlog(3, "hda: device node name blacklisted\n"); ++ assert_int_equal(filter_devnode(blist_devnode_default, NULL, "hda"), ++ MATCH_DEVNODE_BLIST); ++} ++ + static void test_device_blacklist(void **state) + { + expect_condlog(3, "sdb: (foo:bar) vendor/product blacklisted\n"); + assert_int_equal(filter_device(blist_device_foo_bar, NULL, "foo", + "bar", "sdb"), + MATCH_DEVICE_BLIST); ++ assert_int_equal(filter_device(blist_device_foo_inv_bar, NULL, "foo", ++ "bar", "sdb"), ++ MATCH_NOTHING); ++ assert_int_equal(filter_device(blist_device_foo_bar_inv, NULL, "foo", ++ "bar", "sdb"), ++ MATCH_NOTHING); ++ expect_condlog(3, "sdb: (baz:bar) vendor/product blacklisted\n"); ++ assert_int_equal(filter_device(blist_device_foo_inv_bar, NULL, "baz", ++ "bar", "sdb"), ++ MATCH_DEVICE_BLIST); ++ expect_condlog(3, "sdb: (foo:baz) vendor/product blacklisted\n"); ++ assert_int_equal(filter_device(blist_device_foo_bar_inv, NULL, "foo", ++ "baz", "sdb"), ++ MATCH_DEVICE_BLIST); + } + + static void test_device_whitelist(void **state) +@@ -191,6 +282,11 @@ static void test_wwid_blacklist(void **state) + expect_condlog(3, "sdb: wwid xyzzy blacklisted\n"); + assert_int_equal(filter_wwid(blist_wwid_xyzzy, NULL, "xyzzy", "sdb"), + MATCH_WWID_BLIST); ++ assert_int_equal(filter_wwid(blist_wwid_xyzzy_inv, NULL, "xyzzy", ++ "sdb"), MATCH_NOTHING); ++ expect_condlog(3, "sdb: wwid plugh blacklisted\n"); ++ assert_int_equal(filter_wwid(blist_wwid_xyzzy_inv, NULL, "plugh", ++ "sdb"), MATCH_WWID_BLIST); + } + + static void test_wwid_whitelist(void **state) +@@ -218,6 +314,12 @@ static void test_protocol_blacklist(void **state) + expect_condlog(3, "sdb: protocol scsi:fcp blacklisted\n"); + assert_int_equal(filter_protocol(blist_protocol_fcp, NULL, &pp), + MATCH_PROTOCOL_BLIST); ++ assert_int_equal(filter_protocol(blist_protocol_fcp_inv, NULL, &pp), ++ MATCH_NOTHING); ++ pp.sg_id.proto_id = SCSI_PROTOCOL_ATA; ++ expect_condlog(3, "sdb: protocol scsi:ata blacklisted\n"); ++ assert_int_equal(filter_protocol(blist_protocol_fcp_inv, NULL, &pp), ++ MATCH_PROTOCOL_BLIST); + } + + static void test_protocol_whitelist(void **state) +@@ -245,10 +347,17 @@ static void test_protocol_missing(void **state) + static void test_property_blacklist(void **state) + { + static struct udev_device udev = { "sdb", { "ID_FOO", "ID_WWN", "ID_BAR", NULL } }; ++ static struct udev_device udev_inv = { "sdb", { "ID_WWN", NULL } }; + conf.blist_property = blist_property_wwn; + expect_condlog(3, "sdb: udev property ID_WWN blacklisted\n"); + assert_int_equal(filter_property(&conf, &udev, 3, "ID_SERIAL"), + MATCH_PROPERTY_BLIST); ++ conf.blist_property = blist_property_wwn_inv; ++ expect_condlog(3, "sdb: udev property ID_FOO blacklisted\n"); ++ assert_int_equal(filter_property(&conf, &udev, 3, "ID_SERIAL"), ++ MATCH_PROPERTY_BLIST); ++ assert_int_equal(filter_property(&conf, &udev_inv, 3, "ID_SERIAL"), ++ MATCH_NOTHING); + } + + /* the property check works different in that you check all the property +@@ -484,6 +593,7 @@ int test_blacklist(void) + cmocka_unit_test(test_devnode_blacklist), + cmocka_unit_test(test_devnode_whitelist), + cmocka_unit_test(test_devnode_missing), ++ cmocka_unit_test(test_devnode_default), + cmocka_unit_test(test_device_blacklist), + cmocka_unit_test(test_device_whitelist), + cmocka_unit_test(test_device_missing), +diff --git a/tests/test-lib.c b/tests/test-lib.c +index 00bae58e..b7c09cc2 100644 +--- a/tests/test-lib.c ++++ b/tests/test-lib.c +@@ -15,7 +15,7 @@ + #include "test-lib.h" + + const int default_mask = (DI_SYSFS|DI_BLACKLIST|DI_WWID|DI_CHECKER|DI_PRIO); +-const char default_devnode[] = "sdTEST"; ++const char default_devnode[] = "sdxTEST"; + const char default_wwid[] = "TEST-WWID"; + /* default_wwid should be a substring of default_wwid_1! */ + const char default_wwid_1[] = "TEST-WWID-1"; +-- +2.17.2 + diff --git a/0036-libmultipath-fix-enum-misuse-for-find_multipaths.patch b/0036-libmultipath-fix-enum-misuse-for-find_multipaths.patch deleted file mode 100644 index 05c3b2c68dd8ae6b7be7b746257e73b0e9cece3b..0000000000000000000000000000000000000000 --- a/0036-libmultipath-fix-enum-misuse-for-find_multipaths.patch +++ /dev/null @@ -1,26 +0,0 @@ -From fb87e6e9d5778c9b2874496ff6e44c0001a3c228 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 8 Jan 2019 23:54:05 +0100 -Subject: [PATCH] libmultipath(coverity): fix "enum misuse" for find_multipaths - -Signed-off-by: Martin Wilck ---- - libmultipath/dict.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index fd29abca..eaad4f18 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -327,7 +327,7 @@ def_find_multipaths_handler(struct config *conf, vector strvec) - int i; - - if (set_yes_no_undef(strvec, &conf->find_multipaths) == 0 && -- conf->find_multipaths != YNU_UNDEF) -+ conf->find_multipaths != FIND_MULTIPATHS_UNDEF) - return 0; - - buff = set_value(strvec); --- -2.11.0 - diff --git a/0036-multipath-Fix-compiler-warnings-when-built-without-s.patch b/0036-multipath-Fix-compiler-warnings-when-built-without-s.patch new file mode 100644 index 0000000000000000000000000000000000000000..f631fdb1fe3732abcdc58e7506c394e07de500a8 --- /dev/null +++ b/0036-multipath-Fix-compiler-warnings-when-built-without-s.patch @@ -0,0 +1,111 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Marius Bakke +Date: Wed, 17 Jun 2020 01:11:26 +0200 +Subject: [PATCH] multipath: Fix compiler warnings when built without systemd. + +Add ifdef guards for code that is unused when systemd is not available. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/config.c | 6 ++++-- + multipathd/main.c | 10 +++++++++- + 2 files changed, 13 insertions(+), 3 deletions(-) + +diff --git a/libmultipath/config.c b/libmultipath/config.c +index b4d87689..658bec8b 100644 +--- a/libmultipath/config.c ++++ b/libmultipath/config.c +@@ -696,9 +696,9 @@ process_config_dir(struct config *conf, char *dir) + pthread_cleanup_pop(1); + } + ++#ifdef USE_SYSTEMD + static void set_max_checkint_from_watchdog(struct config *conf) + { +-#ifdef USE_SYSTEMD + char *envp = getenv("WATCHDOG_USEC"); + unsigned long checkint; + +@@ -714,8 +714,8 @@ static void set_max_checkint_from_watchdog(struct config *conf) + condlog(3, "enabling watchdog, interval %ld", checkint); + conf->use_watchdog = true; + } +-#endif + } ++#endif + + struct config * + load_config (char * file) +@@ -789,7 +789,9 @@ load_config (char * file) + /* + * fill the voids left in the config file + */ ++#ifdef USE_SYSTEMD + set_max_checkint_from_watchdog(conf); ++#endif + if (conf->max_checkint == 0) { + if (conf->checkint == CHECKINT_UNDEF) + conf->checkint = DEFAULT_CHECKINT; +diff --git a/multipathd/main.c b/multipathd/main.c +index 6b7db2c0..205ddb32 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -176,6 +176,7 @@ daemon_status(void) + /* + * I love you too, systemd ... + */ ++#ifdef USE_SYSTEMD + static const char * + sd_notify_status(enum daemon_status state) + { +@@ -195,7 +196,6 @@ sd_notify_status(enum daemon_status state) + return NULL; + } + +-#ifdef USE_SYSTEMD + static void do_sd_notify(enum daemon_status old_state, + enum daemon_status new_state) + { +@@ -247,7 +247,9 @@ enum daemon_status wait_for_state_change_if(enum daemon_status oldstate, + static void __post_config_state(enum daemon_status state) + { + if (state != running_state && running_state != DAEMON_SHUTDOWN) { ++#ifdef USE_SYSTEMD + enum daemon_status old_state = running_state; ++#endif + + running_state = state; + pthread_cond_broadcast(&config_cond); +@@ -272,7 +274,9 @@ int set_config_state(enum daemon_status state) + pthread_cleanup_push(config_cleanup, NULL); + pthread_mutex_lock(&config_lock); + if (running_state != state) { ++#ifdef USE_SYSTEMD + enum daemon_status old_state = running_state; ++#endif + + if (running_state == DAEMON_SHUTDOWN) + rc = EINVAL; +@@ -2280,7 +2284,9 @@ checkerloop (void *ap) + struct timespec last_time; + struct config *conf; + int foreign_tick = 0; ++#ifdef USE_SYSTEMD + bool use_watchdog; ++#endif + + pthread_cleanup_push(rcu_unregister, NULL); + rcu_register_thread(); +@@ -2294,7 +2300,9 @@ checkerloop (void *ap) + + /* use_watchdog is set from process environment and never changes */ + conf = get_multipath_config(); ++#ifdef USE_SYSTEMD + use_watchdog = conf->use_watchdog; ++#endif + put_multipath_config(conf); + + while (1) { +-- +2.17.2 + diff --git a/0037-libmultipath-fix-possible-NULL-dereference.patch b/0037-libmultipath-fix-possible-NULL-dereference.patch deleted file mode 100644 index b21fbf79293d429dc84633d338aaf58f747c1b62..0000000000000000000000000000000000000000 --- a/0037-libmultipath-fix-possible-NULL-dereference.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 7ec04256a56709963e8b954fc6036ca6ba1db137 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 8 Jan 2019 23:54:09 +0100 -Subject: [PATCH] libmultipath(coverity): fix possible NULL dereference - -coverity warns that recv_packet may set reply to NULL. - -Signed-off-by: Martin Wilck ---- - libmultipath/configure.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 39d2a956..af4d78de 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -1041,7 +1041,7 @@ int check_daemon(void) - if (recv_packet(fd, &reply, timeout) != 0) - goto out; - -- if (strstr(reply, "shutdown")) -+ if (reply && strstr(reply, "shutdown")) - goto out_free; - - ret = 1; --- -2.11.0 - diff --git a/0037-libmultipath-fix-sysfs-dev_loss_tmo-parsing.patch b/0037-libmultipath-fix-sysfs-dev_loss_tmo-parsing.patch new file mode 100644 index 0000000000000000000000000000000000000000..0888750229c2d60e6e3ed155175463f417be8b71 --- /dev/null +++ b/0037-libmultipath-fix-sysfs-dev_loss_tmo-parsing.patch @@ -0,0 +1,43 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 2 Jul 2020 19:38:24 -0500 +Subject: [PATCH] libmultipath: fix sysfs dev_loss_tmo parsing + +dev_loss_tmo is a u32 value. However the kernel sysfs code prints it as +a signed integer. This means that if dev_loss_tmo is above INT_MAX, the +sysfs value will be a negative number. Parsing this was causing +sysfs_set_rport_tmo() to fail. + +Signed-off-by: Benjamin Marzinski +Signed-off-by: Martin Wilck +--- + libmultipath/discovery.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index ffec5162..83a41a4a 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -583,7 +583,7 @@ sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp) + struct udev_device *rport_dev = NULL; + char value[16], *eptr; + char rport_id[32]; +- unsigned long long tmo = 0; ++ unsigned int tmo; + int ret; + + sprintf(rport_id, "rport-%d:%d-%d", +@@ -607,8 +607,8 @@ sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp) + "error %d", rport_id, -ret); + goto out; + } +- tmo = strtoull(value, &eptr, 0); +- if (value == eptr || tmo == ULLONG_MAX) { ++ tmo = strtoul(value, &eptr, 0); ++ if (value == eptr) { + condlog(0, "%s: Cannot parse dev_loss_tmo " + "attribute '%s'", rport_id, value); + goto out; +-- +2.17.2 + diff --git a/0038-fix-syntax-error.patch b/0038-fix-syntax-error.patch deleted file mode 100644 index 8a4f6d5d8204de82e25d18a2ce63d09a4234c718..0000000000000000000000000000000000000000 --- a/0038-fix-syntax-error.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 8e4c5a421ee351fe667b0bf8b99e691ab5c9c13b Mon Sep 17 00:00:00 2001 -From: wangjufeng -Date: Fri, 1 Nov 2019 16:48:49 +0800 -Subject: [PATCH] fix syntax error - ---- - Makefile.inc | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 5ff69a3..3744aa4 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -40,7 +40,7 @@ endif - - ifndef SYSTEMD - ifeq ($(shell systemctl --version > /dev/null 2>&1 && echo 1), 1) -- SYSTEMD = $(shell systemctl --version 2> /dev/null | sed -n 's/systemd \([0-9]*\)/\1/p') -+ SYSTEMD = $(shell systemctl --version 2> /dev/null | sed -n 's/systemd\([0-9]*\)/\1/p' | awk '{print $$1}') - endif - endif - --- -2.19.1 - diff --git a/0038-kpartx-read-devices-with-direct-IO.patch b/0038-kpartx-read-devices-with-direct-IO.patch new file mode 100644 index 0000000000000000000000000000000000000000..eaa91c38c2d28aec867307901deef205520c4367 --- /dev/null +++ b/0038-kpartx-read-devices-with-direct-IO.patch @@ -0,0 +1,267 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 2 Jul 2020 19:38:25 -0500 +Subject: [PATCH] kpartx: read devices with direct IO + +If kpartx is used on top of shared storage, and a device has its +partition table changed on one machine, and then kpartx is run on +another, it may not see the new data, because the cache still contains +the old data, and there is nothing to tell the machine running kpartx to +invalidate it. To solve this, kpartx should read the devices using +direct io. + +One issue with how this code has been updated is that the original code +for getblock() always read 1024 bytes. The new code reads a logical +sector size chunk of the device, and returns a pointer to the 512 byte +sector that the caller asked for, within that (possibly larger) chunk. +This means that if the logical sector size is 512, then the code is now +only reading 512 bytes. Looking through the code for the various +partition types, I can't see a case where more than 512 bytes is needed +and getblock() is used. If anyone has a reason why this code should be +reading 1024 bytes at minmum, I can certainly change this. But when I +looked, I couldn't find a case where reading 512 bytes would cause a +problem. + +Signed-off-by: Benjamin Marzinski +--- + kpartx/dasd.c | 7 ++++--- + kpartx/gpt.c | 22 +++++++++---------- + kpartx/kpartx.c | 56 +++++++++++++++++++++++++++++++++++++++---------- + kpartx/kpartx.h | 2 ++ + 4 files changed, 61 insertions(+), 26 deletions(-) + +diff --git a/kpartx/dasd.c b/kpartx/dasd.c +index 14b9d3aa..f0398645 100644 +--- a/kpartx/dasd.c ++++ b/kpartx/dasd.c +@@ -22,6 +22,7 @@ + * along with this program. If not, see . + */ + ++#define _GNU_SOURCE + #include + #include + #include +@@ -117,13 +118,13 @@ read_dasd_pt(int fd, __attribute__((unused)) struct slice all, + + sprintf(pathname, "/dev/.kpartx-node-%u-%u", + (unsigned int)major(dev), (unsigned int)minor(dev)); +- if ((fd_dasd = open(pathname, O_RDONLY)) == -1) { ++ if ((fd_dasd = open(pathname, O_RDONLY | O_DIRECT)) == -1) { + /* Devicenode does not exist. Try to create one */ + if (mknod(pathname, 0600 | S_IFBLK, dev) == -1) { + /* Couldn't create a device node */ + return -1; + } +- fd_dasd = open(pathname, O_RDONLY); ++ fd_dasd = open(pathname, O_RDONLY | O_DIRECT); + /* + * The file will vanish when the last process (we) + * has ceased to access it. +@@ -175,7 +176,7 @@ read_dasd_pt(int fd, __attribute__((unused)) struct slice all, + * Get volume label, extract name and type. + */ + +- if (!(data = (unsigned char *)malloc(blocksize))) ++ if (aligned_malloc((void **)&data, blocksize, NULL)) + goto out; + + +diff --git a/kpartx/gpt.c b/kpartx/gpt.c +index 785b34ea..f7fefb70 100644 +--- a/kpartx/gpt.c ++++ b/kpartx/gpt.c +@@ -243,8 +243,7 @@ alloc_read_gpt_entries(int fd, gpt_header * gpt) + + if (!count) return NULL; + +- pte = (gpt_entry *)malloc(count); +- if (!pte) ++ if (aligned_malloc((void **)&pte, get_sector_size(fd), &count)) + return NULL; + memset(pte, 0, count); + +@@ -269,12 +268,11 @@ static gpt_header * + alloc_read_gpt_header(int fd, uint64_t lba) + { + gpt_header *gpt; +- gpt = (gpt_header *) +- malloc(sizeof (gpt_header)); +- if (!gpt) ++ size_t size = sizeof (gpt_header); ++ if (aligned_malloc((void **)&gpt, get_sector_size(fd), &size)) + return NULL; +- memset(gpt, 0, sizeof (*gpt)); +- if (!read_lba(fd, lba, gpt, sizeof (gpt_header))) { ++ memset(gpt, 0, size); ++ if (!read_lba(fd, lba, gpt, size)) { + free(gpt); + return NULL; + } +@@ -498,6 +496,7 @@ find_valid_gpt(int fd, gpt_header ** gpt, gpt_entry ** ptes) + gpt_header *pgpt = NULL, *agpt = NULL; + gpt_entry *pptes = NULL, *aptes = NULL; + legacy_mbr *legacymbr = NULL; ++ size_t size = sizeof(legacy_mbr); + uint64_t lastlba; + if (!gpt || !ptes) + return 0; +@@ -526,11 +525,10 @@ find_valid_gpt(int fd, gpt_header ** gpt, gpt_entry ** ptes) + } + + /* This will be added to the EFI Spec. per Intel after v1.02. */ +- legacymbr = malloc(sizeof (*legacymbr)); +- if (legacymbr) { +- memset(legacymbr, 0, sizeof (*legacymbr)); +- read_lba(fd, 0, (uint8_t *) legacymbr, +- sizeof (*legacymbr)); ++ if (aligned_malloc((void **)&legacymbr, get_sector_size(fd), ++ &size) == 0) { ++ memset(legacymbr, 0, size); ++ read_lba(fd, 0, (uint8_t *) legacymbr, size); + good_pmbr = is_pmbr_valid(legacymbr); + free(legacymbr); + legacymbr=NULL; +diff --git a/kpartx/kpartx.c b/kpartx/kpartx.c +index d3620c5c..c24ad6d9 100644 +--- a/kpartx/kpartx.c ++++ b/kpartx/kpartx.c +@@ -19,6 +19,7 @@ + * cva, 2002-10-26 + */ + ++#define _GNU_SOURCE + #include + #include + #include +@@ -41,7 +42,6 @@ + + #define SIZE(a) (sizeof(a)/sizeof((a)[0])) + +-#define READ_SIZE 1024 + #define MAXTYPES 64 + #define MAXSLICES 256 + #define DM_TARGET "linear" +@@ -388,7 +388,7 @@ main(int argc, char **argv){ + set_delimiter(mapname, delim); + } + +- fd = open(device, O_RDONLY); ++ fd = open(device, O_RDONLY | O_DIRECT); + + if (fd == -1) { + perror(device); +@@ -690,9 +690,9 @@ xmalloc (size_t size) { + */ + + static int +-sseek(int fd, unsigned int secnr) { ++sseek(int fd, unsigned int secnr, int secsz) { + off64_t in, out; +- in = ((off64_t) secnr << 9); ++ in = ((off64_t) secnr * secsz); + out = 1; + + if ((out = lseek64(fd, in, SEEK_SET)) != in) +@@ -703,6 +703,31 @@ sseek(int fd, unsigned int secnr) { + return 0; + } + ++int ++aligned_malloc(void **mem_p, size_t align, size_t *size_p) ++{ ++ static size_t pgsize = 0; ++ size_t size; ++ int err; ++ ++ if (!mem_p || !align || (size_p && !*size_p)) ++ return EINVAL; ++ ++ if (!pgsize) ++ pgsize = getpagesize(); ++ ++ if (size_p) ++ size = ((*size_p + align - 1) / align) * align; ++ else ++ size = pgsize; ++ ++ err = posix_memalign(mem_p, pgsize, size); ++ if (!err && size_p) ++ *size_p = size; ++ return err; ++} ++ ++/* always in sector size blocks */ + static + struct block { + unsigned int secnr; +@@ -710,30 +735,39 @@ struct block { + struct block *next; + } *blockhead; + ++/* blknr is always in 512 byte blocks */ + char * +-getblock (int fd, unsigned int secnr) { ++getblock (int fd, unsigned int blknr) { ++ unsigned int secsz = get_sector_size(fd); ++ unsigned int blks_per_sec = secsz / 512; ++ unsigned int secnr = blknr / blks_per_sec; ++ unsigned int blk_off = (blknr % blks_per_sec) * 512; + struct block *bp; + + for (bp = blockhead; bp; bp = bp->next) + + if (bp->secnr == secnr) +- return bp->block; ++ return bp->block + blk_off; + +- if (sseek(fd, secnr)) ++ if (sseek(fd, secnr, secsz)) + return NULL; + + bp = xmalloc(sizeof(struct block)); + bp->secnr = secnr; + bp->next = blockhead; + blockhead = bp; +- bp->block = (char *) xmalloc(READ_SIZE); ++ if (aligned_malloc((void **)&bp->block, secsz, NULL)) { ++ fprintf(stderr, "aligned_malloc failed\n"); ++ exit(1); ++ } + +- if (read(fd, bp->block, READ_SIZE) != READ_SIZE) { ++ if (read(fd, bp->block, secsz) != secsz) { + fprintf(stderr, "read error, sector %d\n", secnr); +- bp->block = NULL; ++ blockhead = bp->next; ++ return NULL; + } + +- return bp->block; ++ return bp->block + blk_off; + } + + int +diff --git a/kpartx/kpartx.h b/kpartx/kpartx.h +index 67edeb82..727632c1 100644 +--- a/kpartx/kpartx.h ++++ b/kpartx/kpartx.h +@@ -1,6 +1,7 @@ + #ifndef _KPARTX_H + #define _KPARTX_H + ++#include + #include + #include + +@@ -61,6 +62,7 @@ extern ptreader read_mac_pt; + extern ptreader read_sun_pt; + extern ptreader read_ps3_pt; + ++int aligned_malloc(void **mem_p, size_t align, size_t *size_p); + char *getblock(int fd, unsigned int secnr); + + static inline unsigned int +-- +2.17.2 + diff --git a/0039-bugfix-change-log-level-to-info-if-alua-is-not-support-by-s.patch b/0039-bugfix-change-log-level-to-info-if-alua-is-not-support-by-s.patch deleted file mode 100644 index 6a0944ae5dfd8f8232a3dd30cb32b20dcbc2e5ea..0000000000000000000000000000000000000000 --- a/0039-bugfix-change-log-level-to-info-if-alua-is-not-support-by-s.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0008a2343765ab689cfc66acd8fc84630611d796 Mon Sep 17 00:00:00 2001 -From: root -Date: Fri, 22 Mar 2019 19:37:43 +0800 -Subject: [PATCH 1/5] change log level to info if alua is not support by - storage server - ---- - libmultipath/prioritizers/alua.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/prioritizers/alua.c b/libmultipath/prioritizers/alua.c -index 1400b11..6b69982 100644 ---- a/libmultipath/prioritizers/alua.c -+++ b/libmultipath/prioritizers/alua.c -@@ -127,7 +127,7 @@ int getprio (struct path * pp, char * args, unsigned int timeout) - } else { - switch(-rc) { - case ALUA_PRIO_NOT_SUPPORTED: -- condlog(0, "%s: alua not supported", pp->dev); -+ condlog(3, "%s: alua not supported", pp->dev); - rc = 0; - break; - case ALUA_PRIO_RTPG_FAILED: --- -2.19.1 - diff --git a/0039-kpartx-handle-alternate-bsd-disklabel-location.patch b/0039-kpartx-handle-alternate-bsd-disklabel-location.patch new file mode 100644 index 0000000000000000000000000000000000000000..4b6e7e51586911f9612f1120f812cb85380dace8 --- /dev/null +++ b/0039-kpartx-handle-alternate-bsd-disklabel-location.patch @@ -0,0 +1,53 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 2 Jul 2020 19:38:26 -0500 +Subject: [PATCH] kpartx: handle alternate bsd disklabel location + +bsd disk labels can either be at the start of the second sector, or 64 +bytes into the first sector, but kpartx only handled the first case. +However the second case is what parted creates, and what the linux +kernel partition code expects. kpartx should handle both cases. + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + kpartx/bsd.c | 16 ++++++++++++++-- + 1 file changed, 14 insertions(+), 2 deletions(-) + +diff --git a/kpartx/bsd.c b/kpartx/bsd.c +index 0e661fbc..950b0f92 100644 +--- a/kpartx/bsd.c ++++ b/kpartx/bsd.c +@@ -1,6 +1,7 @@ + #include "kpartx.h" + #include + ++#define BSD_LABEL_OFFSET 64 + #define BSD_DISKMAGIC (0x82564557UL) /* The disk magic number */ + #define XBSD_MAXPARTITIONS 16 + #define BSD_FS_UNUSED 0 +@@ -60,8 +61,19 @@ read_bsd_pt(int fd, struct slice all, struct slice *sp, unsigned int ns) { + return -1; + + l = (struct bsd_disklabel *) bp; +- if (l->d_magic != BSD_DISKMAGIC) +- return -1; ++ if (l->d_magic != BSD_DISKMAGIC) { ++ /* ++ * BSD disklabels can also start 64 bytes offset from the ++ * start of the first sector ++ */ ++ bp = getblock(fd, offset); ++ if (bp == NULL) ++ return -1; ++ ++ l = (struct bsd_disklabel *)(bp + 64); ++ if (l->d_magic != BSD_DISKMAGIC) ++ return -1; ++ } + + max_partitions = 16; + if (l->d_npartitions < max_partitions) +-- +2.17.2 + diff --git a/0040-bugfix-clear-mpp-path-reference-when-path-is-freed-otherwis.patch b/0040-bugfix-clear-mpp-path-reference-when-path-is-freed-otherwis.patch deleted file mode 100644 index 3de13599478b73add3f0afff4a60cd2341aeb087..0000000000000000000000000000000000000000 --- a/0040-bugfix-clear-mpp-path-reference-when-path-is-freed-otherwis.patch +++ /dev/null @@ -1,139 +0,0 @@ -From 2c3047d7f6bd8cdd1d92cab32893cecdd5a1dfa9 Mon Sep 17 00:00:00 2001 -From: root -Date: Fri, 22 Mar 2019 19:48:35 +0800 -Subject: [PATCH] clear mpp path reference when path is freed, otherwise double - free may occur in verify_paths. - -call stack: - vecs=vecs@entry=0x557b01d62140, rpvec=rpvec@entry=0x0) at structs_vec.c:521 - at main.c:574 - uev=) at main.c:510 - uev_trigger=uev_trigger@entry=0x557affdfe3d0 , trigger_data=) - at uevent.c:178 ---- - libmultipath/discovery.c | 10 ++++++---- - libmultipath/discovery.h | 2 +- - multipathd/main.c | 23 ++++++++++++++++++++++- - 3 files changed, 29 insertions(+), 6 deletions(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 53fc67a..305d27c 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -112,7 +112,7 @@ transport (int h) - } - - int --remove_local_path (vector pathvec, struct path *pp) -+remove_local_path (vector pathvec, struct path *pp, int isfree) - { - int i = -1; - -@@ -127,7 +127,9 @@ remove_local_path (vector pathvec, struct path *pp) - if ((i = find_slot(pathvec, (void *)pp)) != -1) { - vector_del_slot(pathvec, i); - } -- free_path(pp); -+ if(isfree){ -+ free_path(pp); -+ } - return 0; - } - -@@ -235,7 +237,7 @@ path_discover (vector pathvec, struct config * conf, - if (err == 1) - return 1; - if (err == 0) -- remove_local_path(pathvec, pp); -+ remove_local_path(pathvec, pp, 1); - return 0; - } - } -@@ -243,7 +245,7 @@ path_discover (vector pathvec, struct config * conf, - if (err) - return err; - -- remove_local_path(pathvec, pp); -+ remove_local_path(pathvec, pp, 1); - return err; - } - -diff --git a/libmultipath/discovery.h b/libmultipath/discovery.h -index c4b1d25..0fb0d3a 100644 ---- a/libmultipath/discovery.h -+++ b/libmultipath/discovery.h -@@ -53,7 +53,7 @@ ssize_t sysfs_get_vpd (struct udev_device * udev, int pg, unsigned char * buff, - int sysfs_get_asymmetric_access_state(struct path *pp, - char *buff, int buflen); - int get_uid(struct path * pp, int path_state, struct udev_device *udev); --int remove_local_path(vector pathvec, struct path *pp); -+int remove_local_path(vector pathvec, struct path *pp, int isfree); - - /* - * discovery bitmask -diff --git a/multipathd/main.c b/multipathd/main.c -index b180f2a..8de0871 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -815,6 +815,21 @@ ev_remove_map (char * devname, char * alias, int minor, struct vectors * vecs) - return flush_map(mpp, vecs, 0); - } - -+static -+void clear_ref_from_mpp(struct path * pp, struct vectors * vecs) -+{ -+ struct multipath * mpp = NULL; -+ int i = -1; -+ -+ mpp = find_mp_by_wwid(vecs->mpvec, pp->wwid); -+ if(!!mpp){ -+ condlog(2, "%s: clear path from mpp %s", pp->dev, mpp->alias); -+ if ((i = find_slot(mpp->paths, (void *)pp)) != -1){ -+ vector_del_slot(mpp->paths, i); -+ } -+ } -+} -+ - static int - uev_add_path (struct uevent *uev, struct vectors * vecs, int need_do_map) - { -@@ -857,6 +872,7 @@ uev_add_path (struct uevent *uev, struct vectors * vecs, int need_do_map) - i = find_slot(vecs->pathvec, (void *)pp); - if (i != -1) - vector_del_slot(vecs->pathvec, i); -+ clear_ref_from_mpp(pp, vecs); - free_path(pp); - } else { - condlog(0, "%s: failed to reinitialize path", -@@ -918,8 +934,11 @@ ev_add_path (struct path * pp, struct vectors * vecs, int need_do_map) - int ret; - - /* if pp is local path,remove it and return 0. */ -- if (!remove_local_path(vecs->pathvec, pp)) -+ if (!remove_local_path(vecs->pathvec, pp, 0)){ -+ clear_ref_from_mpp(pp, vecs); -+ free_path(pp); - return 0; -+ } - - /* - * need path UID to go any further -@@ -950,6 +969,7 @@ rescan: - int i = find_slot(vecs->pathvec, (void *)pp); - if (i != -1) - vector_del_slot(vecs->pathvec, i); -+ clear_ref_from_mpp(pp, vecs); - free_path(pp); - return 1; - } -@@ -1182,6 +1202,7 @@ out: - if ((i = find_slot(vecs->pathvec, (void *)pp)) != -1) - vector_del_slot(vecs->pathvec, i); - -+ clear_ref_from_mpp(pp, vecs); - free_path(pp); - - return retval; --- -2.19.1 - diff --git a/0040-libmultipath-fix-checker-detection-for-nvme-devices.patch b/0040-libmultipath-fix-checker-detection-for-nvme-devices.patch new file mode 100644 index 0000000000000000000000000000000000000000..1054e30963cb1a0e920dc4687bfa5950faebbbd5 --- /dev/null +++ b/0040-libmultipath-fix-checker-detection-for-nvme-devices.patch @@ -0,0 +1,62 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 2 Jul 2020 19:38:27 -0500 +Subject: [PATCH] libmultipath: fix checker detection for nvme devices + +In order to fix hwhandler autodetection, commit 8794a776 made +detect_alua() differentiate between failures to detect whether alua was +supported, and successfully detecting that it was not supported. +However, this causes nvme devices to get the TUR checker assigned to +them. This is because there is nothing in detect_alua() to make it only +work on scsi devices, and select_checker wasn't updated to handle +detect_alua() failing without setting pp->tpgs to TPGS_NONE. + +detect_alua() should automatically set pp->tpgs to TPGS_NONE and exit on +non-scsi devices. Also, select_checker() should not assume that a +devices is ALUA, simply because if failed to detect if alua was +supported. + +Fixes: 8794a776 "libmultipath: fix ALUA autodetection when paths are + down" +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/discovery.c | 6 ++++++ + libmultipath/propsel.c | 4 +++- + 2 files changed, 9 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index 83a41a4a..aa5942c3 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -887,6 +887,12 @@ detect_alua(struct path * pp) + int tpgs; + unsigned int timeout; + ++ ++ if (pp->bus != SYSFS_BUS_SCSI) { ++ pp->tpgs = TPGS_NONE; ++ return; ++ } ++ + if (sysfs_get_timeout(pp, &timeout) <= 0) + timeout = DEF_TIMEOUT; + +diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c +index 897e48ca..d362beb4 100644 +--- a/libmultipath/propsel.c ++++ b/libmultipath/propsel.c +@@ -521,7 +521,9 @@ int select_checker(struct config *conf, struct path *pp) + if (check_rdac(pp)) { + ckr_name = RDAC; + goto out; +- } else if (path_get_tpgs(pp) != TPGS_NONE) { ++ } ++ path_get_tpgs(pp); ++ if (pp->tpgs != TPGS_NONE && pp->tpgs != TPGS_UNDEF) { + ckr_name = TUR; + goto out; + } +-- +2.17.2 + diff --git a/0041-bugfix-libmultipath-fix-memory-leaks-from-scandir-use.patch b/0041-bugfix-libmultipath-fix-memory-leaks-from-scandir-use.patch deleted file mode 100644 index 8cf6a2f33c807ecce81c2a7c185f4f2a80ba88b7..0000000000000000000000000000000000000000 --- a/0041-bugfix-libmultipath-fix-memory-leaks-from-scandir-use.patch +++ /dev/null @@ -1,91 +0,0 @@ -From a10343b550f56c6c39c6a9b8f9ad38ab825a3fa3 Mon Sep 17 00:00:00 2001 -From: root -Date: Fri, 22 Mar 2019 19:58:56 +0800 -Subject: [PATCH 3/5] libmultipath: fix memory leaks from scandir() use - -upstream commit b0e8a7456dd83cd0a5ecd1005e016656e785405f - -scandir() users must not only free the resulting dirent* array, -but also every member. Add a cleanup function, and fix the -existing users of scandir() in libmultipath. - -Add a small helper macro for casting function pointers to the -type pthread_cleanup_push() expects. ---- - libmultipath/config.c | 10 ++++------ - libmultipath/util.c | 9 +++++++++ - libmultipath/util.h | 8 ++++++++ - 3 files changed, 21 insertions(+), 6 deletions(-) - -diff --git a/libmultipath/config.c b/libmultipath/config.c -index bfd07e3..654f330 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -640,17 +640,13 @@ free_config (struct config * conf) - FREE(conf); - } - --static void free_namelist(void *nl) --{ -- free(nl); --} -- - /* if multipath fails to process the config directory, it should continue, - * with just a warning message */ - static void - process_config_dir(struct config *conf, vector keywords, char *dir) - { - struct dirent **namelist; -+ struct scandir_result sr; - int i, n; - char path[LINE_MAX]; - int old_hwtable_size; -@@ -670,7 +666,9 @@ process_config_dir(struct config *conf, vector keywords, char *dir) - return; - } else if (n == 0) - return; -- pthread_cleanup_push(free_namelist, namelist); -+ sr.di = namelist; -+ sr.n = n; -+ pthread_cleanup_push_cast(free_scandir_result, &sr); - for (i = 0; i < n; i++) { - if (!strstr(namelist[i]->d_name, ".conf")) - continue; -diff --git a/libmultipath/util.c b/libmultipath/util.c -index 3c284b7..2bb1102 100644 ---- a/libmultipath/util.c -+++ b/libmultipath/util.c -@@ -472,3 +472,12 @@ int safe_write(int fd, const void *buf, size_t count) - - return 0; - } -+ -+void free_scandir_result(struct scandir_result *res) -+{ -+ int i; -+ -+ for (i = 0; i < res->n; i++) -+ FREE(res->di[i]); -+ FREE(res->di); -+} -diff --git a/libmultipath/util.h b/libmultipath/util.h -index 56cec76..4374720 100644 ---- a/libmultipath/util.h -+++ b/libmultipath/util.h -@@ -28,5 +28,13 @@ int safe_write(int fd, const void *buf, size_t count); - snprintf(var, sizeof(var), format, ##args) >= sizeof(var) - #define safe_snprintf(var, size, format, args...) \ - snprintf(var, size, format, ##args) >= size -+#define pthread_cleanup_push_cast(f, arg) \ -+ pthread_cleanup_push(((void (*)(void *))&f), (arg)) -+ -+struct scandir_result { -+ struct dirent **di; -+ int n; -+}; -+void free_scandir_result(struct scandir_result *); - - #endif /* _UTIL_H */ --- -2.19.1 - diff --git a/0041-libmultipath-make-dm_get_map-status-return-codes-sym.patch b/0041-libmultipath-make-dm_get_map-status-return-codes-sym.patch new file mode 100644 index 0000000000000000000000000000000000000000..91c9a8bfa20db249258b4f3c317027a498f5b80f --- /dev/null +++ b/0041-libmultipath-make-dm_get_map-status-return-codes-sym.patch @@ -0,0 +1,322 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 2 Jul 2020 19:07:00 -0500 +Subject: [PATCH] libmultipath: make dm_get_map/status return codes symbolic + +dm_get_map() and dm_get_status() now use symbolic return codes. They +also differentiate between failing to get information from device-mapper +and not finding the requested device. These symboilc return codes are +also used by update_multipath_* functions. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/devmapper.c | 51 +++++++++++++++++++++++++------------- + libmultipath/devmapper.h | 6 +++++ + libmultipath/structs_vec.c | 45 +++++++++++++++++++-------------- + multipathd/main.c | 12 ++++----- + 4 files changed, 72 insertions(+), 42 deletions(-) + +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index 27d52398..24cc616a 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -534,36 +534,43 @@ int dm_map_present(const char * str) + + int dm_get_map(const char *name, unsigned long long *size, char *outparams) + { +- int r = 1; ++ int r = DMP_ERR; + struct dm_task *dmt; + uint64_t start, length; + char *target_type = NULL; + char *params = NULL; + + if (!(dmt = libmp_dm_task_create(DM_DEVICE_TABLE))) +- return 1; ++ return r; + + if (!dm_task_set_name(dmt, name)) + goto out; + + dm_task_no_open_count(dmt); + +- if (!dm_task_run(dmt)) ++ errno = 0; ++ if (!dm_task_run(dmt)) { ++ if (dm_task_get_errno(dmt) == ENXIO) ++ r = DMP_NOT_FOUND; + goto out; ++ } + ++ r = DMP_NOT_FOUND; + /* Fetch 1st target */ +- dm_get_next_target(dmt, NULL, &start, &length, +- &target_type, ¶ms); ++ if (dm_get_next_target(dmt, NULL, &start, &length, ++ &target_type, ¶ms) != NULL) ++ /* more than one target */ ++ goto out; + + if (size) + *size = length; + + if (!outparams) { +- r = 0; ++ r = DMP_OK; + goto out; + } + if (snprintf(outparams, PARAMS_SIZE, "%s", params) <= PARAMS_SIZE) +- r = 0; ++ r = DMP_OK; + out: + dm_task_destroy(dmt); + return r; +@@ -637,35 +644,45 @@ is_mpath_part(const char *part_name, const char *map_name) + + int dm_get_status(const char *name, char *outstatus) + { +- int r = 1; ++ int r = DMP_ERR; + struct dm_task *dmt; + uint64_t start, length; + char *target_type = NULL; + char *status = NULL; + + if (!(dmt = libmp_dm_task_create(DM_DEVICE_STATUS))) +- return 1; ++ return r; + + if (!dm_task_set_name(dmt, name)) + goto out; + + dm_task_no_open_count(dmt); + +- if (!dm_task_run(dmt)) ++ errno = 0; ++ if (!dm_task_run(dmt)) { ++ if (dm_task_get_errno(dmt) == ENXIO) ++ r = DMP_NOT_FOUND; + goto out; ++ } + ++ r = DMP_NOT_FOUND; + /* Fetch 1st target */ +- dm_get_next_target(dmt, NULL, &start, &length, +- &target_type, &status); ++ if (dm_get_next_target(dmt, NULL, &start, &length, ++ &target_type, &status) != NULL) ++ goto out; ++ ++ if (!target_type || strcmp(target_type, TGT_MPATH) != 0) ++ goto out; ++ + if (!status) { + condlog(2, "get null status."); + goto out; + } + + if (snprintf(outstatus, PARAMS_SIZE, "%s", status) <= PARAMS_SIZE) +- r = 0; ++ r = DMP_OK; + out: +- if (r) ++ if (r != DMP_OK) + condlog(0, "%s: error getting map status string", name); + + dm_task_destroy(dmt); +@@ -920,7 +937,7 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, + return 1; + + if (need_suspend && +- !dm_get_map(mapname, &mapsize, params) && ++ dm_get_map(mapname, &mapsize, params) == DMP_OK && + strstr(params, "queue_if_no_path")) { + if (!dm_queue_if_no_path(mapname, 0)) + queue_if_no_path = 1; +@@ -1129,7 +1146,7 @@ struct multipath *dm_get_multipath(const char *name) + if (!mpp->alias) + goto out; + +- if (dm_get_map(name, &mpp->size, NULL)) ++ if (dm_get_map(name, &mpp->size, NULL) != DMP_OK) + goto out; + + dm_get_uuid(name, mpp->wwid, WWID_SIZE); +@@ -1313,7 +1330,7 @@ do_foreach_partmaps (const char * mapname, + /* + * and we can fetch the map table from the kernel + */ +- !dm_get_map(names->name, &size, ¶ms[0]) && ++ dm_get_map(names->name, &size, ¶ms[0]) == DMP_OK && + + /* + * and the table maps over the multipath map +diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h +index 5ed7edc5..b2108638 100644 +--- a/libmultipath/devmapper.h ++++ b/libmultipath/devmapper.h +@@ -27,6 +27,12 @@ + #define UUID_PREFIX "mpath-" + #define UUID_PREFIX_LEN (sizeof(UUID_PREFIX) - 1) + ++enum { ++ DMP_ERR, ++ DMP_OK, ++ DMP_NOT_FOUND, ++}; ++ + void dm_init(int verbosity); + int dm_prereq(unsigned int *v); + void skip_libmp_dm_init(void); +diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c +index 077f2e42..8137ea21 100644 +--- a/libmultipath/structs_vec.c ++++ b/libmultipath/structs_vec.c +@@ -196,43 +196,47 @@ extract_hwe_from_path(struct multipath * mpp) + int + update_multipath_table (struct multipath *mpp, vector pathvec, int is_daemon) + { ++ int r = DMP_ERR; + char params[PARAMS_SIZE] = {0}; + + if (!mpp) +- return 1; ++ return r; + +- if (dm_get_map(mpp->alias, &mpp->size, params)) { +- condlog(3, "%s: cannot get map", mpp->alias); +- return 1; ++ r = dm_get_map(mpp->alias, &mpp->size, params); ++ if (r != DMP_OK) { ++ condlog(3, "%s: %s", mpp->alias, (r == DMP_ERR)? "error getting table" : "map not present"); ++ return r; + } + + if (disassemble_map(pathvec, params, mpp, is_daemon)) { + condlog(3, "%s: cannot disassemble map", mpp->alias); +- return 1; ++ return DMP_ERR; + } + +- return 0; ++ return DMP_OK; + } + + int + update_multipath_status (struct multipath *mpp) + { ++ int r = DMP_ERR; + char status[PARAMS_SIZE] = {0}; + + if (!mpp) +- return 1; ++ return r; + +- if (dm_get_status(mpp->alias, status)) { +- condlog(3, "%s: cannot get status", mpp->alias); +- return 1; ++ r = dm_get_status(mpp->alias, status); ++ if (r != DMP_OK) { ++ condlog(3, "%s: %s", mpp->alias, (r == DMP_ERR)? "error getting status" : "map not present"); ++ return r; + } + + if (disassemble_status(status, mpp)) { + condlog(3, "%s: cannot disassemble status", mpp->alias); +- return 1; ++ return DMP_ERR; + } + +- return 0; ++ return DMP_OK; + } + + void sync_paths(struct multipath *mpp, vector pathvec) +@@ -264,10 +268,10 @@ int + update_multipath_strings(struct multipath *mpp, vector pathvec, int is_daemon) + { + struct pathgroup *pgp; +- int i; ++ int i, r = DMP_ERR; + + if (!mpp) +- return 1; ++ return r; + + update_mpp_paths(mpp, pathvec); + condlog(4, "%s: %s", mpp->alias, __FUNCTION__); +@@ -276,18 +280,21 @@ update_multipath_strings(struct multipath *mpp, vector pathvec, int is_daemon) + free_pgvec(mpp->pg, KEEP_PATHS); + mpp->pg = NULL; + +- if (update_multipath_table(mpp, pathvec, is_daemon)) +- return 1; ++ r = update_multipath_table(mpp, pathvec, is_daemon); ++ if (r != DMP_OK) ++ return r; ++ + sync_paths(mpp, pathvec); + +- if (update_multipath_status(mpp)) +- return 1; ++ r = update_multipath_status(mpp); ++ if (r != DMP_OK) ++ return r; + + vector_foreach_slot(mpp->pg, pgp, i) + if (pgp->paths) + path_group_prio_update(pgp); + +- return 0; ++ return DMP_OK; + } + + static void enter_recovery_mode(struct multipath *mpp) +diff --git a/multipathd/main.c b/multipathd/main.c +index 205ddb32..ab141fed 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -418,7 +418,7 @@ int __setup_multipath(struct vectors *vecs, struct multipath *mpp, + goto out; + } + +- if (update_multipath_strings(mpp, vecs->pathvec, 1)) { ++ if (update_multipath_strings(mpp, vecs->pathvec, 1) != DMP_OK) { + condlog(0, "%s: failed to setup multipath", mpp->alias); + goto out; + } +@@ -557,9 +557,9 @@ add_map_without_path (struct vectors *vecs, const char *alias) + mpp->mpe = find_mpe(conf->mptable, mpp->wwid); + put_multipath_config(conf); + +- if (update_multipath_table(mpp, vecs->pathvec, 1)) ++ if (update_multipath_table(mpp, vecs->pathvec, 1) != DMP_OK) + goto out; +- if (update_multipath_status(mpp)) ++ if (update_multipath_status(mpp) != DMP_OK) + goto out; + + if (!vector_alloc_slot(vecs->mpvec)) +@@ -1350,8 +1350,8 @@ map_discovery (struct vectors * vecs) + return 1; + + vector_foreach_slot (vecs->mpvec, mpp, i) +- if (update_multipath_table(mpp, vecs->pathvec, 1) || +- update_multipath_status(mpp)) { ++ if (update_multipath_table(mpp, vecs->pathvec, 1) != DMP_OK || ++ update_multipath_status(mpp) != DMP_OK) { + remove_map(mpp, vecs, 1); + i--; + } +@@ -2091,7 +2091,7 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) + /* + * Synchronize with kernel state + */ +- if (update_multipath_strings(pp->mpp, vecs->pathvec, 1)) { ++ if (update_multipath_strings(pp->mpp, vecs->pathvec, 1) != DMP_OK) { + condlog(1, "%s: Could not synchronize with kernel state", + pp->dev); + pp->dmstate = PSTATE_UNDEF; +-- +2.17.2 + diff --git a/0042-bugfix-libmultipath-fix-memory-leak-in-disassemble_map.patch b/0042-bugfix-libmultipath-fix-memory-leak-in-disassemble_map.patch deleted file mode 100644 index a4873a7eed375c784f9f3d124df127d6ec967c0e..0000000000000000000000000000000000000000 --- a/0042-bugfix-libmultipath-fix-memory-leak-in-disassemble_map.patch +++ /dev/null @@ -1,87 +0,0 @@ -From db72d840682d15abb2e6694704a91200e513dbac Mon Sep 17 00:00:00 2001 -From: root -Date: Fri, 22 Mar 2019 20:33:53 +0800 -Subject: [PATCH 5/5] libmultipath: fix memory leak in disassemble_map - ---- - libmultipath/dmparser.c | 12 ++++++++++-- - libmultipath/structs_vec.c | 10 ++++++++++ - 2 files changed, 20 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/dmparser.c b/libmultipath/dmparser.c -index 620f507..1558c4e 100644 ---- a/libmultipath/dmparser.c -+++ b/libmultipath/dmparser.c -@@ -142,6 +142,7 @@ int disassemble_map(vector pathvec, char *params, struct multipath *mpp, - int def_minio = 0; - struct path * pp; - struct pathgroup * pgp; -+ int pp_unfound; - - p = params; - -@@ -291,6 +292,7 @@ int disassemble_map(vector pathvec, char *params, struct multipath *mpp, - char devname[FILE_NAME_SIZE]; - - pp = NULL; -+ pp_unfound = 0; - p += get_word(p, &word); - - if (!word) -@@ -310,6 +312,7 @@ int disassemble_map(vector pathvec, char *params, struct multipath *mpp, - } - - if (!pp) { -+ pp_unfound = 1; - pp = alloc_path(); - - if (!pp) -@@ -322,8 +325,10 @@ int disassemble_map(vector pathvec, char *params, struct multipath *mpp, - WWID_SIZE - 1); - } - /* Only call this in multipath client mode */ -- if (!is_daemon && store_path(pathvec, pp)) -+ if (!is_daemon && store_path(pathvec, pp)) { -+ free_path(pp); - goto out1; -+ } - } else { - if (!strlen(pp->wwid) && - strlen(mpp->wwid)) -@@ -332,8 +337,11 @@ int disassemble_map(vector pathvec, char *params, struct multipath *mpp, - } - FREE(word); - -- if (store_path(pgp->paths, pp)) -+ if (store_path(pgp->paths, pp)) { -+ if (pp_unfound) -+ free_path(pp); - goto out; -+ } - - /* - * Update wwid for multipaths which are not setup -diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c -index 6c42824..828aef2 100644 ---- a/libmultipath/structs_vec.c -+++ b/libmultipath/structs_vec.c -@@ -252,6 +252,16 @@ void sync_paths(struct multipath *mpp, vector pathvec) - update_mpp_paths(mpp, pathvec); - vector_foreach_slot (mpp->paths, pp, i) - pp->mpp = mpp; -+ -+ vector_foreach_slot (mpp->pg, pgp, i) { -+ vector_foreach_slot (pgp->paths, pp, j) { -+ if ((find_slot(mpp->paths, pp) == -1) \ -+ && (find_slot(pathvec, pp) == -1)) { -+ vector_del_slot(pgp->paths, j--); -+ free_path(pp); -+ } -+ } -+ } - } - - int --- -2.19.1 - diff --git a/0042-multipathd-fix-check_path-errors-with-removed-map.patch b/0042-multipathd-fix-check_path-errors-with-removed-map.patch new file mode 100644 index 0000000000000000000000000000000000000000..155e93ad9b98ba5659875488004a7cf439dadef9 --- /dev/null +++ b/0042-multipathd-fix-check_path-errors-with-removed-map.patch @@ -0,0 +1,116 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 2 Jul 2020 19:07:01 -0500 +Subject: [PATCH] multipathd: fix check_path errors with removed map + +If a multipath device is removed during, or immediately before the call +to check_path(), multipathd can behave incorrectly. A missing multpath +device will cause update_multipath_strings() to fail, setting +pp->dmstate to PSTATE_UNDEF. If the path is up, this state will cause +reinstate_path() to be called, which will also fail. This will trigger +a reload, restoring the recently removed device. + +If update_multipath_strings() fails because there is no multipath +device, check_path should just quit, since the remove dmevent and uevent +are likely already queued up. Also, I don't see any reason to reload the +multipath device if reinstate fails. This code was added by +fac68d7a99ef17d496079538a5c6836acd7911ab, which clamined that reinstate +could fail if the path was disabled. Looking through the current kernel +code, I can't see any reason why a reinstate would fail, where a reload +would help. If the path was missing from the multipath device, +update_multipath_strings() would already catch that, and quit +check_path() early, which make more sense to me than reloading does. + +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 44 +++++++++++++++++++------------------------- + 1 file changed, 19 insertions(+), 25 deletions(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index ab141fed..daf19a4e 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -1615,22 +1615,18 @@ fail_path (struct path * pp, int del_active) + /* + * caller must have locked the path list before calling that function + */ +-static int ++static void + reinstate_path (struct path * pp) + { +- int ret = 0; +- + if (!pp->mpp) +- return 0; ++ return; + +- if (dm_reinstate_path(pp->mpp->alias, pp->dev_t)) { ++ if (dm_reinstate_path(pp->mpp->alias, pp->dev_t)) + condlog(0, "%s: reinstate failed", pp->dev_t); +- ret = 1; +- } else { ++ else { + condlog(2, "%s: reinstated", pp->dev_t); + update_queue_mode_add_path(pp->mpp); + } +- return ret; + } + + static void +@@ -2091,9 +2087,16 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) + /* + * Synchronize with kernel state + */ +- if (update_multipath_strings(pp->mpp, vecs->pathvec, 1) != DMP_OK) { +- condlog(1, "%s: Could not synchronize with kernel state", +- pp->dev); ++ ret = update_multipath_strings(pp->mpp, vecs->pathvec, 1); ++ if (ret != DMP_OK) { ++ if (ret == DMP_NOT_FOUND) { ++ /* multipath device missing. Likely removed */ ++ condlog(1, "%s: multipath device '%s' not found", ++ pp->dev, pp->mpp->alias); ++ return 0; ++ } else ++ condlog(1, "%s: Couldn't synchronize with kernel state", ++ pp->dev); + pp->dmstate = PSTATE_UNDEF; + } + /* if update_multipath_strings orphaned the path, quit early */ +@@ -2183,12 +2186,8 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) + /* + * reinstate this path + */ +- if (!disable_reinstate && reinstate_path(pp)) { +- condlog(3, "%s: reload map", pp->dev); +- ev_add_path(pp, vecs, 1); +- pp->tick = 1; +- return 0; +- } ++ if (!disable_reinstate) ++ reinstate_path(pp); + new_path_up = 1; + + if (oldchkrstate != PATH_UP && oldchkrstate != PATH_GHOST) +@@ -2204,15 +2203,10 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) + else if (newstate == PATH_UP || newstate == PATH_GHOST) { + if ((pp->dmstate == PSTATE_FAILED || + pp->dmstate == PSTATE_UNDEF) && +- !disable_reinstate) { ++ !disable_reinstate) + /* Clear IO errors */ +- if (reinstate_path(pp)) { +- condlog(3, "%s: reload map", pp->dev); +- ev_add_path(pp, vecs, 1); +- pp->tick = 1; +- return 0; +- } +- } else { ++ reinstate_path(pp); ++ else { + LOG_MSG(4, verbosity, pp); + if (pp->checkint != max_checkint) { + /* +-- +2.17.2 + diff --git a/0043-libmultipath-make-dm_flush_maps-only-return-0-on-suc.patch b/0043-libmultipath-make-dm_flush_maps-only-return-0-on-suc.patch new file mode 100644 index 0000000000000000000000000000000000000000..4dce9803c9883789718f844865138eb21df0536e --- /dev/null +++ b/0043-libmultipath-make-dm_flush_maps-only-return-0-on-suc.patch @@ -0,0 +1,46 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 2 Jul 2020 19:07:02 -0500 +Subject: [PATCH] libmultipath: make dm_flush_maps only return 0 on success + +dm_flush_maps() returned both 0 and 1 on error, depending on which part +of the function it was in, but the caller was always treating 0 as a +success. Make dm_flush_maps() always return 1 on error and 0 on success. + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/devmapper.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index 24cc616a..4c86b6d4 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -1007,13 +1007,13 @@ dm_flush_map_nopaths(const char * mapname, int deferred_remove) + + int dm_flush_maps (int retries) + { +- int r = 0; ++ int r = 1; + struct dm_task *dmt; + struct dm_names *names; + unsigned next = 0; + + if (!(dmt = libmp_dm_task_create (DM_DEVICE_LIST))) +- return 0; ++ return r; + + dm_task_no_open_count(dmt); + +@@ -1026,6 +1026,7 @@ int dm_flush_maps (int retries) + if (!names->dev) + goto out; + ++ r = 0; + do { + r |= dm_suspend_and_flush_map(names->name, retries); + next = names->next; +-- +2.17.2 + diff --git a/0043-multipathd-fix-mpp-hwe-handling-when-paths-are-freed.patch b/0043-multipathd-fix-mpp-hwe-handling-when-paths-are-freed.patch deleted file mode 100644 index 5de6b6da76d92ba8c4e56d94a2d607cbf02f2111..0000000000000000000000000000000000000000 --- a/0043-multipathd-fix-mpp-hwe-handling-when-paths-are-freed.patch +++ /dev/null @@ -1,109 +0,0 @@ -multipathd: fix mpp->hwe handling when paths are freed - -Commit 1f962693 didn't deal with all of cases where a path that was part -of a multipath device could be removed. verify_paths() removes any path -that no longer exists in sysfs. mpp->hwe needs to be updated here as -well, since verify_paths() could remove the path whose hwe vector is -pointed to by mpp->hwe. Also, now that extract_hwe_from_path() is -called in verify_paths(), the extract_hwe_from_path() calls that -happened immediately after verify_paths() can be dropped. - -The other part of this fix is mostly cosmetic. In ev_add_path(), if -domap() fails after the path is added to the multipath device and -verify_paths() is called, the code can loop back to the rescan label. If -the size of the path or the multipath device changed in the interim, -ev_add_path() would remove the path, without updating mpp->hwe; but -there is no way for the size to change. Just to make that clearer in the -code, I've moved the size check to before the rescan label so it only -happens once. - -Fixes: 1f962693 "multipathd: fix mpp->hwe handling on path removal" -Cc: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/structs_vec.c | 7 +++++++ - multipathd/main.c | 22 ++++++++-------------- - 2 files changed, 15 insertions(+), 14 deletions(-) - -diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c -index 828aef2..2808efe 100644 ---- a/libmultipath/structs_vec.c -+++ b/libmultipath/structs_vec.c -@@ -418,6 +418,12 @@ int verify_paths(struct multipath *mpp, struct vectors *vecs) - vector_del_slot(mpp->paths, i); - i--; - -+ /* Make sure mpp->hwe doesn't point to freed memory. -+ * We call extract_hwe_from_path() below to restore -+ * mpp->hwe -+ */ -+ if (mpp->hwe == pp->hwe) -+ mpp->hwe = NULL; - if ((j = find_slot(vecs->pathvec, - (void *)pp)) != -1) - vector_del_slot(vecs->pathvec, j); -@@ -427,6 +433,7 @@ int verify_paths(struct multipath *mpp, struct vectors *vecs) - mpp->alias, pp->dev, pp->dev_t); - } - } -+ extract_hwe_from_path(mpp); - return count; - } - -diff --git a/multipathd/main.c b/multipathd/main.c -index 8de0871..872843c 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -472,7 +472,6 @@ retry: - verify_paths(mpp, vecs); - mpp->action = ACT_RELOAD; - -- extract_hwe_from_path(mpp); - if (setup_map(mpp, params, PARAMS_SIZE, vecs)) { - condlog(0, "%s: failed to setup new map in update", mpp->alias); - retries = -1; -@@ -948,6 +947,14 @@ ev_add_path (struct path * pp, struct vectors * vecs, int need_do_map) - goto fail; /* leave path added to pathvec */ - } - mpp = find_mp_by_wwid(vecs->mpvec, pp->wwid); -+ if (mpp && pp->size && mpp->size != pp->size) { -+ condlog(0, "%s: failed to add new path %s, device size mismatch", mpp->alias, pp->dev); -+ int i = find_slot(vecs->pathvec, (void *)pp); -+ if (i != -1) -+ vector_del_slot(vecs->pathvec, i); -+ free_path(pp); -+ return 1; -+ } - if (mpp && mpp->wait_for_udev && - (pathcount(mpp, PATH_UP) > 0 || - (pathcount(mpp, PATH_GHOST) > 0 && pp->tpgs != TPGS_IMPLICIT && -@@ -962,18 +969,6 @@ ev_add_path (struct path * pp, struct vectors * vecs, int need_do_map) - pp->mpp = mpp; - rescan: - if (mpp) { -- if (pp->size && mpp->size != pp->size) { -- condlog(0, "%s: failed to add new path %s, " -- "device size mismatch", -- mpp->alias, pp->dev); -- int i = find_slot(vecs->pathvec, (void *)pp); -- if (i != -1) -- vector_del_slot(vecs->pathvec, i); -- clear_ref_from_mpp(pp, vecs); -- free_path(pp); -- return 1; -- } -- - condlog(4,"%s: adopting all paths for path %s", - mpp->alias, pp->dev); - if (adopt_paths(vecs->pathvec, mpp)) -@@ -981,7 +976,6 @@ rescan: - - verify_paths(mpp, vecs); - mpp->action = ACT_RELOAD; -- extract_hwe_from_path(mpp); - } else { - if (!should_multipath(pp, vecs->pathvec, vecs->mpvec)) { - orphan_path(pp, "only one path"); --- -2.19.1 - diff --git a/0044-bugfix-check-close-return-value.patch b/0044-bugfix-check-close-return-value.patch deleted file mode 100644 index 8115f5c023a99b9c0032eb7cf33e6048fb84fe67..0000000000000000000000000000000000000000 --- a/0044-bugfix-check-close-return-value.patch +++ /dev/null @@ -1,29 +0,0 @@ -Subject: [PATCH] check close return value - ---- - mpathpersist/main.c | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - -diff --git a/mpathpersist/main.c b/mpathpersist/main.c -index 4db07b2..db8b6d7 100644 ---- a/mpathpersist/main.c -+++ b/mpathpersist/main.c -@@ -498,7 +498,14 @@ int main (int argc, char * argv[]) - - out : - if (fd >= 0) -- close(fd); -+ { -+ res = close(fd); -+ if (res < 0) -+ { -+ ret = MPATH_PR_FILE_ERROR; -+ } -+ -+ } - mpath_lib_exit(conf); - udev_unref(udev); - return (ret >= 0) ? ret : MPATH_PR_OTHER; --- -2.19.1 - diff --git a/0044-multipathd-add-del-maps-multipathd-command.patch b/0044-multipathd-add-del-maps-multipathd-command.patch new file mode 100644 index 0000000000000000000000000000000000000000..9f32eb2938ff18cfc4773013cb4172417282b418 --- /dev/null +++ b/0044-multipathd-add-del-maps-multipathd-command.patch @@ -0,0 +1,161 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 2 Jul 2020 19:07:03 -0500 +Subject: [PATCH] multipathd: add "del maps" multipathd command + +This will flush all multipath devices. + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/devmapper.c | 7 +++++-- + libmultipath/devmapper.h | 2 +- + multipath/main.c | 2 +- + multipathd/cli.c | 1 + + multipathd/cli_handlers.c | 19 +++++++++++++++++++ + multipathd/cli_handlers.h | 1 + + multipathd/main.c | 3 ++- + multipathd/main.h | 1 + + 8 files changed, 31 insertions(+), 5 deletions(-) + +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index 4c86b6d4..f597ff8b 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -1005,7 +1005,7 @@ dm_flush_map_nopaths(const char * mapname, int deferred_remove) + + #endif + +-int dm_flush_maps (int retries) ++int dm_flush_maps (int need_suspend, int retries) + { + int r = 1; + struct dm_task *dmt; +@@ -1028,7 +1028,10 @@ int dm_flush_maps (int retries) + + r = 0; + do { +- r |= dm_suspend_and_flush_map(names->name, retries); ++ if (need_suspend) ++ r |= dm_suspend_and_flush_map(names->name, retries); ++ else ++ r |= dm_flush_map(names->name); + next = names->next; + names = (void *) names + next; + } while (next); +diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h +index b2108638..6dd178c8 100644 +--- a/libmultipath/devmapper.h ++++ b/libmultipath/devmapper.h +@@ -57,7 +57,7 @@ int dm_flush_map_nopaths(const char * mapname, int deferred_remove); + #define dm_suspend_and_flush_map(mapname, retries) \ + _dm_flush_map(mapname, 1, 0, 1, retries) + int dm_cancel_deferred_remove(struct multipath *mpp); +-int dm_flush_maps (int retries); ++int dm_flush_maps (int need_suspend, int retries); + int dm_fail_path(const char * mapname, char * path); + int dm_reinstate_path(const char * mapname, char * path); + int dm_queue_if_no_path(const char *mapname, int enable); +diff --git a/multipath/main.c b/multipath/main.c +index c4740fab..d89f0a91 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -1096,7 +1096,7 @@ main (int argc, char *argv[]) + goto out; + } + else if (conf->remove == FLUSH_ALL) { +- r = dm_flush_maps(retries) ? RTVL_FAIL : RTVL_OK; ++ r = dm_flush_maps(1, retries) ? RTVL_FAIL : RTVL_OK; + goto out; + } + while ((r = configure(conf, cmd, dev_type, dev)) == RTVL_RETRY) +diff --git a/multipathd/cli.c b/multipathd/cli.c +index 800c0fbe..bdc9fb10 100644 +--- a/multipathd/cli.c ++++ b/multipathd/cli.c +@@ -568,6 +568,7 @@ cli_init (void) { + add_handler(DEL+PATH, NULL); + add_handler(ADD+MAP, NULL); + add_handler(DEL+MAP, NULL); ++ add_handler(DEL+MAPS, NULL); + add_handler(SWITCH+MAP+GROUP, NULL); + add_handler(RECONFIGURE, NULL); + add_handler(SUSPEND+MAP, NULL); +diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c +index 31c3d9fd..782bb003 100644 +--- a/multipathd/cli_handlers.c ++++ b/multipathd/cli_handlers.c +@@ -852,6 +852,25 @@ cli_del_map (void * v, char ** reply, int * len, void * data) + return rc; + } + ++int ++cli_del_maps (void *v, char **reply, int *len, void *data) ++{ ++ struct vectors * vecs = (struct vectors *)data; ++ struct multipath *mpp; ++ int i, ret = 0; ++ ++ condlog(2, "remove maps (operator)"); ++ vector_foreach_slot(vecs->mpvec, mpp, i) { ++ if (flush_map(mpp, vecs, 0)) ++ ret++; ++ else ++ i--; ++ } ++ /* flush any multipath maps that aren't currently known by multipathd */ ++ ret |= dm_flush_maps(0, 0); ++ return ret; ++} ++ + int + cli_reload(void *v, char **reply, int *len, void *data) + { +diff --git a/multipathd/cli_handlers.h b/multipathd/cli_handlers.h +index 0f451064..6f57b429 100644 +--- a/multipathd/cli_handlers.h ++++ b/multipathd/cli_handlers.h +@@ -26,6 +26,7 @@ int cli_add_path (void * v, char ** reply, int * len, void * data); + int cli_del_path (void * v, char ** reply, int * len, void * data); + int cli_add_map (void * v, char ** reply, int * len, void * data); + int cli_del_map (void * v, char ** reply, int * len, void * data); ++int cli_del_maps (void * v, char ** reply, int * len, void * data); + int cli_switch_group(void * v, char ** reply, int * len, void * data); + int cli_reconfigure(void * v, char ** reply, int * len, void * data); + int cli_resize(void * v, char ** reply, int * len, void * data); +diff --git a/multipathd/main.c b/multipathd/main.c +index daf19a4e..f014d2a1 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -635,7 +635,7 @@ sync_maps_state(vector mpvec) + sync_map_state(mpp); + } + +-static int ++int + flush_map(struct multipath * mpp, struct vectors * vecs, int nopaths) + { + int r; +@@ -1555,6 +1555,7 @@ uxlsnrloop (void * ap) + set_handler_callback(DEL+PATH, cli_del_path); + set_handler_callback(ADD+MAP, cli_add_map); + set_handler_callback(DEL+MAP, cli_del_map); ++ set_handler_callback(DEL+MAPS, cli_del_maps); + set_handler_callback(SWITCH+MAP+GROUP, cli_switch_group); + set_unlocked_handler_callback(RECONFIGURE, cli_reconfigure); + set_handler_callback(SUSPEND+MAP, cli_suspend); +diff --git a/multipathd/main.h b/multipathd/main.h +index 7bb8463f..5dff17e5 100644 +--- a/multipathd/main.h ++++ b/multipathd/main.h +@@ -28,6 +28,7 @@ int ev_add_path (struct path *, struct vectors *, int); + int ev_remove_path (struct path *, struct vectors *, int); + int ev_add_map (char *, const char *, struct vectors *); + int ev_remove_map (char *, char *, int, struct vectors *); ++int flush_map(struct multipath *, struct vectors *, int); + int set_config_state(enum daemon_status); + void * mpath_alloc_prin_response(int prin_sa); + int prin_do_scsi_ioctl(char *, int rq_servact, struct prin_resp * resp, +-- +2.17.2 + diff --git a/0045-multipath-make-flushing-maps-work-like-other-command.patch b/0045-multipath-make-flushing-maps-work-like-other-command.patch new file mode 100644 index 0000000000000000000000000000000000000000..b7450ee09641223314bcb62f6c7d97ae01b6cb68 --- /dev/null +++ b/0045-multipath-make-flushing-maps-work-like-other-command.patch @@ -0,0 +1,104 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 2 Jul 2020 19:07:04 -0500 +Subject: [PATCH] multipath: make flushing maps work like other commands + +The config structure doesn't need a special variable just for removes. +Multipath can just use the cmd variable, like it does for the other +commands. + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/config.h | 3 ++- + libmultipath/configure.h | 3 --- + multipath/main.c | 20 ++++++++++---------- + 3 files changed, 12 insertions(+), 14 deletions(-) + +diff --git a/libmultipath/config.h b/libmultipath/config.h +index ceecff2d..55569360 100644 +--- a/libmultipath/config.h ++++ b/libmultipath/config.h +@@ -38,6 +38,8 @@ enum mpath_cmds { + CMD_ADD_WWID, + CMD_USABLE_PATHS, + CMD_DUMP_CONFIG, ++ CMD_FLUSH_ONE, ++ CMD_FLUSH_ALL, + }; + + enum force_reload_types { +@@ -142,7 +144,6 @@ struct config { + unsigned int max_checkint; + bool use_watchdog; + int pgfailback; +- int remove; + int rr_weight; + int no_path_retry; + int user_friendly_names; +diff --git a/libmultipath/configure.h b/libmultipath/configure.h +index d7509000..0e33bf40 100644 +--- a/libmultipath/configure.h ++++ b/libmultipath/configure.h +@@ -45,9 +45,6 @@ enum { + CP_RETRY, + }; + +-#define FLUSH_ONE 1 +-#define FLUSH_ALL 2 +- + struct vectors; + + int setup_map (struct multipath * mpp, char * params, int params_size, +diff --git a/multipath/main.c b/multipath/main.c +index d89f0a91..101fd656 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -909,10 +909,10 @@ main (int argc, char *argv[]) + cmd = CMD_DRY_RUN; + break; + case 'f': +- conf->remove = FLUSH_ONE; ++ cmd = CMD_FLUSH_ONE; + break; + case 'F': +- conf->remove = FLUSH_ALL; ++ cmd = CMD_FLUSH_ALL; + break; + case 'l': + if (optarg && !strncmp(optarg, "l", 1)) +@@ -1053,6 +1053,10 @@ main (int argc, char *argv[]) + condlog(0, "the -w option requires a device"); + goto out; + } ++ if (cmd == CMD_FLUSH_ONE && dev_type != DEV_DEVMAP) { ++ condlog(0, "the -f option requires a map name to remove"); ++ goto out; ++ } + + switch(delegate_to_multipathd(cmd, dev, dev_type, conf)) { + case DELEGATE_OK: +@@ -1086,16 +1090,12 @@ main (int argc, char *argv[]) + } + if (retries < 0) + retries = conf->remove_retries; +- if (conf->remove == FLUSH_ONE) { +- if (dev_type == DEV_DEVMAP) { +- r = dm_suspend_and_flush_map(dev, retries) ? +- RTVL_FAIL : RTVL_OK; +- } else +- condlog(0, "must provide a map name to remove"); +- ++ if (cmd == CMD_FLUSH_ONE) { ++ r = dm_suspend_and_flush_map(dev, retries) ? ++ RTVL_FAIL : RTVL_OK; + goto out; + } +- else if (conf->remove == FLUSH_ALL) { ++ else if (cmd == CMD_FLUSH_ALL) { + r = dm_flush_maps(1, retries) ? RTVL_FAIL : RTVL_OK; + goto out; + } +-- +2.17.2 + diff --git a/0046-change-kpartx-file-and-default-bindir.patch b/0046-change-kpartx-file-and-default-bindir.patch deleted file mode 100644 index f3ef96bbe95a3347879eb66572d174a72b976670..0000000000000000000000000000000000000000 --- a/0046-change-kpartx-file-and-default-bindir.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 768883da9969b76aade3e16d4a5b8cec47d6f30e Mon Sep 17 00:00:00 2001 -From: wangjufeng -Date: Fri, 10 Jan 2020 11:57:08 +0800 -Subject: [PATCH] kpartx: change kpartx file and default bindir - -Change default bindir of multipath to /usr/sbin. Don't -set device name-partition number delimiter in kpartx rules. - -Signed-off-by: wangjufeng ---- - Makefile.inc | 2 +- - kpartx/kpartx.rules | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index af2f5ba..e6466ee 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -49,7 +49,7 @@ ifndef SYSTEMDPATH - endif - - prefix = --exec_prefix = $(prefix) -+exec_prefix = $(prefix)/usr - usr_prefix = $(prefix) - bindir = $(exec_prefix)/sbin - libudevdir = $(prefix)/$(SYSTEMDPATH)/udev -diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules -index 8f99049..8a3a171 100644 ---- a/kpartx/kpartx.rules -+++ b/kpartx/kpartx.rules -@@ -32,6 +32,6 @@ LABEL="mpath_kpartx_end" - GOTO="kpartx_end" - - LABEL="run_kpartx" --RUN+="/sbin/kpartx -un -p -part /dev/$name" -+RUN+="/sbin/kpartx -un /dev/$name" - - LABEL="kpartx_end" --- -1.8.3.1 - diff --git a/0046-multipath-delegate-flushing-maps-to-multipathd.patch b/0046-multipath-delegate-flushing-maps-to-multipathd.patch new file mode 100644 index 0000000000000000000000000000000000000000..1a4a7711b8e2e89fb063a7007b79a4b8b10b36fd --- /dev/null +++ b/0046-multipath-delegate-flushing-maps-to-multipathd.patch @@ -0,0 +1,64 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 2 Jul 2020 19:07:05 -0500 +Subject: [PATCH] multipath: delegate flushing maps to multipathd + +Since there can be problems with removing maps outside of multipathd, +multipath should attempt to delegate this command to multipathd. +However, multipathd doesn't attempt to suspend the device, in order +to avoid potential hangs. If delegating to multipathd fails, multipath +should try the remove itself. + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + multipath/main.c | 14 ++++++++++++++ + multipath/multipath.8 | 4 ++-- + 2 files changed, 16 insertions(+), 2 deletions(-) + +diff --git a/multipath/main.c b/multipath/main.c +index 101fd656..6a24e483 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -820,6 +820,20 @@ int delegate_to_multipathd(enum mpath_cmds cmd, + if (cmd == CMD_CREATE && conf->force_reload == FORCE_RELOAD_YES) { + p += snprintf(p, n, "reconfigure"); + } ++ else if (cmd == CMD_FLUSH_ONE && dev && dev_type == DEV_DEVMAP) { ++ p += snprintf(p, n, "del map %s", dev); ++ /* multipathd doesn't try as hard, to avoid potentially ++ * hanging. If it fails, retry with the regular multipath ++ * command */ ++ r = NOT_DELEGATED; ++ } ++ else if (cmd == CMD_FLUSH_ALL) { ++ p += snprintf(p, n, "del maps"); ++ /* multipathd doesn't try as hard, to avoid potentially ++ * hanging. If it fails, retry with the regular multipath ++ * command */ ++ r = NOT_DELEGATED; ++ } + /* Add other translations here */ + + if (strlen(command) == 0) +diff --git a/multipath/multipath.8 b/multipath/multipath.8 +index 6fb8645a..5b29a5d9 100644 +--- a/multipath/multipath.8 ++++ b/multipath/multipath.8 +@@ -125,11 +125,11 @@ the system. + Other operation modes are chosen by using one of the following command line switches: + .TP + .B \-f +-Flush (remove) a multipath device map specified as parameter, if unused. ++Flush (remove) a multipath device map specified as parameter, if unused. This operation is delegated to the multipathd daemon if it's running. + . + .TP + .B \-F +-Flush (remove) all unused multipath device maps. ++Flush (remove) all unused multipath device maps. This operation is delegated to the multipathd daemon if it's running. + . + .TP + .B \-l +-- +2.17.2 + diff --git a/0047-multipath-add-option-to-skip-multipathd-delegation.patch b/0047-multipath-add-option-to-skip-multipathd-delegation.patch new file mode 100644 index 0000000000000000000000000000000000000000..51284aaa01ee203b8304b28cc71c8057998e7d0a --- /dev/null +++ b/0047-multipath-add-option-to-skip-multipathd-delegation.patch @@ -0,0 +1,63 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 2 Jul 2020 19:07:06 -0500 +Subject: [PATCH] multipath: add option to skip multipathd delegation + +Add the -D option to allow users to skip delegating commands to +multipathd. + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/config.h | 1 + + multipath/main.c | 8 +++++++- + 2 files changed, 8 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/config.h b/libmultipath/config.h +index 55569360..92c61a0d 100644 +--- a/libmultipath/config.h ++++ b/libmultipath/config.h +@@ -190,6 +190,7 @@ struct config { + int ghost_delay; + int find_multipaths_timeout; + int marginal_pathgroups; ++ int skip_delegate; + unsigned int version[3]; + unsigned int sequence_nr; + +diff --git a/multipath/main.c b/multipath/main.c +index 6a24e483..4c43314e 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -817,6 +817,9 @@ int delegate_to_multipathd(enum mpath_cmds cmd, + *p = '\0'; + n = sizeof(command); + ++ if (conf->skip_delegate) ++ return NOT_DELEGATED; ++ + if (cmd == CMD_CREATE && conf->force_reload == FORCE_RELOAD_YES) { + p += snprintf(p, n, "reconfigure"); + } +@@ -890,7 +893,7 @@ main (int argc, char *argv[]) + multipath_conf = conf; + conf->retrigger_tries = 0; + conf->force_sync = 1; +- while ((arg = getopt(argc, argv, ":adcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { ++ while ((arg = getopt(argc, argv, ":adDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { + switch(arg) { + case 1: printf("optarg : %s\n",optarg); + break; +@@ -922,6 +925,9 @@ main (int argc, char *argv[]) + if (cmd == CMD_CREATE) + cmd = CMD_DRY_RUN; + break; ++ case 'D': ++ conf->skip_delegate = 1; ++ break; + case 'f': + cmd = CMD_FLUSH_ONE; + break; +-- +2.17.2 + diff --git a/0047-multipathd-ignore-failed-wwid-recheck.patch b/0047-multipathd-ignore-failed-wwid-recheck.patch deleted file mode 100644 index 2cca42e52c1221acfc0746f6d43af25f5265f100..0000000000000000000000000000000000000000 --- a/0047-multipathd-ignore-failed-wwid-recheck.patch +++ /dev/null @@ -1,74 +0,0 @@ -author Benjamin Marzinski -Sat, 30 Mar 2019 14:05:56 +0800 (01:05 -0500) -committer Christophe Varoqui -Thu, 18 Apr 2019 19:03:34 +0800 (13:03 +0200) -commit 3ad48a0bc002f3d1b2a27eafecfd7fbb390bfb94 -multipathd: ignore failed wwid recheck - -If disable_changed_wwids is set, when multipathd gets a change event on -a path, it verifies that the wwid hasn't changed in uev_update_path(). -If get_uid() failed, uev_update_path treated this as a wwid change to 0. -This could cause paths to suddenly be dropped due to an issue with -getting the wwid. Even if get_uid() failed because the path was down, -it no change uevent happend when it later became active, multipathd -would continue to ignore the path. Also, scsi_uid_fallback() clears the -failure return if it doesn't attempt to fallback, causing get_uid() -to return success, when it actually failed. - -Multipathd should neither set nor clear wwid_changed if get_uid() -returned failure. Also, scsi_uid_fallback() should retain the old return -value if it doesn't attempt to fallback. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/discovery.c | 6 +++--- - multipathd/main.c | 6 ++++-- - 2 files changed, 7 insertions(+), 5 deletions(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 1369f38..a852843 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -1862,9 +1862,9 @@ get_vpd_uid(struct path * pp) - } - - static ssize_t scsi_uid_fallback(struct path *pp, int path_state, -- const char **origin) -+ const char **origin, ssize_t old_len) - { -- ssize_t len = 0; -+ ssize_t len = old_len; - int retrigger; - struct config *conf; - -@@ -1935,7 +1935,7 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev) - origin = "sysfs"; - } - if (len <= 0 && pp->bus == SYSFS_BUS_SCSI) -- len = scsi_uid_fallback(pp, path_state, &origin); -+ len = scsi_uid_fallback(pp, path_state, &origin, len); - } - if ( len < 0 ) { - condlog(1, "%s: failed to get %s uid: %s", -diff --git a/multipathd/main.c b/multipathd/main.c -index 872843c..49d1469 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -1246,9 +1246,11 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) - char wwid[WWID_SIZE]; - - strcpy(wwid, pp->wwid); -- get_uid(pp, pp->state, uev->udev); -+ rc = get_uid(pp, pp->state, uev->udev); - -- if (strncmp(wwid, pp->wwid, WWID_SIZE) != 0) { -+ if (rc != 0) -+ strcpy(pp->wwid, wwid); -+ else if (strncmp(wwid, pp->wwid, WWID_SIZE) != 0) { - condlog(0, "%s: path wwid changed from '%s' to '%s'. %s", - uev->kernel, wwid, pp->wwid, - (disable_changed_wwids ? "disallowing" : --- -2.19.1 - - diff --git a/0048-Makefile.inc-trim-extra-information-from-systemd-ver.patch b/0048-Makefile.inc-trim-extra-information-from-systemd-ver.patch new file mode 100644 index 0000000000000000000000000000000000000000..5c3f61412df8cf202a583ba5e619853bed218621 --- /dev/null +++ b/0048-Makefile.inc-trim-extra-information-from-systemd-ver.patch @@ -0,0 +1,30 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 6 Jul 2020 13:21:12 -0500 +Subject: [PATCH] Makefile.inc: trim extra information from systemd version + +Some systemd versions print extra information in the +"pkg-config --modversion" output, which confuses make. Trim this +off. + +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile.inc b/Makefile.inc +index e7256e3a..8ea3352d 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -37,7 +37,7 @@ endif + + ifndef SYSTEMD + ifeq ($(shell pkg-config --modversion libsystemd >/dev/null 2>&1 && echo 1), 1) +- SYSTEMD = $(shell pkg-config --modversion libsystemd) ++ SYSTEMD = $(shell pkg-config --modversion libsystemd | awk '{print $$1}') + else + ifeq ($(shell systemctl --version >/dev/null 2>&1 && echo 1), 1) + SYSTEMD = $(shell systemctl --version 2> /dev/null | \ +-- +2.17.2 + diff --git a/0048-libmultipath-group_by_prio-fix-signedness-bug.patch b/0048-libmultipath-group_by_prio-fix-signedness-bug.patch deleted file mode 100644 index 7248399033fec13b4dbe0dd491a6709a3b057131..0000000000000000000000000000000000000000 --- a/0048-libmultipath-group_by_prio-fix-signedness-bug.patch +++ /dev/null @@ -1,30 +0,0 @@ -From a358e60548ddb4631ed1b4ea404f71e1ea8f57e5 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 11 Apr 2019 12:49:20 +0200 -Subject: [PATCH 1/8] libmultipath: group_by_prio: fix signedness bug - -pp->priority can be negative, so we we shouldn't compare -it with an unsigned int. - -Signed-off-by: Martin Wilck ---- - libmultipath/pgpolicies.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/pgpolicies.c b/libmultipath/pgpolicies.c -index ac2596a..660768a 100644 ---- a/libmultipath/pgpolicies.c -+++ b/libmultipath/pgpolicies.c -@@ -312,7 +312,7 @@ out: - int group_by_prio(struct multipath *mp) - { - int i; -- unsigned int prio; -+ int prio; - struct path * pp; - struct pathgroup * pgp; - vector pathvec = NULL; --- -1.8.3.1 - - diff --git a/0049-kpartx-fix-Wsign-compare-error.patch b/0049-kpartx-fix-Wsign-compare-error.patch new file mode 100644 index 0000000000000000000000000000000000000000..ffaa477820e487c3e81320fe0d9b4ab01bb86928 --- /dev/null +++ b/0049-kpartx-fix-Wsign-compare-error.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 6 Jul 2020 17:28:46 -0500 +Subject: [PATCH] kpartx: fix -Wsign-compare error + +Signed-off-by: Benjamin Marzinski +--- + kpartx/kpartx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kpartx/kpartx.c b/kpartx/kpartx.c +index c24ad6d9..653ce0c8 100644 +--- a/kpartx/kpartx.c ++++ b/kpartx/kpartx.c +@@ -738,7 +738,7 @@ struct block { + /* blknr is always in 512 byte blocks */ + char * + getblock (int fd, unsigned int blknr) { +- unsigned int secsz = get_sector_size(fd); ++ int secsz = get_sector_size(fd); + unsigned int blks_per_sec = secsz / 512; + unsigned int secnr = blknr / blks_per_sec; + unsigned int blk_off = (blknr % blks_per_sec) * 512; +-- +2.17.2 + diff --git a/0049-multipathd-handle-NULL-return-from-genhelp_handler.patch b/0049-multipathd-handle-NULL-return-from-genhelp_handler.patch deleted file mode 100644 index e3ed6b65cdfc1d54e6e7cafd2de3afec2c588326..0000000000000000000000000000000000000000 --- a/0049-multipathd-handle-NULL-return-from-genhelp_handler.patch +++ /dev/null @@ -1,44 +0,0 @@ -From dc8b964a03a547eb8dc62b317f9f168a35943ebf Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 17 May 2019 11:14:10 -0500 -Subject: [PATCH 2/8] multipathd: handle NULL return from genhelp_handler - -parse_cmd() wasn't checking if genhelp_handler() returned NULL. It was simply -assuming that it got a string. On NULL, it now returns an error. Found by -Coverity. - -Signed-off-by: Benjamin Marzinski ---- - multipathd/cli.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/multipathd/cli.c b/multipathd/cli.c -index a75afe3..ff17a5b 100644 ---- a/multipathd/cli.c -+++ b/multipathd/cli.c -@@ -465,6 +465,8 @@ parse_cmd (char * cmd, char ** reply, int * len, void * data, int timeout ) - - if (r) { - *reply = genhelp_handler(cmd, r); -+ if (*reply == NULL) -+ return EINVAL; - *len = strlen(*reply) + 1; - return 0; - } -@@ -472,9 +474,11 @@ parse_cmd (char * cmd, char ** reply, int * len, void * data, int timeout ) - h = find_handler(fingerprint(cmdvec)); - - if (!h || !h->fn) { -+ free_keys(cmdvec); - *reply = genhelp_handler(cmd, EINVAL); -+ if (*reply == NULL) -+ return EINVAL; - *len = strlen(*reply) + 1; -- free_keys(cmdvec); - return 0; - } - --- -1.8.3.1 - - diff --git a/0011-change-order-of-multipath.rules.patch b/0050-RH-fixup-udev-rules-for-redhat.patch similarity index 47% rename from 0011-change-order-of-multipath.rules.patch rename to 0050-RH-fixup-udev-rules-for-redhat.patch index 90de0e73e53c42a42d170c2e6ef537866044aca6..b1f5bebc5d489ea01170e4c7533fc8a267c32f2c 100644 --- a/0011-change-order-of-multipath.rules.patch +++ b/0050-RH-fixup-udev-rules-for-redhat.patch @@ -1,19 +1,46 @@ -From 4340aca696857c1077b00ff6bdc0454a07929aad Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski -Date: Fri, 15 May 2015 18:14:09 -0500 -Subject: [PATCH] change order of multipath.rules +Date: Thu, 13 Apr 2017 07:22:23 -0500 +Subject: [PATCH] RH: fixup udev rules for redhat -At least for RedHat, the rule that calls scsi_id is -60-persistent-storage.rules, so the multipath rule needs to come -after this. +The multipath rules need to run after scsi_id is run. This means moving +them after 60-persistent-storage.rules for redhat. Redhat also uses a +different naming scheme for partitions than SuSE. Signed-off-by: Benjamin Marzinski --- - multipath/Makefile | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) + Makefile.inc | 2 +- + kpartx/kpartx.rules | 2 +- + multipath/Makefile | 4 ++-- + 3 files changed, 4 insertions(+), 4 deletions(-) +diff --git a/Makefile.inc b/Makefile.inc +index 8ea3352d..873fb62f 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -53,7 +53,7 @@ endif + prefix = + exec_prefix = $(prefix) + usr_prefix = $(prefix) +-bindir = $(exec_prefix)/sbin ++bindir = $(exec_prefix)/usr/sbin + libudevdir = $(prefix)/$(SYSTEMDPATH)/udev + udevrulesdir = $(libudevdir)/rules.d + multipathdir = $(TOPDIR)/libmultipath +diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules +index d7527d7d..0e0d70d5 100644 +--- a/kpartx/kpartx.rules ++++ b/kpartx/kpartx.rules +@@ -36,6 +36,6 @@ LABEL="mpath_kpartx_end" + GOTO="kpartx_end" + + LABEL="run_kpartx" +-RUN+="/sbin/kpartx -un -p -part /dev/$name" ++RUN+="/sbin/kpartx -un /dev/$name" + + LABEL="kpartx_end" diff --git a/multipath/Makefile b/multipath/Makefile -index 0828a8f..b9bbb3c 100644 +index 0828a8f7..b9bbb3cf 100644 --- a/multipath/Makefile +++ b/multipath/Makefile @@ -24,7 +24,7 @@ install: @@ -35,5 +62,5 @@ index 0828a8f..b9bbb3c 100644 $(RM) $(DESTDIR)$(man5dir)/$(EXEC).conf.5.gz -- -1.8.3.1 +2.17.2 diff --git a/0050-libmultipath-fix-parsing-of-VPD-83-type-1-T10-vendor.patch b/0050-libmultipath-fix-parsing-of-VPD-83-type-1-T10-vendor.patch deleted file mode 100644 index 9f537771eb7f131dfd7458265d3e2f818fc1aa7c..0000000000000000000000000000000000000000 --- a/0050-libmultipath-fix-parsing-of-VPD-83-type-1-T10-vendor.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 552bcf2f6245cbce4326455e28ab7c1160871978 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 24 Jun 2019 11:27:40 +0200 -Subject: [PATCH 3/8] libmultipath: fix parsing of VPD 83 type 1 (T10 vendor - ID) - -In the buffer overflow case, the code would set p_len = out_len - len - 2, -then len = len + plen = out_len - 2, and check if len >= out_len - 1, -which is never the case. Rather, set p_len = out_len - len -1, and -check the length again before appending the underscore. - -Fixes: 18176202e75c "Read wwid from sysfs vpg_pg83 attribute" -Signed-off-by: Martin Wilck ---- - libmultipath/discovery.c | 11 +++++++++-- - 1 file changed, 9 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index a852843..9e99d9d 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -1151,8 +1151,11 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, - p = vpd; - while ((p = memchr(vpd, ' ', vpd_len))) { - p_len = p - vpd; -- if (len + p_len > out_len - 1) -- p_len = out_len - len - 2; -+ if (len + p_len > out_len - 1) { -+ condlog(1, "%s: WWID overflow, type 1, %d/%lu bytes required", -+ __func__, len + p_len, out_len); -+ p_len = out_len - len - 1; -+ } - memcpy(out + len, vpd, p_len); - len += p_len; - if (len >= out_len - 1) { -@@ -1161,6 +1164,10 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, - } - out[len] = '_'; - len ++; -+ if (len >= out_len - 1) { -+ out[len] = '\0'; -+ break; -+ } - vpd = p; - vpd_len -= p_len; - while (vpd && *vpd == ' ') { --- -1.8.3.1 - - diff --git a/0012-RH-Remove-the-property-blacklist-exception-builtin.patch b/0051-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 56% rename from 0012-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0051-RH-Remove-the-property-blacklist-exception-builtin.patch index 87eba36477684a679377e9872ecb22a22982d75b..f760f877f3ed57679ae988d6956b83ee60aeb0f8 100644 --- a/0012-RH-Remove-the-property-blacklist-exception-builtin.patch +++ b/0051-RH-Remove-the-property-blacklist-exception-builtin.patch @@ -13,15 +13,16 @@ it. Signed-off-by: Benjamin Marzinski --- - libmultipath/blacklist.c | 12 ++++-------- - multipath/multipath.conf.5 | 14 ++++++-------- - 2 files changed, 10 insertions(+), 16 deletions(-) + libmultipath/blacklist.c | 9 ++------- + multipath/multipath.conf.5 | 11 ++++++----- + tests/blacklist.c | 6 ++---- + 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c -index 318ec03..c0cfbca 100644 +index db58ccca..0c58aa32 100644 --- a/libmultipath/blacklist.c +++ b/libmultipath/blacklist.c -@@ -204,12 +204,6 @@ setup_default_blist (struct config * conf) +@@ -187,12 +187,6 @@ setup_default_blist (struct config * conf) if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT)) return 1; @@ -34,14 +35,10 @@ index 318ec03..c0cfbca 100644 vector_foreach_slot (conf->hwtable, hwe, i) { if (hwe->bl_product) { if (find_blacklist_device(conf->blist_device, -@@ -394,9 +388,11 @@ filter_property(struct config * conf, struct udev_device * udev) - if (udev) { - /* - * This is the inverse of the 'normal' matching; -- * the environment variable _has_ to match. -+ * the environment variable _has_ to match -+ * if a whitelist is present. - */ +@@ -394,7 +388,8 @@ filter_property(struct config *conf, struct udev_device *udev, int lvl, + *uid_attribute != '\0'; + bool uid_attr_seen = false; + - r = MATCH_PROPERTY_BLIST_MISSING; + if (VECTOR_SIZE(conf->elist_property)) + r = MATCH_PROPERTY_BLIST_MISSING; @@ -49,10 +46,10 @@ index 318ec03..c0cfbca 100644 udev_device_get_properties_list_entry(udev)) { diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 6333366..3dab26b 100644 +index 5adaced6..42a192f6 100644 --- a/multipath/multipath.conf.5 +++ b/multipath/multipath.conf.5 -@@ -1195,16 +1195,14 @@ keywords. Both are regular expressions. For a full description of these keywords +@@ -1296,9 +1296,14 @@ keywords. Both are regular expressions. For a full description of these keywords Regular expression for an udev property. All devices that have matching udev properties will be excluded/included. The handling of the \fIproperty\fR keyword is special, @@ -61,20 +58,48 @@ index 6333366..3dab26b 100644 +least one whitelisted udev property; otherwise they're treated as blacklisted, and the message "\fIblacklisted, udev property missing\fR" is displayed in the logs. --. --.RS --.PP --The default \fIblacklist exception\fR is: \fB(SCSI_IDENT_|ID_WWN)\fR, causing --well-behaved SCSI devices and devices that provide a WWN (World Wide Number) --to be included, and all others to be excluded. --.RE +For example, setting the property blacklist_exception to +\fB(SCSI_IDENT_|ID_WWN)\fR, will cause well-behaved SCSI devices and devices +that provide a WWN (World Wide Number) to be included, and all others to be +excluded. This works to exclude most non-multipathable devices. + . + .RS + .PP +@@ -1309,10 +1314,6 @@ Blacklisting by missing properties is only applied to devices which do have the + property specified by \fIuid_attribute\fR (e.g. \fIID_SERIAL\fR) + set. Previously, it was applied to every device, possibly causing devices to be + blacklisted because of temporary I/O error conditions. +-.PP +-The default \fIblacklist exception\fR is: \fB(SCSI_IDENT_|ID_WWN)\fR, causing +-well-behaved SCSI devices and devices that provide a WWN (World Wide Number) +-to be included, and all others to be excluded. + .RE .TP .B protocol - Regular expression for the protocol of a device to be excluded/included. +diff --git a/tests/blacklist.c b/tests/blacklist.c +index d5c40898..d20e97af 100644 +--- a/tests/blacklist.c ++++ b/tests/blacklist.c +@@ -380,7 +380,7 @@ static void test_property_missing(void **state) + conf.blist_property = blist_property_wwn; + expect_condlog(3, "sdb: blacklisted, udev property missing\n"); + assert_int_equal(filter_property(&conf, &udev, 3, "ID_SERIAL"), +- MATCH_PROPERTY_BLIST_MISSING); ++ MATCH_NOTHING); + assert_int_equal(filter_property(&conf, &udev, 3, "ID_BLAH"), + MATCH_NOTHING); + assert_int_equal(filter_property(&conf, &udev, 3, ""), +@@ -472,9 +472,7 @@ static void test_filter_path_missing1(void **state) + conf.blist_device = blist_device_foo_bar; + conf.blist_protocol = blist_protocol_fcp; + conf.blist_wwid = blist_wwid_xyzzy; +- expect_condlog(3, "sdb: blacklisted, udev property missing\n"); +- assert_int_equal(filter_path(&conf, &miss1_pp), +- MATCH_PROPERTY_BLIST_MISSING); ++ assert_int_equal(filter_path(&conf, &miss1_pp), MATCH_NOTHING); + } + + /* This one matches the property whitelist, to test the other missing -- -2.7.4 +2.17.2 diff --git a/0051-libmultipath-Fix-buffer-overflow-in-parse_vpd_pg80.patch b/0051-libmultipath-Fix-buffer-overflow-in-parse_vpd_pg80.patch deleted file mode 100644 index 627443f0f617d52e5c3d6850ca676eaa0891f4eb..0000000000000000000000000000000000000000 --- a/0051-libmultipath-Fix-buffer-overflow-in-parse_vpd_pg80.patch +++ /dev/null @@ -1,31 +0,0 @@ -From c00ee906582b87aeced4b2fb0caa011edb5cbc17 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 24 Jun 2019 11:27:41 +0200 -Subject: [PATCH 4/8] libmultipath: Fix buffer overflow in parse_vpd_pg80() - -We set out[len] = '\0' later, thus we should set len to no more then -out_len - 1. - -Fixes: 756ef73b7197 "Separate out vpd parsing functions" -Signed-off-by: Martin Wilck ---- - libmultipath/discovery.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 9e99d9d..416823b 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -999,7 +999,7 @@ parse_vpd_pg80(const unsigned char *in, char *out, size_t out_len) - if (len >= out_len) { - condlog(2, "vpd pg80 overflow, %d/%d bytes required", - len, (int)out_len); -- len = out_len; -+ len = out_len - 1; - } - if (len > 0) { - memcpy(out, in + 4, len); --- -1.8.3.1 - - diff --git a/0052-RH-don-t-start-without-a-config-file.patch b/0052-RH-don-t-start-without-a-config-file.patch new file mode 100644 index 0000000000000000000000000000000000000000..47123007d4d1bfa59309b699554e34b7dbc0af64 --- /dev/null +++ b/0052-RH-don-t-start-without-a-config-file.patch @@ -0,0 +1,106 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 15 Oct 2014 10:39:30 -0500 +Subject: [PATCH] RH: don't start without a config file + +If /etc/multipath.conf doesn't exist, don't start multipathd and blacklist +all devices when running multipath. A completely blank configuration file +is almost never what users want. Also, people may have the multipath +packages installed but don't want to use them. This patch provides a +simple way to disable multipath. Simply removing or renaming +/etc/multipath.conf will keep multipath from doing anything. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/config.c | 15 +++++++++++++++ + libmultipath/config.h | 1 + + multipath/multipath.rules | 1 + + multipathd/multipathd.8 | 2 ++ + multipathd/multipathd.service | 1 + + 5 files changed, 20 insertions(+) + +diff --git a/libmultipath/config.c b/libmultipath/config.c +index 658bec8b..1c02e230 100644 +--- a/libmultipath/config.c ++++ b/libmultipath/config.c +@@ -26,6 +26,7 @@ + #include "devmapper.h" + #include "mpath_cmd.h" + #include "propsel.h" ++#include "version.h" + + static int + hwe_strmatch (const struct hwentry *hwe1, const struct hwentry *hwe2) +@@ -778,6 +779,20 @@ load_config (char * file) + goto out; + } + factorize_hwtable(conf->hwtable, builtin_hwtable_size, file); ++ } else { ++ condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices."); ++ if (conf->blist_devnode == NULL) { ++ conf->blist_devnode = vector_alloc(); ++ if (!conf->blist_devnode) { ++ condlog(0, "cannot allocate blacklist\n"); ++ goto out; ++ } ++ } ++ if (store_ble(conf->blist_devnode, strdup(".*"), ++ ORIGIN_NO_CONFIG)) { ++ condlog(0, "cannot store default no-config blacklist\n"); ++ goto out; ++ } + } + + conf->processed_main_config = 1; +diff --git a/libmultipath/config.h b/libmultipath/config.h +index 92c61a0d..160867cd 100644 +--- a/libmultipath/config.h ++++ b/libmultipath/config.h +@@ -9,6 +9,7 @@ + + #define ORIGIN_DEFAULT 0 + #define ORIGIN_CONFIG 1 ++#define ORIGIN_NO_CONFIG 2 + + /* + * In kernel, fast_io_fail == 0 means immediate failure on rport delete. +diff --git a/multipath/multipath.rules b/multipath/multipath.rules +index 9df11a95..0486bf70 100644 +--- a/multipath/multipath.rules ++++ b/multipath/multipath.rules +@@ -9,6 +9,7 @@ IMPORT{cmdline}="nompath" + ENV{nompath}=="?*", GOTO="end_mpath" + IMPORT{cmdline}="multipath" + ENV{multipath}=="off", GOTO="end_mpath" ++TEST!="/etc/multipath.conf", GOTO="end_mpath" + + ENV{DEVTYPE}!="partition", GOTO="test_dev" + IMPORT{parent}="DM_MULTIPATH_DEVICE_PATH" +diff --git a/multipathd/multipathd.8 b/multipathd/multipathd.8 +index 048a838d..8bd47a80 100644 +--- a/multipathd/multipathd.8 ++++ b/multipathd/multipathd.8 +@@ -39,6 +39,8 @@ map regains its maximum performance and redundancy. + This daemon executes the external \fBmultipath\fR tool when events occur. + In turn, the multipath tool signals the multipathd daemon when it is done with + devmap reconfiguration, so that it can refresh its failed path list. ++ ++In this Linux distribution, multipathd does not run unless a /etc/multipath.conf file exists. + . + . + .\" ---------------------------------------------------------------------------- +diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service +index ba24983e..17434cef 100644 +--- a/multipathd/multipathd.service ++++ b/multipathd/multipathd.service +@@ -4,6 +4,7 @@ Wants=systemd-udev-trigger.service systemd-udev-settle.service + Before=iscsi.service iscsid.service lvm2-activation-early.service + Before=local-fs-pre.target blk-availability.service + After=multipathd.socket systemd-udev-trigger.service systemd-udev-settle.service ++ConditionPathExists=/etc/multipath.conf + DefaultDependencies=no + Conflicts=shutdown.target + ConditionKernelCommandLine=!nompath +-- +2.17.2 + diff --git a/0052-libmultipath-fix-another-WWID-overflow-in-parse_vpd_.patch b/0052-libmultipath-fix-another-WWID-overflow-in-parse_vpd_.patch deleted file mode 100644 index abeb26dc6ed47da1d36c7e1692a9ab5522eeec87..0000000000000000000000000000000000000000 --- a/0052-libmultipath-fix-another-WWID-overflow-in-parse_vpd_.patch +++ /dev/null @@ -1,31 +0,0 @@ -From f39a97d2972e3959985c2771f1fc53c45897acfb Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 24 Jun 2019 11:27:43 +0200 -Subject: [PATCH 5/8] libmultipath: fix another WWID overflow in - parse_vpd_pg83() - -This one is an obvious typo. - -Fixes: 18176202e75c "Read wwid from sysfs vpg_pg83 attribute" -Signed-off-by: Martin Wilck ---- - libmultipath/discovery.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 416823b..c57369c 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -1136,7 +1136,7 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, - len = 1; - vpd += 4; - vpd_len -= 4; -- if (vpd_len > out_len + 2) -+ if (vpd_len > out_len - 2) - vpd_len = out_len - 2; - memcpy(out, vpd, vpd_len); - len = vpd_len + 1; --- -1.8.3.1 - - diff --git a/0053-RH-use-rpm-optflags-if-present.patch b/0053-RH-use-rpm-optflags-if-present.patch new file mode 100644 index 0000000000000000000000000000000000000000..d6c97c1b90d3abaa00930903f4ed253e3360c4e2 --- /dev/null +++ b/0053-RH-use-rpm-optflags-if-present.patch @@ -0,0 +1,60 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 19 Apr 2017 06:10:01 -0500 +Subject: [PATCH] RH: use rpm optflags if present + +Use the passed in optflags when compiling as an RPM, and keep the +default flags as close as possible to the current fedora flags, while +still being generic. + +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 24 ++++++++++++++++++------ + 1 file changed, 18 insertions(+), 6 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 873fb62f..479523bc 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -89,15 +89,27 @@ TEST_CC_OPTION = $(shell \ + echo "$(2)"; \ + fi) + +-STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector) + ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers,) + WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered -Wno-error=clobbered,) + +-OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 +-WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 -Werror=implicit-int \ ++ifndef RPM_OPT_FLAGS ++ STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector) ++ OPTFLAGS := -O2 -g -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions \ ++ $(STACKPROT) -grecord-gcc-switches \ ++ -fasynchronous-unwind-tables --param=ssp-buffer-size=4 ++ ifeq ($(shell test -f /usr/lib/rpm/redhat/redhat-hardened-cc1 && echo 1),1) ++ OPTFLAGS += -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 ++ endif ++ ifeq ($(shell test -f /usr/lib/rpm/redhat/redhat-annobin-cc1 && echo 1),1) ++ OPTFLAGS += -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 ++ endif ++else ++ OPTFLAGS := $(RPM_OPT_FLAGS) --param=ssp-buffer-size=4 ++endif ++WARNFLAGS := -Werror -Wextra -Wformat=2 -Werror=implicit-int \ + -Werror=implicit-function-declaration -Werror=format-security \ +- $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) +-CPPFLAGS := -Wp,-D_FORTIFY_SOURCE=2 ++ $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) \ ++ -Wstrict-prototypes + CFLAGS := $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ + -DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" \ + -MMD -MP +@@ -135,4 +147,4 @@ check_file = $(shell \ + + %.o: %.c + @echo building $@ because of $? +- $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< ++ $(CC) $(CFLAGS) -c -o $@ $< +-- +2.17.2 + diff --git a/0053-libmultipath-fix-possible-WWID-overflow-in-parse_vpd.patch b/0053-libmultipath-fix-possible-WWID-overflow-in-parse_vpd.patch deleted file mode 100644 index 256de9a422cb8a6fa5f73305f5ee8e1149eefa0a..0000000000000000000000000000000000000000 --- a/0053-libmultipath-fix-possible-WWID-overflow-in-parse_vpd.patch +++ /dev/null @@ -1,66 +0,0 @@ -From e8a63834f966cc605429c5b2ab3edc79a46c3bff Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 24 Jun 2019 11:27:42 +0200 -Subject: [PATCH 6/8] libmultipath: fix possible WWID overflow in - parse_vpd_pg83() - -We have to check the remaining length before printing to the -output buffer, not afterwards. - -Fixes: 18176202e75c "Read wwid from sysfs vpg_pg83 attribute" -Signed-off-by: Martin Wilck ---- - libmultipath/discovery.c | 16 +++------------- - 1 file changed, 3 insertions(+), 13 deletions(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index c57369c..34d425b 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -1098,11 +1098,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, - int i; - - len = sprintf(out, "%d", vpd_type); -- for (i = 0; i < vpd_len; i++) { -+ for (i = 0; i < vpd_len && len < out_len - 2; i++) { - len += sprintf(out + len, - "%02x", vpd[i]); -- if (len >= out_len) -- break; - } - } else if (vpd_type == 0x8) { - if (!memcmp("eui.", vpd, 4)) { -@@ -1110,27 +1108,19 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, - len = 1; - vpd += 4; - vpd_len -= 4; -- for (i = 0; i < vpd_len; i++) { -+ for (i = 0; i < vpd_len && len < out_len - 1; i++) { - len += sprintf(out + len, "%c", - tolower(vpd[i])); -- if (len >= out_len) -- break; - } -- len = vpd_len + 1; -- out[len] = '\0'; - } else if (!memcmp("naa.", vpd, 4)) { - out[0] = '3'; - len = 1; - vpd += 4; - vpd_len -= 4; -- for (i = 0; i < vpd_len; i++) { -+ for (i = 0; i < vpd_len && len < out_len - 1; i++) { - len += sprintf(out + len, "%c", - tolower(vpd[i])); -- if (len >= out_len) -- break; - } -- len = vpd_len + 1; -- out[len] = '\0'; - } else { - out[0] = '8'; - len = 1; --- -1.8.3.1 - - diff --git a/0013-RH-add-mpathconf.patch b/0054-RH-add-mpathconf.patch similarity index 74% rename from 0013-RH-add-mpathconf.patch rename to 0054-RH-add-mpathconf.patch index 10af8449c8b822214504b92ec8091bc807b1047b..64807114860af888550f5fd8b34286e6e7a79611 100644 --- a/0013-RH-add-mpathconf.patch +++ b/0054-RH-add-mpathconf.patch @@ -10,22 +10,31 @@ command line. But, mostly it is used to get a multipath.conf file with the OS defaults, and to enable and disable multipathing via a single command. -Changed-by: hy-euler - Do not modify the file libmultipath/config.c, because it modifies - another patch which is not present in openEuler. - Signed-off-by: Benjamin Marzinski -Signed-off-by: hy-euler --- + libmultipath/config.c | 2 + multipath/Makefile | 5 + - multipath/mpathconf | 464 ++++++++++++++++++++++++++++++++++++++++++++++++++ - multipath/mpathconf.8 | 119 +++++++++++++ - 3 files changed, 588 insertions(+) + multipath/mpathconf | 565 ++++++++++++++++++++++++++++++++++++++++++ + multipath/mpathconf.8 | 135 ++++++++++ + 4 files changed, 707 insertions(+) create mode 100644 multipath/mpathconf create mode 100644 multipath/mpathconf.8 +diff --git a/libmultipath/config.c b/libmultipath/config.c +index 1c02e230..a253a936 100644 +--- a/libmultipath/config.c ++++ b/libmultipath/config.c +@@ -781,6 +781,8 @@ load_config (char * file) + factorize_hwtable(conf->hwtable, builtin_hwtable_size, file); + } else { + condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices."); ++ condlog(0, "You can run \"/sbin/mpathconf --enable\" to create"); ++ condlog(0, "/etc/multipath.conf. See man mpathconf(8) for more details"); + if (conf->blist_devnode == NULL) { + conf->blist_devnode = vector_alloc(); + if (!conf->blist_devnode) { diff --git a/multipath/Makefile b/multipath/Makefile -index b9bbb3c..e720c7f 100644 +index b9bbb3cf..e720c7f6 100644 --- a/multipath/Makefile +++ b/multipath/Makefile @@ -18,10 +18,12 @@ $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so @@ -60,10 +69,10 @@ index b9bbb3c..e720c7f 100644 $(RM) core *.o $(EXEC) *.gz diff --git a/multipath/mpathconf b/multipath/mpathconf new file mode 100644 -index 0000000..e839134 +index 00000000..f0d09cbb --- /dev/null +++ b/multipath/mpathconf -@@ -0,0 +1,464 @@ +@@ -0,0 +1,565 @@ +#!/bin/bash +# +# Copyright (C) 2010 Red Hat, Inc. All rights reserved. @@ -83,7 +92,7 @@ index 0000000..e839134 +# This program was largely ripped off from lvmconf +# + -+unset ENABLE FIND FRIENDLY MODULE MULTIPATHD HAVE_DISABLE HAVE_WWID_DISABLE HAVE_FIND HAVE_BLACKLIST HAVE_EXCEPTIONS HAVE_DEFAULTS HAVE_FRIENDLY HAVE_MULTIPATHD HAVE_MODULE HAVE_OUTFILE SHOW_STATUS CHANGED_CONFIG WWID_LIST ++unset ENABLE FIND FRIENDLY PROPERTY FOREIGN MODULE MULTIPATHD HAVE_DISABLE HAVE_WWID_DISABLE HAVE_FIND HAVE_BLACKLIST HAVE_EXCEPTIONS HAVE_DEFAULTS HAVE_FRIENDLY HAVE_PROPERTY HAVE_FOREIGN HAVE_MULTIPATHD HAVE_MODULE HAVE_OUTFILE SHOW_STATUS CHANGED_CONFIG WWID_LIST + +DEFAULT_CONFIG="# device-mapper-multipath configuration file + @@ -98,10 +107,6 @@ index 0000000..e839134 +defaults { + user_friendly_names yes + find_multipaths yes -+} -+ -+blacklist_exceptions { -+ property \"(SCSI_IDENT_|ID_WWN)\" +}" + +CONFIGFILE="/etc/multipath.conf" @@ -120,6 +125,8 @@ index 0000000..e839134 + echo "Only allow certain wwids (instead of enable): --allow " + echo "Set user_friendly_names (Default y): --user_friendly_names " + echo "Set find_multipaths (Default y): --find_multipaths " ++ echo "Set default property blacklist (Default n): --property_blacklist " ++ echo "Set enable_foreign to show foreign devices (Default n): --enable_foreign " + echo "Load the dm-multipath modules on enable (Default y): --with_module " + echo "start/stop/reload multipathd (Default n): --with_multipathd " + echo "select output file (Default /etc/multipath.conf): --outfile " @@ -221,6 +228,24 @@ index 0000000..e839134 + exit 1 + fi + ;; ++ --property_blacklist) ++ if [ -n "$2" ]; then ++ PROPERTY=$2 ++ shift 2 ++ else ++ usage ++ exit 1 ++ fi ++ ;; ++ --enable_foreign) ++ if [ -n "$2" ]; then ++ FOREIGN=$2 ++ shift 2 ++ else ++ usage ++ exit 1 ++ fi ++ ;; + --with_module) + if [ -n "$2" ]; then + MODULE=$2 @@ -258,11 +283,13 @@ index 0000000..e839134 + +function validate_args +{ -+ if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$MODULE" ]; then ++ if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$PROPERTY" -o -n "$MODULE" -o -n "$FOREIGN" ]; then + echo "ignoring extra parameters on disable" + FRIENDLY="" + FIND="" ++ PROPERTY="" + MODULE="" ++ FOREIGN="" + fi + if [ -n "$FRIENDLY" ] && [ "$FRIENDLY" != "y" -a "$FRIENDLY" != "n" ]; then + echo "--user_friendly_names must be either 'y' or 'n'" @@ -272,7 +299,15 @@ index 0000000..e839134 + echo "--find_multipaths must be either 'y' or 'n'" + exit 1 + fi -+ if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" ]; then ++ if [ -n "$PROPERTY" ] && [ "$PROPERTY" != "y" -a "$PROPERTY" != "n" ]; then ++ echo "--property_blacklist must be either 'y' or 'n'" ++ exit 1 ++ fi ++ if [ -n "$FOREIGN" ] && [ "$FOREIGN" != "y" -a "$FOREIGN" != "n" ]; then ++ echo "--enable_foreign must be either 'y' or 'n'" ++ exit 1 ++ fi ++ if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" -a -z "$PROPERTY" -a -z "$FOREIGN" ]; then + SHOW_STATUS=1 + fi + if [ -n "$MODULE" ] && [ "$MODULE" != "y" -a "$MODULE" != "n" ]; then @@ -373,6 +408,25 @@ index 0000000..e839134 + elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]]*\(no\|0\)" ; then + HAVE_FRIENDLY=0 + fi ++ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*enable_foreign" ; then ++ HAVE_FOREIGN=0 ++ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]]*\"\^\$\"" ; then ++ HAVE_FOREIGN=1 ++ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]]*\"NONE\"" ; then ++ HAVE_FOREIGN=1 ++ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]] \"\.\?\*\"" ; then ++ HAVE_FOREIGN=2 ++ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign" ; then ++ HAVE_FOREIGN=3 ++ fi ++fi ++ ++if [ "$HAVE_EXCEPTIONS" = "1" ]; then ++ if sed -n '/^blacklist_exceptions[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"" ; then ++ HAVE_PROPERTY=1 ++ elif sed -n '/^blacklist_exceptions[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"" ; then ++ HAVE_PROPERTY=0 ++ fi +fi + +if [ -n "$SHOW_STATUS" ]; then @@ -391,6 +445,20 @@ index 0000000..e839134 + else + echo "user_friendly_names is enabled" + fi ++ if [ -z "$HAVE_PROPERTY" -o "$HAVE_PROPERTY" = 0 ]; then ++ echo "default property blacklist is disabled" ++ else ++ echo "default property blacklist is enabled" ++ fi ++ if [ -z "$HAVE_FOREIGN" -o "$HAVE_FOREIGN" = 0 ]; then ++ echo "enable_foreign is not set (no foreign multipath devices will be shown)" ++ elif [ "$HAVE_FOREIGN" = 1 ]; then ++ echo "enable_foreign is set (no foreign multipath devices will be shown)" ++ elif [ "$HAVE_FOREIGN" = 2 ]; then ++ echo "enable_foreign is set (all foreign multipath devices will be shown)" ++ else ++ echo "enable_foreign is set (foreign multipath devices may not be shown)" ++ fi + if [ -n "$HAVE_MODULE" ]; then + if [ "$HAVE_MODULE" = 1 ]; then + echo "dm_multipath module is loaded" @@ -498,6 +566,48 @@ index 0000000..e839134 + fi +fi + ++if [ "$PROPERTY" = "n" ]; then ++ if [ "$HAVE_PROPERTY" = 1 ]; then ++ sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/# property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE ++ CHANGED_CONFIG=1 ++ fi ++elif [ "$PROPERTY" = "y" ]; then ++ if [ -z "$HAVE_PROPERTY" -a -z "$HAVE_EXCEPTIONS" ]; then ++ cat >> $TMPFILE << _EOF_ ++ ++blacklist_exceptions { ++ property "(SCSI_IDENT_|ID_WWN)" ++} ++_EOF_ ++ CHANGED_CONFIG=1 ++ elif [ -z "$HAVE_PROPERTY" ]; then ++ sed -i '/^blacklist_exceptions[[:space:]]*{/ a\ ++ property "(SCSI_IDENT_|ID_WWN)" ++' $TMPFILE ++ CHANGED_CONFIG=1 ++ elif [ "$HAVE_PROPERTY" = 0 ]; then ++ sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/ property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE ++ CHANGED_CONFIG=1 ++ fi ++fi ++ ++if [ "$FOREIGN" = "y" ]; then ++ if [ -z "$HAVE_FOREIGN" ]; then ++ sed -i '/^defaults[[:space:]]*{/ a\ ++ enable_foreign ".*" ++' $TMPFILE ++ CHANGED_CONFIG=1 ++ elif [ "$HAVE_FOREIGN" = 0 -o "$HAVE_FOREIGN" = 1 -o "$HAVE_FOREIGN" = 3 ]; then ++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*#\?[[:space:]]*enable_foreign.*$/ enable_foreign ".*"/' $TMPFILE ++ CHANGED_CONFIG=1 ++ fi ++elif [ "$FOREIGN" = "n" ]; then ++ if [ "$HAVE_FOREIGN" = 2 -o "$HAVE_FOREIGN" = 3 ]; then ++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*enable_foreign/# enable_foreign/' $TMPFILE ++ CHANGED_CONFIG=1 ++ fi ++fi ++ +if [ -f "$OUTPUTFILE" ]; then + cp $OUTPUTFILE $OUTPUTFILE.old + if [ $? != 0 ]; then @@ -530,10 +640,10 @@ index 0000000..e839134 +fi diff --git a/multipath/mpathconf.8 b/multipath/mpathconf.8 new file mode 100644 -index 0000000..5b7ae0c +index 00000000..b82961d6 --- /dev/null +++ b/multipath/mpathconf.8 -@@ -0,0 +1,119 @@ +@@ -0,0 +1,135 @@ +.TH MPATHCONF 8 "June 2010" "" "Linux Administrator's Manual" +.SH NAME +mpathconf - A tool for configuring device-mapper-multipath @@ -605,7 +715,7 @@ index 0000000..5b7ae0c +mpathconf will not be able to revert back to its previous state. Because +of this, \fB--outfile\fP is required when using \fB--allow\fP. +.TP -+.B --user_friendly_name \fP { \fBy\fP | \fBn\fP } ++.B --user_friendly_names \fP { \fBy\fP | \fBn\fP } +If set to \fBy\fP, this adds the line +.B user_friendly_names yes +to the @@ -619,7 +729,23 @@ index 0000000..5b7ae0c +to the +.B /etc/multipath.conf +defaults section. If set to \fBn\fP, this removes the line, if present. This -+command can be used aldong with any other command. ++command can be used along with any other command. ++.TP ++.B --property_blacklist \fP { \fBy\fP | \fBn\fP } ++If set to \fBy\fP, this adds the line ++.B property "(SCSI_IDENT_|ID_WWN)" ++to the ++.B /etc/multipath.conf ++blacklist_exceptions section. If set to \fBn\fP, this removes the line, if ++present. This command can be used along with any other command. ++.TP ++.B --enable_foreign\fP { \fBy\fP | \fBn\fP } ++If set to \fBn\fP, this adds the line ++.B enable_foreign "^$" ++to the ++.B /etc/multipath.conf ++defaults section. if set to \fBy\fP, this removes the line, if present. This ++command can be used along with any other command. +.TP +.B --outfile \fB\fP +Write the resulting multipath configuration to \fB\fP instead of @@ -654,6 +780,5 @@ index 0000000..5b7ae0c +.SH AUTHOR +Benjamin Marzinski -- -2.7.4 - +2.17.2 diff --git a/0054-libmultipath-fix-parsing-of-SCSI-name-string-iqn-for.patch b/0054-libmultipath-fix-parsing-of-SCSI-name-string-iqn-for.patch deleted file mode 100644 index e2973af894db631d044079591dc2d6ec46fc95c7..0000000000000000000000000000000000000000 --- a/0054-libmultipath-fix-parsing-of-SCSI-name-string-iqn-for.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 02748f3907fc95fbbf368ffda4ffb4bbf60f948d Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 24 Jun 2019 11:27:44 +0200 -Subject: [PATCH 7/8] libmultipath: fix parsing of SCSI name string, iqn format - -Do not overwrite the leading '8'. - -Signed-off-by: Martin Wilck ---- - libmultipath/discovery.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 34d425b..a4769ee 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -1123,12 +1123,11 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, - } - } else { - out[0] = '8'; -- len = 1; - vpd += 4; - vpd_len -= 4; - if (vpd_len > out_len - 2) - vpd_len = out_len - 2; -- memcpy(out, vpd, vpd_len); -+ memcpy(out + 1, vpd, vpd_len); - len = vpd_len + 1; - out[len] = '\0'; - } --- -1.8.3.1 - - diff --git a/0055-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0055-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch new file mode 100644 index 0000000000000000000000000000000000000000..a10f14738a9cdd64cdd055a2d6208f92bf9e17d8 --- /dev/null +++ b/0055-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch @@ -0,0 +1,169 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Fri, 17 Oct 2014 11:20:34 -0500 +Subject: [PATCH] RH: add wwids from kernel cmdline mpath.wwids with -A + +This patch adds another option to multipath, "-A", which reads +/proc/cmdline for mpath.wwid= options, and adds any wwids it finds +to /etc/multipath/wwids. While this isn't usually important during +normal operation, since these wwids should already be added, it can be +helpful during installation, to make sure that multipath can claim +devices as its own, before LVM or something else makes use of them. The +patch also execs "/sbin/multipath -A" before running multipathd in +multipathd.service + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/wwids.c | 44 +++++++++++++++++++++++++++++++++++ + libmultipath/wwids.h | 1 + + multipath/main.c | 10 ++++++-- + multipath/multipath.8 | 7 +++++- + multipathd/multipathd.service | 1 + + 5 files changed, 60 insertions(+), 3 deletions(-) + +diff --git a/libmultipath/wwids.c b/libmultipath/wwids.c +index 61d9c39e..c7a16636 100644 +--- a/libmultipath/wwids.c ++++ b/libmultipath/wwids.c +@@ -451,3 +451,47 @@ int unmark_failed_wwid(const char *wwid) + print_failed_wwid_result("unmark_failed", wwid, r); + return r; + } ++ ++int remember_cmdline_wwid(void) ++{ ++ FILE *f = NULL; ++ char buf[LINE_MAX], *next, *ptr; ++ int ret = 0; ++ ++ f = fopen("/proc/cmdline", "re"); ++ if (!f) { ++ condlog(0, "can't open /proc/cmdline : %s", strerror(errno)); ++ return -1; ++ } ++ ++ if (!fgets(buf, sizeof(buf), f)) { ++ if (ferror(f)) ++ condlog(0, "read of /proc/cmdline failed : %s", ++ strerror(errno)); ++ else ++ condlog(0, "couldn't read /proc/cmdline"); ++ fclose(f); ++ return -1; ++ } ++ fclose(f); ++ next = buf; ++ while((ptr = strstr(next, "mpath.wwid="))) { ++ ptr += 11; ++ next = strpbrk(ptr, " \t\n"); ++ if (next) { ++ *next = '\0'; ++ next++; ++ } ++ if (strlen(ptr)) { ++ if (remember_wwid(ptr) != 0) ++ ret = -1; ++ } ++ else { ++ condlog(0, "empty mpath.wwid kernel command line option"); ++ ret = -1; ++ } ++ if (!next) ++ break; ++ } ++ return ret; ++} +diff --git a/libmultipath/wwids.h b/libmultipath/wwids.h +index 0c6ee54d..e32a0b0e 100644 +--- a/libmultipath/wwids.h ++++ b/libmultipath/wwids.h +@@ -17,6 +17,7 @@ int remember_wwid(char *wwid); + int check_wwids_file(char *wwid, int write_wwid); + int remove_wwid(char *wwid); + int replace_wwids(vector mp); ++int remember_cmdline_wwid(void); + + enum { + WWID_IS_NOT_FAILED = 0, +diff --git a/multipath/main.c b/multipath/main.c +index 4c43314e..c73f6963 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -135,7 +135,7 @@ usage (char * progname) + fprintf (stderr, " %s [-v level] [-R retries] -F\n", progname); + fprintf (stderr, " %s [-v level] [-l|-ll] [device]\n", progname); + fprintf (stderr, " %s [-v level] [-a|-w] device\n", progname); +- fprintf (stderr, " %s [-v level] -W\n", progname); ++ fprintf (stderr, " %s [-v level] [-A|-W]\n", progname); + fprintf (stderr, " %s [-v level] [-i] [-c|-C] device\n", progname); + fprintf (stderr, " %s [-v level] [-i] [-u|-U]\n", progname); + fprintf (stderr, " %s [-h|-t|-T]\n", progname); +@@ -149,6 +149,8 @@ usage (char * progname) + " -f flush a multipath device map\n" + " -F flush all multipath device maps\n" + " -a add a device wwid to the wwids file\n" ++ " -A add devices from kernel command line mpath.wwids\n" ++ " parameters to wwids file\n" + " -c check if a device should be a path in a multipath device\n" + " -C check if a multipath device has usable paths\n" + " -q allow queue_if_no_path when multipathd is not running\n" +@@ -893,7 +895,7 @@ main (int argc, char *argv[]) + multipath_conf = conf; + conf->retrigger_tries = 0; + conf->force_sync = 1; +- while ((arg = getopt(argc, argv, ":adDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { ++ while ((arg = getopt(argc, argv, ":aAdDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { + switch(arg) { + case 1: printf("optarg : %s\n",optarg); + break; +@@ -970,6 +972,10 @@ main (int argc, char *argv[]) + case 'T': + cmd = CMD_DUMP_CONFIG; + break; ++ case 'A': ++ if (remember_cmdline_wwid() != 0) ++ exit(RTVL_FAIL); ++ exit(RTVL_OK); + case 'h': + usage(argv[0]); + exit(RTVL_OK); +diff --git a/multipath/multipath.8 b/multipath/multipath.8 +index 5b29a5d9..0478f4e7 100644 +--- a/multipath/multipath.8 ++++ b/multipath/multipath.8 +@@ -63,7 +63,7 @@ multipath \- Device mapper target autoconfig. + .B multipath + .RB [\| \-v\ \c + .IR level \|] +-.B -W ++.RB [\| \-A | \-W \|] + . + .LP + .B multipath +@@ -145,6 +145,11 @@ device mapper, path checkers ...). + Add the WWID for the specified device to the WWIDs file. + . + .TP ++.B \-A ++Add the WWIDs from any kernel command line \fImpath.wwid\fR parameters to the ++WWIDs file. ++. ++.TP + .B \-w + Remove the WWID for the specified device from the WWIDs file. + . +diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service +index 17434cef..0fbcc46b 100644 +--- a/multipathd/multipathd.service ++++ b/multipathd/multipathd.service +@@ -15,6 +15,7 @@ Type=notify + NotifyAccess=main + LimitCORE=infinity + ExecStartPre=-/sbin/modprobe -a scsi_dh_alua scsi_dh_emc scsi_dh_rdac dm-multipath ++ExecStartPre=-/sbin/multipath -A + ExecStart=/sbin/multipathd -d -s + ExecReload=/sbin/multipathd reconfigure + TasksMax=infinity +-- +2.17.2 + diff --git a/0055-libmultipath-fix-double-free-in-pgpolicyfn-error-pat.patch b/0055-libmultipath-fix-double-free-in-pgpolicyfn-error-pat.patch deleted file mode 100644 index aa13194d770fdebea350befcfdbb41044de74b8a..0000000000000000000000000000000000000000 --- a/0055-libmultipath-fix-double-free-in-pgpolicyfn-error-pat.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 27039be7cfd551646425b0ebc43a87e86484c370 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 23 Aug 2019 12:48:50 -0500 -Subject: [PATCH 8/8] libmultipath: fix double free in pgpolicyfn error paths - -In the pgpolicy functions, if an error is encountered after -alloc_pathgroup() is called, but before the path group is added to a -multipath device with add_pathgroup(), the pathgroup needs to be cleaned -up by calling free_pathgroup(). However, after the pathgroup has been -added to the multipath device, calling free_pgvec() will clean it up. In -this case, if free_pathgroup() is called first, the recently added -pathgroup will be freed twice. - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/pgpolicies.c | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - -diff --git a/libmultipath/pgpolicies.c b/libmultipath/pgpolicies.c -index 660768a..9acf46a 100644 ---- a/libmultipath/pgpolicies.c -+++ b/libmultipath/pgpolicies.c -@@ -125,7 +125,7 @@ int group_by_node_name(struct multipath * mp) - - /* feed the first path */ - if (store_path(pgp->paths, pp)) -- goto out2; -+ goto out1; - - bitmap[i] = 1; - -@@ -139,7 +139,7 @@ int group_by_node_name(struct multipath * mp) - if (!strncmp(pp->tgt_node_name, pp2->tgt_node_name, - NODE_NAME_SIZE)) { - if (store_path(pgp->paths, pp2)) -- goto out2; -+ goto out1; - - bitmap[j] = 1; - } -@@ -201,7 +201,7 @@ int group_by_serial(struct multipath * mp) - - /* feed the first path */ - if (store_path(pgp->paths, pp)) -- goto out2; -+ goto out1; - - bitmap[i] = 1; - -@@ -214,7 +214,7 @@ int group_by_serial(struct multipath * mp) - - if (0 == strcmp(pp->serial, pp2->serial)) { - if (store_path(pgp->paths, pp2)) -- goto out2; -+ goto out1; - - bitmap[j] = 1; - } -@@ -258,7 +258,7 @@ int one_path_per_group(struct multipath *mp) - goto out1; - - if (store_path(pgp->paths, pp)) -- goto out1; -+ goto out; - } - sort_pathgroups(mp); - free_pathvec(mp->paths, KEEP_PATHS); -@@ -379,7 +379,7 @@ int group_by_prio(struct multipath *mp) - vector_foreach_slot(pathvec, pp, i) { - if (pp->priority == prio) { - if (store_path(pgp->paths, pp)) -- goto out2; -+ goto out1; - - vector_del_slot(pathvec, i); - i--; --- -1.8.3.1 - - diff --git a/0056-RH-warn-on-invalid-regex-instead-of-failing.patch b/0056-RH-warn-on-invalid-regex-instead-of-failing.patch new file mode 100644 index 0000000000000000000000000000000000000000..4bdd97e56f837eebbde85850d87772de352089f7 --- /dev/null +++ b/0056-RH-warn-on-invalid-regex-instead-of-failing.patch @@ -0,0 +1,121 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 6 Nov 2017 21:39:28 -0600 +Subject: [PATCH] RH: warn on invalid regex instead of failing + +multipath.conf used to allow "*" as a match everything regular expression, +instead of requiring ".*". Instead of erroring when the old style +regular expressions are used, it should print a warning and convert +them. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/dict.c | 27 +++++++++++++++++++++------ + libmultipath/parser.c | 13 +++++++++++++ + libmultipath/parser.h | 1 + + 3 files changed, 35 insertions(+), 6 deletions(-) + +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index 0e9ea387..184d4b22 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -103,6 +103,21 @@ set_str(vector strvec, void *ptr) + return 0; + } + ++static int ++set_regex(vector strvec, void *ptr) ++{ ++ char **str_ptr = (char **)ptr; ++ ++ if (*str_ptr) ++ FREE(*str_ptr); ++ *str_ptr = set_regex_value(strvec); ++ ++ if (!*str_ptr) ++ return 1; ++ ++ return 0; ++} ++ + static int + set_yes_no(vector strvec, void *ptr) + { +@@ -1504,7 +1519,7 @@ ble_ ## option ## _handler (struct config *conf, vector strvec) \ + if (!conf->option) \ + return 1; \ + \ +- buff = set_value(strvec); \ ++ buff = set_regex_value(strvec); \ + if (!buff) \ + return 1; \ + \ +@@ -1520,7 +1535,7 @@ ble_ ## option ## _ ## name ## _handler (struct config *conf, vector strvec) \ + if (!conf->option) \ + return 1; \ + \ +- buff = set_value(strvec); \ ++ buff = set_regex_value(strvec); \ + if (!buff) \ + return 1; \ + \ +@@ -1623,16 +1638,16 @@ device_handler(struct config *conf, vector strvec) + return 0; + } + +-declare_hw_handler(vendor, set_str) ++declare_hw_handler(vendor, set_regex) + declare_hw_snprint(vendor, print_str) + +-declare_hw_handler(product, set_str) ++declare_hw_handler(product, set_regex) + declare_hw_snprint(product, print_str) + +-declare_hw_handler(revision, set_str) ++declare_hw_handler(revision, set_regex) + declare_hw_snprint(revision, print_str) + +-declare_hw_handler(bl_product, set_str) ++declare_hw_handler(bl_product, set_regex) + declare_hw_snprint(bl_product, print_str) + + declare_hw_handler(hwhandler, set_str) +diff --git a/libmultipath/parser.c b/libmultipath/parser.c +index 11a6168c..a7285a35 100644 +--- a/libmultipath/parser.c ++++ b/libmultipath/parser.c +@@ -384,6 +384,19 @@ oom: + return NULL; + } + ++void * ++set_regex_value(vector strvec) ++{ ++ char *buff = set_value(strvec); ++ ++ if (buff && strcmp("*", buff) == 0) { ++ condlog(0, "Invalid regular expression \"*\" in multipath.conf. Using \".*\""); ++ FREE(buff); ++ return strdup(".*"); ++ } ++ return buff; ++} ++ + /* non-recursive configuration stream handler */ + static int kw_level = 0; + +diff --git a/libmultipath/parser.h b/libmultipath/parser.h +index 62906e98..b7917052 100644 +--- a/libmultipath/parser.h ++++ b/libmultipath/parser.h +@@ -77,6 +77,7 @@ extern void dump_keywords(vector keydump, int level); + extern void free_keywords(vector keywords); + extern vector alloc_strvec(char *string); + extern void *set_value(vector strvec); ++extern void *set_regex_value(vector strvec); + extern int process_file(struct config *conf, char *conf_file); + extern struct keyword * find_keyword(vector keywords, vector v, char * name); + int snprint_keyword(char *buff, int len, char *fmt, struct keyword *kw, +-- +2.17.2 + diff --git a/0056-libmultipath-fix-files-read-from-config_dir.patch b/0056-libmultipath-fix-files-read-from-config_dir.patch deleted file mode 100644 index e0b7c6a9daef511817192de5d861eaaf13ede19a..0000000000000000000000000000000000000000 --- a/0056-libmultipath-fix-files-read-from-config_dir.patch +++ /dev/null @@ -1,41 +0,0 @@ -From dbd6e0f8ad3d145c73175a6f99eab401408d9d54 Mon Sep 17 00:00:00 2001 -From: Enzo Matsumiya -Date: Fri, 7 Feb 2020 11:45:25 -0300 -Subject: [PATCH] libmultipath: fix files read from config_dir - -If config_dir contains a file named, for example, "some.conf.backup", this file -will still be loaded by multipath because process_config_dir() -(libmultipath/config.c) uses strstr() to check for the ".conf" extension, but -that doesn't guarantee that ".conf" is at the end of the filename. - -This patch will make sure that only files ending in ".conf" are loaded from -config_dir. - -This is to comply with config_dir entry description in man 5 multipath.conf. - -Signed-off-by: Enzo Matsumiya ---- - libmultipath/config.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/config.c b/libmultipath/config.c -index 5af7af5..7c641a3 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -669,8 +669,11 @@ process_config_dir(struct config *conf, vector keywords, char *dir) - sr.n = n; - pthread_cleanup_push_cast(free_scandir_result, &sr); - for (i = 0; i < n; i++) { -- if (!strstr(namelist[i]->d_name, ".conf")) -+ char *ext = strrchr(namelist[i]->d_name, '.'); -+ -+ if (!ext || strcmp(ext, ".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'; --- -1.8.3.1 - - diff --git a/0045-fix-find-multipath-failure.patch b/0057-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 55% rename from 0045-fix-find-multipath-failure.patch rename to 0057-RH-reset-default-find_mutipaths-value-to-off.patch index 7d871316a73ec6bbfef1764d7f51c2d503cde381..2dfb52e25c3c7ea61f3044f7bed4fc1e7a16b064 100644 --- a/0045-fix-find-multipath-failure.patch +++ b/0057-RH-reset-default-find_mutipaths-value-to-off.patch @@ -1,20 +1,21 @@ -From eba371974dc9343740ff3b3fd18caab8529291d1 Mon Sep 17 00:00:00 2001 -From: openEuler Buildteam -Date: Thu, 2 Jan 2020 15:34:13 +0800 -Subject: [PATCH] device-mapper-multipath: fix find multipath failure +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 7 Jun 2018 17:43:52 -0500 +Subject: [PATCH] RH: reset default find_mutipaths value to off -when DEFAULT_FIND_MULTIPATHS is FIND_MULTIPATHS_STRICT, it fail to -find multipath in find_multipaths function, use FIND_MULTIPATHS_OFF -instead of FIND_MULTIPATHS_STRICT. +Upstream has changed to default find_multipaths to "strict". For now +Redhat will retain the previous default of "off". + +Signed-off-by: Benjamin Marzinski --- libmultipath/defaults.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h -index 7f3839f..c84d31d 100644 +index 01a501bd..984d8dd8 100644 --- a/libmultipath/defaults.h +++ b/libmultipath/defaults.h -@@ -17,7 +17,7 @@ +@@ -22,7 +22,7 @@ #define DEFAULT_NO_PATH_RETRY NO_PATH_RETRY_UNDEF #define DEFAULT_VERBOSITY 2 #define DEFAULT_REASSIGN_MAPS 0 @@ -24,5 +25,5 @@ index 7f3839f..c84d31d 100644 #define DEFAULT_DEV_LOSS_TMO 600 #define DEFAULT_RETAIN_HWHANDLER RETAIN_HWHANDLER_ON -- -1.8.3.1 +2.17.2 diff --git a/0057-libmultipath-fix-sgio_get_vpd-looping.patch b/0057-libmultipath-fix-sgio_get_vpd-looping.patch deleted file mode 100644 index 9fa294b969abd8704d59cb0bd77f77b7be1bb144..0000000000000000000000000000000000000000 --- a/0057-libmultipath-fix-sgio_get_vpd-looping.patch +++ /dev/null @@ -1,50 +0,0 @@ -From b3d65f57bc63ccfc52b89adb7ab7c0bc659c00af Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 19 Feb 2020 00:48:29 -0600 -Subject: [PATCH] libmultipath: fix sgio_get_vpd looping - -If do_inq returns a page with a length that is less than maxlen, but -larger than DEFAULT_SGIO_LEN, this function will loop forever. Also -if do_inq returns with a length equal to or greater than maxlen, -sgio_get_vpd will exit immediately, even if it hasn't read the entire -page. Fix these issues, modify the tests to verify the new behavior. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/discovery.c | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index a4769ee..400959d 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -956,6 +956,7 @@ static int - sgio_get_vpd (unsigned char * buff, int maxlen, int fd, int pg) - { - int len = DEFAULT_SGIO_LEN; -+ int rlen; - - if (fd < 0) { - errno = EBADF; -@@ -963,12 +964,11 @@ sgio_get_vpd (unsigned char * buff, int maxlen, int fd, int pg) - } - retry: - if (0 == do_inq(fd, 0, 1, pg, buff, len)) { -- len = get_unaligned_be16(&buff[2]) + 4; -- if (len >= maxlen) -- return len; -- if (len > DEFAULT_SGIO_LEN) -- goto retry; -- return len; -+ rlen = get_unaligned_be16(&buff[2]) + 4; -+ if (rlen <= len || len >= maxlen) -+ return rlen; -+ len = (rlen < maxlen)? rlen : maxlen; -+ goto retry; - } - return -1; - } --- -1.8.3.1 - - diff --git a/0058-RH-Fix-nvme-compilation-warning.patch b/0058-RH-Fix-nvme-compilation-warning.patch new file mode 100644 index 0000000000000000000000000000000000000000..fc6ccd7954fc10d66965b734fca57dbd2e587d20 --- /dev/null +++ b/0058-RH-Fix-nvme-compilation-warning.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Fri, 25 Jan 2019 14:54:56 -0600 +Subject: [PATCH] RH: Fix nvme compilation warning + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/nvme/argconfig.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmultipath/nvme/argconfig.h b/libmultipath/nvme/argconfig.h +index adb192b6..bfd10ef8 100644 +--- a/libmultipath/nvme/argconfig.h ++++ b/libmultipath/nvme/argconfig.h +@@ -76,7 +76,7 @@ struct argconfig_commandline_options { + extern "C" { + #endif + +-typedef void argconfig_help_func(); ++typedef void argconfig_help_func(void); + void argconfig_append_usage(const char *str); + void argconfig_print_help(const char *program_desc, + const struct argconfig_commandline_options *options); +-- +2.17.2 + diff --git a/0059-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0059-RH-attempt-to-get-ANA-info-via-sysfs-first.patch new file mode 100644 index 0000000000000000000000000000000000000000..14b3367aad8ea7e54ed1ef5c819d475a5ef3c9e4 --- /dev/null +++ b/0059-RH-attempt-to-get-ANA-info-via-sysfs-first.patch @@ -0,0 +1,87 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 11 Apr 2019 13:25:42 -0500 +Subject: [PATCH] RH: attempt to get ANA info via sysfs first + +When the ANA prioritizer is run, first see if the "ana_state" sysfs file +exists, and if it does, try to read the state from there. If that fails, +fallback to using an ioctl. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/prioritizers/ana.c | 31 +++++++++++++++++++++++++++++-- + 1 file changed, 29 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/prioritizers/ana.c b/libmultipath/prioritizers/ana.c +index b5c7873d..e139360c 100644 +--- a/libmultipath/prioritizers/ana.c ++++ b/libmultipath/prioritizers/ana.c +@@ -24,6 +24,7 @@ + #include "prio.h" + #include "util.h" + #include "structs.h" ++#include "sysfs.h" + + enum { + ANA_ERR_GETCTRL_FAILED = 1, +@@ -36,6 +37,7 @@ enum { + ANA_ERR_GETNS_FAILED, + ANA_ERR_NO_MEMORY, + ANA_ERR_NO_INFORMATION, ++ ANA_ERR_INVALID_STATE, + }; + + static const char *ana_errmsg[] = { +@@ -49,6 +51,7 @@ static const char *ana_errmsg[] = { + [ANA_ERR_GETNS_FAILED] = "couldn't get namespace info", + [ANA_ERR_NO_MEMORY] = "out of memory", + [ANA_ERR_NO_INFORMATION] = "invalid fd", ++ [ANA_ERR_INVALID_STATE] = "invalid state", + }; + + static const char *anas_string[] = { +@@ -107,6 +110,27 @@ static int get_ana_state(__u32 nsid, __u32 anagrpid, void *ana_log, + return -ANA_ERR_GETANAS_NOTFOUND; + } + ++static int get_ana_info_sysfs(struct path *pp) ++{ ++ char state[32]; ++ ++ if (!pp->udev || sysfs_attr_get_value(pp->udev, "ana_state", state, ++ sizeof(state)) <= 0) ++ return -ANA_ERR_NO_INFORMATION; ++ ++ if (strcmp(state, "optimized") == 0) ++ return NVME_ANA_OPTIMIZED; ++ if (strcmp(state, "non-optimized") == 0) ++ return NVME_ANA_NONOPTIMIZED; ++ if (strcmp(state, "inaccessible") == 0) ++ return NVME_ANA_INACCESSIBLE; ++ if (strcmp(state, "persistent-loss") == 0) ++ return NVME_ANA_PERSISTENT_LOSS; ++ if (strcmp(state, "change") == 0) ++ return NVME_ANA_CHANGE; ++ return -ANA_ERR_INVALID_STATE; ++} ++ + static int get_ana_info(struct path * pp) + { + int rc; +@@ -210,8 +234,11 @@ int getprio(struct path *pp, __attribute__((unused)) char *args, + + if (pp->fd < 0) + rc = -ANA_ERR_NO_INFORMATION; +- else +- rc = get_ana_info(pp); ++ else { ++ rc = get_ana_info_sysfs(pp); ++ if (rc < 0) ++ rc = get_ana_info(pp); ++ } + + switch (rc) { + case NVME_ANA_OPTIMIZED: +-- +2.17.2 + diff --git a/0060-RH-work-around-gcc-10-format-truncation-issue.patch b/0060-RH-work-around-gcc-10-format-truncation-issue.patch new file mode 100644 index 0000000000000000000000000000000000000000..c501ce99607414a153574e8fd0dcaf3591133d55 --- /dev/null +++ b/0060-RH-work-around-gcc-10-format-truncation-issue.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Fri, 29 May 2020 17:21:21 -0500 +Subject: [PATCH] RH: work around gcc 10 format-truncation issue + +gcc 10 was returning false positives on some architectures, when trying +to determine if a snprintf() function could silently truncate its +output. Instead of changing the code to pretend that this is possible, +make these warnings, instead of errors. + +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 479523bc..e2f5d0dc 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -109,7 +109,7 @@ endif + WARNFLAGS := -Werror -Wextra -Wformat=2 -Werror=implicit-int \ + -Werror=implicit-function-declaration -Werror=format-security \ + $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) \ +- -Wstrict-prototypes ++ -Wstrict-prototypes -Wno-error=format-truncation + CFLAGS := $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ + -DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" \ + -MMD -MP +-- +2.17.2 + diff --git a/multipath-tools-0.8.4.tgz b/multipath-tools-0.8.4.tgz new file mode 100644 index 0000000000000000000000000000000000000000..3c7963df4c1b6178f991c31a6515e582a910e607 Binary files /dev/null and b/multipath-tools-0.8.4.tgz differ diff --git a/multipath-tools-ef6d98b.tgz b/multipath-tools-ef6d98b.tgz deleted file mode 100644 index 37d46dffd158cbe9d6b8999b51e94ecbfc7ecf1c..0000000000000000000000000000000000000000 Binary files a/multipath-tools-ef6d98b.tgz and /dev/null differ diff --git a/multipath-tools.spec b/multipath-tools.spec index 635903f99dc90a5ca2f6dbfb7d0e2a9487a9c2f0..d4afbf001c34d1f99b972a99e4568af1ee5639b8 100644 --- a/multipath-tools.spec +++ b/multipath-tools.spec @@ -1,212 +1,257 @@ Name: multipath-tools -Version: 0.7.7 -Release: 20 -Summary: Tools to manage multipath devices with the device-mapper -License: GPLv2-or-later and LGPLv2+ +Version: 0.8.4 +Release: 3 +Summary: Tools to manage multipath devices using device-mapper +License: GPLv2 URL: http://christophe.varoqui.free.fr/ -# curl "https://git.opensvc.com/?p=multipath-tools/.git;a=snapshot;h=ef6d98b;sf=tgz" -o multipath-tools-ef6d98b.tgz -Source0: multipath-tools-ef6d98b.tgz +# The source for this package was pulled from upstream's git repo. Use the +# following command to generate the tarball +# curl "https://git.opensvc.com/gitweb.cgi?p=multipath-tools/.git;a=snapshot;h=d4915917655b3d205aa0e339ca13080ed8182d0d;sf=tgz" -o multipath-tools-0.8.4.tgz +Source0: multipath-tools-0.8.4.tgz Source1: multipath.conf -Patch0: 0000-libmultipath-remove-last-of-rbd-code.patch -Patch1: 0001-libmultipath-fix-detect-alua-corner-case.patch -Patch2: 0002-multipath-fix-setting-conf-version.patch -Patch3: 0003-mpathpersist-add-param-alltgpt-option.patch -Patch4: 0004-libmutipath-remove-unused-IDE-bus-type.patch -Patch5: 0005-multipathd-add-new-protocol-path-wildcard.patch -Patch6: 0006-libmultipath-add-protocol-blacklist-option.patch -Patch7: 0007-libmultipath-remove-_filter_-blacklist-functions.patch -Patch8: 0008-multipath-tests-change-to-work-with-old-make-version.patch -Patch9: 0009-multipath-tests-add-blacklist-tests.patch -Patch10: 0010-mpathpersist-add-missing-param-rk-usage-info.patch -Patch11: 0011-change-order-of-multipath.rules.patch -Patch12: 0012-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch13: 0013-RH-add-mpathconf.patch -Patch14: 0014-fix-segfault-when-mount-or-umount-VIMS-with-reservation-conflict.patch -Patch15: 0015-fix-multipathd-resize-when-not-all-paths-size-are-equal.patch -Patch16: 0016-multipathd-disable-queueing-for-recreated-map-in-uev.patch -Patch17: 0017-avoid-handling-paths-repeatedly-in-coalesce-paths.patch -Patch18: 0018-fix-bugs-backported-from-next-branch.patch -Patch19: 0019-bugfix-fix-change-reservation-key-to-uint8-for-memcmp.patch -Patch20: 0020-bugfix-ignore-for-clear-mismatch-key.patch -Patch21: 0021-bugfix-flush-and-sync-before-reboot.patch -Patch22: 0022-bugfix-RH-remove-local-disk-from-pathvec.patch -Patch23: 0023-bugfix-lun-expansion-failure-when-there-is-offline-path.patch -Patch24: 0024-bugfix-some-memory-leaks-issues-in-libmpathpersist.patch -Patch25: 0025-libmultipath-fix-set_int-error-path.patch -Patch26: 0026-libmultipath-free-allocated-value-in-set_int.patch -Patch27: 0027-libmultipath-fix-memory-issue-in-path_latency-prio.patch -Patch28: 0028-libmultipath-fix-null-dereference-int-alloc_path_group.patch -Patch29: 0029-multipath-fix-max-array-size-in-print_cmd_valid.patch -Patch30: 0030-multipathd-minor-fixes.patch -Patch31: 0031-multipathd-fix-memory-leak-on-error-in-configure.patch -Patch32: 0032-multipathd-check-for-NULL-udevice-in-cli_add_path.patch -Patch33: 0033-kpartx-fix-apparent-out-of-bounds-access.patch -Patch34: 0034-libmultipath-fix-apparent-overflow.patch -Patch35: 0035-libmultipath-fix-int-overflow-in-sysfs_set_scsi_tmo.patch -Patch36: 0036-libmultipath-fix-enum-misuse-for-find_multipaths.patch -Patch37: 0037-libmultipath-fix-possible-NULL-dereference.patch -Patch38: 0038-fix-syntax-error.patch -Patch39: 0039-bugfix-change-log-level-to-info-if-alua-is-not-support-by-s.patch -Patch40: 0040-bugfix-clear-mpp-path-reference-when-path-is-freed-otherwis.patch -Patch41: 0041-bugfix-libmultipath-fix-memory-leaks-from-scandir-use.patch -Patch42: 0042-bugfix-libmultipath-fix-memory-leak-in-disassemble_map.patch -Patch43: 0043-multipathd-fix-mpp-hwe-handling-when-paths-are-freed.patch -Patch44: 0044-bugfix-check-close-return-value.patch -Patch45: 0045-fix-find-multipath-failure.patch -Patch46: 0046-change-kpartx-file-and-default-bindir.patch -Patch47: 0047-multipathd-ignore-failed-wwid-recheck.patch -Patch48: 0048-libmultipath-group_by_prio-fix-signedness-bug.patch -Patch49: 0049-multipathd-handle-NULL-return-from-genhelp_handler.patch -Patch50: 0050-libmultipath-fix-parsing-of-VPD-83-type-1-T10-vendor.patch -Patch51: 0051-libmultipath-Fix-buffer-overflow-in-parse_vpd_pg80.patch -Patch52: 0052-libmultipath-fix-another-WWID-overflow-in-parse_vpd_.patch -Patch53: 0053-libmultipath-fix-possible-WWID-overflow-in-parse_vpd.patch -Patch54: 0054-libmultipath-fix-parsing-of-SCSI-name-string-iqn-for.patch -Patch55: 0055-libmultipath-fix-double-free-in-pgpolicyfn-error-pat.patch -Patch56: 0056-libmultipath-fix-files-read-from-config_dir.patch -Patch57: 0057-libmultipath-fix-sgio_get_vpd-looping.patch - - -BuildRequires: gcc, libaio-devel, userspace-rcu-devel, device-mapper-devel >= 1.02.89 -BuildRequires: libselinux-devel, libsepol-devel, readline-devel, ncurses-devel, git -BuildRequires: systemd-units, systemd-devel, json-c-devel, perl-interpreter, pkgconfig -Requires: userspace-rcu, json-c, device-mapper >= 1.02.96 -Requires: kpartx = %{version}-%{release} -Requires(post): systemd-units -Requires(preun): systemd-units +Patch0001: 0001-libmpathpersist-limit-PRIN-allocation-length-to-8192.patch +Patch0002: 0002-libmpathpersist-format_transportids-avoid-PROUT-over.patch +Patch0003: 0003-libmpathpersist-mpath_format_readfullstatus-use-real.patch +Patch0004: 0004-libmultipath-assign-variable-to-make-gcc-happy.patch +Patch0005: 0005-libmutipath-don-t-close-fd-on-dm_lib_release.patch +Patch0006: 0006-libmultipath-allow-force-reload-with-no-active-paths.patch +Patch0007: 0007-kpartx.rules-honor-DM_UDEV_DISABLE_OTHER_RULES_FLAG.patch +Patch0008: 0008-kpartx.rules-check-for-skip_kpartx-on-synthetic-ueve.patch +Patch0009: 0009-libmpathpersist-depend-on-libmultipath.patch +Patch0010: 0010-multipath-tools-Makefile-more-dependency-fixes-for-p.patch +Patch0011: 0011-multipath-tools-Makefile.inc-separate-out-OPTFLAGS.patch +Patch0012: 0012-multipath-tools-Makefile.inc-allow-user-settings-for.patch +Patch0013: 0013-multipath-tools-Makefile.inc-set-Wno-error-clobbered.patch +Patch0014: 0014-libmultipath-discovery.c-use-z-qualifier-for-size_t.patch +Patch0015: 0015-libmultipath-eliminate-more-signed-unsigned-comparis.patch +Patch0016: 0016-libmultipath-set_uint-fix-parsing-for-32bit.patch +Patch0017: 0017-multipath-tools-tests-Makefile-add-lmpathcmd-to-LIBD.patch +Patch0018: 0018-multipath-tools-tests-Makefile-Fix-OBJDEPS-for-hwtab.patch +Patch0019: 0019-multipath-tools-tests-test-lib.c-drop-__wrap_is_clai.patch +Patch0020: 0020-multipath-tools-tests-directio-fix-Wmaybe-uninitaliz.patch +Patch0021: 0021-libmultipath-move-libsg-into-libmultipath.patch +Patch0022: 0022-multipath-tools-Makefile-add-install-dependency.patch +Patch0023: 0023-libmultipath-make-libmp_dm_init-optional.patch +Patch0024: 0024-libmultipath-make-sysfs_is_multipathed-able-to-retur.patch +Patch0025: 0025-multipath-centralize-validation-code.patch +Patch0026: 0026-Unit-tests-for-is_path_valid.patch +Patch0027: 0027-libmultipath-simplify-failed-wwid-code.patch +Patch0028: 0028-libmultipath-use-atomic-linkat-in-mark_failed_wwid.patch +Patch0029: 0029-fix-boolean-value-with-json-c-0.14.patch +Patch0030: 0030-libmultipath-fix-condlog-NULL-argument-in-uevent_get.patch +Patch0031: 0031-libmultipath-set-enable_foreign-to-NONE-by-default.patch +Patch0032: 0032-multipath-add-e-option-to-enable-foreign-libraries.patch +Patch0033: 0033-libmultipath-remove-_blacklist_exceptions-functions.patch +Patch0034: 0034-libmultipath-fix-parser-issue-with-comments-in-strin.patch +Patch0035: 0035-libmultipath-invert-regexes-that-start-with-exclamat.patch +Patch0036: 0036-multipath-Fix-compiler-warnings-when-built-without-s.patch +Patch0037: 0037-libmultipath-fix-sysfs-dev_loss_tmo-parsing.patch +Patch0038: 0038-kpartx-read-devices-with-direct-IO.patch +Patch0039: 0039-kpartx-handle-alternate-bsd-disklabel-location.patch +Patch0040: 0040-libmultipath-fix-checker-detection-for-nvme-devices.patch +Patch0041: 0041-libmultipath-make-dm_get_map-status-return-codes-sym.patch +Patch0042: 0042-multipathd-fix-check_path-errors-with-removed-map.patch +Patch0043: 0043-libmultipath-make-dm_flush_maps-only-return-0-on-suc.patch +Patch0044: 0044-multipathd-add-del-maps-multipathd-command.patch +Patch0045: 0045-multipath-make-flushing-maps-work-like-other-command.patch +Patch0046: 0046-multipath-delegate-flushing-maps-to-multipathd.patch +Patch0047: 0047-multipath-add-option-to-skip-multipathd-delegation.patch +Patch0048: 0048-Makefile.inc-trim-extra-information-from-systemd-ver.patch +Patch0049: 0049-kpartx-fix-Wsign-compare-error.patch +Patch0050: 0050-RH-fixup-udev-rules-for-redhat.patch +Patch0051: 0051-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0052: 0052-RH-don-t-start-without-a-config-file.patch +Patch0053: 0053-RH-use-rpm-optflags-if-present.patch +Patch0054: 0054-RH-add-mpathconf.patch +Patch0055: 0055-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0056: 0056-RH-warn-on-invalid-regex-instead-of-failing.patch +Patch0057: 0057-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0058: 0058-RH-Fix-nvme-compilation-warning.patch +Patch0059: 0059-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0060: 0060-RH-work-around-gcc-10-format-truncation-issue.patch + +Requires: %{name}-libs = %{version}-%{release} +Requires: kpartx = %{version}-%{release} +Requires: device-mapper >= 1.02.96 +Requires: userspace-rcu +Requires(post): systemd-units +Requires(preun): systemd-units Requires(postun): systemd-units -Conflicts: mdadm < 4.1-rc2.0.2 -Conflicts: udisks2 < 2.8.0-2 -Provides: device-mapper-multipath -Obsoletes: device-mapper-multipath -Provides: device-mapper-multipath-libs -Obsoletes: device-mapper-multipath-libs -Provides: libdmmp -Obsoletes: libdmmp +Conflicts: mdadm < 4.1-rc2.0.2 +Conflicts: udisks2 < 2.8.0-2 +BuildRequires: libaio-devel, device-mapper-devel >= 1.02.89 +BuildRequires: libselinux-devel, libsepol-devel +BuildRequires: readline-devel, ncurses-devel +BuildRequires: systemd-units, systemd-devel +BuildRequires: json-c-devel, perl-interpreter, pkgconfig, gcc +BuildRequires: userspace-rcu-devel %description -This package provides the multipath tool and the multipathd daemon -to manage dm-multipath devices. multipath can detect and set up -multipath maps. multipathd sets up multipath maps automatically, -monitors path devices for failure, removal, or addition, and applies -the necessary changes to the multipath maps to ensure continuous -availability of the map devices. +%{name} provides tools to manage multipath devices by +instructing the device-mapper multipath kernel module what to do. +The tools are : +* multipath - Scan the system for multipath devices and assemble them. +* multipathd - Detects when paths fail and execs multipath to update things. + +%package libs +Summary: The %{name} modules and shared library +License: GPLv2 and LGPLv2+ + +%description libs +The %{name}-libs provides the path checker +and prioritizer modules. It also contains the libmpathpersist and +libmpathcmd shared libraries, as well as multipath's internal library, +libmultipath. %package devel -Summary: Development libraries for %{name} -Requires: %{name} = %{version}-%{release} -Obsoletes: %{name}-libs < %{version}-%{release} -Provides: libdmmp-devel -Obsoletes: libdmmp-devel -Provides: device-mapper-multipath-devel -Obsoletes: device-mapper-multipath-devel -Requires: pkgconfig -Obsoletes: libdmmp +Summary: Development libraries and headers for %{name} +Requires: %{name} = %{version}-%{release} +Requires: %{name}-libs = %{version}-%{release} %description devel -This package contains the development libraries for %{name} -that are %{name}'s libbmpathpersist and libmpathcmd libraries. - -%package help -Summary: Including man files for multipath-tools. -Requires: man -Provides: device-mapper-multipath-help -Obsoletes: device-mapper-multipath-help -%description help -This contains man files for the using of multipath-tools. +This package contains the files need to develop applications that use +device-mapper-multipath's lbmpathpersist and libmpathcmd libraries. %package -n kpartx -Summary: Create device maps from partition tables. +Summary: Partition device manager for device-mapper devices %description -n kpartx -Reads partition tables and create device maps over partitions segments detected. +kpartx manages partition creation and removal for device-mapper devices. + +%package -n libdmmp +Summary: multipath-tools C API library +License: GPLv3+ +Requires: json-c +Requires: %{name} = %{version}-%{release} +Requires: %{name}-libs = %{version}-%{release} + +%description -n libdmmp +This package contains the shared library for the multipath-tools +C API library. + +%package -n libdmmp-devel +Summary: multipath-tools C API library headers +Requires: pkgconfig +Requires: libdmmp = %{version}-%{release} + +%description -n libdmmp-devel +This package contains the files needed to develop applications that use +multipath-tools's libdmmp C API library %prep -%autosetup -Sgit -n multipath-tools-ef6d98b +%autosetup -n multipath-tools-d491591 -p1 cp %{SOURCE1} . %build -%make_build LIB=%{_lib} +%define _sbindir /usr/sbin +%define _libdir /usr/%{_lib} +%define _libmpathdir %{_libdir}/multipath +%define _pkgconfdir %{_libdir}/pkgconfig +make %{?_smp_mflags} LIB=%{_lib} %install make install \ - DESTDIR=%{buildroot} \ - bindir=/usr/sbin \ - syslibdir=/usr/%{_lib} \ - usrlibdir=/usr/%{_lib} \ - libdir=/usr/%{_lib}/multipath \ - rcdir=%{_initrddir} \ - unitdir=%{_unitdir} \ - includedir=%{_includedir} \ - pkgconfdir=/usr/%{_lib}/pkgconfig + DESTDIR=%{buildroot} \ + bindir=%{_sbindir} \ + syslibdir=%{_libdir} \ + usrlibdir=%{_libdir} \ + libdir=%{_libmpathdir} \ + rcdir=%{_initrddir} \ + unitdir=%{_unitdir} \ + includedir=%{_includedir} \ + pkgconfdir=%{_pkgconfdir} install -d %{buildroot}/etc/multipath rm -rf %{buildroot}/%{_initrddir} + %post -/sbin/ldconfig +%systemd_post multipathd.service %preun %systemd_preun multipathd.service %postun -/sbin/ldconfig if [ $1 -ge 1 ] ; then - /sbin/multipathd forcequeueing daemon > /dev/null 2>&1 || : + /sbin/multipathd forcequeueing daemon > /dev/null 2>&1 || : fi %systemd_postun_with_restart multipathd.service %triggerun -- %{name} < 0.4.9-37 /bin/systemctl --quiet is-enabled multipathd.service >/dev/null 2>&1 && /bin/systemctl reenable multipathd.service ||: - %files -%doc README README.alua multipath.conf -%license LICENSES/GPL-2.0 LICENSES/LGPL-2.0 LICENSES/GPL-3.0 -%{_unitdir}/* - /usr/sbin/multipath - /usr/sbin/multipathd - /usr/sbin/mpathconf - /usr/sbin/mpathpersist - /usr/%{_lib}/libmultipath.so - /usr/%{_lib}/libmultipath.so.* - /usr/%{_lib}/libmpathpersist.so.* - /usr/%{_lib}/libmpathcmd.so.* - /usr/%{_lib}/libdmmp.so.* -%dir /etc/multipath -%dir /usr/%{_lib}/multipath - /usr/%{_lib}/multipath/* +%license LICENSES/GPL-2.0 LICENSES/LGPL-2.0 +%{_sbindir}/multipath +%{_sbindir}/multipathd +%{_sbindir}/mpathconf +%{_sbindir}/mpathpersist +%{_unitdir}/multipathd.service +%{_unitdir}/multipathd.socket +%{_mandir}/man5/multipath.conf.5.gz +%{_mandir}/man8/multipath.8.gz +%{_mandir}/man8/multipathd.8.gz +%{_mandir}/man8/mpathconf.8.gz +%{_mandir}/man8/mpathpersist.8.gz %config /usr/lib/udev/rules.d/62-multipath.rules %config /usr/lib/udev/rules.d/11-dm-mpath.rules +%doc README +%doc README.alua +%doc multipath.conf +%dir /etc/multipath +%files libs +%license LICENSES/GPL-2.0 LICENSES/LGPL-2.0 +%doc README +%{_libdir}/libmultipath.so +%{_libdir}/libmultipath.so.* +%{_libdir}/libmpathpersist.so.* +%{_libdir}/libmpathcmd.so.* +%dir %{_libmpathdir} +%{_libmpathdir}/* + +%ldconfig_scriptlets libs %files devel %doc README - %{_includedir}/*.h -%dir %{_includedir}/libdmmp - %{_includedir}/libdmmp/* - /usr/%{_lib}/libmpathpersist.so - /usr/%{_lib}/libmpathcmd.so - /usr/%{_lib}/libdmmp.so - /usr/%{_lib}/pkgconfig/libdmmp.pc - -%files help -%{_mandir}/man3/* -%{_mandir}/man5/* -%{_mandir}/man8/* +%{_libdir}/libmpathpersist.so +%{_libdir}/libmpathcmd.so +%{_includedir}/mpath_cmd.h +%{_includedir}/mpath_persist.h +%{_mandir}/man3/mpath_persistent_reserve_in.3.gz +%{_mandir}/man3/mpath_persistent_reserve_out.3.gz %files -n kpartx %license LICENSES/GPL-2.0 %doc README -/usr/sbin/kpartx +%{_sbindir}/kpartx /usr/lib/udev/kpartx_id +%{_mandir}/man8/kpartx.8.gz %config /usr/lib/udev/rules.d/11-dm-parts.rules %config /usr/lib/udev/rules.d/66-kpartx.rules %config /usr/lib/udev/rules.d/68-del-part-nodes.rules +%files -n libdmmp +%license LICENSES/GPL-3.0 +%doc README +%{_libdir}/libdmmp.so.* + +%ldconfig_scriptlets -n libdmmp + +%files -n libdmmp-devel +%doc README +%{_libdir}/libdmmp.so +%dir %{_includedir}/libdmmp +%{_includedir}/libdmmp/* +%{_mandir}/man3/dmmp_* +%{_mandir}/man3/libdmmp.h.3.gz +%{_pkgconfdir}/libdmmp.pc %changelog +* Wed Jul 15 2020 wangyue - 0.8.4-3 +- upgrade the version to 0.8.4 + * Sun Jul 5 2020 Zhiqiang Liu - 0.7.7-20 - remove useless readme files.