diff --git a/.gitignore b/.gitignore index 9e336c4..0a86d83 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ multipath-tools-091027.tar.gz /multipath-tools-07e7bd5.tgz /multipath-tools-1cb704b.tgz /multipath-tools-0.7.7.tgz +/multipath-tools-ef6d98b.tgz diff --git a/0001-libmultipath-remove-last-of-rbd-code.patch b/0001-libmultipath-remove-last-of-rbd-code.patch new file mode 100644 index 0000000..7f26eb8 --- /dev/null +++ b/0001-libmultipath-remove-last-of-rbd-code.patch @@ -0,0 +1,41 @@ +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-multipath-tools-add-RDAC-SUN-ArrayStorage-to-hwtable.patch b/0001-multipath-tools-add-RDAC-SUN-ArrayStorage-to-hwtable.patch deleted file mode 100644 index 1d983e9..0000000 --- a/0001-multipath-tools-add-RDAC-SUN-ArrayStorage-to-hwtable.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Wed, 11 Apr 2018 15:14:13 +0200 -Subject: [PATCH] multipath-tools: add RDAC SUN/ArrayStorage to hwtable - -Already in scsi_dh: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/scsi/scsi_dh.c#n70 - -Cc: NetApp RDAC team -Cc: Christophe Varoqui -Cc: DM ML -Signed-off-by: Xose Vazquez Perez -Signed-off-by: Benjamin Marzinski ---- - libmultipath/hwtable.c | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index 88b4700..827e899 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -890,6 +890,18 @@ static struct hwentry default_hw[] = { - .no_path_retry = 30, - }, - { -+ .vendor = "SUN", -+ .product = "ArrayStorage", -+ .bl_product = "Universal Xport", -+ .pgpolicy = GROUP_BY_PRIO, -+ .checker_name = RDAC, -+ .features = "2 pg_init_retries 50", -+ .hwhandler = "1 rdac", -+ .prio_name = PRIO_RDAC, -+ .pgfailback = -FAILBACK_IMMEDIATE, -+ .no_path_retry = 30, -+ }, -+ { - /* ZFS Storage Appliances */ - .vendor = "SUN", - .product = "(Sun Storage|ZFS Storage|COMSTAR)", --- -2.7.4 - diff --git a/0019-libmultipath-fix-detect-alua-corner-case.patch b/0002-libmultipath-fix-detect-alua-corner-case.patch similarity index 92% rename from 0019-libmultipath-fix-detect-alua-corner-case.patch rename to 0002-libmultipath-fix-detect-alua-corner-case.patch index 23908fa..6d6fa64 100644 --- a/0019-libmultipath-fix-detect-alua-corner-case.patch +++ b/0002-libmultipath-fix-detect-alua-corner-case.patch @@ -14,10 +14,10 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c -index 62a6893..f626c74 100644 +index af3ed62..fdb5953 100644 --- a/libmultipath/propsel.c +++ b/libmultipath/propsel.c -@@ -403,9 +403,11 @@ int select_hwhandler(struct config *conf, struct multipath *mp) +@@ -420,9 +420,11 @@ int select_hwhandler(struct config *conf, struct multipath *mp) bool all_tpgs = true; dh_state = &handler[2]; diff --git a/0002-multipath-tools-remove-c-from-__cpluscplus-misspelle.patch b/0002-multipath-tools-remove-c-from-__cpluscplus-misspelle.patch deleted file mode 100644 index 73f000a..0000000 --- a/0002-multipath-tools-remove-c-from-__cpluscplus-misspelle.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Tue, 24 Apr 2018 15:03:40 +0200 -Subject: [PATCH] multipath-tools: remove "c" from __cpluscplus, misspelled - -found by cppcheck(http://cppcheck.sf.net/): -[libmpathcmd/mpath_cmd.h:24]: (error) Invalid number of character '{' when these macros are defined: '__cpluscplus'. - -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM ML -Signed-off-by: Xose Vazquez Perez -Signed-off-by: Benjamin Marzinski ---- - libmpathcmd/mpath_cmd.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmpathcmd/mpath_cmd.h b/libmpathcmd/mpath_cmd.h -index aaa8da9..df9d938 100644 ---- a/libmpathcmd/mpath_cmd.h -+++ b/libmpathcmd/mpath_cmd.h -@@ -20,7 +20,7 @@ - #ifndef LIB_MPATH_CMD_H - #define LIB_MPATH_CMD_H - --#ifdef __cpluscplus -+#ifdef __cplusplus - extern "C" { - #endif - --- -2.7.4 - diff --git a/0020-multipath-fix-setting-conf-version.patch b/0003-multipath-fix-setting-conf-version.patch similarity index 100% rename from 0020-multipath-fix-setting-conf-version.patch rename to 0003-multipath-fix-setting-conf-version.patch diff --git a/0003-multipath-tools-remove-emacs-autoconfig-of-kpartx-gp.patch b/0003-multipath-tools-remove-emacs-autoconfig-of-kpartx-gp.patch deleted file mode 100644 index 7358e1a..0000000 --- a/0003-multipath-tools-remove-emacs-autoconfig-of-kpartx-gp.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Thu, 12 Apr 2018 18:17:13 +0200 -Subject: [PATCH] multipath-tools: remove emacs autoconfig of kpartx/gpt.h - -Cc: Christophe Varoqui -Cc: DM ML -Signed-off-by: Xose Vazquez Perez -Signed-off-by: Benjamin Marzinski ---- - kpartx/gpt.h | 19 ------------------- - 1 file changed, 19 deletions(-) - -diff --git a/kpartx/gpt.h b/kpartx/gpt.h -index 66ce8f1..7bb54b7 100644 ---- a/kpartx/gpt.h -+++ b/kpartx/gpt.h -@@ -109,22 +109,3 @@ int read_gpt_pt (int fd, struct slice all, struct slice *sp, int ns); - - - #endif -- --/* -- * Overrides for Emacs so that we follow Linus's tabbing style. -- * Emacs will notice this stuff at the end of the file and automatically -- * adjust the settings for this buffer only. This must remain at the end -- * of the file. -- * --------------------------------------------------------------------------- -- * Local variables: -- * c-indent-level: 4 -- * c-brace-imaginary-offset: 0 -- * c-brace-offset: -4 -- * c-argdecl-indent: 4 -- * c-label-offset: -4 -- * c-continued-statement-offset: 4 -- * c-continued-brace-offset: 0 -- * indent-tabs-mode: nil -- * tab-width: 8 -- * End: -- */ --- -2.7.4 - diff --git a/0004-mpathpersist-add-param-alltgpt-option.patch b/0004-mpathpersist-add-param-alltgpt-option.patch new file mode 100644 index 0000000..8485d37 --- /dev/null +++ b/0004-mpathpersist-add-param-alltgpt-option.patch @@ -0,0 +1,152 @@ +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-multipath-tools-replace-FSF-address-with-a-www-point.patch b/0004-multipath-tools-replace-FSF-address-with-a-www-point.patch deleted file mode 100644 index 13f18b5..0000000 --- a/0004-multipath-tools-replace-FSF-address-with-a-www-point.patch +++ /dev/null @@ -1,191 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Fri, 11 May 2018 15:42:43 +0200 -Subject: [PATCH] multipath-tools: replace FSF address with a www pointer - -Less prone to future modifications, new FSF licences -point exactly to this url: . -And sending a smail to FSF is outdated. - -First clean up was done in 5619a39c433ac3d10a88079593cec1aa6472cbeb - -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM ML -Signed-off-by: Xose Vazquez Perez -Signed-off-by: Benjamin Marzinski ---- - libmultipath/dm-generic.c | 4 +--- - libmultipath/dm-generic.h | 4 +--- - libmultipath/foreign.c | 4 +--- - libmultipath/foreign.h | 4 +--- - libmultipath/foreign/nvme.c | 4 +--- - libmultipath/generic.c | 4 +--- - libmultipath/generic.h | 4 +--- - tests/dmevents.c | 2 +- - tests/parser.c | 2 +- - tests/uevent.c | 2 +- - tests/util.c | 2 +- - 11 files changed, 11 insertions(+), 25 deletions(-) - -diff --git a/libmultipath/dm-generic.c b/libmultipath/dm-generic.c -index bdc9ca0..d752991 100644 ---- a/libmultipath/dm-generic.c -+++ b/libmultipath/dm-generic.c -@@ -12,9 +12,7 @@ - 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, write to the Free Software -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, -- USA. -+ along with this program. If not, see . - */ - - #include -diff --git a/libmultipath/dm-generic.h b/libmultipath/dm-generic.h -index 5d59724..986429f 100644 ---- a/libmultipath/dm-generic.h -+++ b/libmultipath/dm-generic.h -@@ -12,9 +12,7 @@ - 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, write to the Free Software -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, -- USA. -+ along with this program. If not, see . - */ - #ifndef _DM_GENERIC_H - #define _DM_GENERIC_H -diff --git a/libmultipath/foreign.c b/libmultipath/foreign.c -index 7217184..80b399b 100644 ---- a/libmultipath/foreign.c -+++ b/libmultipath/foreign.c -@@ -12,9 +12,7 @@ - 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, write to the Free Software -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, -- USA. -+ along with this program. If not, see . - */ - - #include -diff --git a/libmultipath/foreign.h b/libmultipath/foreign.h -index 973f368..697f12f 100644 ---- a/libmultipath/foreign.h -+++ b/libmultipath/foreign.h -@@ -12,9 +12,7 @@ - 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, write to the Free Software -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, -- USA. -+ along with this program. If not, see . - */ - #ifndef _FOREIGN_H - #define _FOREIGN_H -diff --git a/libmultipath/foreign/nvme.c b/libmultipath/foreign/nvme.c -index 235f75d..280b6bd 100644 ---- a/libmultipath/foreign/nvme.c -+++ b/libmultipath/foreign/nvme.c -@@ -12,9 +12,7 @@ - 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, write to the Free Software -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, -- USA. -+ along with this program. If not, see . - */ - - #include -diff --git a/libmultipath/generic.c b/libmultipath/generic.c -index 6f7a2cd..0d1e632 100644 ---- a/libmultipath/generic.c -+++ b/libmultipath/generic.c -@@ -12,9 +12,7 @@ - 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, write to the Free Software -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, -- USA. -+ along with this program. If not, see . - */ - - -diff --git a/libmultipath/generic.h b/libmultipath/generic.h -index 7f7fe66..6346ffe 100644 ---- a/libmultipath/generic.h -+++ b/libmultipath/generic.h -@@ -12,9 +12,7 @@ - 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, write to the Free Software -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, -- USA. -+ along with this program. If not, see . - */ - #ifndef _GENERIC_H - #define _GENERIC_H -diff --git a/tests/dmevents.c b/tests/dmevents.c -index bba51dc..3399c81 100644 ---- a/tests/dmevents.c -+++ b/tests/dmevents.c -@@ -12,7 +12,7 @@ - * 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, write to the Free Software -+ * along with this program. If not, see . - * - */ - -diff --git a/tests/parser.c b/tests/parser.c -index a7e7598..29859da 100644 ---- a/tests/parser.c -+++ b/tests/parser.c -@@ -12,7 +12,7 @@ - * 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, write to the Free Software -+ * along with this program. If not, see . - * - */ - -diff --git a/tests/uevent.c b/tests/uevent.c -index acfcb14..b0d0bfd 100644 ---- a/tests/uevent.c -+++ b/tests/uevent.c -@@ -12,7 +12,7 @@ - * 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, write to the Free Software -+ * along with this program. If not, see . - * - */ - -diff --git a/tests/util.c b/tests/util.c -index 113b134..839effd 100644 ---- a/tests/util.c -+++ b/tests/util.c -@@ -12,7 +12,7 @@ - * 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, write to the Free Software -+ * along with this program. If not, see . - * - */ - --- -2.7.4 - diff --git a/0005-libmutipath-remove-unused-IDE-bus-type.patch b/0005-libmutipath-remove-unused-IDE-bus-type.patch new file mode 100644 index 0000000..5dda5a7 --- /dev/null +++ b/0005-libmutipath-remove-unused-IDE-bus-type.patch @@ -0,0 +1,25 @@ +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-multipath-tools-Remove-trailing-leading-whitespaces-.patch b/0005-multipath-tools-Remove-trailing-leading-whitespaces-.patch deleted file mode 100644 index 953e739..0000000 --- a/0005-multipath-tools-Remove-trailing-leading-whitespaces-.patch +++ /dev/null @@ -1,156 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Fri, 11 May 2018 15:43:11 +0200 -Subject: [PATCH] multipath-tools: Remove trailing/leading whitespaces and - reformat code - -Cc: Christophe Varoqui -Cc: device-mapper development -Signed-off-by: Xose Vazquez Perez -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 23 +++++++++++------------ - kpartx/mac.h | 2 +- - kpartx/test-kpartx | 2 +- - libmpathcmd/Makefile | 2 +- - libmultipath/hwtable.c | 14 +++++++------- - libmultipath/print.h | 2 +- - multipathd/main.h | 6 +++--- - 7 files changed, 25 insertions(+), 26 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 57a1835..af2f5ba 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -103,21 +103,20 @@ LDFLAGS = -Wl,-z,relro -Wl,-z,now - BIN_LDFLAGS = -pie - - # Check whether a function with name $1 has been declared in header file $2. --check_func = \ -- $(shell \ -+check_func = $(shell \ - if grep -Eq "^[^[:blank:]]+[[:blank:]]+$1[[:blank:]]*(.*)*" "$2"; then \ -- found=1; \ -- status="yes"; \ -- else \ -- found=0; \ -- status="no"; \ -- fi; \ -- echo 1>&2 "Checking for $1 in $2 ... $$status"; \ -- echo "$$found" \ -- ) -+ found=1; \ -+ status="yes"; \ -+ else \ -+ found=0; \ -+ status="no"; \ -+ fi; \ -+ echo 1>&2 "Checking for $1 in $2 ... $$status"; \ -+ echo "$$found" \ -+ ) - - # Checker whether a file with name $1 exists --check_file = $(shell \ -+check_file = $(shell \ - if [ -f "$1" ]; then \ - found=1; \ - status="yes"; \ -diff --git a/kpartx/mac.h b/kpartx/mac.h -index a44cf38..55c3ec9 100644 ---- a/kpartx/mac.h -+++ b/kpartx/mac.h -@@ -24,7 +24,7 @@ struct mac_driver_desc { - uint16_t signature; /* expected to be MAC_DRIVER_MAGIC */ - uint16_t block_size; - uint32_t block_count; -- /* ... more stuff */ -+ /* ... more stuff */ - }; - - #endif -diff --git a/kpartx/test-kpartx b/kpartx/test-kpartx -index 9cee20f..d2001dc 100755 ---- a/kpartx/test-kpartx -+++ b/kpartx/test-kpartx -@@ -131,7 +131,7 @@ step "create DM devices (spans)" - # They also serve as DM devices to test partition removal on those. - - TABLE="\ --0 $((SIZE/SECTSIZ-OFFS)) linear $DEV1 $OFFS -+0 $((SIZE/SECTSIZ-OFFS)) linear $DEV1 $OFFS - $((SIZE/SECTSIZ-OFFS)) $((SIZE/SECTSIZ-OFFS)) linear $DEV2 $OFFS" - - SPAN1=kpt -diff --git a/libmpathcmd/Makefile b/libmpathcmd/Makefile -index 53c0899..0f6b816 100644 ---- a/libmpathcmd/Makefile -+++ b/libmpathcmd/Makefile -@@ -27,7 +27,7 @@ uninstall: - $(RM) $(DESTDIR)$(includedir)/mpath_cmd.h - - clean: dep_clean -- $(RM) core *.a *.o *.so *.so.* *.gz -+ $(RM) core *.a *.o *.so *.so.* *.gz - - include $(wildcard $(OBJS:.o=.d)) - -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index 827e899..2ca6888 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -78,13 +78,13 @@ - #endif - - static struct hwentry default_hw[] = { -- /* -- * Generic NVMe -- * -- * Due to the parsing logic in find_hwe(), generic entries -- * have to be put on top of this list, and more specific ones -- * below. -- */ -+ /* -+ * Generic NVMe devices -+ * -+ * Due to the parsing logic in find_hwe(), generic entries -+ * have to be put on top of this list, and more specific ones -+ * below. -+ */ - { - .vendor = "NVME", - .product = ".*", -diff --git a/libmultipath/print.h b/libmultipath/print.h -index 7ba6438..9b5a23a 100644 ---- a/libmultipath/print.h -+++ b/libmultipath/print.h -@@ -113,7 +113,7 @@ int _snprint_multipath (const struct gen_multipath *, char *, int, - const char *, int); - #define snprint_multipath(buf, len, fmt, mp, v) \ - _snprint_multipath(dm_multipath_to_gen(mp), buf, len, fmt, v) --int _snprint_multipath_topology (const struct gen_multipath *, char *, int, -+int _snprint_multipath_topology (const struct gen_multipath *, char *, int, - int verbosity); - #define snprint_multipath_topology(buf, len, mpp, v) \ - _snprint_multipath_topology (dm_multipath_to_gen(mpp), buf, len, v) -diff --git a/multipathd/main.h b/multipathd/main.h -index af39558..8fd426b 100644 ---- a/multipathd/main.h -+++ b/multipathd/main.h -@@ -29,11 +29,11 @@ int ev_remove_map (char *, char *, int, struct vectors *); - 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, -- int noisy); -+ int noisy); - void dumpHex(const char * , int len, int no_ascii); - int prout_do_scsi_ioctl(char * , int rq_servact, int rq_scope, -- unsigned int rq_type, struct prout_param_descriptor *param, -- int noisy); -+ unsigned int rq_type, -+ struct prout_param_descriptor *param, int noisy); - int mpath_pr_event_handle(struct path *pp); - void * mpath_pr_event_handler_fn (void * ); - int update_map_pr(struct multipath *mpp); --- -2.7.4 - diff --git a/0006-multipath-tools-fix-compilation-with-musl-libc.patch b/0006-multipath-tools-fix-compilation-with-musl-libc.patch deleted file mode 100644 index c6fd5b4..0000000 --- a/0006-multipath-tools-fix-compilation-with-musl-libc.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Fri, 11 May 2018 18:39:44 +0200 -Subject: [PATCH] multipath-tools: fix compilation with musl libc -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -In file included from alias.c:15: -file.h:9:47: error: unknown type name ‘mode_t’; did you mean ‘time_t’? - int ensure_directories_exist(const char *str, mode_t dir_mode); - ^~~~~~ - time_t - -sysfs.c: In function ‘sysfs_is_multipathed’: -sysfs.c:304:15: error: ‘PATH_MAX’ undeclared (first use in this function); did you mean ‘PATH_UP’? - char pathbuf[PATH_MAX]; - ^~~~~~~~ - PATH_UP - -Cc: Martin Wilck -Cc: Christophe Varoqui -Cc: DM ML -Signed-off-by: Xose Vazquez Perez -Signed-off-by: Benjamin Marzinski ---- - libmultipath/file.h | 2 ++ - libmultipath/sysfs.c | 1 + - 2 files changed, 3 insertions(+) - -diff --git a/libmultipath/file.h b/libmultipath/file.h -index 29520c7..3c75c90 100644 ---- a/libmultipath/file.h -+++ b/libmultipath/file.h -@@ -5,6 +5,8 @@ - #ifndef _FILE_H - #define _FILE_H - -+#include -+ - #define FILE_TIMEOUT 30 - int ensure_directories_exist(const char *str, mode_t dir_mode); - int open_file(const char *file, int *can_write, const char *header); -diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c -index ee72e6a..16e0a73 100644 ---- a/libmultipath/sysfs.c -+++ b/libmultipath/sysfs.c -@@ -28,6 +28,7 @@ - #include - #include - #include -+#include - - #include "checkers.h" - #include "vector.h" --- -2.7.4 - diff --git a/0006-multipathd-add-new-protocol-path-wildcard.patch b/0006-multipathd-add-new-protocol-path-wildcard.patch new file mode 100644 index 0000000..479788e --- /dev/null +++ b/0006-multipathd-add-new-protocol-path-wildcard.patch @@ -0,0 +1,92 @@ +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/0007-libmultipath-add-protocol-blacklist-option.patch b/0007-libmultipath-add-protocol-blacklist-option.patch new file mode 100644 index 0000000..16a1899 --- /dev/null +++ b/0007-libmultipath-add-protocol-blacklist-option.patch @@ -0,0 +1,425 @@ +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/0007-multipath-tools-add-x-to-doc-preclean.pl-and-split-m.patch b/0007-multipath-tools-add-x-to-doc-preclean.pl-and-split-m.patch deleted file mode 100644 index 9e608e1..0000000 --- a/0007-multipath-tools-add-x-to-doc-preclean.pl-and-split-m.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Sun, 13 May 2018 00:39:41 +0200 -Subject: [PATCH] multipath-tools: add +x to doc-preclean.pl and split-man.pl - -It is not strictly necessary, but it helps identify bin files. - -Cc: Christophe Varoqui -Cc: DM ML -Signed-off-by: Xose Vazquez Perez -Signed-off-by: Benjamin Marzinski ---- - libdmmp/docs/doc-preclean.pl | 0 - libdmmp/docs/split-man.pl | 0 - 2 files changed, 0 insertions(+), 0 deletions(-) - mode change 100644 => 100755 libdmmp/docs/doc-preclean.pl - mode change 100644 => 100755 libdmmp/docs/split-man.pl - -diff --git a/libdmmp/docs/doc-preclean.pl b/libdmmp/docs/doc-preclean.pl -old mode 100644 -new mode 100755 -diff --git a/libdmmp/docs/split-man.pl b/libdmmp/docs/split-man.pl -old mode 100644 -new mode 100755 --- -2.7.4 - diff --git a/0008-libmultipath-remove-_filter_-blacklist-functions.patch b/0008-libmultipath-remove-_filter_-blacklist-functions.patch new file mode 100644 index 0000000..b8e8e07 --- /dev/null +++ b/0008-libmultipath-remove-_filter_-blacklist-functions.patch @@ -0,0 +1,296 @@ +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-multipath-tools-refresh-kernel-doc-from-kernel-sourc.patch b/0008-multipath-tools-refresh-kernel-doc-from-kernel-sourc.patch deleted file mode 100644 index 3752158..0000000 --- a/0008-multipath-tools-refresh-kernel-doc-from-kernel-sourc.patch +++ /dev/null @@ -1,784 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Sun, 13 May 2018 00:39:42 +0200 -Subject: [PATCH] multipath-tools: refresh kernel-doc from kernel sources - -Cc: Gris Ge -Cc: Christophe Varoqui -Cc: device-mapper development -Signed-off-by: Xose Vazquez Perez -Signed-off-by: Benjamin Marzinski ---- - libdmmp/docs/kernel-doc | 671 ++++++++++++++++++++++++++---------------------- - 1 file changed, 368 insertions(+), 303 deletions(-) - -diff --git a/libdmmp/docs/kernel-doc b/libdmmp/docs/kernel-doc -index fee8952..0057d8e 100755 ---- a/libdmmp/docs/kernel-doc -+++ b/libdmmp/docs/kernel-doc -@@ -1,4 +1,5 @@ - #!/usr/bin/env perl -+# SPDX-License-Identifier: GPL-2.0 - - use warnings; - use strict; -@@ -328,13 +329,15 @@ my $lineprefix=""; - use constant { - STATE_NORMAL => 0, # normal code - STATE_NAME => 1, # looking for function name -- STATE_FIELD => 2, # scanning field start -- STATE_PROTO => 3, # scanning prototype -- STATE_DOCBLOCK => 4, # documentation block -- STATE_INLINE => 5, # gathering documentation outside main block -+ STATE_BODY_MAYBE => 2, # body - or maybe more description -+ STATE_BODY => 3, # the body of the comment -+ STATE_PROTO => 4, # scanning prototype -+ STATE_DOCBLOCK => 5, # documentation block -+ STATE_INLINE => 6, # gathering documentation outside main block - }; - my $state; - my $in_doc_sect; -+my $leading_space; - - # Inline documentation state - use constant { -@@ -363,7 +366,7 @@ my $doc_sect = $doc_com . - my $doc_content = $doc_com_body . '(.*)'; - my $doc_block = $doc_com . 'DOC:\s*(.*)?'; - my $doc_inline_start = '^\s*/\*\*\s*$'; --my $doc_inline_sect = '\s*\*\s*(@[\w\s]+):(.*)'; -+my $doc_inline_sect = '\s*\*\s*(@\s*[\w][\w\.]*\s*):(.*)'; - my $doc_inline_end = '^\s*\*/\s*$'; - my $doc_inline_oneline = '^\s*/\*\*\s*(@[\w\s]+):\s*(.*)\s*\*/\s*$'; - my $export_symbol = '^\s*EXPORT_SYMBOL(_GPL)?\s*\(\s*(\w+)\s*\)\s*;'; -@@ -553,10 +556,9 @@ sub output_highlight { - } - if ($line eq ""){ - if (! $output_preformatted) { -- print $lineprefix, local_unescape($blankline); -+ print $lineprefix, $blankline; - } - } else { -- $line =~ s/\\\\\\/\&/g; - if ($output_mode eq "man" && substr($line, 0, 1) eq ".") { - print "\\&$line"; - } else { -@@ -747,17 +749,73 @@ sub output_blockhead_rst(%) { - } - } - --sub output_highlight_rst { -- my $contents = join "\n",@_; -- my $line; -- -- # undo the evil effects of xml_escape() earlier -- $contents = xml_unescape($contents); -- -+# -+# Apply the RST highlights to a sub-block of text. -+# -+sub highlight_block($) { -+ # The dohighlight kludge requires the text be called $contents -+ my $contents = shift; - eval $dohighlight; - die $@ if $@; -+ return $contents; -+} - -- foreach $line (split "\n", $contents) { -+# -+# Regexes used only here. -+# -+my $sphinx_literal = '^[^.].*::$'; -+my $sphinx_cblock = '^\.\.\ +code-block::'; -+ -+sub output_highlight_rst { -+ my $input = join "\n",@_; -+ my $output = ""; -+ my $line; -+ my $in_literal = 0; -+ my $litprefix; -+ my $block = ""; -+ -+ foreach $line (split "\n",$input) { -+ # -+ # If we're in a literal block, see if we should drop out -+ # of it. Otherwise pass the line straight through unmunged. -+ # -+ if ($in_literal) { -+ if (! ($line =~ /^\s*$/)) { -+ # -+ # If this is the first non-blank line in a literal -+ # block we need to figure out what the proper indent is. -+ # -+ if ($litprefix eq "") { -+ $line =~ /^(\s*)/; -+ $litprefix = '^' . $1; -+ $output .= $line . "\n"; -+ } elsif (! ($line =~ /$litprefix/)) { -+ $in_literal = 0; -+ } else { -+ $output .= $line . "\n"; -+ } -+ } else { -+ $output .= $line . "\n"; -+ } -+ } -+ # -+ # Not in a literal block (or just dropped out) -+ # -+ if (! $in_literal) { -+ $block .= $line . "\n"; -+ if (($line =~ /$sphinx_literal/) || ($line =~ /$sphinx_cblock/)) { -+ $in_literal = 1; -+ $litprefix = ""; -+ $output .= highlight_block($block); -+ $block = "" -+ } -+ } -+ } -+ -+ if ($block) { -+ $output .= highlight_block($block); -+ } -+ foreach $line (split "\n", $output) { - print $lineprefix . $line . "\n"; - } - } -@@ -1062,7 +1120,7 @@ sub dump_struct($$) { - # Handle bitmaps - $arg =~ s/:\s*\d+\s*//g; - # Handle arrays -- $arg =~ s/\[\S+\]//g; -+ $arg =~ s/\[.*\]//g; - # The type may have multiple words, - # and multiple IDs can be defined, like: - # const struct foo, *bar, foobar -@@ -1422,8 +1480,6 @@ sub push_parameter($$$$) { - } - } - -- $param = xml_escape($param); -- - # strip spaces from $param so that it is one continuous string - # on @parameterlist; - # this fixes a problem where check_sections() cannot find -@@ -1522,6 +1578,7 @@ sub dump_function($$) { - $prototype =~ s/__meminit +//; - $prototype =~ s/__must_check +//; - $prototype =~ s/__weak +//; -+ $prototype =~ s/__sched +//; - my $define = $prototype =~ s/^#\s*define\s+//; #ak added - $prototype =~ s/__attribute__\s*\(\( - (?: -@@ -1748,47 +1805,6 @@ sub process_proto_type($$) { - } - } - --# xml_escape: replace <, >, and & in the text stream; --# --# however, formatting controls that are generated internally/locally in the --# kernel-doc script are not escaped here; instead, they begin life like --# $blankline_html (4 of '\' followed by a mnemonic + ':'), then these strings --# are converted to their mnemonic-expected output, without the 4 * '\' & ':', --# just before actual output; (this is done by local_unescape()) --sub xml_escape($) { -- my $text = shift; -- if ($output_mode eq "man") { -- return $text; -- } -- $text =~ s/\&/\\\\\\amp;/g; -- $text =~ s/\/\\\\\\gt;/g; -- return $text; --} -- --# xml_unescape: reverse the effects of xml_escape --sub xml_unescape($) { -- my $text = shift; -- if ($output_mode eq "man") { -- return $text; -- } -- $text =~ s/\\\\\\amp;/\&/g; -- $text =~ s/\\\\\\lt;//g; -- return $text; --} -- --# convert local escape strings to html --# local escape strings look like: '\\\\menmonic:' (that's 4 backslashes) --sub local_unescape($) { -- my $text = shift; -- if ($output_mode eq "man") { -- return $text; -- } -- $text =~ s/\\\\\\\\lt://g; -- return $text; --} - - sub map_filename($) { - my $file; -@@ -1826,15 +1842,291 @@ sub process_export_file($) { - close(IN); - } - --sub process_file($) { -- my $file; -+# -+# Parsers for the various processing states. -+# -+# STATE_NORMAL: looking for the /** to begin everything. -+# -+sub process_normal() { -+ if (/$doc_start/o) { -+ $state = STATE_NAME; # next line is always the function name -+ $in_doc_sect = 0; -+ $declaration_start_line = $. + 1; -+ } -+} -+ -+# -+# STATE_NAME: Looking for the "name - description" line -+# -+sub process_name($$) { -+ my $file = shift; - my $identifier; -- my $func; - my $descr; -- my $in_purpose = 0; -+ -+ if (/$doc_block/o) { -+ $state = STATE_DOCBLOCK; -+ $contents = ""; -+ $new_start_line = $. + 1; -+ -+ if ( $1 eq "" ) { -+ $section = $section_intro; -+ } else { -+ $section = $1; -+ } -+ } -+ elsif (/$doc_decl/o) { -+ $identifier = $1; -+ if (/\s*([\w\s]+?)(\(\))?\s*-/) { -+ $identifier = $1; -+ } -+ -+ $state = STATE_BODY; -+ # if there's no @param blocks need to set up default section -+ # here -+ $contents = ""; -+ $section = $section_default; -+ $new_start_line = $. + 1; -+ if (/-(.*)/) { -+ # strip leading/trailing/multiple spaces -+ $descr= $1; -+ $descr =~ s/^\s*//; -+ $descr =~ s/\s*$//; -+ $descr =~ s/\s+/ /g; -+ $declaration_purpose = $descr; -+ $state = STATE_BODY_MAYBE; -+ } else { -+ $declaration_purpose = ""; -+ } -+ -+ if (($declaration_purpose eq "") && $verbose) { -+ print STDERR "${file}:$.: warning: missing initial short description on line:\n"; -+ print STDERR $_; -+ ++$warnings; -+ } -+ -+ if ($identifier =~ m/^struct/) { -+ $decl_type = 'struct'; -+ } elsif ($identifier =~ m/^union/) { -+ $decl_type = 'union'; -+ } elsif ($identifier =~ m/^enum/) { -+ $decl_type = 'enum'; -+ } elsif ($identifier =~ m/^typedef/) { -+ $decl_type = 'typedef'; -+ } else { -+ $decl_type = 'function'; -+ } -+ -+ if ($verbose) { -+ print STDERR "${file}:$.: info: Scanning doc for $identifier\n"; -+ } -+ } else { -+ print STDERR "${file}:$.: warning: Cannot understand $_ on line $.", -+ " - I thought it was a doc line\n"; -+ ++$warnings; -+ $state = STATE_NORMAL; -+ } -+} -+ -+ -+# -+# STATE_BODY and STATE_BODY_MAYBE: the bulk of a kerneldoc comment. -+# -+sub process_body($$) { -+ my $file = shift; -+ -+ if (/$doc_sect/i) { # case insensitive for supported section names -+ $newsection = $1; -+ $newcontents = $2; -+ -+ # map the supported section names to the canonical names -+ if ($newsection =~ m/^description$/i) { -+ $newsection = $section_default; -+ } elsif ($newsection =~ m/^context$/i) { -+ $newsection = $section_context; -+ } elsif ($newsection =~ m/^returns?$/i) { -+ $newsection = $section_return; -+ } elsif ($newsection =~ m/^\@return$/) { -+ # special: @return is a section, not a param description -+ $newsection = $section_return; -+ } -+ -+ if (($contents ne "") && ($contents ne "\n")) { -+ if (!$in_doc_sect && $verbose) { -+ print STDERR "${file}:$.: warning: contents before sections\n"; -+ ++$warnings; -+ } -+ dump_section($file, $section, $contents); -+ $section = $section_default; -+ } -+ -+ $in_doc_sect = 1; -+ $state = STATE_BODY; -+ $contents = $newcontents; -+ $new_start_line = $.; -+ while (substr($contents, 0, 1) eq " ") { -+ $contents = substr($contents, 1); -+ } -+ if ($contents ne "") { -+ $contents .= "\n"; -+ } -+ $section = $newsection; -+ $leading_space = undef; -+ } elsif (/$doc_end/) { -+ if (($contents ne "") && ($contents ne "\n")) { -+ dump_section($file, $section, $contents); -+ $section = $section_default; -+ $contents = ""; -+ } -+ # look for doc_com + + doc_end: -+ if ($_ =~ m'\s*\*\s*[a-zA-Z_0-9:\.]+\*/') { -+ print STDERR "${file}:$.: warning: suspicious ending line: $_"; -+ ++$warnings; -+ } -+ -+ $prototype = ""; -+ $state = STATE_PROTO; -+ $brcount = 0; -+ } elsif (/$doc_content/) { -+ # miguel-style comment kludge, look for blank lines after -+ # @parameter line to signify start of description -+ if ($1 eq "") { -+ if ($section =~ m/^@/ || $section eq $section_context) { -+ dump_section($file, $section, $contents); -+ $section = $section_default; -+ $contents = ""; -+ $new_start_line = $.; -+ } else { -+ $contents .= "\n"; -+ } -+ $state = STATE_BODY; -+ } elsif ($state == STATE_BODY_MAYBE) { -+ # Continued declaration purpose -+ chomp($declaration_purpose); -+ $declaration_purpose .= " " . $1; -+ $declaration_purpose =~ s/\s+/ /g; -+ } else { -+ my $cont = $1; -+ if ($section =~ m/^@/ || $section eq $section_context) { -+ if (!defined $leading_space) { -+ if ($cont =~ m/^(\s+)/) { -+ $leading_space = $1; -+ } else { -+ $leading_space = ""; -+ } -+ } -+ $cont =~ s/^$leading_space//; -+ } -+ $contents .= $cont . "\n"; -+ } -+ } else { -+ # i dont know - bad line? ignore. -+ print STDERR "${file}:$.: warning: bad line: $_"; -+ ++$warnings; -+ } -+} -+ -+ -+# -+# STATE_PROTO: reading a function/whatever prototype. -+# -+sub process_proto($$) { -+ my $file = shift; -+ -+ if (/$doc_inline_oneline/) { -+ $section = $1; -+ $contents = $2; -+ if ($contents ne "") { -+ $contents .= "\n"; -+ dump_section($file, $section, $contents); -+ $section = $section_default; -+ $contents = ""; -+ } -+ } elsif (/$doc_inline_start/) { -+ $state = STATE_INLINE; -+ $inline_doc_state = STATE_INLINE_NAME; -+ } elsif ($decl_type eq 'function') { -+ process_proto_function($_, $file); -+ } else { -+ process_proto_type($_, $file); -+ } -+} -+ -+# -+# STATE_DOCBLOCK: within a DOC: block. -+# -+sub process_docblock($$) { -+ my $file = shift; -+ -+ if (/$doc_end/) { -+ dump_doc_section($file, $section, $contents); -+ $section = $section_default; -+ $contents = ""; -+ $function = ""; -+ %parameterdescs = (); -+ %parametertypes = (); -+ @parameterlist = (); -+ %sections = (); -+ @sectionlist = (); -+ $prototype = ""; -+ $state = STATE_NORMAL; -+ } elsif (/$doc_content/) { -+ if ( $1 eq "" ) { -+ $contents .= $blankline; -+ } else { -+ $contents .= $1 . "\n"; -+ } -+ } -+} -+ -+# -+# STATE_INLINE: docbook comments within a prototype. -+# -+sub process_inline($$) { -+ my $file = shift; -+ -+ # First line (state 1) needs to be a @parameter -+ if ($inline_doc_state == STATE_INLINE_NAME && /$doc_inline_sect/o) { -+ $section = $1; -+ $contents = $2; -+ $new_start_line = $.; -+ if ($contents ne "") { -+ while (substr($contents, 0, 1) eq " ") { -+ $contents = substr($contents, 1); -+ } -+ $contents .= "\n"; -+ } -+ $inline_doc_state = STATE_INLINE_TEXT; -+ # Documentation block end */ -+ } elsif (/$doc_inline_end/) { -+ if (($contents ne "") && ($contents ne "\n")) { -+ dump_section($file, $section, $contents); -+ $section = $section_default; -+ $contents = ""; -+ } -+ $state = STATE_PROTO; -+ $inline_doc_state = STATE_INLINE_NA; -+ # Regular text -+ } elsif (/$doc_content/) { -+ if ($inline_doc_state == STATE_INLINE_TEXT) { -+ $contents .= $1 . "\n"; -+ # nuke leading blank lines -+ if ($contents =~ /^\s*$/) { -+ $contents = ""; -+ } -+ } elsif ($inline_doc_state == STATE_INLINE_NAME) { -+ $inline_doc_state = STATE_INLINE_ERROR; -+ print STDERR "${file}:$.: warning: "; -+ print STDERR "Incorrect use of kernel-doc format: $_"; -+ ++$warnings; -+ } -+ } -+} -+ -+ -+sub process_file($) { -+ my $file; - my $initial_section_counter = $section_counter; - my ($orig_file) = @_; -- my $leading_space; - - $file = map_filename($orig_file); - -@@ -1853,250 +2145,23 @@ sub process_file($) { - } - # Replace tabs by spaces - while ($_ =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {}; -+ # Hand this line to the appropriate state handler - if ($state == STATE_NORMAL) { -- if (/$doc_start/o) { -- $state = STATE_NAME; # next line is always the function name -- $in_doc_sect = 0; -- $declaration_start_line = $. + 1; -- } -- } elsif ($state == STATE_NAME) {# this line is the function name (always) -- if (/$doc_block/o) { -- $state = STATE_DOCBLOCK; -- $contents = ""; -- $new_start_line = $. + 1; -- -- if ( $1 eq "" ) { -- $section = $section_intro; -- } else { -- $section = $1; -- } -- } -- elsif (/$doc_decl/o) { -- $identifier = $1; -- if (/\s*([\w\s]+?)\s*-/) { -- $identifier = $1; -- } -- -- $state = STATE_FIELD; -- # if there's no @param blocks need to set up default section -- # here -- $contents = ""; -- $section = $section_default; -- $new_start_line = $. + 1; -- if (/-(.*)/) { -- # strip leading/trailing/multiple spaces -- $descr= $1; -- $descr =~ s/^\s*//; -- $descr =~ s/\s*$//; -- $descr =~ s/\s+/ /g; -- $declaration_purpose = xml_escape($descr); -- $in_purpose = 1; -- } else { -- $declaration_purpose = ""; -- } -- -- if (($declaration_purpose eq "") && $verbose) { -- print STDERR "${file}:$.: warning: missing initial short description on line:\n"; -- print STDERR $_; -- ++$warnings; -- } -- -- if ($identifier =~ m/^struct/) { -- $decl_type = 'struct'; -- } elsif ($identifier =~ m/^union/) { -- $decl_type = 'union'; -- } elsif ($identifier =~ m/^enum/) { -- $decl_type = 'enum'; -- } elsif ($identifier =~ m/^typedef/) { -- $decl_type = 'typedef'; -- } else { -- $decl_type = 'function'; -- } -- -- if ($verbose) { -- print STDERR "${file}:$.: info: Scanning doc for $identifier\n"; -- } -- } else { -- print STDERR "${file}:$.: warning: Cannot understand $_ on line $.", -- " - I thought it was a doc line\n"; -- ++$warnings; -- $state = STATE_NORMAL; -- } -- } elsif ($state == STATE_FIELD) { # look for head: lines, and include content -- if (/$doc_sect/i) { # case insensitive for supported section names -- $newsection = $1; -- $newcontents = $2; -- -- # map the supported section names to the canonical names -- if ($newsection =~ m/^description$/i) { -- $newsection = $section_default; -- } elsif ($newsection =~ m/^context$/i) { -- $newsection = $section_context; -- } elsif ($newsection =~ m/^returns?$/i) { -- $newsection = $section_return; -- } elsif ($newsection =~ m/^\@return$/) { -- # special: @return is a section, not a param description -- $newsection = $section_return; -- } -- -- if (($contents ne "") && ($contents ne "\n")) { -- if (!$in_doc_sect && $verbose) { -- print STDERR "${file}:$.: warning: contents before sections\n"; -- ++$warnings; -- } -- dump_section($file, $section, xml_escape($contents)); -- $section = $section_default; -- } -- -- $in_doc_sect = 1; -- $in_purpose = 0; -- $contents = $newcontents; -- $new_start_line = $.; -- while (substr($contents, 0, 1) eq " ") { -- $contents = substr($contents, 1); -- } -- if ($contents ne "") { -- $contents .= "\n"; -- } -- $section = $newsection; -- $leading_space = undef; -- } elsif (/$doc_end/) { -- if (($contents ne "") && ($contents ne "\n")) { -- dump_section($file, $section, xml_escape($contents)); -- $section = $section_default; -- $contents = ""; -- } -- # look for doc_com + + doc_end: -- if ($_ =~ m'\s*\*\s*[a-zA-Z_0-9:\.]+\*/') { -- print STDERR "${file}:$.: warning: suspicious ending line: $_"; -- ++$warnings; -- } -- -- $prototype = ""; -- $state = STATE_PROTO; -- $brcount = 0; --# print STDERR "end of doc comment, looking for prototype\n"; -- } elsif (/$doc_content/) { -- # miguel-style comment kludge, look for blank lines after -- # @parameter line to signify start of description -- if ($1 eq "") { -- if ($section =~ m/^@/ || $section eq $section_context) { -- dump_section($file, $section, xml_escape($contents)); -- $section = $section_default; -- $contents = ""; -- $new_start_line = $.; -- } else { -- $contents .= "\n"; -- } -- $in_purpose = 0; -- } elsif ($in_purpose == 1) { -- # Continued declaration purpose -- chomp($declaration_purpose); -- $declaration_purpose .= " " . xml_escape($1); -- $declaration_purpose =~ s/\s+/ /g; -- } else { -- my $cont = $1; -- if ($section =~ m/^@/ || $section eq $section_context) { -- if (!defined $leading_space) { -- if ($cont =~ m/^(\s+)/) { -- $leading_space = $1; -- } else { -- $leading_space = ""; -- } -- } -- -- $cont =~ s/^$leading_space//; -- } -- $contents .= $cont . "\n"; -- } -- } else { -- # i dont know - bad line? ignore. -- print STDERR "${file}:$.: warning: bad line: $_"; -- ++$warnings; -- } -+ process_normal(); -+ } elsif ($state == STATE_NAME) { -+ process_name($file, $_); -+ } elsif ($state == STATE_BODY || $state == STATE_BODY_MAYBE) { -+ process_body($file, $_); - } elsif ($state == STATE_INLINE) { # scanning for inline parameters -- # First line (state 1) needs to be a @parameter -- if ($inline_doc_state == STATE_INLINE_NAME && /$doc_inline_sect/o) { -- $section = $1; -- $contents = $2; -- $new_start_line = $.; -- if ($contents ne "") { -- while (substr($contents, 0, 1) eq " ") { -- $contents = substr($contents, 1); -- } -- $contents .= "\n"; -- } -- $inline_doc_state = STATE_INLINE_TEXT; -- # Documentation block end */ -- } elsif (/$doc_inline_end/) { -- if (($contents ne "") && ($contents ne "\n")) { -- dump_section($file, $section, xml_escape($contents)); -- $section = $section_default; -- $contents = ""; -- } -- $state = STATE_PROTO; -- $inline_doc_state = STATE_INLINE_NA; -- # Regular text -- } elsif (/$doc_content/) { -- if ($inline_doc_state == STATE_INLINE_TEXT) { -- $contents .= $1 . "\n"; -- # nuke leading blank lines -- if ($contents =~ /^\s*$/) { -- $contents = ""; -- } -- } elsif ($inline_doc_state == STATE_INLINE_NAME) { -- $inline_doc_state = STATE_INLINE_ERROR; -- print STDERR "${file}:$.: warning: "; -- print STDERR "Incorrect use of kernel-doc format: $_"; -- ++$warnings; -- } -- } -- } elsif ($state == STATE_PROTO) { # scanning for function '{' (end of prototype) -- if (/$doc_inline_oneline/) { -- $section = $1; -- $contents = $2; -- if ($contents ne "") { -- $contents .= "\n"; -- dump_section($file, $section, xml_escape($contents)); -- $section = $section_default; -- $contents = ""; -- } -- } elsif (/$doc_inline_start/) { -- $state = STATE_INLINE; -- $inline_doc_state = STATE_INLINE_NAME; -- } elsif ($decl_type eq 'function') { -- process_proto_function($_, $file); -- } else { -- process_proto_type($_, $file); -- } -+ process_inline($file, $_); -+ } elsif ($state == STATE_PROTO) { -+ process_proto($file, $_); - } elsif ($state == STATE_DOCBLOCK) { -- if (/$doc_end/) -- { -- dump_doc_section($file, $section, xml_escape($contents)); -- $section = $section_default; -- $contents = ""; -- $function = ""; -- %parameterdescs = (); -- %parametertypes = (); -- @parameterlist = (); -- %sections = (); -- @sectionlist = (); -- $prototype = ""; -- $state = STATE_NORMAL; -- } -- elsif (/$doc_content/) -- { -- if ( $1 eq "" ) -- { -- $contents .= $blankline; -- } -- else -- { -- $contents .= $1 . "\n"; -- } -- } -+ process_docblock($file, $_); - } - } -+ -+ # Make sure we got something interesting. - if ($initial_section_counter == $section_counter) { - if ($output_mode ne "none") { - print STDERR "${file}:1: warning: no structured comments found\n"; --- -2.7.4 - diff --git a/0009-multipath-tests-change-to-work-with-old-make-version.patch b/0009-multipath-tests-change-to-work-with-old-make-version.patch new file mode 100644 index 0000000..186015a --- /dev/null +++ b/0009-multipath-tests-change-to-work-with-old-make-version.patch @@ -0,0 +1,28 @@ +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-multipath-tools-configure-hitachi-ams2000-and-hus100.patch b/0009-multipath-tools-configure-hitachi-ams2000-and-hus100.patch deleted file mode 100644 index 2cae075..0000000 --- a/0009-multipath-tools-configure-hitachi-ams2000-and-hus100.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Mon, 14 May 2018 17:30:17 +0200 -Subject: [PATCH] multipath-tools: configure hitachi ams2000 and hus100 as full - active arrays - -AMS2000 and HUS100 families are active/active arrays. - -Based on https://support.hitachivantara.com/download/epcra/df818913.pdf -and internal hitachi docs. - -Cc: Matthias Rudolph -Cc: Christophe Varoqui -Cc: DM-DEV ML -Signed-off-by: Xose Vazquez Perez -Signed-off-by: Benjamin Marzinski ---- - libmultipath/hwtable.c | 10 ++++++++-- - 1 file changed, 8 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index 2ca6888..148f0ba 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -398,13 +398,13 @@ static struct hwentry default_hw[] = { - * Mail : matthias.rudolph@hds.com - */ - { -- /* USP-V, HUS VM, VSP, VSP G1X00 and VSP GX00 families */ -+ /* USP-V, HUS VM, VSP, VSP G1X00 and VSP GX00 families / HP XP */ - .vendor = "(HITACHI|HP)", - .product = "^OPEN-", - .pgpolicy = MULTIBUS, - }, - { -- /* AMS 2000 and HUS 100 families */ -+ /* AMS other than AMS 2000 */ - .vendor = "HITACHI", - .product = "^DF", - .no_path_retry = NO_PATH_RETRY_QUEUE, -@@ -412,6 +412,12 @@ static struct hwentry default_hw[] = { - .pgfailback = -FAILBACK_IMMEDIATE, - .prio_name = PRIO_HDS, - }, -+ { -+ /* AMS 2000 and HUS 100 families */ -+ .vendor = "HITACHI", -+ .product = "^DF600F", -+ .pgpolicy = MULTIBUS, -+ }, - /* - * IBM - * --- -2.7.4 - diff --git a/0010-libmultipath-don-t-reject-maps-with-undefined-prio.patch b/0010-libmultipath-don-t-reject-maps-with-undefined-prio.patch deleted file mode 100644 index 2dda2ed..0000000 --- a/0010-libmultipath-don-t-reject-maps-with-undefined-prio.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 21 Mar 2018 10:34:18 +0100 -Subject: [PATCH] libmultipath: don't reject maps with undefined prio - -libmultipath's prio routines can deal with pp->priority == PRIO_UNDEF -just fine. PRIO_UNDEF is just a very low priority. So there's -no reason to reject setting up a multipath map because paths have -undefined priority. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 5 ----- - 1 file changed, 5 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 5796683..5c54f9b 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -1063,9 +1063,6 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, - continue; - } - -- if (pp1->priority == PRIO_UNDEF) -- mpp->action = ACT_REJECT; -- - if (!mpp->paths) { - condlog(0, "%s: skip coalesce (no paths)", mpp->alias); - remove_map(mpp, vecs, 0); -@@ -1091,8 +1088,6 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, - mpp->size); - mpp->action = ACT_REJECT; - } -- if (pp2->priority == PRIO_UNDEF) -- mpp->action = ACT_REJECT; - } - verify_paths(mpp, vecs); - --- -2.7.4 - diff --git a/0010-multipath-tests-add-blacklist-tests.patch b/0010-multipath-tests-add-blacklist-tests.patch new file mode 100644 index 0000000..cf7eff8 --- /dev/null +++ b/0010-multipath-tests-add-blacklist-tests.patch @@ -0,0 +1,559 @@ +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/0011-mpathpersist-add-missing-param-rk-usage-info.patch b/0011-mpathpersist-add-missing-param-rk-usage-info.patch new file mode 100644 index 0000000..e05d9e6 --- /dev/null +++ b/0011-mpathpersist-add-missing-param-rk-usage-info.patch @@ -0,0 +1,25 @@ +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/0011-multipathd-handle-errors-in-uxlsnr-as-fatal.patch b/0011-multipathd-handle-errors-in-uxlsnr-as-fatal.patch deleted file mode 100644 index 96a814f..0000000 --- a/0011-multipathd-handle-errors-in-uxlsnr-as-fatal.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 21 Mar 2018 10:34:19 +0100 -Subject: [PATCH] multipathd: handle errors in uxlsnr as fatal - -The ppoll() calls of the uxlsnr thread are vital for proper functioning of -multipathd. If the uxlsnr thread can't open the socket or fails to call ppoll() -for other reasons, quit the daemon. If we don't do that, multipathd may -hang in a state where it can't be terminated any more, because the uxlsnr -thread is responsible for handling all signals. This happens e.g. if -systemd's multipathd.socket is running in and multipathd is started from -outside systemd. - -24f2844 "multipathd: fix signal blocking logic" has made this problem more -severe. Before that patch, the signals weren't actually blocked in any thread. -That's not to say 24f2844 was wrong. I still think it's correct, we just -need this one on top. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - multipathd/uxlsnr.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/multipathd/uxlsnr.c b/multipathd/uxlsnr.c -index cdafd82..6f66666 100644 ---- a/multipathd/uxlsnr.c -+++ b/multipathd/uxlsnr.c -@@ -178,7 +178,7 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, void * trigger_data) - - if (ux_sock == -1) { - condlog(1, "could not create uxsock: %d", errno); -- return NULL; -+ exit_daemon(); - } - - pthread_cleanup_push(uxsock_cleanup, (void *)ux_sock); -@@ -187,7 +187,7 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, void * trigger_data) - polls = (struct pollfd *)MALLOC((MIN_POLLS + 1) * sizeof(struct pollfd)); - if (!polls) { - condlog(0, "uxsock: failed to allocate poll fds"); -- return NULL; -+ exit_daemon(); - } - sigfillset(&mask); - sigdelset(&mask, SIGINT); -@@ -249,6 +249,7 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, void * trigger_data) - - /* something went badly wrong! */ - condlog(0, "uxsock: poll failed with %d", errno); -+ exit_daemon(); - break; - } - --- -2.7.4 - diff --git a/0021-RH-fixup-udev-rules-for-redhat.patch b/0012-RH-fixup-udev-rules-for-redhat.patch similarity index 96% rename from 0021-RH-fixup-udev-rules-for-redhat.patch rename to 0012-RH-fixup-udev-rules-for-redhat.patch index 4ef3e70..0c0fa55 100644 --- a/0021-RH-fixup-udev-rules-for-redhat.patch +++ b/0012-RH-fixup-udev-rules-for-redhat.patch @@ -65,10 +65,10 @@ index 0828a8f..b9bbb3c 100644 $(RM) $(DESTDIR)$(man5dir)/$(EXEC).conf.5.gz diff --git a/multipath/main.c b/multipath/main.c -index 3f0a6aa..6fdde03 100644 +index fc5bf16..39f6f1f 100644 --- a/multipath/main.c +++ b/multipath/main.c -@@ -389,7 +389,7 @@ static int find_multipaths_check_timeout(const struct path *pp, long tmo, +@@ -403,7 +403,7 @@ static int find_multipaths_check_timeout(const struct path *pp, long tmo, struct timespec now, ftimes[2], tdiff; struct stat st; long fd; diff --git a/0012-libmultipath-fix-error-parsing-find_multipaths-stric.patch b/0012-libmultipath-fix-error-parsing-find_multipaths-stric.patch deleted file mode 100644 index 8ce2431..0000000 --- a/0012-libmultipath-fix-error-parsing-find_multipaths-stric.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 15 May 2018 14:32:44 +0200 -Subject: [PATCH] libmultipath: fix error parsing "find_multipaths strict" - -If "find_multipaths strict" is set in multipath.conf, the error message -"illegal value for find_multipaths: strict" is printed. This causes no -functional problem, as "strict" happens to be the default, fallback -value. It should be fixed nonetheless. FIND_MULTIPATHS_STRICT, having -the highest numeric value, must be last in the enum. - -Fixes: c36f2f42 "libmultipath: change find_multipaths option to multi-value" -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/structs.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index eb6a178..e424b15 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -122,9 +122,9 @@ enum find_multipaths_states { - FIND_MULTIPATHS_UNDEF = YNU_UNDEF, - FIND_MULTIPATHS_OFF = YNU_NO, - FIND_MULTIPATHS_ON = _FIND_MULTIPATHS_F, -- FIND_MULTIPATHS_STRICT = _FIND_MULTIPATHS_F|_FIND_MULTIPATHS_N, - 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_LAST, - }; - --- -2.7.4 - diff --git a/0013-RH-Remove-the-property-blacklist-exception-builtin.patch b/0013-RH-Remove-the-property-blacklist-exception-builtin.patch new file mode 100644 index 0000000..87eba36 --- /dev/null +++ b/0013-RH-Remove-the-property-blacklist-exception-builtin.patch @@ -0,0 +1,80 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 2 Jul 2014 12:49:53 -0500 +Subject: [PATCH] RH: Remove the property blacklist exception builtin + +Multipath set the default property blacklist exceptions to +(ID_SCSI_VPD|ID_WWN). This has the effect of blacklisting some internal +devices. These devices may never have multiple paths, but it is nice +to be able to set multipath up on them all the same. This patch simply +removes the default, and makes it so that if no property +blacklist_exception is given, then devices aren't failed for not matching +it. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/blacklist.c | 12 ++++-------- + multipath/multipath.conf.5 | 14 ++++++-------- + 2 files changed, 10 insertions(+), 16 deletions(-) + +diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c +index 318ec03..c0cfbca 100644 +--- a/libmultipath/blacklist.c ++++ b/libmultipath/blacklist.c +@@ -204,12 +204,6 @@ setup_default_blist (struct config * conf) + if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT)) + return 1; + +- str = STRDUP("(SCSI_IDENT_|ID_WWN)"); +- if (!str) +- return 1; +- if (store_ble(conf->elist_property, str, ORIGIN_DEFAULT)) +- return 1; +- + 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. + */ +- r = MATCH_PROPERTY_BLIST_MISSING; ++ if (VECTOR_SIZE(conf->elist_property)) ++ r = MATCH_PROPERTY_BLIST_MISSING; + udev_list_entry_foreach(list_entry, + udev_device_get_properties_list_entry(udev)) { + +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 +index 6333366..3dab26b 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 + 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, +-because devices \fBmust\fR have at least one whitelisted udev property; ++because if a property blacklist_exception is set, devices \fBmust\fR have at ++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. + .TP + .B protocol + Regular expression for the protocol of a device to be excluded/included. +-- +2.7.4 + diff --git a/0013-libmultipath-print-correct-default-for-delay_-_check.patch b/0013-libmultipath-print-correct-default-for-delay_-_check.patch deleted file mode 100644 index c767804..0000000 --- a/0013-libmultipath-print-correct-default-for-delay_-_check.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 7 May 2018 17:16:05 -0500 -Subject: [PATCH] libmultipath: print correct default for delay_*_checks - -These options default to "no", so they should display that when the -config is printed. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/dict.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index 4040611..3e7c5d6 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -1115,7 +1115,8 @@ print_off_int_undef(char * buff, int len, long v) - } - - declare_def_handler(delay_watch_checks, set_off_int_undef) --declare_def_snprint(delay_watch_checks, print_off_int_undef) -+declare_def_snprint_defint(delay_watch_checks, print_off_int_undef, -+ DEFAULT_DELAY_CHECKS) - declare_ovr_handler(delay_watch_checks, set_off_int_undef) - declare_ovr_snprint(delay_watch_checks, print_off_int_undef) - declare_hw_handler(delay_watch_checks, set_off_int_undef) -@@ -1123,7 +1124,8 @@ declare_hw_snprint(delay_watch_checks, print_off_int_undef) - declare_mp_handler(delay_watch_checks, set_off_int_undef) - declare_mp_snprint(delay_watch_checks, print_off_int_undef) - declare_def_handler(delay_wait_checks, set_off_int_undef) --declare_def_snprint(delay_wait_checks, print_off_int_undef) -+declare_def_snprint_defint(delay_wait_checks, print_off_int_undef, -+ DEFAULT_DELAY_CHECKS) - declare_ovr_handler(delay_wait_checks, set_off_int_undef) - declare_ovr_snprint(delay_wait_checks, print_off_int_undef) - declare_hw_handler(delay_wait_checks, set_off_int_undef) --- -2.7.4 - diff --git a/0023-RH-don-t-start-without-a-config-file.patch b/0014-RH-don-t-start-without-a-config-file.patch similarity index 92% rename from 0023-RH-don-t-start-without-a-config-file.patch rename to 0014-RH-don-t-start-without-a-config-file.patch index 886f1c8..2fb890b 100644 --- a/0023-RH-don-t-start-without-a-config-file.patch +++ b/0014-RH-don-t-start-without-a-config-file.patch @@ -20,7 +20,7 @@ Signed-off-by: Benjamin Marzinski 5 files changed, 20 insertions(+) diff --git a/libmultipath/config.c b/libmultipath/config.c -index 5872927..0607403 100644 +index 0aef186..6a9340a 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c @@ -26,6 +26,7 @@ @@ -30,11 +30,11 @@ index 5872927..0607403 100644 +#include "version.h" static int - hwe_strmatch (struct hwentry *hwe1, struct hwentry *hwe2) -@@ -658,6 +659,20 @@ load_config (char * file) - factorize_hwtable(conf->hwtable, builtin_hwtable_size); + hwe_strmatch (const struct hwentry *hwe1, const struct hwentry *hwe2) +@@ -745,6 +746,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) { @@ -53,7 +53,7 @@ index 5872927..0607403 100644 conf->processed_main_config = 1; diff --git a/libmultipath/config.h b/libmultipath/config.h -index fcbe3fc..3a42435 100644 +index 7d0cd9a..d7fb8e2 100644 --- a/libmultipath/config.h +++ b/libmultipath/config.h @@ -9,6 +9,7 @@ @@ -77,7 +77,7 @@ index d658073..b3f54d7 100644 ENV{DEVTYPE}!="partition", GOTO="test_dev" IMPORT{parent}="DM_MULTIPATH_DEVICE_PATH" diff --git a/multipathd/multipathd.8 b/multipathd/multipathd.8 -index e78ac9e..09cdead 100644 +index 94c3f97..ed13efd 100644 --- a/multipathd/multipathd.8 +++ b/multipathd/multipathd.8 @@ -38,6 +38,8 @@ map regains its maximum performance and redundancy. diff --git a/0014-multipath.conf.5-clarify-property-whitelist-handling.patch b/0014-multipath.conf.5-clarify-property-whitelist-handling.patch deleted file mode 100644 index 0ab4e06..0000000 --- a/0014-multipath.conf.5-clarify-property-whitelist-handling.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 9 May 2018 14:32:59 -0500 -Subject: [PATCH] multipath.conf.5: clarify property whitelist handling - -Signed-off-by: Benjamin Marzinski ---- - multipath/multipath.conf.5 | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index f689795..96d1b66 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -1181,10 +1181,9 @@ and - keywords. For a full description of these keywords please see the \fIdevices\fR - section description. - .LP --The \fIproperty\fR blacklist and whitelist handling is different from the usual --handling in the sense that the whitelist \fIhas\fR to be set, otherwise the --device will be blacklisted. In these cases the message \fIblacklisted, udev --property missing\fR will be displayed. -+The \fIproperty\fR whitelist handling is different from the usual -+handling in the sense that the device \fIhas\fR to have a udev property that -+matches the whitelist, otherwise the device will be blacklisted. In these cases the message \fIblacklisted, udev property missing\fR will be displayed. - . - . - .\" ---------------------------------------------------------------------------- --- -2.7.4 - diff --git a/0024-RH-use-rpm-optflags-if-present.patch b/0015-RH-use-rpm-optflags-if-present.patch similarity index 100% rename from 0024-RH-use-rpm-optflags-if-present.patch rename to 0015-RH-use-rpm-optflags-if-present.patch diff --git a/0015-mpathpersist-add-all_tg_pt-option.patch b/0015-mpathpersist-add-all_tg_pt-option.patch deleted file mode 100644 index be2681d..0000000 --- a/0015-mpathpersist-add-all_tg_pt-option.patch +++ /dev/null @@ -1,317 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 31 May 2018 17:47:11 -0500 -Subject: [PATCH] mpathpersist: add all_tg_pt option - -Some arrays, such as the EMC VNX, don't follow the scsi persistent -reservations spec in making key registrations per I_T NEXUS. Instead, -the registration is shared by all target ports connected to a given -host. This causes mpathpersist to fail whenever it tries to register a -key, since it will receive a registration conflict on some of the paths. - -To deal with this, mpathpersist needs to track the hosts that it has -done a registration on, and only register once per host. The new -"all_tg_pt" multipath.conf option is used to set which arrays need this -feature. I currently don't know if all EMC VNX arrays handle persistent -reservations like this, or if it is configurable. A future patch will -update the VNX built-in config, if this is indeed their default (or -only) setting. - -Multipathd doesn't need to worry about this. It is often the case that -when a path device comes back, it will still have the keys registered to -it. Because of this, multipathd uses register-and-ignore, which means -that it won't cause an error if the registration has already happened -down a different target port. - -Signed-off-by: Benjamin Marzinski ---- - libmpathpersist/mpath_persist.c | 28 ++++++++++++++++++++++------ - libmultipath/config.c | 2 ++ - libmultipath/config.h | 2 ++ - libmultipath/defaults.h | 1 + - libmultipath/dict.c | 10 ++++++++++ - libmultipath/propsel.c | 15 +++++++++++++++ - libmultipath/propsel.h | 1 + - libmultipath/structs.h | 7 +++++++ - multipath/multipath.conf.5 | 11 +++++++++++ - 9 files changed, 71 insertions(+), 6 deletions(-) - -diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c -index 907a17c..ca91c55 100644 ---- a/libmpathpersist/mpath_persist.c -+++ b/libmpathpersist/mpath_persist.c -@@ -335,6 +335,7 @@ int mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, - - conf = get_multipath_config(); - select_reservation_key(conf, mpp); -+ select_all_tg_pt(conf, mpp); - put_multipath_config(conf); - - memcpy(&prkey, paramp->sa_key, 8); -@@ -456,7 +457,7 @@ int mpath_prout_reg(struct multipath *mpp,int rq_servact, int rq_scope, - unsigned int rq_type, struct prout_param_descriptor * paramp, int noisy) - { - -- int i, j; -+ int i, j, k; - struct pathgroup *pgp = NULL; - struct path *pp = NULL; - int rollback = 0; -@@ -481,11 +482,13 @@ int mpath_prout_reg(struct multipath *mpp,int rq_servact, int rq_scope, - } - - struct threadinfo thread[active_pathcount]; -+ int hosts[active_pathcount]; - - memset(thread, 0, sizeof(thread)); - - /* init thread parameter */ - for (i =0; i< active_pathcount; i++){ -+ hosts[i] = -1; - thread[i].param.rq_servact = rq_servact; - thread[i].param.rq_scope = rq_scope; - thread[i].param.rq_type = rq_type; -@@ -514,6 +517,17 @@ 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) { -+ 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); -+ break; -+ } -+ } -+ if (k < count) -+ continue; -+ } - strncpy(thread[count].param.dev, pp->dev, - FILE_NAME_SIZE - 1); - -@@ -531,10 +545,12 @@ int mpath_prout_reg(struct multipath *mpp,int rq_servact, int rq_scope, - condlog (0, "%s: failed to create thread %d", mpp->wwid, rc); - thread[count].param.status = MPATH_PR_THREAD_ERROR; - } -+ else -+ hosts[count] = pp->sg_id.host_no; - count = count + 1; - } - } -- for( i=0; i < active_pathcount ; i++){ -+ for( i=0; i < count ; i++){ - if (thread[i].param.status != MPATH_PR_THREAD_ERROR) { - rc = pthread_join(thread[i].id, NULL); - if (rc){ -@@ -557,7 +573,7 @@ int mpath_prout_reg(struct multipath *mpp,int rq_servact, int rq_scope, - } - if (rollback && ((rq_servact == MPATH_PROUT_REG_SA) && sa_key != 0 )){ - condlog (3, "%s: ERROR: initiating pr out rollback", mpp->wwid); -- for( i=0 ; i < active_pathcount ; i++){ -+ for( i=0 ; i < count ; i++){ - if(thread[i].param.status == MPATH_PR_SUCCESS) { - memcpy(&thread[i].param.paramp->key, &thread[i].param.paramp->sa_key, 8); - memset(&thread[i].param.paramp->sa_key, 0, 8); -@@ -571,7 +587,7 @@ int mpath_prout_reg(struct multipath *mpp,int rq_servact, int rq_scope, - } else - thread[i].param.status = MPATH_PR_SKIP; - } -- for(i=0; i < active_pathcount ; i++){ -+ for(i=0; i < count ; i++){ - if (thread[i].param.status != MPATH_PR_SKIP && - thread[i].param.status != MPATH_PR_THREAD_ERROR) { - rc = pthread_join(thread[i].id, NULL); -@@ -720,7 +736,7 @@ int mpath_prout_rel(struct multipath *mpp,int rq_servact, int rq_scope, - } - } - pthread_attr_destroy (&attr); -- for (i = 0; i < active_pathcount; i++){ -+ for (i = 0; i < count; i++){ - if (thread[i].param.status != MPATH_PR_THREAD_ERROR) { - rc = pthread_join (thread[i].id, NULL); - if (rc){ -@@ -729,7 +745,7 @@ int mpath_prout_rel(struct multipath *mpp,int rq_servact, int rq_scope, - } - } - -- for (i = 0; i < active_pathcount; i++){ -+ for (i = 0; i < count; i++){ - /* check thread status here and return the status */ - - if (thread[i].param.status == MPATH_PR_RESERV_CONFLICT) -diff --git a/libmultipath/config.c b/libmultipath/config.c -index 085a3e1..5872927 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -352,6 +352,7 @@ merge_hwe (struct hwentry * dst, struct hwentry * src) - merge_num(skip_kpartx); - merge_num(max_sectors_kb); - merge_num(ghost_delay); -+ merge_num(all_tg_pt); - - snprintf(id, sizeof(id), "%s/%s", dst->vendor, dst->product); - reconcile_features_with_options(id, &dst->features, -@@ -622,6 +623,7 @@ load_config (char * file) - conf->disable_changed_wwids = DEFAULT_DISABLE_CHANGED_WWIDS; - conf->remove_retries = 0; - conf->ghost_delay = DEFAULT_GHOST_DELAY; -+ conf->all_tg_pt = DEFAULT_ALL_TG_PT; - - /* - * preload default hwtable -diff --git a/libmultipath/config.h b/libmultipath/config.h -index 6e69a37..1bf708a 100644 ---- a/libmultipath/config.h -+++ b/libmultipath/config.h -@@ -82,6 +82,7 @@ struct hwentry { - int skip_kpartx; - int max_sectors_kb; - int ghost_delay; -+ int all_tg_pt; - char * bl_product; - }; - -@@ -194,6 +195,7 @@ struct config { - char * partition_delim; - char * config_dir; - int prkey_source; -+ int all_tg_pt; - struct be64 reservation_key; - - vector keywords; -diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h -index d7b87b4..f076b4b 100644 ---- a/libmultipath/defaults.h -+++ b/libmultipath/defaults.h -@@ -43,6 +43,7 @@ - #define DEFAULT_GHOST_DELAY GHOST_DELAY_OFF - #define DEFAULT_FIND_MULTIPATHS_TIMEOUT -10 - #define DEFAULT_UNKNOWN_FIND_MULTIPATHS_TIMEOUT 1 -+#define DEFAULT_ALL_TG_PT ALL_TG_PT_OFF - - #define DEFAULT_CHECKINT 5 - #define MAX_CHECKINT(a) (a << 2) -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index 3e7c5d6..2557b8a 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -1178,6 +1178,13 @@ declare_hw_snprint(ghost_delay, print_off_int_undef) - declare_mp_handler(ghost_delay, set_off_int_undef) - declare_mp_snprint(ghost_delay, print_off_int_undef) - -+declare_def_handler(all_tg_pt, set_yes_no_undef) -+declare_def_snprint_defint(all_tg_pt, print_yes_no_undef, DEFAULT_ALL_TG_PT) -+declare_ovr_handler(all_tg_pt, set_yes_no_undef) -+declare_ovr_snprint(all_tg_pt, print_yes_no_undef) -+declare_hw_handler(all_tg_pt, set_yes_no_undef) -+declare_hw_snprint(all_tg_pt, print_yes_no_undef) -+ - - static int - def_uxsock_timeout_handler(struct config *conf, vector strvec) -@@ -1509,6 +1516,7 @@ init_keywords(vector keywords) - install_keyword("prkeys_file", &def_prkeys_file_handler, &snprint_def_prkeys_file); - install_keyword("log_checker_err", &def_log_checker_err_handler, &snprint_def_log_checker_err); - install_keyword("reservation_key", &def_reservation_key_handler, &snprint_def_reservation_key); -+ install_keyword("all_tg_pt", &def_all_tg_pt_handler, &snprint_def_all_tg_pt); - install_keyword("retain_attached_hw_handler", &def_retain_hwhandler_handler, &snprint_def_retain_hwhandler); - install_keyword("detect_prio", &def_detect_prio_handler, &snprint_def_detect_prio); - install_keyword("detect_checker", &def_detect_checker_handler, &snprint_def_detect_checker); -@@ -1618,6 +1626,7 @@ init_keywords(vector keywords) - install_keyword("skip_kpartx", &hw_skip_kpartx_handler, &snprint_hw_skip_kpartx); - install_keyword("max_sectors_kb", &hw_max_sectors_kb_handler, &snprint_hw_max_sectors_kb); - install_keyword("ghost_delay", &hw_ghost_delay_handler, &snprint_hw_ghost_delay); -+ install_keyword("all_tg_pt", &hw_all_tg_pt_handler, &snprint_hw_all_tg_pt); - install_sublevel_end(); - - install_keyword_root("overrides", &overrides_handler); -@@ -1654,6 +1663,7 @@ init_keywords(vector keywords) - install_keyword("skip_kpartx", &ovr_skip_kpartx_handler, &snprint_ovr_skip_kpartx); - install_keyword("max_sectors_kb", &ovr_max_sectors_kb_handler, &snprint_ovr_max_sectors_kb); - install_keyword("ghost_delay", &ovr_ghost_delay_handler, &snprint_ovr_ghost_delay); -+ install_keyword("all_tg_pt", &ovr_all_tg_pt_handler, &snprint_ovr_all_tg_pt); - - install_keyword_root("multipaths", &multipaths_handler); - install_keyword_multi("multipath", &multipath_handler, NULL); -diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c -index 627d366..9ca1355 100644 ---- a/libmultipath/propsel.c -+++ b/libmultipath/propsel.c -@@ -978,3 +978,18 @@ out: - pp->dev, pp->find_multipaths_timeout, origin); - return 0; - } -+ -+int select_all_tg_pt (struct config *conf, struct multipath * mp) -+{ -+ const char *origin; -+ -+ mp_set_ovr(all_tg_pt); -+ mp_set_hwe(all_tg_pt); -+ mp_set_conf(all_tg_pt); -+ mp_set_default(all_tg_pt, DEFAULT_ALL_TG_PT); -+out: -+ condlog(3, "%s: all_tg_pt = %s %s", mp->alias, -+ (mp->all_tg_pt == ALL_TG_PT_ON)? "yes" : "no", -+ origin); -+ return 0; -+} -diff --git a/libmultipath/propsel.h b/libmultipath/propsel.h -index a022bee..ae99b92 100644 ---- a/libmultipath/propsel.h -+++ b/libmultipath/propsel.h -@@ -34,3 +34,4 @@ int select_ghost_delay(struct config *conf, struct multipath * mp); - void reconcile_features_with_options(const char *id, char **features, - int* no_path_retry, - int *retain_hwhandler); -+int select_all_tg_pt (struct config *conf, struct multipath * mp); -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index e424b15..0194b1e 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -217,6 +217,12 @@ enum prkey_sources { - PRKEY_SOURCE_FILE, - }; - -+enum all_tg_pt_states { -+ ALL_TG_PT_UNDEF = YNU_UNDEF, -+ ALL_TG_PT_OFF = YNU_NO, -+ ALL_TG_PT_ON = YNU_YES, -+}; -+ - struct sg_id { - int host_no; - int channel; -@@ -362,6 +368,7 @@ struct multipath { - int prkey_source; - struct be64 reservation_key; - unsigned char prflag; -+ int all_tg_pt; - struct gen_multipath generic_mp; - }; - -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 96d1b66..0c1f174 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -743,6 +743,17 @@ 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. -+.RS -+.TP -+The default is: \fBno\fR -+.RE -+. -+. -+.TP - .B retain_attached_hw_handler - (Obsolete for kernels >= 4.3) If set to - .I yes --- -2.7.4 - diff --git a/0025-RH-add-mpathconf.patch b/0016-RH-add-mpathconf.patch similarity index 92% rename from 0025-RH-add-mpathconf.patch rename to 0016-RH-add-mpathconf.patch index 5cad22b..cfb9ed9 100644 --- a/0025-RH-add-mpathconf.patch +++ b/0016-RH-add-mpathconf.patch @@ -12,23 +12,24 @@ a single command. Signed-off-by: Benjamin Marzinski --- - libmultipath/config.c | 1 + + libmultipath/config.c | 2 + multipath/Makefile | 5 + multipath/mpathconf | 464 ++++++++++++++++++++++++++++++++++++++++++++++++++ - multipath/mpathconf.8 | 101 +++++++++++ - 4 files changed, 571 insertions(+) + multipath/mpathconf.8 | 119 +++++++++++++ + 4 files changed, 590 insertions(+) create mode 100644 multipath/mpathconf create mode 100644 multipath/mpathconf.8 diff --git a/libmultipath/config.c b/libmultipath/config.c -index 0607403..5c98e48 100644 +index 6a9340a..bfd07e3 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c -@@ -661,6 +661,7 @@ load_config (char * file) - +@@ -748,6 +748,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 to create or modify /etc/multipath.conf"); ++ 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) { @@ -538,10 +539,10 @@ index 0000000..e839134 +fi diff --git a/multipath/mpathconf.8 b/multipath/mpathconf.8 new file mode 100644 -index 0000000..4cd3267 +index 0000000..5b7ae0c --- /dev/null +++ b/multipath/mpathconf.8 -@@ -0,0 +1,101 @@ +@@ -0,0 +1,119 @@ +.TH MPATHCONF 8 "June 2010" "" "Linux Administrator's Manual" +.SH NAME +mpathconf - A tool for configuring device-mapper-multipath @@ -563,7 +564,9 @@ index 0000000..4cd3267 +.B multipathd +service to start automatically or not. If +.B mpathconf -+is called with no commands, it will display the current configuration. ++is called with no commands, it will display the current configuration, but ++will not create of modify ++.B /etc/multipath.conf + +The default options for mpathconf are +.B --with_module @@ -592,13 +595,25 @@ index 0000000..4cd3267 +.B --enable +Removes any line that blacklists all device nodes from the +.B /etc/multipath.conf -+blacklist section. ++blacklist section. Also, creates ++.B /etc/multipath.conf ++if it doesn't exist. +.TP +.B --disable +Adds a line that blacklists all device nodes to the +.B /etc/multipath.conf +blacklist section. If no blacklist section exists, it will create one. +.TP ++.B --allow \fB\fP ++Modifies the \fB/etc/multipath/conf\fP blacklist to blacklist all ++wwids and the blacklist_exceptions to whitelist \fB\fP. \fB\fP ++can be in the form of MAJOR:MINOR, a wwid, or the name of a device-mapper ++device, either a multipath device, or any device on stacked on top of one or ++more multipath devices. This command can be used multiple times to allow ++multiple devices. \fBNOTE:\fP This action will create a configuration file that ++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 } +If set to \fBy\fP, this adds the line +.B user_friendly_names yes @@ -614,6 +629,10 @@ index 0000000..4cd3267 +.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. ++.TP ++.B --outfile \fB\fP ++Write the resulting multipath configuration to \fB\fP instead of ++\fB/etc/multipath.conf\fP. +.SH OPTIONS +.TP +.B --with_module\fP { \fBy\fP | \fBn\fP } diff --git a/0016-libmultipath-remove-rbd-code.patch b/0016-libmultipath-remove-rbd-code.patch deleted file mode 100644 index 8d19547..0000000 --- a/0016-libmultipath-remove-rbd-code.patch +++ /dev/null @@ -1,1093 +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 rbd code - -The Ceph tean has asked to drop support for multipathed rbd, since it -was running into data corruption issues. There was never an upstream -Ceph release based on it, and because of the corruption, there should be -no users of this code. This patch simply reverts all the rbd code from -multipath. - -Cc: Michael Christie -Cc: Jason Dillaman -Signed-off-by: Benjamin Marzinski ---- - libmultipath/checkers.c | 22 -- - libmultipath/checkers.h | 6 - - libmultipath/checkers/Makefile | 7 - - libmultipath/checkers/cciss_tur.c | 5 - - libmultipath/checkers/directio.c | 5 - - libmultipath/checkers/emc_clariion.c | 5 - - libmultipath/checkers/hp_sw.c | 5 - - libmultipath/checkers/rbd.c | 653 ----------------------------------- - libmultipath/checkers/rdac.c | 5 - - libmultipath/checkers/readsector0.c | 5 - - libmultipath/checkers/tur.c | 5 - - libmultipath/discovery.c | 70 ---- - libmultipath/hwtable.c | 12 - - multipath/multipath.conf.5 | 3 - - multipathd/main.c | 11 - - 15 files changed, 819 deletions(-) - delete mode 100644 libmultipath/checkers/rbd.c - -diff --git a/libmultipath/checkers.c b/libmultipath/checkers.c -index 08cdfc3..0bacc86 100644 ---- a/libmultipath/checkers.c -+++ b/libmultipath/checkers.c -@@ -141,13 +141,6 @@ struct checker * add_checker (char *multipath_dir, char * name) - if (!c->free) - goto out; - -- c->repair = (void (*)(struct checker *)) dlsym(c->handle, -- "libcheck_repair"); -- errstr = dlerror(); -- if (errstr != NULL) -- condlog(0, "A dynamic linking error occurred: (%s)", errstr); -- if (!c->repair) -- goto out; - done: - c->fd = -1; - c->sync = 1; -@@ -222,20 +215,6 @@ void checker_put (struct checker * dst) - free_checker(src); - } - --void checker_repair (struct checker * c) --{ -- if (!checker_selected(c)) -- return; -- -- c->message[0] = '\0'; -- if (c->disable) { -- MSG(c, "checker disabled"); -- return; -- } -- if (c->repair) -- c->repair(c); --} -- - int checker_check (struct checker * c, int path_state) - { - int r; -@@ -310,7 +289,6 @@ void checker_get (char *multipath_dir, struct checker * dst, char * name) - dst->sync = src->sync; - strncpy(dst->name, src->name, CHECKER_NAME_LEN); - strncpy(dst->message, src->message, CHECKER_MSG_LEN); -- dst->repair = src->repair; - dst->check = src->check; - dst->init = src->init; - dst->free = src->free; -diff --git a/libmultipath/checkers.h b/libmultipath/checkers.h -index 52154ca..7b18a1a 100644 ---- a/libmultipath/checkers.h -+++ b/libmultipath/checkers.h -@@ -86,7 +86,6 @@ enum path_check_state { - #define READSECTOR0 "readsector0" - #define CCISS_TUR "cciss_tur" - #define NONE "none" --#define RBD "rbd" - - #define ASYNC_TIMEOUT_SEC 30 - -@@ -113,9 +112,6 @@ struct checker { - multipath-wide. Use MALLOC if - you want to stuff data in. */ - int (*check)(struct checker *); -- void (*repair)(struct checker *); /* called if check returns -- PATH_DOWN to bring path into -- usable state */ - int (*init)(struct checker *); /* to allocate the context */ - void (*free)(struct checker *); /* to free the context */ - }; -@@ -136,7 +132,6 @@ void checker_set_async (struct checker *); - void checker_set_fd (struct checker *, int); - void checker_enable (struct checker *); - void checker_disable (struct checker *); --void checker_repair (struct checker *); - int checker_check (struct checker *, int); - int checker_selected (struct checker *); - char * checker_name (struct checker *); -@@ -148,6 +143,5 @@ void checker_get (char *, struct checker *, char *); - int libcheck_check(struct checker *); - int libcheck_init(struct checker *); - void libcheck_free(struct checker *); --void libcheck_repair(struct checker *); - - #endif /* _CHECKERS_H */ -diff --git a/libmultipath/checkers/Makefile b/libmultipath/checkers/Makefile -index 87c15bd..02caea6 100644 ---- a/libmultipath/checkers/Makefile -+++ b/libmultipath/checkers/Makefile -@@ -15,15 +15,8 @@ LIBS= \ - libcheckhp_sw.so \ - libcheckrdac.so - --ifneq ($(call check_file,/usr/include/rados/librados.h),0) --LIBS += libcheckrbd.so --endif -- - all: $(LIBS) - --libcheckrbd.so: rbd.o -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ -lrados -ludev -- - libcheckdirectio.so: libsg.o directio.o - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ -laio - -diff --git a/libmultipath/checkers/cciss_tur.c b/libmultipath/checkers/cciss_tur.c -index 436470c..1cab201 100644 ---- a/libmultipath/checkers/cciss_tur.c -+++ b/libmultipath/checkers/cciss_tur.c -@@ -59,11 +59,6 @@ void libcheck_free (struct checker * c) - return; - } - --void libcheck_repair (struct checker * c) --{ -- return; --} -- - int libcheck_check(struct checker * c) - { - int rc; -diff --git a/libmultipath/checkers/directio.c b/libmultipath/checkers/directio.c -index ce60e4c..a80848d 100644 ---- a/libmultipath/checkers/directio.c -+++ b/libmultipath/checkers/directio.c -@@ -118,11 +118,6 @@ void libcheck_free (struct checker * c) - free(ct); - } - --void libcheck_repair (struct checker * c) --{ -- return; --} -- - static int - check_state(int fd, struct directio_context *ct, int sync, int timeout_secs) - { -diff --git a/libmultipath/checkers/emc_clariion.c b/libmultipath/checkers/emc_clariion.c -index 9c1ffed..9115b1b 100644 ---- a/libmultipath/checkers/emc_clariion.c -+++ b/libmultipath/checkers/emc_clariion.c -@@ -90,11 +90,6 @@ void libcheck_free (struct checker * c) - free(c->context); - } - --void libcheck_repair (struct checker * c) --{ -- return; --} -- - int libcheck_check (struct checker * c) - { - unsigned char sense_buffer[128] = { 0, }; -diff --git a/libmultipath/checkers/hp_sw.c b/libmultipath/checkers/hp_sw.c -index cee9aab..0ad34a6 100644 ---- a/libmultipath/checkers/hp_sw.c -+++ b/libmultipath/checkers/hp_sw.c -@@ -45,11 +45,6 @@ void libcheck_free (struct checker * c) - return; - } - --void libcheck_repair (struct checker * c) --{ -- return; --} -- - static int - do_inq(int sg_fd, int cmddt, int evpd, unsigned int pg_op, - void *resp, int mx_resp_len, int noisy, unsigned int timeout) -diff --git a/libmultipath/checkers/rbd.c b/libmultipath/checkers/rbd.c -deleted file mode 100644 -index 4ff54f4..0000000 ---- a/libmultipath/checkers/rbd.c -+++ /dev/null -@@ -1,653 +0,0 @@ --/* -- * Copyright (c) 2016 Red Hat -- * Copyright (c) 2004 Christophe Varoqui -- * -- * Code based off of tur.c and ceph's krbd.cc -- */ --#define _GNU_SOURCE --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#include "rados/librados.h" -- --#include "structs.h" --#include "checkers.h" -- --#include "../libmultipath/debug.h" --#include "../libmultipath/util.h" --#include "../libmultipath/time-util.h" --#include "../libmultipath/util.h" -- --struct rbd_checker_context; --typedef int (thread_fn)(struct rbd_checker_context *ct, char *msg); -- --#define RBD_MSG(msg, fmt, args...) snprintf(msg, CHECKER_MSG_LEN, fmt, ##args); -- --#define RBD_FEATURE_EXCLUSIVE_LOCK (1 << 2) -- --struct rbd_checker_context { -- int rbd_bus_id; -- char *client_addr; -- char *config_info; -- char *snap; -- char *pool; -- char *image; -- char *username; -- int remapped; -- int blacklisted; -- unsigned lock_on_read:1; -- -- rados_t cluster; -- -- int state; -- int running; -- time_t time; -- thread_fn *fn; -- pthread_t thread; -- pthread_mutex_t lock; -- pthread_cond_t active; -- pthread_spinlock_t hldr_lock; -- int holders; -- char message[CHECKER_MSG_LEN]; --}; -- --int libcheck_init(struct checker * c) --{ -- struct rbd_checker_context *ct; -- struct udev_device *block_dev; -- struct udev_device *bus_dev; -- struct udev *udev; -- struct stat sb; -- const char *block_name, *addr, *config_info, *features_str; -- const char *image, *pool, *snap, *username; -- uint64_t features = 0; -- char sysfs_path[PATH_SIZE]; -- int ret; -- -- ct = malloc(sizeof(struct rbd_checker_context)); -- if (!ct) -- return 1; -- memset(ct, 0, sizeof(struct rbd_checker_context)); -- ct->holders = 1; -- pthread_cond_init_mono(&ct->active); -- pthread_mutex_init(&ct->lock, NULL); -- pthread_spin_init(&ct->hldr_lock, PTHREAD_PROCESS_PRIVATE); -- c->context = ct; -- -- /* -- * The rbd block layer sysfs device is not linked to the rbd bus -- * device that we interact with, so figure that out now. -- */ -- if (fstat(c->fd, &sb) != 0) -- goto free_ct; -- -- udev = udev_new(); -- if (!udev) -- goto free_ct; -- -- block_dev = udev_device_new_from_devnum(udev, 'b', sb.st_rdev); -- if (!block_dev) -- goto free_udev; -- -- block_name = udev_device_get_sysname(block_dev); -- ret = sscanf(block_name, "rbd%d", &ct->rbd_bus_id); -- -- udev_device_unref(block_dev); -- if (ret != 1) -- goto free_udev; -- -- snprintf(sysfs_path, sizeof(sysfs_path), "/sys/bus/rbd/devices/%d", -- ct->rbd_bus_id); -- bus_dev = udev_device_new_from_syspath(udev, sysfs_path); -- if (!bus_dev) -- goto free_udev; -- -- addr = udev_device_get_sysattr_value(bus_dev, "client_addr"); -- if (!addr) { -- condlog(0, "rbd%d: Could not find client_addr in rbd sysfs. " -- "Try updating kernel", ct->rbd_bus_id); -- goto free_dev; -- } -- -- ct->client_addr = strdup(addr); -- if (!ct->client_addr) -- goto free_dev; -- -- features_str = udev_device_get_sysattr_value(bus_dev, "features"); -- if (!features_str) -- goto free_addr; -- features = strtoll(features_str, NULL, 16); -- if (!(features & RBD_FEATURE_EXCLUSIVE_LOCK)) { -- condlog(3, "rbd%d: Exclusive lock not set.", ct->rbd_bus_id); -- goto free_addr; -- } -- -- config_info = udev_device_get_sysattr_value(bus_dev, "config_info"); -- if (!config_info) -- goto free_addr; -- -- if (!strstr(config_info, "noshare")) { -- condlog(3, "rbd%d: Only nonshared clients supported.", -- ct->rbd_bus_id); -- goto free_addr; -- } -- -- if (strstr(config_info, "lock_on_read")) -- ct->lock_on_read = 1; -- -- ct->config_info = strdup(config_info); -- if (!ct->config_info) -- goto free_addr; -- -- username = strstr(config_info, "name="); -- if (username) { -- char *end; -- int len; -- -- username += 5; -- end = strchr(username, ','); -- if (!end) -- goto free_info; -- len = end - username; -- -- ct->username = malloc(len + 1); -- if (!ct->username) -- goto free_info; -- strncpy(ct->username, username, len); -- ct->username[len] = '\0'; -- } -- -- image = udev_device_get_sysattr_value(bus_dev, "name"); -- if (!image) -- goto free_username; -- -- ct->image = strdup(image); -- if (!ct->image) -- goto free_username; -- -- pool = udev_device_get_sysattr_value(bus_dev, "pool"); -- if (!pool) -- goto free_image; -- -- ct->pool = strdup(pool); -- if (!ct->pool) -- goto free_image; -- -- snap = udev_device_get_sysattr_value(bus_dev, "current_snap"); -- if (!snap) -- goto free_pool; -- -- if (strcmp("-", snap)) { -- ct->snap = strdup(snap); -- if (!ct->snap) -- goto free_pool; -- } -- -- if (rados_create(&ct->cluster, NULL) < 0) { -- condlog(0, "rbd%d: Could not create rados cluster", -- ct->rbd_bus_id); -- goto free_snap; -- } -- -- if (rados_conf_read_file(ct->cluster, NULL) < 0) { -- condlog(0, "rbd%d: Could not read rados conf", ct->rbd_bus_id); -- goto shutdown_rados; -- } -- -- ret = rados_connect(ct->cluster); -- if (ret < 0) { -- condlog(0, "rbd%d: Could not connect to rados cluster", -- ct->rbd_bus_id); -- goto shutdown_rados; -- } -- -- udev_device_unref(bus_dev); -- udev_unref(udev); -- -- condlog(3, "rbd%d checker init %s %s/%s@%s %s", ct->rbd_bus_id, -- ct->client_addr, ct->pool, ct->image, ct->snap ? ct->snap : "-", -- ct->username ? ct->username : "none"); -- return 0; -- --shutdown_rados: -- rados_shutdown(ct->cluster); --free_snap: -- if (ct->snap) -- free(ct->snap); --free_pool: -- free(ct->pool); --free_image: -- free(ct->image); --free_username: -- if (ct->username) -- free(ct->username); --free_info: -- free(ct->config_info); --free_addr: -- free(ct->client_addr); --free_dev: -- udev_device_unref(bus_dev); --free_udev: -- udev_unref(udev); --free_ct: -- free(ct); -- return 1; --} -- --static void cleanup_context(struct rbd_checker_context *ct) --{ -- pthread_mutex_destroy(&ct->lock); -- pthread_cond_destroy(&ct->active); -- pthread_spin_destroy(&ct->hldr_lock); -- -- rados_shutdown(ct->cluster); -- -- if (ct->username) -- free(ct->username); -- if (ct->snap) -- free(ct->snap); -- free(ct->pool); -- free(ct->image); -- free(ct->config_info); -- free(ct->client_addr); -- free(ct); --} -- --void libcheck_free(struct checker * c) --{ -- if (c->context) { -- struct rbd_checker_context *ct = c->context; -- int holders; -- pthread_t thread; -- -- pthread_spin_lock(&ct->hldr_lock); -- ct->holders--; -- holders = ct->holders; -- thread = ct->thread; -- pthread_spin_unlock(&ct->hldr_lock); -- if (holders) -- pthread_cancel(thread); -- else -- cleanup_context(ct); -- c->context = NULL; -- } --} -- --static int rbd_is_blacklisted(struct rbd_checker_context *ct, char *msg) --{ -- char *addr_tok, *start, *save; -- const char *cmd[2]; -- char *blklist, *stat; -- size_t blklist_len, stat_len; -- int ret; -- char *end; -- -- cmd[0] = "{\"prefix\": \"osd blacklist ls\"}"; -- cmd[1] = NULL; -- -- ret = rados_mon_command(ct->cluster, (const char **)cmd, 1, "", 0, -- &blklist, &blklist_len, &stat, &stat_len); -- if (ret < 0) { -- RBD_MSG(msg, "checker failed: mon command failed %d", ret); -- return ret; -- } -- -- if (!blklist || !blklist_len) -- goto free_bufs; -- -- /* -- * parse list of addrs with the format -- * ipv4:port/nonce date time\n -- * or -- * [ipv6]:port/nonce date time\n -- */ -- ret = 0; -- for (start = blklist; ; start = NULL) { -- addr_tok = strtok_r(start, "\n", &save); -- if (!addr_tok || !strlen(addr_tok)) -- break; -- -- end = strchr(addr_tok, ' '); -- if (!end) { -- RBD_MSG(msg, "checker failed: invalid blacklist %s", -- addr_tok); -- break; -- } -- *end = '\0'; -- -- if (!strcmp(addr_tok, ct->client_addr)) { -- ct->blacklisted = 1; -- RBD_MSG(msg, "%s is blacklisted", ct->client_addr); -- ret = 1; -- break; -- } -- } -- --free_bufs: -- rados_buffer_free(blklist); -- rados_buffer_free(stat); -- return ret; --} -- --static int rbd_check(struct rbd_checker_context *ct, char *msg) --{ -- if (ct->blacklisted || rbd_is_blacklisted(ct, msg) == 1) -- return PATH_DOWN; -- -- RBD_MSG(msg, "checker reports path is up"); -- /* -- * Path may have issues, but the ceph cluster is at least -- * accepting IO, so we can attempt to do IO. -- * -- * TODO: in future versions, we can run other tests to -- * verify OSDs and networks. -- */ -- return PATH_UP; --} -- --static int sysfs_write_rbd_bus(const char *which, const char *buf, -- size_t buf_len) --{ -- char sysfs_path[PATH_SIZE]; -- int fd; -- int r; -- -- /* we require newer kernels so single_major should always be there */ -- snprintf(sysfs_path, sizeof(sysfs_path), -- "/sys/bus/rbd/%s_single_major", which); -- fd = open(sysfs_path, O_WRONLY); -- if (fd < 0) -- return -errno; -- -- r = safe_write(fd, buf, buf_len); -- close(fd); -- return r; --} -- --static int rbd_remap(struct rbd_checker_context *ct) --{ -- char *argv[11]; -- pid_t pid; -- int ret = 0, i = 0; -- int status; -- -- pid = fork(); -- switch (pid) { -- case 0: -- argv[i++] = "rbd"; -- argv[i++] = "map"; -- if (ct->lock_on_read) -- argv[i++] = "-o noshare,lock_on_read"; -- else -- argv[i++] = "-o noshare"; -- if (ct->username) { -- argv[i++] = "--id"; -- argv[i++] = ct->username; -- } -- argv[i++] = "--pool"; -- argv[i++] = ct->pool; -- if (ct->snap) { -- argv[i++] = "--snap"; -- argv[i++] = ct->snap; -- } -- argv[i++] = ct->image; -- argv[i] = NULL; -- -- ret = execvp(argv[0], argv); -- condlog(0, "rbd%d: Error executing rbd: %s", ct->rbd_bus_id, -- strerror(errno)); -- exit(-1); -- case -1: -- condlog(0, "rbd%d: fork failed: %s", ct->rbd_bus_id, -- strerror(errno)); -- return -1; -- default: -- ret = -1; -- wait(&status); -- if (WIFEXITED(status)) { -- status = WEXITSTATUS(status); -- if (status == 0) -- ret = 0; -- else -- condlog(0, "rbd%d: failed with %d", -- ct->rbd_bus_id, status); -- } -- } -- -- return ret; --} -- --static int sysfs_write_rbd_remove(const char *buf, int buf_len) --{ -- return sysfs_write_rbd_bus("remove", buf, buf_len); --} -- --static int rbd_rm_blacklist(struct rbd_checker_context *ct) --{ -- const char *cmd[2]; -- char *stat, *cmd_str; -- size_t stat_len; -- int ret; -- -- ret = asprintf(&cmd_str, "{\"prefix\": \"osd blacklist\", \"blacklistop\": \"rm\", \"addr\": \"%s\"}", -- ct->client_addr); -- if (ret == -1) -- return -ENOMEM; -- -- cmd[0] = cmd_str; -- cmd[1] = NULL; -- -- ret = rados_mon_command(ct->cluster, (const char **)cmd, 1, "", 0, -- NULL, NULL, &stat, &stat_len); -- if (ret < 0) { -- condlog(1, "rbd%d: repair failed to remove blacklist for %s %d", -- ct->rbd_bus_id, ct->client_addr, ret); -- goto free_cmd; -- } -- -- condlog(1, "rbd%d: repair rm blacklist for %s", -- ct->rbd_bus_id, ct->client_addr); -- free(stat); --free_cmd: -- free(cmd_str); -- return ret; --} -- --static int rbd_repair(struct rbd_checker_context *ct, char *msg) --{ -- char del[17]; -- int ret; -- -- if (!ct->blacklisted) -- return PATH_UP; -- -- if (!ct->remapped) { -- ret = rbd_remap(ct); -- if (ret) { -- RBD_MSG(msg, "repair failed to remap. Err %d", ret); -- return PATH_DOWN; -- } -- } -- ct->remapped = 1; -- -- snprintf(del, sizeof(del), "%d force", ct->rbd_bus_id); -- ret = sysfs_write_rbd_remove(del, strlen(del) + 1); -- if (ret) { -- RBD_MSG(msg, "repair failed to clean up. Err %d", ret); -- return PATH_DOWN; -- } -- -- ret = rbd_rm_blacklist(ct); -- if (ret) { -- RBD_MSG(msg, "repair could not remove blacklist entry. Err %d", -- ret); -- return PATH_DOWN; -- } -- -- ct->remapped = 0; -- ct->blacklisted = 0; -- -- RBD_MSG(msg, "has been repaired"); -- return PATH_UP; --} -- --#define rbd_thread_cleanup_push(ct) pthread_cleanup_push(cleanup_func, ct) --#define rbd_thread_cleanup_pop(ct) pthread_cleanup_pop(1) -- --static void cleanup_func(void *data) --{ -- int holders; -- struct rbd_checker_context *ct = data; -- pthread_spin_lock(&ct->hldr_lock); -- ct->holders--; -- holders = ct->holders; -- ct->thread = 0; -- pthread_spin_unlock(&ct->hldr_lock); -- if (!holders) -- cleanup_context(ct); -- rcu_unregister_thread(); --} -- --static void *rbd_thread(void *ctx) --{ -- struct rbd_checker_context *ct = ctx; -- int state; -- -- /* This thread can be canceled, so setup clean up */ -- rbd_thread_cleanup_push(ct) -- rcu_register_thread(); -- condlog(3, "rbd%d: thread starting up", ct->rbd_bus_id); -- -- ct->message[0] = '\0'; -- -- /* checker start up */ -- pthread_mutex_lock(&ct->lock); -- ct->state = PATH_PENDING; -- pthread_mutex_unlock(&ct->lock); -- -- state = ct->fn(ct, ct->message); -- -- /* checker done */ -- pthread_mutex_lock(&ct->lock); -- ct->state = state; -- pthread_cond_signal(&ct->active); -- pthread_mutex_unlock(&ct->lock); -- -- condlog(3, "rbd%d: thead finished, state %s", ct->rbd_bus_id, -- checker_state_name(state)); -- rbd_thread_cleanup_pop(ct); -- return ((void *)0); --} -- --static void rbd_timeout(struct timespec *tsp) --{ -- clock_gettime(CLOCK_MONOTONIC, tsp); -- tsp->tv_nsec += 1000 * 1000; /* 1 millisecond */ -- normalize_timespec(tsp); --} -- --static int rbd_exec_fn(struct checker *c, thread_fn *fn) --{ -- struct rbd_checker_context *ct = c->context; -- struct timespec tsp; -- pthread_attr_t attr; -- int rbd_status, r; -- -- if (c->sync) -- return fn(ct, c->message); -- /* -- * Async mode -- */ -- r = pthread_mutex_lock(&ct->lock); -- if (r != 0) { -- condlog(2, "rbd%d: mutex lock failed with %d", ct->rbd_bus_id, -- r); -- MSG(c, "rbd%d: thread failed to initialize", ct->rbd_bus_id); -- return PATH_WILD; -- } -- -- if (ct->running) { -- /* Check if checker is still running */ -- if (ct->thread) { -- condlog(3, "rbd%d: thread not finished", -- ct->rbd_bus_id); -- rbd_status = PATH_PENDING; -- } else { -- /* checker done */ -- ct->running = 0; -- rbd_status = ct->state; -- strncpy(c->message, ct->message, CHECKER_MSG_LEN); -- c->message[CHECKER_MSG_LEN - 1] = '\0'; -- } -- pthread_mutex_unlock(&ct->lock); -- } else { -- /* Start new checker */ -- ct->state = PATH_UNCHECKED; -- ct->fn = fn; -- pthread_spin_lock(&ct->hldr_lock); -- ct->holders++; -- pthread_spin_unlock(&ct->hldr_lock); -- setup_thread_attr(&attr, 32 * 1024, 1); -- r = pthread_create(&ct->thread, &attr, rbd_thread, ct); -- if (r) { -- pthread_mutex_unlock(&ct->lock); -- ct->thread = 0; -- ct->holders--; -- condlog(3, "rbd%d failed to start rbd thread, using sync mode", -- ct->rbd_bus_id); -- return fn(ct, c->message); -- } -- pthread_attr_destroy(&attr); -- rbd_timeout(&tsp); -- r = pthread_cond_timedwait(&ct->active, &ct->lock, &tsp); -- rbd_status = ct->state; -- strncpy(c->message, ct->message,CHECKER_MSG_LEN); -- c->message[CHECKER_MSG_LEN -1] = '\0'; -- pthread_mutex_unlock(&ct->lock); -- -- if (ct->thread && -- (rbd_status == PATH_PENDING || rbd_status == PATH_UNCHECKED)) { -- condlog(3, "rbd%d: thread still running", -- ct->rbd_bus_id); -- ct->running = 1; -- rbd_status = PATH_PENDING; -- } -- } -- -- return rbd_status; --} -- --void libcheck_repair(struct checker * c) --{ -- struct rbd_checker_context *ct = c->context; -- -- if (!ct || !ct->blacklisted) -- return; -- rbd_exec_fn(c, rbd_repair); --} -- --int libcheck_check(struct checker * c) --{ -- struct rbd_checker_context *ct = c->context; -- -- if (!ct) -- return PATH_UNCHECKED; -- -- if (ct->blacklisted) -- return PATH_DOWN; -- -- return rbd_exec_fn(c, rbd_check); --} -diff --git a/libmultipath/checkers/rdac.c b/libmultipath/checkers/rdac.c -index a643a4a..5104e4e 100644 ---- a/libmultipath/checkers/rdac.c -+++ b/libmultipath/checkers/rdac.c -@@ -139,11 +139,6 @@ void libcheck_free (struct checker * c) - return; - } - --void libcheck_repair (struct checker * c) --{ -- return; --} -- - static int - do_inq(int sg_fd, unsigned int pg_op, void *resp, int mx_resp_len, - unsigned int timeout) -diff --git a/libmultipath/checkers/readsector0.c b/libmultipath/checkers/readsector0.c -index 8fccb46..1c2a868 100644 ---- a/libmultipath/checkers/readsector0.c -+++ b/libmultipath/checkers/readsector0.c -@@ -23,11 +23,6 @@ void libcheck_free (struct checker * c) - return; - } - --void libcheck_repair (struct checker * c) --{ -- return; --} -- - int libcheck_check (struct checker * c) - { - unsigned char buf[4096]; -diff --git a/libmultipath/checkers/tur.c b/libmultipath/checkers/tur.c -index eb3348d..bf8486d 100644 ---- a/libmultipath/checkers/tur.c -+++ b/libmultipath/checkers/tur.c -@@ -112,11 +112,6 @@ void libcheck_free (struct checker * c) - return; - } - --void libcheck_repair (struct checker * c) --{ -- return; --} -- - #define TUR_MSG(fmt, args...) \ - do { \ - char msg[CHECKER_MSG_LEN]; \ -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 1ef1dfa..18ad0e2 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -1246,21 +1246,6 @@ nvme_sysfs_pathinfo (struct path * pp, vector hwtable) - } - - static int --rbd_sysfs_pathinfo (struct path * pp, vector hwtable) --{ -- sprintf(pp->vendor_id, "Ceph"); -- sprintf(pp->product_id, "RBD"); -- -- condlog(3, "%s: vendor = %s product = %s", pp->dev, pp->vendor_id, -- pp->product_id); -- /* -- * set the hwe configlet pointer -- */ -- pp->hwe = find_hwe(hwtable, pp->vendor_id, pp->product_id, NULL); -- return 0; --} -- --static int - ccw_sysfs_pathinfo (struct path * pp, vector hwtable) - { - struct udev_device *parent; -@@ -1486,8 +1471,6 @@ sysfs_pathinfo(struct path * pp, vector hwtable) - pp->bus = SYSFS_BUS_CCW; - if (!strncmp(pp->dev,"sd", 2)) - pp->bus = SYSFS_BUS_SCSI; -- if (!strncmp(pp->dev,"rbd", 3)) -- pp->bus = SYSFS_BUS_RBD; - if (!strncmp(pp->dev,"nvme", 4)) - pp->bus = SYSFS_BUS_NVME; - -@@ -1502,9 +1485,6 @@ sysfs_pathinfo(struct path * pp, vector hwtable) - } else if (pp->bus == SYSFS_BUS_CCISS) { - if (cciss_sysfs_pathinfo(pp, hwtable)) - return 1; -- } else if (pp->bus == SYSFS_BUS_RBD) { -- if (rbd_sysfs_pathinfo(pp, hwtable)) -- return 1; - } else if (pp->bus == SYSFS_BUS_NVME) { - if (nvme_sysfs_pathinfo(pp, hwtable)) - return 1; -@@ -1753,53 +1733,6 @@ get_udev_uid(struct path * pp, char *uid_attribute, struct udev_device *udev) - } - - static int --get_rbd_uid(struct path * pp) --{ -- struct udev_device *rbd_bus_dev; -- int ret, rbd_bus_id; -- const char *pool, *image, *snap; -- char sysfs_path[PATH_SIZE]; -- uint64_t snap_id, max_snap_id = -3; -- -- ret = sscanf(pp->dev, "rbd%d", &rbd_bus_id); -- if (ret != 1) -- return -EINVAL; -- -- snprintf(sysfs_path, sizeof(sysfs_path), "/sys/bus/rbd/devices/%d", -- rbd_bus_id); -- rbd_bus_dev = udev_device_new_from_syspath(udev, sysfs_path); -- if (!rbd_bus_dev) -- return -ENODEV; -- -- ret = -EINVAL; -- pool = udev_device_get_sysattr_value(rbd_bus_dev, "pool_id"); -- if (!pool) -- goto free_dev; -- -- image = udev_device_get_sysattr_value(rbd_bus_dev, "image_id"); -- if (!image) -- goto free_dev; -- -- snap = udev_device_get_sysattr_value(rbd_bus_dev, "snap_id"); -- if (!snap) -- goto free_dev; -- snap_id = strtoull(snap, NULL, 19); -- if (snap_id >= max_snap_id) -- ret = snprintf(pp->wwid, WWID_SIZE, "%s-%s", pool, image); -- else -- ret = snprintf(pp->wwid, WWID_SIZE, "%s-%s-%s", pool, -- image, snap); -- if (ret >= WWID_SIZE) { -- condlog(0, "%s: wwid overflow", pp->dev); -- ret = -EOVERFLOW; -- } -- --free_dev: -- udev_device_unref(rbd_bus_dev); -- return ret; --} -- --static int - get_vpd_uid(struct path * pp) - { - struct udev_device *parent = pp->udev; -@@ -1876,9 +1809,6 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev) - } else - len = strlen(pp->wwid); - origin = "callout"; -- } else if (pp->bus == SYSFS_BUS_RBD) { -- len = get_rbd_uid(pp); -- origin = "sysfs"; - } else { - - if (udev && pp->uid_attribute) { -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index 148f0ba..d529bae 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -1000,18 +1000,6 @@ static struct hwentry default_hw[] = { - .prio_name = PRIO_ALUA, - }, - /* -- * Red Hat -- * -- * Maintainer: Mike Christie -- * Mail: mchristi@redhat.com -- */ -- { -- .vendor = "Ceph", -- .product = "RBD", -- .checker_name = RBD, -- .deferred_remove = DEFERRED_REMOVE_ON, -- }, -- /* - * Kove - */ - { -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 0c1f174..31f4585 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -482,9 +482,6 @@ Check the path state for HP/COMPAQ Smart Array(CCISS) controllers. - .I none - Do not check the device, fallback to use the values retrieved from sysfs - .TP --.I rbd --Check if the path is in the Ceph blacklist and remap the path if it is. --.TP - The default is: \fBtur\fR - .RE - . -diff --git a/multipathd/main.c b/multipathd/main.c -index 0db88ee..d40c416 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -1783,15 +1783,6 @@ int update_path_groups(struct multipath *mpp, struct vectors *vecs, int refresh) - return 0; - } - --void repair_path(struct path * pp) --{ -- if (pp->state != PATH_DOWN) -- return; -- -- checker_repair(&pp->checker); -- LOG_MSG(1, checker_message(&pp->checker)); --} -- - /* - * Returns '1' if the path has been checked, '-1' if it was blacklisted - * and '0' otherwise -@@ -1972,7 +1963,6 @@ check_path (struct vectors * vecs, struct path * pp, int ticks) - pp->mpp->failback_tick = 0; - - pp->mpp->stat_path_failures++; -- repair_path(pp); - return 1; - } - -@@ -2071,7 +2061,6 @@ check_path (struct vectors * vecs, struct path * pp, int ticks) - } - - pp->state = newstate; -- repair_path(pp); - - if (pp->mpp->wait_for_udev) - return 1; --- -2.7.4 - diff --git a/0026-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0017-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 86% rename from 0026-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0017-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch index ddf022f..a8ccd2b 100644 --- a/0026-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +++ b/0017-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch @@ -86,10 +86,10 @@ index 0c6ee54..e32a0b0 100644 enum { WWID_IS_NOT_FAILED = 0, diff --git a/multipath/main.c b/multipath/main.c -index 6fdde03..7bac232 100644 +index 39f6f1f..cc94f56 100644 --- a/multipath/main.c +++ b/multipath/main.c -@@ -109,7 +109,7 @@ usage (char * progname) +@@ -122,7 +122,7 @@ usage (char * progname) { fprintf (stderr, VERSION_STRING); fprintf (stderr, "Usage:\n"); @@ -97,8 +97,8 @@ index 6fdde03..7bac232 100644 + fprintf (stderr, " %s [-a|-A|-c|-w|-W] [-d] [-r] [-i] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname); fprintf (stderr, " %s -l|-ll|-f [-v lvl] [-b fil] [-R num] [dev]\n", progname); fprintf (stderr, " %s -F [-v lvl] [-R num]\n", progname); - fprintf (stderr, " %s -t\n", progname); -@@ -123,6 +123,8 @@ usage (char * progname) + fprintf (stderr, " %s [-t|-T]\n", progname); +@@ -136,6 +136,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" @@ -107,19 +107,19 @@ index 6fdde03..7bac232 100644 " -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" -@@ -907,7 +909,7 @@ main (int argc, char *argv[]) +@@ -870,7 +872,7 @@ main (int argc, char *argv[]) exit(1); multipath_conf = conf; conf->retrigger_tries = 0; -- while ((arg = getopt(argc, argv, ":adcChl::FfM:v:p:b:BrR:itquUwW")) != EOF ) { -+ while ((arg = getopt(argc, argv, ":aAdcChl::FfM:v:p:b:BrR:itquUwW")) != EOF ) { +- while ((arg = getopt(argc, argv, ":adcChl::FfM:v:p:b:BrR:itTquUwW")) != EOF ) { ++ while ((arg = getopt(argc, argv, ":aAdcChl::FfM:v:p:b:BrR:itTquUwW")) != EOF ) { switch(arg) { case 1: printf("optarg : %s\n",optarg); break; -@@ -974,6 +976,10 @@ main (int argc, char *argv[]) - case 't': - r = dump_config(conf); - goto out_free_config; +@@ -940,6 +942,10 @@ main (int argc, char *argv[]) + case 'T': + cmd = CMD_DUMP_CONFIG; + break; + case 'A': + if (remember_cmdline_wwid() != 0) + exit(1); @@ -128,19 +128,19 @@ index 6fdde03..7bac232 100644 usage(argv[0]); exit(0); diff --git a/multipath/multipath.8 b/multipath/multipath.8 -index 914a8cb..8c6a4c1 100644 +index b5e5292..5bd5229 100644 --- a/multipath/multipath.8 +++ b/multipath/multipath.8 @@ -25,7 +25,7 @@ multipath \- Device mapper target autoconfig. .RB [\| \-b\ \c .IR bindings_file \|] .RB [\| \-d \|] --.RB [\| \-h | \-l | \-ll | \-f | \-t | \-F | \-B | \-c | \-C | \-q | \-r | \-i | \-a | \-u | \-U | \-w | \-W \|] -+.RB [\| \-h | \-l | \-ll | \-f | \-t | \-F | \-B | \-c | \-C | \-q | \-r | \-i | \-a | \-A | \-u | \-U | \-w | \-W \|] +-.RB [\| \-h | \-l | \-ll | \-f | \-t | \-T | \-F | \-B | \-c | \-C | \-q | \-r | \-i | \-a | \-u | \-U | \-w | \-W \|] ++.RB [\| \-h | \-l | \-ll | \-f | \-t | \-T | \-F | \-B | \-c | \-C | \-q | \-r | \-i | \-a | \-A | \-u | \-U | \-w | \-W \|] .RB [\| \-p\ \c .IR failover | multibus | group_by_serial | group_by_prio | group_by_node_name \|] .RB [\| \-R\ \c -@@ -135,6 +135,9 @@ Add the WWID for the specified device to the WWIDs file. +@@ -141,6 +141,9 @@ Add the WWID for the specified device to the WWIDs file. Check if the device specified in the program environment should be a path in a multipath device. . diff --git a/0017-mpathpersist-fix-aptpl-support.patch b/0017-mpathpersist-fix-aptpl-support.patch deleted file mode 100644 index b98d310..0000000 --- a/0017-mpathpersist-fix-aptpl-support.patch +++ /dev/null @@ -1,543 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 4 Jun 2018 22:04:44 -0500 -Subject: [PATCH] mpathpersist: fix aptpl support - -The "Active Persist Through Power Loss" flag must be set whenever a key -is registered. However, there is no way for multipathd to know if this -was set by mpathpersist. The result is that if a path goes down and -comes back up (or if it wasn't up when mpathpersist was first run) -multipathd will clear the aptpl flag when it reregisters the key on it. - -To fix this, multipath.conf now accepts an optional ":aptpl" appended -on the reservation_key value. If this is added to the reservation_key -multipathd will set the aptpl flag when it reregisters the key. If -reservation_key is set to "file", this will automatically be tracked -in the /etc/multipath/prkeys file. - -To track this flag in the prkeys file, without changing the format -I've made "0x" stand for non-aptpl keys, and "0X" stand -for aptpl keys. Since previously, all keys used a lower-case x, this -will default to the current behavior for existing keys. Obviously, the -next time mpathpersist is run, this will be changed if --param-aptpl -is used. Since there are no more flags that are in sg_persist that -multipathd needs to care about in mpathpersist, there shouldn't need -to be any more flags added to the prkeys file. - -Signed-off-by: Benjamin Marzinski ---- - libmpathpersist/mpath_persist.c | 3 ++- - libmpathpersist/mpath_updatepr.c | 11 +++++++---- - libmpathpersist/mpathpr.h | 3 ++- - libmultipath/Makefile | 2 +- - libmultipath/config.h | 2 ++ - libmultipath/dict.c | 23 +++++++++++++++++++---- - libmultipath/dict.h | 3 ++- - libmultipath/prkey.c | 27 ++++++++++++++++++++++++--- - libmultipath/prkey.h | 6 ++++-- - libmultipath/propsel.c | 6 ++++-- - libmultipath/structs.h | 1 + - libmultipath/util.c | 16 ++++++++++++++++ - libmultipath/util.h | 1 + - multipath/multipath.conf.5 | 7 +++++-- - multipathd/cli_handlers.c | 15 ++++++++++----- - multipathd/main.c | 1 + - 16 files changed, 101 insertions(+), 26 deletions(-) - -diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c -index ca91c55..6e9e67f 100644 ---- a/libmpathpersist/mpath_persist.c -+++ b/libmpathpersist/mpath_persist.c -@@ -344,7 +344,8 @@ int mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, - rq_servact == MPATH_PROUT_REG_SA) || - rq_servact == MPATH_PROUT_REG_IGN_SA)) { - memcpy(&mpp->reservation_key, paramp->sa_key, 8); -- if (update_prkey(alias, get_be64(mpp->reservation_key))) { -+ if (update_prkey_flags(alias, get_be64(mpp->reservation_key), -+ paramp->sa_flags)) { - condlog(0, "%s: failed to set prkey for multipathd.", - alias); - ret = MPATH_PR_DMMP_ERROR; -diff --git a/libmpathpersist/mpath_updatepr.c b/libmpathpersist/mpath_updatepr.c -index 8063e90..0aca28e 100644 ---- a/libmpathpersist/mpath_updatepr.c -+++ b/libmpathpersist/mpath_updatepr.c -@@ -1,7 +1,5 @@ - #include - #include --#include -- - #include - #include - #include -@@ -11,6 +9,8 @@ - #include - #include - #include -+#include -+#include - #include "debug.h" - #include "mpath_cmd.h" - #include "uxsock.h" -@@ -59,11 +59,14 @@ int update_prflag(char *mapname, int set) { - return do_update_pr(mapname, (set)? "setprstatus" : "unsetprstatus"); - } - --int update_prkey(char *mapname, uint64_t prkey) { -+int update_prkey_flags(char *mapname, uint64_t prkey, uint8_t sa_flags) { - char str[256]; -+ char *flagstr = ""; - -+ if (sa_flags & MPATH_F_APTPL_MASK) -+ flagstr = ":aptpl"; - if (prkey) -- sprintf(str, "setprkey key %" PRIx64, prkey); -+ sprintf(str, "setprkey key %" PRIx64 "%s", prkey, flagstr); - else - sprintf(str, "unsetprkey"); - return do_update_pr(mapname, str); -diff --git a/libmpathpersist/mpathpr.h b/libmpathpersist/mpathpr.h -index 72feb60..5ea8cd6 100644 ---- a/libmpathpersist/mpathpr.h -+++ b/libmpathpersist/mpathpr.h -@@ -46,7 +46,8 @@ int send_prout_activepath(char * dev, int rq_servact, int rq_scope, - unsigned int rq_type, struct prout_param_descriptor * paramp, int noisy); - - int update_prflag(char *mapname, int set); --int update_prkey(char *mapname, uint64_t prkey); -+int update_prkey_flags(char *mapname, uint64_t prkey, uint8_t sa_flags); -+#define update_prkey(mapname, prkey) update_prkey_flags(mapname, prkey, 0) - void * mpath_alloc_prin_response(int prin_sa); - int update_map_pr(struct multipath *mpp); - -diff --git a/libmultipath/Makefile b/libmultipath/Makefile -index f51786d..33f5269 100644 ---- a/libmultipath/Makefile -+++ b/libmultipath/Makefile -@@ -7,7 +7,7 @@ SONAME = 0 - DEVLIB = libmultipath.so - LIBS = $(DEVLIB).$(SONAME) - --CFLAGS += $(LIB_CFLAGS) -I$(mpathcmddir) -+CFLAGS += $(LIB_CFLAGS) -I$(mpathcmddir) -I$(mpathpersistdir) - - LIBDEPS += -lpthread -ldl -ldevmapper -ludev -L$(mpathcmddir) -lmpathcmd -lurcu -laio - -diff --git a/libmultipath/config.h b/libmultipath/config.h -index 1bf708a..fcbe3fc 100644 ---- a/libmultipath/config.h -+++ b/libmultipath/config.h -@@ -98,6 +98,7 @@ struct mpentry { - char * prio_args; - int prkey_source; - struct be64 reservation_key; -+ uint8_t sa_flags; - int pgpolicy; - int pgfailback; - int rr_weight; -@@ -197,6 +198,7 @@ struct config { - int prkey_source; - int all_tg_pt; - struct be64 reservation_key; -+ uint8_t sa_flags; - - vector keywords; - vector mptable; -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index 2557b8a..7ad0f5a 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -22,6 +22,8 @@ - #include "util.h" - #include - #include -+#include -+#include - #include "mpath_cmd.h" - #include "dict.h" - -@@ -1012,10 +1014,12 @@ snprint_def_log_checker_err (struct config *conf, char * buff, int len, - } - - static int --set_reservation_key(vector strvec, struct be64 *be64_ptr, int *source_ptr) -+set_reservation_key(vector strvec, struct be64 *be64_ptr, uint8_t *flags_ptr, -+ int *source_ptr) - { - char *buff; - uint64_t prkey; -+ uint8_t sa_flags; - - buff = set_value(strvec); - if (!buff) -@@ -1023,35 +1027,43 @@ set_reservation_key(vector strvec, struct be64 *be64_ptr, int *source_ptr) - - if (strcmp(buff, "file") == 0) { - *source_ptr = PRKEY_SOURCE_FILE; -+ *flags_ptr = 0; - put_be64(*be64_ptr, 0); - FREE(buff); - return 0; - } - -- if (parse_prkey(buff, &prkey) != 0) { -+ if (parse_prkey_flags(buff, &prkey, &sa_flags) != 0) { - FREE(buff); - return 1; - } - *source_ptr = PRKEY_SOURCE_CONF; -+ *flags_ptr = sa_flags; - put_be64(*be64_ptr, prkey); - FREE(buff); - return 0; - } - - int --print_reservation_key(char * buff, int len, struct be64 key, int source) -+print_reservation_key(char * buff, int len, struct be64 key, uint8_t flags, -+ int source) - { -+ char *flagstr = ""; - if (source == PRKEY_SOURCE_NONE) - return 0; - if (source == PRKEY_SOURCE_FILE) - return snprintf(buff, len, "file"); -- return snprintf(buff, len, "0x%" PRIx64, get_be64(key)); -+ if (flags & MPATH_F_APTPL_MASK) -+ flagstr = ":aptpl"; -+ return snprintf(buff, len, "0x%" PRIx64 "%s", get_be64(key), -+ flagstr); - } - - static int - def_reservation_key_handler(struct config *conf, vector strvec) - { - return set_reservation_key(strvec, &conf->reservation_key, -+ &conf->sa_flags, - &conf->prkey_source); - } - -@@ -1060,6 +1072,7 @@ snprint_def_reservation_key (struct config *conf, char * buff, int len, - const void * data) - { - return print_reservation_key(buff, len, conf->reservation_key, -+ conf->sa_flags, - conf->prkey_source); - } - -@@ -1070,6 +1083,7 @@ mp_reservation_key_handler(struct config *conf, vector strvec) - if (!mpe) - return 1; - return set_reservation_key(strvec, &mpe->reservation_key, -+ &mpe->sa_flags, - &mpe->prkey_source); - } - -@@ -1079,6 +1093,7 @@ snprint_mp_reservation_key (struct config *conf, char * buff, int len, - { - const struct mpentry * mpe = (const struct mpentry *)data; - return print_reservation_key(buff, len, mpe->reservation_key, -+ mpe->sa_flags, - mpe->prkey_source); - } - -diff --git a/libmultipath/dict.h b/libmultipath/dict.h -index 7564892..a40ac66 100644 ---- a/libmultipath/dict.h -+++ b/libmultipath/dict.h -@@ -15,6 +15,7 @@ int print_pgpolicy(char *buff, int len, long v); - int print_no_path_retry(char *buff, int len, long v); - int print_fast_io_fail(char *buff, int len, long v); - int print_dev_loss(char *buff, int len, unsigned long v); --int print_reservation_key(char * buff, int len, struct be64 key, int source); -+int print_reservation_key(char * buff, int len, struct be64 key, uint8_t -+ flags, int source); - int print_off_int_undef(char *buff, int len, long v); - #endif /* _DICT_H */ -diff --git a/libmultipath/prkey.c b/libmultipath/prkey.c -index 89b90ed..d645f81 100644 ---- a/libmultipath/prkey.c -+++ b/libmultipath/prkey.c -@@ -11,6 +11,8 @@ - #include - #include - #include -+#include -+#include - - #define PRKEY_READ 0 - #define PRKEY_WRITE 1 -@@ -108,7 +110,8 @@ static int do_prkey(int fd, char *wwid, char *keystr, int cmd) - return 0; - } - --int get_prkey(struct config *conf, struct multipath *mpp, uint64_t *prkey) -+int get_prkey(struct config *conf, struct multipath *mpp, uint64_t *prkey, -+ uint8_t *sa_flags) - { - int fd; - int unused; -@@ -124,6 +127,9 @@ int get_prkey(struct config *conf, struct multipath *mpp, uint64_t *prkey) - ret = do_prkey(fd, mpp->wwid, keystr, PRKEY_READ); - if (ret) - goto out_file; -+ *sa_flags = 0; -+ if (strchr(keystr, 'X')) -+ *sa_flags = MPATH_F_APTPL_MASK; - ret = !!parse_prkey(keystr, prkey); - out_file: - close(fd); -@@ -131,7 +137,8 @@ out: - return ret; - } - --int set_prkey(struct config *conf, struct multipath *mpp, uint64_t prkey) -+int set_prkey(struct config *conf, struct multipath *mpp, uint64_t prkey, -+ uint8_t sa_flags) - { - int fd; - int can_write = 1; -@@ -141,6 +148,12 @@ int set_prkey(struct config *conf, struct multipath *mpp, uint64_t prkey) - if (!strlen(mpp->wwid)) - goto out; - -+ if (sa_flags & ~MPATH_F_APTPL_MASK) { -+ condlog(0, "unsupported pr flags, 0x%x", -+ sa_flags & ~MPATH_F_APTPL_MASK); -+ sa_flags &= MPATH_F_APTPL_MASK; -+ } -+ - fd = open_file(conf->prkeys_file, &can_write, PRKEYS_FILE_HEADER); - if (fd < 0) - goto out; -@@ -149,7 +162,15 @@ int set_prkey(struct config *conf, struct multipath *mpp, uint64_t prkey) - goto out_file; - } - if (prkey) { -- snprintf(keystr, PRKEY_SIZE, "0x%016" PRIx64, prkey); -+ /* using the capitalization of the 'x' is a hack, but -+ * it's unlikely that mpath_persist will support more options -+ * since sg_persist doesn't, and this lets us keep the -+ * same file format as before instead of needing to change -+ * the format of the prkeys file */ -+ if (sa_flags) -+ snprintf(keystr, PRKEY_SIZE, "0X%016" PRIx64, prkey); -+ else -+ snprintf(keystr, PRKEY_SIZE, "0x%016" PRIx64, prkey); - keystr[PRKEY_SIZE - 1] = '\0'; - ret = do_prkey(fd, mpp->wwid, keystr, PRKEY_WRITE); - } -diff --git a/libmultipath/prkey.h b/libmultipath/prkey.h -index 4028e70..6739191 100644 ---- a/libmultipath/prkey.h -+++ b/libmultipath/prkey.h -@@ -13,7 +13,9 @@ - "# prkey wwid\n" \ - "#\n" - --int set_prkey(struct config *conf, struct multipath *mpp, uint64_t prkey); --int get_prkey(struct config *conf, struct multipath *mpp, uint64_t *prkey); -+int set_prkey(struct config *conf, struct multipath *mpp, uint64_t prkey, -+ uint8_t sa_flags); -+int get_prkey(struct config *conf, struct multipath *mpp, uint64_t *prkey, -+ uint8_t *sa_flags); - - #endif /* _PRKEY_H */ -diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c -index 9ca1355..62a6893 100644 ---- a/libmultipath/propsel.c -+++ b/libmultipath/propsel.c -@@ -106,6 +106,7 @@ do { \ - if (src && src->prkey_source != PRKEY_SOURCE_NONE) { \ - mp->prkey_source = src->prkey_source; \ - mp->reservation_key = src->reservation_key; \ -+ mp->sa_flags = src->sa_flags; \ - origin = msg; \ - goto out; \ - } \ -@@ -703,18 +704,19 @@ int select_reservation_key(struct config *conf, struct multipath *mp) - do_prkey_set(mp->mpe, multipaths_origin); - do_prkey_set(conf, conf_origin); - put_be64(mp->reservation_key, 0); -+ mp->sa_flags = 0; - mp->prkey_source = PRKEY_SOURCE_NONE; - return 0; - out: - if (mp->prkey_source == PRKEY_SOURCE_FILE) { - from_file = " (from prkeys file)"; -- if (get_prkey(conf, mp, &prkey) != 0) -+ if (get_prkey(conf, mp, &prkey, &mp->sa_flags) != 0) - put_be64(mp->reservation_key, 0); - else - put_be64(mp->reservation_key, prkey); - } - print_reservation_key(buff, PRKEY_SIZE, mp->reservation_key, -- mp->prkey_source); -+ mp->sa_flags, mp->prkey_source); - condlog(3, "%s: reservation_key = %s %s%s", mp->alias, buff, origin, - from_file); - return 0; -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index 0194b1e..987479f 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -367,6 +367,7 @@ struct multipath { - /* persistent management data*/ - int prkey_source; - struct be64 reservation_key; -+ uint8_t sa_flags; - unsigned char prflag; - int all_tg_pt; - struct gen_multipath generic_mp; -diff --git a/libmultipath/util.c b/libmultipath/util.c -index 7251ad0..8d8fcc8 100644 ---- a/libmultipath/util.c -+++ b/libmultipath/util.c -@@ -10,6 +10,8 @@ - #include - #include - #include -+#include -+#include - - #include "util.h" - #include "debug.h" -@@ -435,6 +437,20 @@ int parse_prkey(char *ptr, uint64_t *prkey) - return 0; - } - -+int parse_prkey_flags(char *ptr, uint64_t *prkey, uint8_t *flags) -+{ -+ char *flagstr; -+ -+ flagstr = strchr(ptr, ':'); -+ *flags = 0; -+ if (flagstr) { -+ *flagstr++ = '\0'; -+ if (strlen(flagstr) == 5 && strcmp(flagstr, "aptpl") == 0) -+ *flags = MPATH_F_APTPL_MASK; -+ } -+ return parse_prkey(ptr, prkey); -+} -+ - int safe_write(int fd, const void *buf, size_t count) - { - while (count > 0) { -diff --git a/libmultipath/util.h b/libmultipath/util.h -index a3ab894..56cec76 100644 ---- a/libmultipath/util.h -+++ b/libmultipath/util.h -@@ -19,6 +19,7 @@ void setup_thread_attr(pthread_attr_t *attr, size_t stacksize, int detached); - int systemd_service_enabled(const char *dev); - int get_linux_version_code(void); - int parse_prkey(char *ptr, uint64_t *prkey); -+int parse_prkey_flags(char *ptr, uint64_t *prkey, uint8_t *flags); - int safe_write(int fd, const void *buf, size_t count); - - #define KERNEL_VERSION(maj, min, ptc) ((((maj) * 256) + (min)) * 256 + (ptc)) -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 31f4585..30d8598 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -726,14 +726,17 @@ This is the service action reservation key used by mpathpersist. It must be - set for all multipath devices using persistent reservations, and it must be - the same as the RESERVATION KEY field of the PERSISTENT RESERVE OUT parameter - list which contains an 8-byte value provided by the application client to the --device server to identify the I_T nexus. -+device server to identify the I_T nexus. If the \fI--param-aptpl\fR option is -+used when registering the key with mpathpersist, \fB:aptpl\fR must be appended -+to the end of the reservation key. - .RS - .PP - Alternatively, this can be set to \fBfile\fR, which will store the RESERVATION - KEY registered by mpathpersist in the \fIprkeys_file\fR. multipathd will then - use this key to register additional paths as they appear. When the - registration is removed, the RESERVATION KEY is removed from the --\fIprkeys_file\fR. -+\fIprkeys_file\fR. The prkeys file will automatically keep track of whether -+the key was registered with \fI--param-aptpl\fR. - .TP - The default is: \fB\fR - .RE -diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c -index ba50fb8..6452796 100644 ---- a/multipathd/cli_handlers.c -+++ b/multipathd/cli_handlers.c -@@ -21,6 +21,7 @@ - #include "sysfs.h" - #include - #include -+#include - #include "util.h" - #include "prkey.h" - #include "propsel.h" -@@ -1463,6 +1464,7 @@ cli_getprkey(void * v, char ** reply, int * len, void * data) - struct multipath * mpp; - struct vectors * vecs = (struct vectors *)data; - char *mapname = get_keyparam(v, MAP); -+ char *flagstr = ""; - - mapname = convert_dev(mapname, 0); - condlog(3, "%s: get persistent reservation key (operator)", mapname); -@@ -1478,8 +1480,10 @@ cli_getprkey(void * v, char ** reply, int * len, void * data) - *len = strlen(*reply) + 1; - return 0; - } -- snprintf(*reply, 20, "0x%" PRIx64 "\n", -- get_be64(mpp->reservation_key)); -+ if (mpp->sa_flags & MPATH_F_APTPL_MASK) -+ flagstr = ":aptpl"; -+ snprintf(*reply, 20, "0x%" PRIx64 "%s\n", -+ get_be64(mpp->reservation_key), flagstr); - (*reply)[19] = '\0'; - *len = strlen(*reply) + 1; - return 0; -@@ -1503,7 +1507,7 @@ cli_unsetprkey(void * v, char ** reply, int * len, void * data) - - conf = get_multipath_config(); - pthread_cleanup_push(put_multipath_config, conf); -- ret = set_prkey(conf, mpp, 0); -+ ret = set_prkey(conf, mpp, 0, 0); - pthread_cleanup_pop(1); - - return ret; -@@ -1517,6 +1521,7 @@ cli_setprkey(void * v, char ** reply, int * len, void * data) - char *mapname = get_keyparam(v, MAP); - char *keyparam = get_keyparam(v, KEY); - uint64_t prkey; -+ uint8_t flags; - int ret; - struct config *conf; - -@@ -1527,14 +1532,14 @@ cli_setprkey(void * v, char ** reply, int * len, void * data) - if (!mpp) - return 1; - -- if (parse_prkey(keyparam, &prkey) != 0) { -+ if (parse_prkey_flags(keyparam, &prkey, &flags) != 0) { - condlog(0, "%s: invalid prkey : '%s'", mapname, keyparam); - return 1; - } - - conf = get_multipath_config(); - pthread_cleanup_push(put_multipath_config, conf); -- ret = set_prkey(conf, mpp, prkey); -+ ret = set_prkey(conf, mpp, prkey, flags); - pthread_cleanup_pop(1); - - return ret; -diff --git a/multipathd/main.c b/multipathd/main.c -index d40c416..6b1e782 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -3089,6 +3089,7 @@ void * mpath_pr_event_handler_fn (void * pathp ) - - param= malloc(sizeof(struct prout_param_descriptor)); - memset(param, 0 , sizeof(struct prout_param_descriptor)); -+ param->sa_flags = mpp->sa_flags; - memcpy(param->sa_key, &mpp->reservation_key, 8); - param->num_transportid = 0; - --- -2.7.4 - diff --git a/0027-RH-warn-on-invalid-regex-instead-of-failing.patch b/0018-RH-warn-on-invalid-regex-instead-of-failing.patch similarity index 93% rename from 0027-RH-warn-on-invalid-regex-instead-of-failing.patch rename to 0018-RH-warn-on-invalid-regex-instead-of-failing.patch index a23e167..b414639 100644 --- a/0027-RH-warn-on-invalid-regex-instead-of-failing.patch +++ b/0018-RH-warn-on-invalid-regex-instead-of-failing.patch @@ -16,7 +16,7 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index 7ad0f5a..ab808d6 100644 +index 32524d5..cce05e7 100644 --- a/libmultipath/dict.c +++ b/libmultipath/dict.c @@ -55,6 +55,21 @@ set_str(vector strvec, void *ptr) @@ -41,7 +41,7 @@ index 7ad0f5a..ab808d6 100644 set_yes_no(vector strvec, void *ptr) { char * buff; -@@ -1271,7 +1286,7 @@ ble_ ## option ## _handler (struct config *conf, vector strvec) \ +@@ -1333,7 +1348,7 @@ ble_ ## option ## _handler (struct config *conf, vector strvec) \ if (!conf->option) \ return 1; \ \ @@ -50,7 +50,7 @@ index 7ad0f5a..ab808d6 100644 if (!buff) \ return 1; \ \ -@@ -1287,7 +1302,7 @@ ble_ ## option ## _ ## name ## _handler (struct config *conf, vector strvec) \ +@@ -1349,7 +1364,7 @@ ble_ ## option ## _ ## name ## _handler (struct config *conf, vector strvec) \ if (!conf->option) \ return 1; \ \ @@ -59,7 +59,7 @@ index 7ad0f5a..ab808d6 100644 if (!buff) \ return 1; \ \ -@@ -1388,16 +1403,16 @@ device_handler(struct config *conf, vector strvec) +@@ -1452,16 +1467,16 @@ device_handler(struct config *conf, vector strvec) return 0; } diff --git a/0018-multipath-don-t-check-timestamps-without-a-path.patch b/0018-multipath-don-t-check-timestamps-without-a-path.patch deleted file mode 100644 index 5a3fd83..0000000 --- a/0018-multipath-don-t-check-timestamps-without-a-path.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 5 Jun 2018 15:31:55 -0500 -Subject: [PATCH] multipath: don't check timestamps without a path - -If a path was blacklisted, pathvec could exist but have no path in it. -print_cmd_valid wasn't checking this before calling -find_multipaths_check_timeout(). This was causing it to dereference a -NULL pointer in these cases. - -Signed-off-by: Benjamin Marzinski ---- - multipath/main.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - -diff --git a/multipath/main.c b/multipath/main.c -index c69e996..3f0a6aa 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -482,10 +482,8 @@ static int print_cmd_valid(int k, const vector pathvec, - pp, pp->find_multipaths_timeout, &until); - if (wait != FIND_MULTIPATHS_WAITING) - k = 1; -- } else if (pathvec != NULL) { -- pp = VECTOR_SLOT(pathvec, 0); -+ } else if (pathvec != NULL && (pp = VECTOR_SLOT(pathvec, 0))) - wait = find_multipaths_check_timeout(pp, 0, &until); -- } - if (wait == FIND_MULTIPATHS_WAITING) - printf("FIND_MULTIPATHS_WAIT_UNTIL=\"%ld.%06ld\"\n", - until.tv_sec, until.tv_nsec/1000); --- -2.7.4 - diff --git a/0028-RH-reset-default-find_mutipaths-value-to-off.patch b/0019-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 97% rename from 0028-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0019-RH-reset-default-find_mutipaths-value-to-off.patch index 05e6864..782c3d3 100644 --- a/0028-RH-reset-default-find_mutipaths-value-to-off.patch +++ b/0019-RH-reset-default-find_mutipaths-value-to-off.patch @@ -12,7 +12,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h -index f076b4b..70ba98a 100644 +index 7f3839f..c84d31d 100644 --- a/libmultipath/defaults.h +++ b/libmultipath/defaults.h @@ -17,7 +17,7 @@ diff --git a/0022-RH-Remove-the-property-blacklist-exception-builtin.patch b/0022-RH-Remove-the-property-blacklist-exception-builtin.patch deleted file mode 100644 index 451c524..0000000 --- a/0022-RH-Remove-the-property-blacklist-exception-builtin.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 2 Jul 2014 12:49:53 -0500 -Subject: [PATCH] RH: Remove the property blacklist exception builtin - -Multipath set the default property blacklist exceptions to -(ID_SCSI_VPD|ID_WWN). This has the effect of blacklisting some internal -devices. These devices may never have multiple paths, but it is nice -to be able to set multipath up on them all the same. This patch simply -removes the default, and makes it so that if no property -blacklist_exception is given, then devices aren't failed for not matching -it. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/blacklist.c | 15 ++++++--------- - multipath/multipath.conf.5 | 14 ++++++++------ - 2 files changed, 14 insertions(+), 15 deletions(-) - -diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c -index ee396e2..19d4697 100644 ---- a/libmultipath/blacklist.c -+++ b/libmultipath/blacklist.c -@@ -181,12 +181,6 @@ setup_default_blist (struct config * conf) - if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT)) - return 1; - -- str = STRDUP("(SCSI_IDENT_|ID_WWN)"); -- if (!str) -- return 1; -- if (store_ble(conf->elist_property, str, ORIGIN_DEFAULT)) -- return 1; -- - vector_foreach_slot (conf->hwtable, hwe, i) { - if (hwe->bl_product) { - if (_blacklist_device(conf->blist_device, hwe->vendor, -@@ -390,9 +384,12 @@ 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, -- MATCH_PROPERTY_BLIST_MISSING); -- return MATCH_PROPERTY_BLIST_MISSING; -+ if (VECTOR_SIZE(conf->elist_property)) { -+ log_filter(devname, NULL, NULL, NULL, NULL, -+ MATCH_PROPERTY_BLIST_MISSING); -+ return MATCH_PROPERTY_BLIST_MISSING; -+ } -+ return 0; - } - - void -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 30d8598..c45da9f 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -1179,10 +1179,6 @@ The \fIWorld Wide Identification\fR of a device. - .TP - .B property - Regular expression of the udev property to be whitelisted. --.RS --.TP --The default is: \fB(SCSI_IDENT_|ID_WWN)\fR --.RE - .TP - .B device - Subsection for the device description. This subsection recognizes the -@@ -1193,8 +1189,14 @@ keywords. For a full description of these keywords please see the \fIdevices\fR - section description. - .LP - The \fIproperty\fR whitelist handling is different from the usual --handling in the sense that the device \fIhas\fR to have a udev property that --matches the whitelist, otherwise the device will be blacklisted. In these cases the message \fIblacklisted, udev property missing\fR will be displayed. -+handling in the sense that if the propery whitelist is set, the device -+\fIhas\fR to have a udev property that matches the whitelist, otherwise the -+device will be blacklisted. In these cases the message \fIblacklisted, udev -+property missing\fR will be displayed. For example settting the -+property blacklist_exception to \fB(SCSI_IDENT_|ID_WWN)\fR will blacklist -+all devices that have no udev property whose name regex matches either -+\fBSCSI_IDENT_\fR or \fBID_WWN\fR. This works to exclude most -+non-multipathable devices. - . - . - .\" ---------------------------------------------------------------------------- --- -2.7.4 - diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 962708e..21f2296 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,43 +1,34 @@ Name: device-mapper-multipath Version: 0.7.7 -Release: 3%{?dist} +Release: 4.gitef6d98b%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ # 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/?p=multipath-tools/.git;a=snapshot;h=refs/tags/0.7.7;sf=tgz" -o multipath-tools-0.7.7.tgz -Source0: multipath-tools-0.7.7.tgz +# 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 Source1: multipath.conf -Patch0001: 0001-multipath-tools-add-RDAC-SUN-ArrayStorage-to-hwtable.patch -Patch0002: 0002-multipath-tools-remove-c-from-__cpluscplus-misspelle.patch -Patch0003: 0003-multipath-tools-remove-emacs-autoconfig-of-kpartx-gp.patch -Patch0004: 0004-multipath-tools-replace-FSF-address-with-a-www-point.patch -Patch0005: 0005-multipath-tools-Remove-trailing-leading-whitespaces-.patch -Patch0006: 0006-multipath-tools-fix-compilation-with-musl-libc.patch -Patch0007: 0007-multipath-tools-add-x-to-doc-preclean.pl-and-split-m.patch -Patch0008: 0008-multipath-tools-refresh-kernel-doc-from-kernel-sourc.patch -Patch0009: 0009-multipath-tools-configure-hitachi-ams2000-and-hus100.patch -Patch0010: 0010-libmultipath-don-t-reject-maps-with-undefined-prio.patch -Patch0011: 0011-multipathd-handle-errors-in-uxlsnr-as-fatal.patch -Patch0012: 0012-libmultipath-fix-error-parsing-find_multipaths-stric.patch -Patch0013: 0013-libmultipath-print-correct-default-for-delay_-_check.patch -Patch0014: 0014-multipath.conf.5-clarify-property-whitelist-handling.patch -Patch0015: 0015-mpathpersist-add-all_tg_pt-option.patch -Patch0016: 0016-libmultipath-remove-rbd-code.patch -Patch0017: 0017-mpathpersist-fix-aptpl-support.patch -Patch0018: 0018-multipath-don-t-check-timestamps-without-a-path.patch -Patch0019: 0019-libmultipath-fix-detect-alua-corner-case.patch -Patch0020: 0020-multipath-fix-setting-conf-version.patch -Patch0021: 0021-RH-fixup-udev-rules-for-redhat.patch -Patch0022: 0022-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0023: 0023-RH-don-t-start-without-a-config-file.patch -Patch0024: 0024-RH-use-rpm-optflags-if-present.patch -Patch0025: 0025-RH-add-mpathconf.patch -Patch0026: 0026-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0027: 0027-RH-warn-on-invalid-regex-instead-of-failing.patch -Patch0028: 0028-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0001: 0001-libmultipath-remove-last-of-rbd-code.patch +Patch0002: 0002-libmultipath-fix-detect-alua-corner-case.patch +Patch0003: 0003-multipath-fix-setting-conf-version.patch +Patch0004: 0004-mpathpersist-add-param-alltgpt-option.patch +Patch0005: 0005-libmutipath-remove-unused-IDE-bus-type.patch +Patch0006: 0006-multipathd-add-new-protocol-path-wildcard.patch +Patch0007: 0007-libmultipath-add-protocol-blacklist-option.patch +Patch0008: 0008-libmultipath-remove-_filter_-blacklist-functions.patch +Patch0009: 0009-multipath-tests-change-to-work-with-old-make-version.patch +Patch0010: 0010-multipath-tests-add-blacklist-tests.patch +Patch0011: 0011-mpathpersist-add-missing-param-rk-usage-info.patch +Patch0012: 0012-RH-fixup-udev-rules-for-redhat.patch +Patch0013: 0013-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0014: 0014-RH-don-t-start-without-a-config-file.patch +Patch0015: 0015-RH-use-rpm-optflags-if-present.patch +Patch0016: 0016-RH-add-mpathconf.patch +Patch0017: 0017-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0018: 0018-RH-warn-on-invalid-regex-instead-of-failing.patch +Patch0019: 0019-RH-reset-default-find_mutipaths-value-to-off.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -53,7 +44,7 @@ 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 +BuildRequires: json-c-devel, perl-interpreter, pkgconfig, gcc BuildRequires: userspace-rcu-devel %description @@ -110,7 +101,7 @@ This package contains the files needed to develop applications that use device-mapper-multipath's libdmmp C API library %prep -%setup -q -n multipath-tools-0.7.7 +%setup -q -n multipath-tools-ef6d98b %patch0001 -p1 %patch0002 -p1 %patch0003 -p1 @@ -130,15 +121,6 @@ device-mapper-multipath's libdmmp C API library %patch0017 -p1 %patch0018 -p1 %patch0019 -p1 -%patch0020 -p1 -%patch0021 -p1 -%patch0022 -p1 -%patch0023 -p1 -%patch0024 -p1 -%patch0025 -p1 -%patch0026 -p1 -%patch0027 -p1 -%patch0028 -p1 cp %{SOURCE1} . %build @@ -254,6 +236,28 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Thu Jul 12 2018 Benjamin Marzinski 0.7.7-4.gitef6d98b +- Update Source to latest upstream commit + * Previous patches 0001-0018 are included in this commit +- Rename files + * Previous patches 0019-0028 are now patches 0002-0003 & 0012-0019 +- Add 0001-libmultipath-remove-last-of-rbd-code.patch +- Add 0004-mpathpersist-add-param-alltgpt-option.patch + * mpathpersist now accepts --param-alltgpt +- Add 0005-libmutipath-remove-unused-IDE-bus-type.patch +- Add 0006-multipathd-add-new-protocol-path-wildcard.patch + * multipathd show paths format now accepts %P for the path protocol/transport +- Add 0007-libmultipath-add-protocol-blacklist-option.patch + * You can now use the "protocol" blacklist section parameter to blacklist + by protocol/transport +- Add 0008-libmultipath-remove-_filter_-blacklist-functions.patch +- Add 0009-multipath-tests-change-to-work-with-old-make-version.patch +- Add 0010-multipath-tests-add-blacklist-tests.patch +- Add 0011-mpathpersist-add-missing-param-rk-usage-info.patch +- Refresh 0013-RH-Remove-the-property-blacklist-exception-builtin.patch +- Modify 0016-RH-add-mpathconf.patch + * improve usage message and man page + * Thu Jul 12 2018 Fedora Release Engineering - 0.7.7-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild diff --git a/sources b/sources index 1f27345..8155f49 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (multipath-tools-0.7.7.tgz) = 5c487e118b5c1f1b5ea4fe5b6c220dd09ba991df518eb4fdfec6b0cefb48ba2f3e885c779420670b0cdbc8205b09309731bef3a3bd928f367516414bf9d1bb21 +SHA512 (multipath-tools-ef6d98b.tgz) = 03ed4b01d653d91f8a76d98f2a25af817213310f55d5015b89f0d1a69c55390a9e5cb3cb441a38f0497b51716423cee2061b5ec49bfdb05812e70766a0e724ef SHA512 (multipath.conf) = 71953dce5a68adcf60a942305f5a66023e6f4c4baf53b1bfdb4edf65ed5b8e03db804363c36d1dcfd85591f4766f52b515269904c53b84d7b076da0b80b09942