From 9aa42b3e73be7392ad68f6268eb8155f51fb1668 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= Date: Mon, 13 Apr 2020 19:26:27 +0200 Subject: [PATCH 01/67] Add 0032-add-support-for-upcoming-json-c-0.14.0.patch --- ...d-support-for-upcoming-json-c-0.14.0.patch | 28 +++++++++++++++++++ device-mapper-multipath.spec | 6 +++- 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 0032-add-support-for-upcoming-json-c-0.14.0.patch diff --git a/0032-add-support-for-upcoming-json-c-0.14.0.patch b/0032-add-support-for-upcoming-json-c-0.14.0.patch new file mode 100644 index 0000000..34d02f7 --- /dev/null +++ b/0032-add-support-for-upcoming-json-c-0.14.0.patch @@ -0,0 +1,28 @@ +From 8438a9cd8d7ed88645fa8e6a8f19c0fd9ae872a7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= +Date: Mon, 13 Apr 2020 19:22:02 +0200 +Subject: [PATCH] Add support for upcoming json-c 0.14.0. + +TRUE/FALSE are not defined anymore. 1 and 0 are used instead. +This is backwards compatible, as earlier versions of json-c are +using the same integer values in their present definitions. +--- + libdmmp/libdmmp_private.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libdmmp/libdmmp_private.h b/libdmmp/libdmmp_private.h +index ac85b63f..4378962b 100644 +--- a/libdmmp/libdmmp_private.h ++++ b/libdmmp/libdmmp_private.h +@@ -82,7 +82,7 @@ static out_type func_name(struct dmmp_context *ctx, const char *var_name) { \ + do { \ + json_type j_type = json_type_null; \ + json_object *j_obj_tmp = NULL; \ +- if (json_object_object_get_ex(j_obj, key, &j_obj_tmp) != TRUE) { \ ++ if (json_object_object_get_ex(j_obj, key, &j_obj_tmp) != 1) { \ + _error(ctx, "Invalid JSON output from multipathd IPC: " \ + "key '%s' not found", key); \ + rc = DMMP_ERR_IPC_ERROR; \ +-- +2.26.0 + diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 1db2d51..25c084b 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.8.2 -Release: 4%{?dist} +Release: 5%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -41,6 +41,7 @@ Patch0028: 0028-RH-reset-default-find_mutipaths-value-to-off.patch Patch0029: 0029-RH-Fix-nvme-compilation-warning.patch Patch0030: 0030-RH-attempt-to-get-ANA-info-via-sysfs-first.patch Patch0031: 0031-multipath-fix-issues-found-by-compiling-with-gcc-10.patch +Patch0032: 0032-add-support-for-upcoming-json-c-0.14.0.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -235,6 +236,9 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Mon Apr 13 2020 Björn Esser - 0.8.2-5 +- Add 0032-add-support-for-upcoming-json-c-0.14.0.patch + * Mon Apr 13 2020 Björn Esser - 0.8.2-4 - Fix macro escaping in %%changelog From 2a2c997c5285c41f8def2f1a4f8abb6cd8753c31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= Date: Wed, 22 Apr 2020 00:03:14 +0200 Subject: [PATCH 02/67] Rebuild (json-c) --- device-mapper-multipath.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 25c084b..7c4945f 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.8.2 -Release: 5%{?dist} +Release: 6%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -236,6 +236,9 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Tue Apr 21 2020 Björn Esser - 0.8.2-6 +- Rebuild (json-c) + * Mon Apr 13 2020 Björn Esser - 0.8.2-5 - Add 0032-add-support-for-upcoming-json-c-0.14.0.patch From c80b4a3ee2129dafd08eca7c9fd72d4c1ad5ce98 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Fri, 29 May 2020 20:47:35 -0500 Subject: [PATCH 03/67] device-mapper-multipath-0.8.4-1 Update Source to upstream version 0.8.2 * Previoud patches 0001-0020 & 0031 are included in this commit Rename files * Previous patches 0021-0032 are now patches 0012-0022 Add 0001-libmultipath-assign-variable-to-make-gcc-happy.patch Add 0002-libmutipath-don-t-close-fd-on-dm_lib_release.patch Add 0003-libmultipath-allow-force-reload-with-no-active-paths.patch Add 0004-libmpathpersist-depend-on-libmultipath.patch Add 0005-multipath-tools-Makefile-more-dependency-fixes-for-p.patch Add 0006-multipath-tools-Makefile.inc-set-Wno-error-clobbered.patch Add 0007-libmultipath-discovery.c-use-z-qualifier-for-size_t.patch Add 0008-libmultipath-eliminate-more-signed-unsigned-comparis.patch Add 0009-libmultipath-set_uint-fix-parsing-for-32bit.patch Add 0010-multipath-tools-Makefile-add-install-dependency.patch Add 0012-libmultipath-fix-condlog-NULL-argument-in-uevent_get.patch Add 0023-RH-work-around-gcc-10-format-truncation-issue.patch * The above 10 patches have been submitted upstream --- .gitignore | 1 + ...th-assign-variable-to-make-gcc-happy.patch | 42 + ...e-vector_foreach_slot_backwards-work.patch | 31 - ...-marginal-paths-and-groups-infrastru.patch | 301 ------- ...ath-don-t-close-fd-on-dm_lib_release.patch | 66 ++ ...ow-force-reload-with-no-active-paths.patch | 64 ++ ...-add-path-grouping-policy-unit-tests.patch | 749 ------------------ ...bmpathpersist-depend-on-libmultipath.patch | 31 + ...d-wrapper-function-around-pgpolicyfn.patch | 260 ------ ...Makefile-more-dependency-fixes-for-p.patch | 34 + ...olicy-tests-to-work-with-group_paths.patch | 420 ---------- ...-double-free-in-pgpolicyfn-error-pat.patch | 79 -- ...Makefile.inc-set-Wno-error-clobbered.patch | 33 + ...path-consolidate-group_by_-functions.patch | 253 ------ ...scovery.c-use-z-qualifier-for-size_t.patch | 91 +++ ...minate-more-signed-unsigned-comparis.patch | 185 +++++ ...-make-pgpolicyfn-take-a-paths-vector.patch | 174 ---- ...ke-group_paths-handle-marginal-paths.patch | 185 ----- ...ipath-set_uint-fix-parsing-for-32bit.patch | 49 ++ ...ools-Makefile-add-install-dependency.patch | 33 + ...dd-tests-for-grouping-marginal-paths.patch | 701 ---------------- ...d-support-for-upcoming-json-c-0.14.0.patch | 8 +- ...dd-marginal_pathgroups-config-option.patch | 642 --------------- ...-condlog-NULL-argument-in-uevent_get.patch | 46 ++ ...libmutipath-deprecate-delay_-_checks.patch | 381 --------- ... 0013-RH-fixup-udev-rules-for-redhat.patch | 4 +- 0013-multipathd-use-marginal_pathgroups.patch | 111 --- ...property-blacklist-exception-builtin.patch | 21 +- 0014-multipath-update-man-pages.patch | 99 --- ...RH-don-t-start-without-a-config-file.patch | 8 +- ...th.conf-add-enable_foreign-parameter.patch | 230 ------ ... 0016-RH-use-rpm-optflags-if-present.patch | 47 +- ...f.5-document-foreign-library-support.patch | 75 -- ...hconf.patch => 0017-RH-add-mpathconf.patch | 137 +++- ...athpersist-remove-broken-unused-code.patch | 51 -- ...om-kernel-cmdline-mpath.wwids-with-A.patch | 14 +- ...path-EMC-PowerMax-NVMe-device-config.patch | 33 - ...-on-invalid-regex-instead-of-failing.patch | 14 +- 0019-mpathpersist-fix-leaks.patch | 132 --- ...-default-find_mutipaths-value-to-off.patch | 6 +- ...ltipath-fix-mpcontext-initialization.patch | 232 ------ ...0021-RH-Fix-nvme-compilation-warning.patch | 2 +- ...empt-to-get-ANA-info-via-sysfs-first.patch | 16 +- ...round-gcc-10-format-truncation-issue.patch | 31 + ...ssues-found-by-compiling-with-gcc-10.patch | 119 --- device-mapper-multipath.spec | 84 +- sources | 2 +- 47 files changed, 952 insertions(+), 5375 deletions(-) create mode 100644 0001-libmultipath-assign-variable-to-make-gcc-happy.patch delete mode 100644 0001-libmultipath-make-vector_foreach_slot_backwards-work.patch delete mode 100644 0002-libmultipath-add-marginal-paths-and-groups-infrastru.patch create mode 100644 0002-libmutipath-don-t-close-fd-on-dm_lib_release.patch create mode 100644 0003-libmultipath-allow-force-reload-with-no-active-paths.patch delete mode 100644 0003-tests-add-path-grouping-policy-unit-tests.patch create mode 100644 0004-libmpathpersist-depend-on-libmultipath.patch delete mode 100644 0004-libmultipath-add-wrapper-function-around-pgpolicyfn.patch create mode 100644 0005-multipath-tools-Makefile-more-dependency-fixes-for-p.patch delete mode 100644 0005-tests-update-pgpolicy-tests-to-work-with-group_paths.patch delete mode 100644 0006-libmultipath-fix-double-free-in-pgpolicyfn-error-pat.patch create mode 100644 0006-multipath-tools-Makefile.inc-set-Wno-error-clobbered.patch delete mode 100644 0007-libmultipath-consolidate-group_by_-functions.patch create mode 100644 0007-libmultipath-discovery.c-use-z-qualifier-for-size_t.patch create mode 100644 0008-libmultipath-eliminate-more-signed-unsigned-comparis.patch delete mode 100644 0008-libmultipath-make-pgpolicyfn-take-a-paths-vector.patch delete mode 100644 0009-libmultipath-make-group_paths-handle-marginal-paths.patch create mode 100644 0009-libmultipath-set_uint-fix-parsing-for-32bit.patch create mode 100644 0010-multipath-tools-Makefile-add-install-dependency.patch delete mode 100644 0010-tests-add-tests-for-grouping-marginal-paths.patch rename 0032-add-support-for-upcoming-json-c-0.14.0.patch => 0011-libdmmp-Add-support-for-upcoming-json-c-0.14.0.patch (83%) delete mode 100644 0011-libmultipath-add-marginal_pathgroups-config-option.patch create mode 100644 0012-libmultipath-fix-condlog-NULL-argument-in-uevent_get.patch delete mode 100644 0012-libmutipath-deprecate-delay_-_checks.patch rename 0021-RH-fixup-udev-rules-for-redhat.patch => 0013-RH-fixup-udev-rules-for-redhat.patch (95%) delete mode 100644 0013-multipathd-use-marginal_pathgroups.patch rename 0022-RH-Remove-the-property-blacklist-exception-builtin.patch => 0014-RH-Remove-the-property-blacklist-exception-builtin.patch (87%) delete mode 100644 0014-multipath-update-man-pages.patch rename 0023-RH-don-t-start-without-a-config-file.patch => 0015-RH-don-t-start-without-a-config-file.patch (95%) delete mode 100644 0015-multipath.conf-add-enable_foreign-parameter.patch rename 0024-RH-use-rpm-optflags-if-present.patch => 0016-RH-use-rpm-optflags-if-present.patch (52%) delete mode 100644 0016-multipath.conf.5-document-foreign-library-support.patch rename 0025-RH-add-mpathconf.patch => 0017-RH-add-mpathconf.patch (78%) delete mode 100644 0017-mpathpersist-remove-broken-unused-code.patch rename 0026-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch => 0018-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch (94%) delete mode 100644 0018-libmultipath-EMC-PowerMax-NVMe-device-config.patch rename 0027-RH-warn-on-invalid-regex-instead-of-failing.patch => 0019-RH-warn-on-invalid-regex-instead-of-failing.patch (89%) delete mode 100644 0019-mpathpersist-fix-leaks.patch rename 0028-RH-reset-default-find_mutipaths-value-to-off.patch => 0020-RH-reset-default-find_mutipaths-value-to-off.patch (88%) delete mode 100644 0020-libmultipath-fix-mpcontext-initialization.patch rename 0029-RH-Fix-nvme-compilation-warning.patch => 0021-RH-Fix-nvme-compilation-warning.patch (92%) rename 0030-RH-attempt-to-get-ANA-info-via-sysfs-first.patch => 0022-RH-attempt-to-get-ANA-info-via-sysfs-first.patch (83%) create mode 100644 0023-RH-work-around-gcc-10-format-truncation-issue.patch delete mode 100644 0031-multipath-fix-issues-found-by-compiling-with-gcc-10.patch diff --git a/.gitignore b/.gitignore index 5bb1f09..703cbe1 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ multipath-tools-091027.tar.gz /multipath-tools-2df6110.tgz /multipath-tools-0.8.0.tgz /multipath-tools-0.8.2.tgz +/multipath-tools-0.8.4.tgz diff --git a/0001-libmultipath-assign-variable-to-make-gcc-happy.patch b/0001-libmultipath-assign-variable-to-make-gcc-happy.patch new file mode 100644 index 0000000..06de678 --- /dev/null +++ b/0001-libmultipath-assign-variable-to-make-gcc-happy.patch @@ -0,0 +1,42 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 17 Mar 2020 17:28:24 -0500 +Subject: [PATCH] libmultipath: assign variable to make gcc happy +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +There is nothing wrong with is_queueing not being set at the start +of __set_no_path_retry(), it will always get set before it is accessed, +but gcc 8.2.1 is failing with + +structs_vec.c: In function ‘__set_no_path_retry’: +structs_vec.c:339:7: error: ‘is_queueing’ may be used uninitialized in +this function [-Werror=maybe-uninitialized] + bool is_queueing; + ^~~~~~~~~~~ + +so, assign a value to make it happy. + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/structs_vec.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c +index 3dbbaa0f..077f2e42 100644 +--- a/libmultipath/structs_vec.c ++++ b/libmultipath/structs_vec.c +@@ -336,7 +336,7 @@ static void leave_recovery_mode(struct multipath *mpp) + + void __set_no_path_retry(struct multipath *mpp, bool check_features) + { +- bool is_queueing; ++ bool is_queueing = false; /* assign a value to make gcc happy */ + + check_features = check_features && mpp->features != NULL; + if (check_features) +-- +2.17.2 + diff --git a/0001-libmultipath-make-vector_foreach_slot_backwards-work.patch b/0001-libmultipath-make-vector_foreach_slot_backwards-work.patch deleted file mode 100644 index 4533e32..0000000 --- a/0001-libmultipath-make-vector_foreach_slot_backwards-work.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 1dd540c6bf5bac70d5d61b869ac652523b91ee2b Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 24 May 2019 17:30:07 -0500 -Subject: [PATCH] libmultipath: make vector_foreach_slot_backwards work as - expected - -All of the code that uses vector_foreach_slot_backwards() treats "i" as -the index of the entry "p", but the way it was coded, that wasn't the -case. "i" was the number of the entry counting from 1, not 0. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/vector.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/vector.h b/libmultipath/vector.h -index 41d2b896..344dffd5 100644 ---- a/libmultipath/vector.h -+++ b/libmultipath/vector.h -@@ -40,7 +40,7 @@ typedef struct _vector *vector; - #define vector_foreach_slot_after(v,p,i) \ - for (; (v) && i < VECTOR_SIZE(v) && ((p) = (v)->slot[i]); i++) - #define vector_foreach_slot_backwards(v,p,i) \ -- for (i = VECTOR_SIZE(v); i > 0 && ((p) = (v)->slot[i-1]); i--) -+ for (i = VECTOR_SIZE(v) - 1; (int)i >= 0 && ((p) = (v)->slot[i]); i--) - - #define identity(x) (x) - /* --- -2.17.2 - diff --git a/0002-libmultipath-add-marginal-paths-and-groups-infrastru.patch b/0002-libmultipath-add-marginal-paths-and-groups-infrastru.patch deleted file mode 100644 index cf96b2f..0000000 --- a/0002-libmultipath-add-marginal-paths-and-groups-infrastru.patch +++ /dev/null @@ -1,301 +0,0 @@ -From 668bc6e2f142ed81936329de144f57026c90edf2 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 1 Jul 2019 15:19:29 -0500 -Subject: [PATCH] libmultipath: add marginal paths and groups infrastructure - -This commit adds a marginal variable ot the paths and pathgroups structs. -The marginal paths variable can be set by - -multipathd path setmarginal - -and cleared by - -multipathd path unsetmarginal - -All of the marginal paths on a multipath device can be cleared by - -multipathd map unsetmarginal - -Currently, the marginal variable of a pathgroup will not change. This -will be added by a future commit. The marginal state of a path or -pathgroup is printable with the %M wildcard, and is displayed in the -json output. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/print.c | 18 ++++++++ - libmultipath/print.h | 6 ++- - libmultipath/structs.h | 2 + - multipathd/cli.c | 5 +++ - multipathd/cli.h | 4 ++ - multipathd/cli_handlers.c | 91 +++++++++++++++++++++++++++++++++++++++ - multipathd/cli_handlers.h | 3 ++ - multipathd/main.c | 3 ++ - 8 files changed, 130 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/print.c b/libmultipath/print.c -index fc40b0f0..907469ad 100644 ---- a/libmultipath/print.c -+++ b/libmultipath/print.c -@@ -502,6 +502,14 @@ snprint_pg_state (char * buff, size_t len, const struct pathgroup * pgp) - } - } - -+static int -+snprint_pg_marginal (char * buff, size_t len, const struct pathgroup * pgp) -+{ -+ if (pgp->marginal) -+ return snprintf(buff, len, "marginal"); -+ return snprintf(buff, len, "normal"); -+} -+ - static int - snprint_path_size (char * buff, size_t len, const struct path * pp) - { -@@ -672,6 +680,14 @@ snprint_path_protocol(char * buff, size_t len, const struct path * pp) - } - } - -+int -+snprint_path_marginal(char * buff, size_t len, const struct path * pp) -+{ -+ if (pp->marginal) -+ return snprintf(buff, len, "marginal"); -+ return snprintf(buff, len, "normal"); -+} -+ - struct multipath_data mpd[] = { - {'n', "name", 0, snprint_name}, - {'w', "uuid", 0, snprint_multipath_uuid}, -@@ -713,6 +729,7 @@ struct path_data pd[] = { - {'p', "pri", 0, snprint_pri}, - {'S', "size", 0, snprint_path_size}, - {'z', "serial", 0, snprint_path_serial}, -+ {'M', "marginal_st", 0, snprint_path_marginal}, - {'m', "multipath", 0, snprint_path_mpp}, - {'N', "host WWNN", 0, snprint_host_wwnn}, - {'n', "target WWNN", 0, snprint_tgt_wwnn}, -@@ -729,6 +746,7 @@ struct pathgroup_data pgd[] = { - {'s', "selector", 0, snprint_pg_selector}, - {'p', "pri", 0, snprint_pg_pri}, - {'t', "dm_st", 0, snprint_pg_state}, -+ {'M', "marginal_st", 0, snprint_pg_marginal}, - {0, NULL, 0 , NULL} - }; - -diff --git a/libmultipath/print.h b/libmultipath/print.h -index e2fb865c..7e36ec63 100644 ---- a/libmultipath/print.h -+++ b/libmultipath/print.h -@@ -50,7 +50,8 @@ - #define PRINT_JSON_GROUP "{\n" \ - " \"selector\" : \"%s\",\n" \ - " \"pri\" : %p,\n" \ -- " \"dm_st\" : \"%t\"," -+ " \"dm_st\" : \"%t\",\n" \ -+ " \"marginal_st\" : \"%M\"," - - #define PRINT_JSON_GROUP_NUM " \"group\" : %d,\n" - -@@ -66,7 +67,8 @@ - " \"target_wwnn\" : \"%n\",\n" \ - " \"host_wwpn\" : \"%R\",\n" \ - " \"target_wwpn\" : \"%r\",\n" \ -- " \"host_adapter\" : \"%a\"" -+ " \"host_adapter\" : \"%a\",\n" \ -+ " \"marginal_st\" : \"%M\"" - - #define MAX_LINE_LEN 80 - #define MAX_LINES 64 -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index 7879d763..1a3d827b 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -289,6 +289,7 @@ struct path { - int io_err_pathfail_cnt; - int io_err_pathfail_starttime; - int find_multipaths_timeout; -+ int marginal; - /* configlet pointers */ - vector hwe; - struct gen_path generic_path; -@@ -403,6 +404,7 @@ struct pathgroup { - int status; - int priority; - int enabled_paths; -+ int marginal; - vector paths; - struct multipath *mpp; - struct gen_pathgroup generic_pg; -diff --git a/multipathd/cli.c b/multipathd/cli.c -index 17795b61..800c0fbe 100644 ---- a/multipathd/cli.c -+++ b/multipathd/cli.c -@@ -215,6 +215,8 @@ load_keys (void) - r += add_key(keys, "unsetprkey", UNSETPRKEY, 0); - r += add_key(keys, "key", KEY, 1); - r += add_key(keys, "local", LOCAL, 0); -+ r += add_key(keys, "setmarginal", SETMARGINAL, 0); -+ r += add_key(keys, "unsetmarginal", UNSETMARGINAL, 0); - - - if (r) { -@@ -589,6 +591,9 @@ cli_init (void) { - add_handler(UNSETPRKEY+MAP, NULL); - add_handler(FORCEQ+DAEMON, NULL); - add_handler(RESTOREQ+DAEMON, NULL); -+ add_handler(SETMARGINAL+PATH, NULL); -+ add_handler(UNSETMARGINAL+PATH, NULL); -+ add_handler(UNSETMARGINAL+MAP, NULL); - - return 0; - } -diff --git a/multipathd/cli.h b/multipathd/cli.h -index 32dcffac..fdfb9aed 100644 ---- a/multipathd/cli.h -+++ b/multipathd/cli.h -@@ -45,6 +45,8 @@ enum { - __UNSETPRKEY, - __KEY, - __LOCAL, -+ __SETMARGINAL, -+ __UNSETMARGINAL, - }; - - #define LIST (1 << __LIST) -@@ -89,6 +91,8 @@ enum { - #define UNSETPRKEY (1ULL << __UNSETPRKEY) - #define KEY (1ULL << __KEY) - #define LOCAL (1ULL << __LOCAL) -+#define SETMARGINAL (1ULL << __SETMARGINAL) -+#define UNSETMARGINAL (1ULL << __UNSETMARGINAL) - - #define INITIAL_REPLY_LEN 1200 - -diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c -index 4c32d953..8a899049 100644 ---- a/multipathd/cli_handlers.c -+++ b/multipathd/cli_handlers.c -@@ -1537,3 +1537,94 @@ cli_setprkey(void * v, char ** reply, int * len, void * data) - - return ret; - } -+ -+int cli_set_marginal(void * v, char ** reply, int * len, void * data) -+{ -+ struct vectors * vecs = (struct vectors *)data; -+ char * param = get_keyparam(v, PATH); -+ struct path * pp; -+ -+ param = convert_dev(param, 1); -+ pp = find_path_by_dev(vecs->pathvec, param); -+ -+ if (!pp) -+ pp = find_path_by_devt(vecs->pathvec, param); -+ -+ if (!pp || !pp->mpp || !pp->mpp->alias) -+ return 1; -+ -+ condlog(2, "%s: set marginal path %s (operator)", -+ pp->mpp->alias, pp->dev_t); -+ if (pp->mpp->wait_for_udev) { -+ condlog(2, "%s: device not fully created, failing set marginal", -+ pp->mpp->alias); -+ return 1; -+ } -+ pp->marginal = 1; -+ -+ return update_path_groups(pp->mpp, vecs, 0); -+} -+ -+int cli_unset_marginal(void * v, char ** reply, int * len, void * data) -+{ -+ struct vectors * vecs = (struct vectors *)data; -+ char * param = get_keyparam(v, PATH); -+ struct path * pp; -+ -+ param = convert_dev(param, 1); -+ pp = find_path_by_dev(vecs->pathvec, param); -+ -+ if (!pp) -+ pp = find_path_by_devt(vecs->pathvec, param); -+ -+ if (!pp || !pp->mpp || !pp->mpp->alias) -+ return 1; -+ -+ condlog(2, "%s: unset marginal path %s (operator)", -+ pp->mpp->alias, pp->dev_t); -+ if (pp->mpp->wait_for_udev) { -+ condlog(2, "%s: device not fully created, " -+ "failing unset marginal", pp->mpp->alias); -+ return 1; -+ } -+ pp->marginal = 0; -+ -+ return update_path_groups(pp->mpp, vecs, 0); -+} -+ -+int cli_unset_all_marginal(void * v, char ** reply, int * len, void * data) -+{ -+ struct vectors * vecs = (struct vectors *)data; -+ char * mapname = get_keyparam(v, MAP); -+ struct multipath *mpp; -+ struct pathgroup * pgp; -+ struct path * pp; -+ unsigned int i, j; -+ int minor; -+ -+ mapname = convert_dev(mapname, 0); -+ condlog(2, "%s: unset all marginal paths (operator)", -+ mapname); -+ -+ if (sscanf(mapname, "dm-%d", &minor) == 1) -+ mpp = find_mp_by_minor(vecs->mpvec, minor); -+ else -+ mpp = find_mp_by_alias(vecs->mpvec, mapname); -+ -+ if (!mpp) { -+ condlog(0, "%s: invalid map name. " -+ "cannot unset marginal paths", mapname); -+ return 1; -+ } -+ if (mpp->wait_for_udev) { -+ condlog(2, "%s: device not fully created, " -+ "failing unset all marginal", mpp->alias); -+ return 1; -+ } -+ -+ vector_foreach_slot (mpp->pg, pgp, i) -+ vector_foreach_slot (pgp->paths, pp, j) -+ pp->marginal = 0; -+ -+ return update_path_groups(mpp, vecs, 0); -+} -diff --git a/multipathd/cli_handlers.h b/multipathd/cli_handlers.h -index edbdf063..0f451064 100644 ---- a/multipathd/cli_handlers.h -+++ b/multipathd/cli_handlers.h -@@ -49,3 +49,6 @@ int cli_unsetprstatus(void * v, char ** reply, int * len, void * data); - int cli_getprkey(void * v, char ** reply, int * len, void * data); - int cli_setprkey(void * v, char ** reply, int * len, void * data); - int cli_unsetprkey(void * v, char ** reply, int * len, void * data); -+int cli_set_marginal(void * v, char ** reply, int * len, void * data); -+int cli_unset_marginal(void * v, char ** reply, int * len, void * data); -+int cli_unset_all_marginal(void * v, char ** reply, int * len, void * data); -diff --git a/multipathd/main.c b/multipathd/main.c -index 7a5cd115..7db15736 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -1609,6 +1609,9 @@ uxlsnrloop (void * ap) - set_handler_callback(GETPRKEY+MAP, cli_getprkey); - set_handler_callback(SETPRKEY+MAP+KEY, cli_setprkey); - set_handler_callback(UNSETPRKEY+MAP, cli_unsetprkey); -+ set_handler_callback(SETMARGINAL+PATH, cli_set_marginal); -+ set_handler_callback(UNSETMARGINAL+PATH, cli_unset_marginal); -+ set_handler_callback(UNSETMARGINAL+MAP, cli_unset_all_marginal); - - umask(077); - uxsock_listen(&uxsock_trigger, ux_sock, ap); --- -2.17.2 - diff --git a/0002-libmutipath-don-t-close-fd-on-dm_lib_release.patch b/0002-libmutipath-don-t-close-fd-on-dm_lib_release.patch new file mode 100644 index 0000000..9a1ce41 --- /dev/null +++ b/0002-libmutipath-don-t-close-fd-on-dm_lib_release.patch @@ -0,0 +1,66 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Sat, 21 Mar 2020 23:49:59 -0500 +Subject: [PATCH] libmutipath: don't close fd on dm_lib_release + +If dm_hold_control_open() isn't set, when dm_lib_release() is called, it +will close the control fd. The control fd will get re-opened on the next +dm_task_run() call, but if there is a dm_task_run() call already +in progress in another thread, it can fail. Since many of the +device-mapper callouts happen with the vecs lock held, this wasn't too +noticeable, but there is code that calls dm_task_run() without the +vecs lock held, notably the dmevent waiter code. + +Since, as Martin pointed out, dm_hold_control_open() hasn't always +existed in libdevmapper, check if it's supported on compilation, +and update the version requirements if so. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/Makefile | 4 ++++ + libmultipath/devmapper.c | 7 ++++++- + 2 files changed, 10 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/Makefile b/libmultipath/Makefile +index e5651e49..ad690a49 100644 +--- a/libmultipath/Makefile ++++ b/libmultipath/Makefile +@@ -36,6 +36,10 @@ ifneq ($(call check_func,dm_task_deferred_remove,/usr/include/libdevmapper.h),0) + CFLAGS += -DLIBDM_API_DEFERRED + endif + ++ifneq ($(call check_func,dm_hold_control_dev,/usr/include/libdevmapper.h),0) ++ CFLAGS += -DLIBDM_API_HOLD_CONTROL ++endif ++ + OBJS = memory.o parser.o vector.o devmapper.o callout.o \ + hwtable.o blacklist.o util.o dmparser.o config.o \ + structs.o discovery.o propsel.o dict.o \ +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index bed8ddc6..13a1cf53 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -108,7 +108,9 @@ dm_lib_prereq (void) + { + char version[64]; + int v[3]; +-#if defined(LIBDM_API_DEFERRED) ++#if defined(LIBDM_API_HOLD_CONTROL) ++ int minv[3] = {1, 2, 111}; ++#elif defined(LIBDM_API_DEFERRED) + int minv[3] = {1, 2, 89}; + #elif defined(DM_SUBSYSTEM_UDEV_FLAG0) + int minv[3] = {1, 2, 82}; +@@ -254,6 +256,9 @@ void libmp_dm_init(void) + memcpy(conf->version, version, sizeof(version)); + put_multipath_config(conf); + dm_init(verbosity); ++#ifdef LIBDM_API_HOLD_CONTROL ++ dm_hold_control_dev(1); ++#endif + dm_udev_set_sync_support(libmp_dm_udev_sync); + } + +-- +2.17.2 + diff --git a/0003-libmultipath-allow-force-reload-with-no-active-paths.patch b/0003-libmultipath-allow-force-reload-with-no-active-paths.patch new file mode 100644 index 0000000..a6efaaa --- /dev/null +++ b/0003-libmultipath-allow-force-reload-with-no-active-paths.patch @@ -0,0 +1,64 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 19 Mar 2020 22:17:51 -0500 +Subject: [PATCH] libmultipath: allow force reload with no active paths + +If the partition information has changed on multipath devices (say, +because it was updated on another node that has access to the same +storage), users expect that running "multipathd reconfigure" will update +that. However, if the checkers for the multipath device are pending for +too long when the the device is reconfigured, multipathd will give up +waiting for them, and refuse to reload the device, since there are no +active paths. This means that no kpartx update will be triggered. + +Multipath is fully capable of reloading a multipath device that has no +active paths. This has been possible for years. If multipath is supposed +to reload the device, it should do so, even if there are no active paths. + +Generally, when multipath is force reloaded, kpartx will be updated. +However when a device is reloaded with no paths, the udev rules won't +run kpartx. But they also weren't running kpartx when the first valid +path appeared, even though the dm activation rules get run in this case. +This changes 11-dm-mpath.rules to run kpartx when a device goes from no +usable paths to having usable paths. + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/configure.c | 6 ------ + multipath/11-dm-mpath.rules | 2 +- + 2 files changed, 1 insertion(+), 7 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index c95848a0..96c79610 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -710,12 +710,6 @@ select_action (struct multipath * mpp, vector curmp, int force_reload) + return; + } + +- if (pathcount(mpp, PATH_UP) == 0) { +- mpp->action = ACT_IMPOSSIBLE; +- condlog(3, "%s: set ACT_IMPOSSIBLE (no usable path)", +- mpp->alias); +- return; +- } + if (force_reload) { + mpp->force_udev_reload = 1; + mpp->action = ACT_RELOAD; +diff --git a/multipath/11-dm-mpath.rules b/multipath/11-dm-mpath.rules +index 07320a14..cd522e8c 100644 +--- a/multipath/11-dm-mpath.rules ++++ b/multipath/11-dm-mpath.rules +@@ -75,7 +75,7 @@ ENV{MPATH_DEVICE_READY}=="0", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1" + ENV{MPATH_DEVICE_READY}!="0", ENV{.MPATH_DEVICE_READY_OLD}=="0",\ + ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="$env{DM_DISABLE_OTHER_RULES_FLAG_OLD}",\ + ENV{DM_DISABLE_OTHER_RULES_FLAG_OLD}="",\ +- ENV{DM_ACTIVATION}="1" ++ ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0" + + # The code to check multipath state ends here. We need to set + # properties and symlinks regardless whether the map is usable or +-- +2.17.2 + diff --git a/0003-tests-add-path-grouping-policy-unit-tests.patch b/0003-tests-add-path-grouping-policy-unit-tests.patch deleted file mode 100644 index e6478c0..0000000 --- a/0003-tests-add-path-grouping-policy-unit-tests.patch +++ /dev/null @@ -1,749 +0,0 @@ -From a8f8ac6519aa46c4514c0f16073c2c6a7cb48a6a Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 9 Jul 2019 16:31:25 -0500 -Subject: [PATCH] tests: add path grouping policy unit tests. - -In preparation for changing the path grouping code, add some unit tests -to verify that it works correctly. The only test that currently fails -(and so it being skipped) is using MULTIBUS when mp->paths is empty. All -the other path grouping policies free mp->paths, even if it is empty. -one_group() should as well. This will be fixed when the path grouping -code is updated. - -Signed-off-by: Benjamin Marzinski ---- - tests/Makefile | 2 +- - tests/pgpolicy.c | 708 +++++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 709 insertions(+), 1 deletion(-) - create mode 100644 tests/pgpolicy.c - -diff --git a/tests/Makefile b/tests/Makefile -index bf159b2d..a5cdf390 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 blacklist unaligned vpd -+TESTS := uevent parser util dmevents hwtable blacklist unaligned vpd pgpolicy - - .SILENT: $(TESTS:%=%.o) - .PRECIOUS: $(TESTS:%=%-test) -diff --git a/tests/pgpolicy.c b/tests/pgpolicy.c -new file mode 100644 -index 00000000..fbb8589e ---- /dev/null -+++ b/tests/pgpolicy.c -@@ -0,0 +1,708 @@ -+/* -+ * 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 -+#include -+#include -+ -+#include "globals.c" -+#include "pgpolicies.h" -+ -+struct multipath mp8, mp4, mp1, mp0, mp_null; -+struct path p8[8], p4[4], p1[1]; -+ -+ -+static void set_priority(struct path *pp, int *prio, int size) -+{ -+ int i; -+ -+ for (i = 0; i < size; i++) { -+ pp[i].priority = prio[i]; -+ } -+} -+ -+static void set_tgt_node_name(struct path *pp, char **tgt_node_name, int size) -+{ -+ int i; -+ -+ for (i = 0; i < size; i++) { -+ strcpy(pp[i].tgt_node_name, tgt_node_name[i]); -+ } -+} -+ -+static void set_serial(struct path *pp, char **serial, int size) -+{ -+ int i; -+ -+ for (i = 0; i < size; i++) { -+ strcpy(pp[i].serial, serial[i]); -+ } -+} -+ -+static int setup(void **state) -+{ -+ int i; -+ -+ for (i = 0; i < 8; i++) { -+ sprintf(p8[i].dev, "p8_%d", i); -+ sprintf(p8[i].dev_t, "8:%d", i); -+ p8[i].state = PATH_UP; -+ } -+ for (i = 0; i < 4; i++) { -+ sprintf(p4[i].dev, "p4_%d", i); -+ sprintf(p4[i].dev_t, "4:%d", i); -+ p4[i].state = PATH_UP; -+ } -+ sprintf(p1[0].dev, "p1_0"); -+ sprintf(p1[0].dev_t, "4:0"); -+ p1[0].state = PATH_UP; -+ return 0; -+} -+ -+static int setupX(struct multipath *mp, struct path *pp, int size) -+{ -+ int i; -+ int prio[8] = {10, 10, 10, 10, 10, 10, 10, 10}; -+ -+ mp->paths = vector_alloc(); -+ if (!mp->paths) -+ return -1; -+ for (i = 0; i < size; i++) { -+ if (!vector_alloc_slot(mp->paths)) -+ return -1; -+ vector_set_slot(mp->paths, &pp[i]); -+ } -+ set_priority(pp, prio, size); -+ return 0; -+} -+ -+static int setup8(void **state) -+{ -+ return setupX(&mp8, p8, 8); -+} -+ -+static int setup4(void **state) -+{ -+ return setupX(&mp4, p4, 4); -+} -+ -+static int setup1(void **state) -+{ -+ return setupX(&mp1, p1, 1); -+} -+ -+static int setup0(void **state) -+{ -+ return setupX(&mp0, NULL, 0); -+} -+ -+static int setup_null(void **state) -+{ -+ return 0; -+} -+ -+static int teardownX(struct multipath *mp) -+{ -+ free_pgvec(mp->pg, KEEP_PATHS); -+ mp->pg = NULL; -+ return 0; -+} -+ -+static int teardown8(void **state) -+{ -+ return teardownX(&mp8); -+} -+ -+static int teardown4(void **state) -+{ -+ return teardownX(&mp4); -+} -+ -+static int teardown1(void **state) -+{ -+ return teardownX(&mp1); -+} -+ -+static int teardown0(void **state) -+{ -+ return teardownX(&mp0); -+} -+ -+static int teardown_null(void **state) -+{ -+ return teardownX(&mp_null); -+} -+ -+static void -+verify_pathgroups(struct multipath *mp, struct path *pp, int **groups, -+ int *group_size, int size) -+{ -+ int i, j; -+ struct pathgroup *pgp; -+ -+ assert_null(mp->paths); -+ assert_non_null(mp->pg); -+ assert_int_equal(VECTOR_SIZE(mp->pg), size); -+ for (i = 0; i < size; i++) { -+ pgp = VECTOR_SLOT(mp->pg, i); -+ assert_non_null(pgp); -+ assert_non_null(pgp->paths); -+ assert_int_equal(VECTOR_SIZE(pgp->paths), group_size[i]); -+ for (j = 0; j < group_size[i]; j++) { -+ int path_nr = groups[i][j]; -+ struct path *pgp_path = VECTOR_SLOT(pgp->paths, j); -+ struct path *pp_path = &pp[path_nr]; -+ /* Test names instead of pointers to get a more -+ * useful error message */ -+ assert_string_equal(pgp_path->dev, pp_path->dev); -+ /* This test is just a backkup in case the -+ * something wenth wrong naming the paths */ -+ assert_ptr_equal(pgp_path, pp_path); -+ } -+ } -+} -+ -+static void test_one_group8(void **state) -+{ -+ int paths[] = {0,1,2,3,4,5,6,7}; -+ int *groups[] = {paths}; -+ int group_size[] = {8}; -+ -+ assert_int_equal(one_group(&mp8), 0); -+ verify_pathgroups(&mp8, p8, groups, group_size, 1); -+} -+ -+static void test_one_group4(void **state) -+{ -+ int paths[] = {0,1,2,3}; -+ int *groups[] = {paths}; -+ int group_size[] = {4}; -+ -+ assert_int_equal(one_group(&mp4), 0); -+ verify_pathgroups(&mp4, p4, groups, group_size, 1); -+} -+ -+static void test_one_group1(void **state) -+{ -+ int paths[] = {0}; -+ int *groups[] = {paths}; -+ int group_size[] = {1}; -+ -+ assert_int_equal(one_group(&mp1), 0); -+ verify_pathgroups(&mp1, p1, groups, group_size, 1); -+} -+ -+static void test_one_group0(void **state) -+{ -+ assert_int_equal(one_group(&mp0), 0); -+ skip(); /* BROKEN */ -+ verify_pathgroups(&mp0, NULL, NULL, NULL, 0); -+} -+ -+static void test_one_group_null(void **state) -+{ -+ assert_int_equal(one_group(&mp_null), 0); -+ verify_pathgroups(&mp_null, NULL, NULL, NULL, 0); -+} -+ -+static void test_one_path_per_group_same8(void **state) -+{ -+ int paths[] = {0,1,2,3,4,5,6,7}; -+ int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3], -+ &paths[4], &paths[5], &paths[6], &paths[7]}; -+ int group_size[] = {1,1,1,1,1,1,1,1}; -+ -+ assert_int_equal(one_path_per_group(&mp8), 0); -+ verify_pathgroups(&mp8, p8, groups, group_size, 8); -+} -+ -+static void test_one_path_per_group_increasing8(void **state) -+{ -+ int prio[] = {1,2,3,4,5,6,7,8}; -+ int paths[] = {7,6,5,4,3,2,1,0}; -+ int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3], -+ &paths[4], &paths[5], &paths[6], &paths[7]}; -+ int group_size[] = {1,1,1,1,1,1,1,1}; -+ -+ set_priority(p8, prio, 8); -+ assert_int_equal(one_path_per_group(&mp8), 0); -+ verify_pathgroups(&mp8, p8, groups, group_size, 8); -+} -+ -+static void test_one_path_per_group_decreasing8(void **state) -+{ -+ int prio[] = {8,7,6,5,4,3,2,1}; -+ int paths[] = {0,1,2,3,4,5,6,7}; -+ int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3], -+ &paths[4], &paths[5], &paths[6], &paths[7]}; -+ int group_size[] = {1,1,1,1,1,1,1,1}; -+ -+ set_priority(p8, prio, 8); -+ assert_int_equal(one_path_per_group(&mp8), 0); -+ verify_pathgroups(&mp8, p8, groups, group_size, 8); -+} -+ -+static void test_one_path_per_group_mixed8(void **state) -+{ -+ int prio[] = {7,1,3,3,5,2,8,2}; -+ int paths[] = {6,0,4,2,3,5,7,1}; -+ int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3], -+ &paths[4], &paths[5], &paths[6], &paths[7]}; -+ int group_size[] = {1,1,1,1,1,1,1,1}; -+ -+ set_priority(p8, prio, 8); -+ assert_int_equal(one_path_per_group(&mp8), 0); -+ verify_pathgroups(&mp8, p8, groups, group_size, 8); -+} -+ -+static void test_one_path_per_group4(void **state) -+{ -+ int paths[] = {0,1,2,3}; -+ int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3]}; -+ int group_size[] = {1,1,1,1}; -+ -+ assert_int_equal(one_path_per_group(&mp4), 0); -+ verify_pathgroups(&mp4, p4, groups, group_size, 4); -+} -+ -+static void test_one_path_per_group1(void **state) -+{ -+ int paths[] = {0}; -+ int *groups[] = {paths}; -+ int group_size[] = {1}; -+ -+ assert_int_equal(one_path_per_group(&mp1), 0); -+ verify_pathgroups(&mp1, p1, groups, group_size, 1); -+} -+ -+static void test_one_path_per_group0(void **state) -+{ -+ assert_int_equal(one_path_per_group(&mp0), 0); -+ verify_pathgroups(&mp0, NULL, NULL, NULL, 0); -+} -+ -+static void test_one_path_per_group_null(void **state) -+{ -+ assert_int_equal(one_path_per_group(&mp_null), 0); -+ verify_pathgroups(&mp_null, NULL, NULL, NULL, 0); -+} -+ -+static void test_group_by_prio_same8(void **state) -+{ -+ int paths[] = {0,1,2,3,4,5,6,7}; -+ int *groups[] = {paths}; -+ int group_size[] = {8}; -+ -+ assert_int_equal(group_by_prio(&mp8), 0); -+ verify_pathgroups(&mp8, p8, groups, group_size, 1); -+} -+ -+static void test_group_by_prio_increasing8(void **state) -+{ -+ int prio[] = {1,2,3,4,5,6,7,8}; -+ int paths[] = {7,6,5,4,3,2,1,0}; -+ int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3], -+ &paths[4], &paths[5], &paths[6], &paths[7]}; -+ int group_size[] = {1,1,1,1,1,1,1,1}; -+ -+ set_priority(p8, prio, 8); -+ assert_int_equal(group_by_prio(&mp8), 0); -+ verify_pathgroups(&mp8, p8, groups, group_size, 8); -+} -+ -+static void test_group_by_prio_decreasing8(void **state) -+{ -+ int prio[] = {8,7,6,5,4,3,2,1}; -+ int paths[] = {0,1,2,3,4,5,6,7}; -+ int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3], -+ &paths[4], &paths[5], &paths[6], &paths[7]}; -+ int group_size[] = {1,1,1,1,1,1,1,1}; -+ -+ set_priority(p8, prio, 8); -+ assert_int_equal(group_by_prio(&mp8), 0); -+ verify_pathgroups(&mp8, p8, groups, group_size, 8); -+} -+ -+static void test_group_by_prio_mixed8(void **state) -+{ -+ int prio[] = {7,1,3,3,5,2,8,2}; -+ int group0[] = {6}; -+ int group1[] = {0}; -+ int group2[] = {4}; -+ int group3[] = {2,3}; -+ int group4[] = {5,7}; -+ int group5[] = {1}; -+ int *groups[] = {group0, group1, group2, group3, -+ group4, group5}; -+ int group_size[] = {1,1,1,2,2,1}; -+ -+ set_priority(p8, prio, 8); -+ assert_int_equal(group_by_prio(&mp8), 0); -+ verify_pathgroups(&mp8, p8, groups, group_size, 6); -+} -+ -+static void test_group_by_prio_2_groups8(void **state) -+{ -+ int prio[] = {1,2,2,1,2,1,1,2}; -+ int group0[] = {1,2,4,7}; -+ int group1[] = {0,3,5,6}; -+ int *groups[] = {group0, group1}; -+ int group_size[] = {4,4}; -+ -+ set_priority(p8, prio, 8); -+ assert_int_equal(group_by_prio(&mp8), 0); -+ verify_pathgroups(&mp8, p8, groups, group_size, 2); -+} -+ -+static void test_group_by_prio_mixed4(void **state) -+{ -+ int prio[] = {2,3,1,3}; -+ int group0[] = {1,3}; -+ int group1[] = {0}; -+ int group2[] = {2}; -+ int *groups[] = {group0, group1, group2}; -+ int group_size[] = {2,1,1}; -+ -+ set_priority(p4, prio, 4); -+ assert_int_equal(group_by_prio(&mp4), 0); -+ verify_pathgroups(&mp4, p4, groups, group_size, 3); -+} -+ -+static void test_group_by_prio_2_groups4(void **state) -+{ -+ int prio[] = {2,1,1,2}; -+ int group0[] = {0,3}; -+ int group1[] = {1,2}; -+ int *groups[] = {group0, group1}; -+ int group_size[] = {2,2}; -+ -+ set_priority(p4, prio, 4); -+ assert_int_equal(group_by_prio(&mp4), 0); -+ verify_pathgroups(&mp4, p4, groups, group_size, 2); -+} -+ -+static void test_group_by_prio1(void **state) -+{ -+ int paths[] = {0}; -+ int *groups[] = {paths}; -+ int group_size[] = {1}; -+ -+ assert_int_equal(group_by_prio(&mp1), 0); -+ verify_pathgroups(&mp1, p1, groups, group_size, 1); -+} -+ -+static void test_group_by_prio0(void **state) -+{ -+ assert_int_equal(group_by_prio(&mp0), 0); -+ verify_pathgroups(&mp0, NULL, NULL, NULL, 0); -+} -+ -+static void test_group_by_prio_null(void **state) -+{ -+ assert_int_equal(group_by_prio(&mp_null), 0); -+ verify_pathgroups(&mp_null, NULL, NULL, NULL, 0); -+} -+ -+static void test_group_by_node_name_same8(void **state) -+{ -+ char *node_name[] = {"a","a","a","a","a","a","a","a"}; -+ int paths[] = {0,1,2,3,4,5,6,7}; -+ int *groups[] = {paths}; -+ int group_size[] = {8}; -+ -+ set_tgt_node_name(p8, node_name, 8); -+ assert_int_equal(group_by_node_name(&mp8), 0); -+ verify_pathgroups(&mp8, p8, groups, group_size, 1); -+} -+ -+static void test_group_by_node_name_increasing8(void **state) -+{ -+ char *node_name[] = {"a","b","c","d","e","f","g","h"}; -+ int prio[] = {1,2,3,4,5,6,7,8}; -+ int paths[] = {7,6,5,4,3,2,1,0}; -+ int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3], -+ &paths[4], &paths[5], &paths[6], &paths[7]}; -+ int group_size[] = {1,1,1,1,1,1,1,1}; -+ -+ set_priority(p8, prio, 8); -+ set_tgt_node_name(p8, node_name, 8); -+ assert_int_equal(group_by_node_name(&mp8), 0); -+ verify_pathgroups(&mp8, p8, groups, group_size, 8); -+} -+ -+static void test_group_by_node_name_3_groups8(void **state) -+{ -+ char *node_name[] = {"a","b","a","c","b","c","c","a"}; -+ int prio[] = {4,1,4,1,1,1,1,4}; -+ int group0[] = {0,2,7}; -+ int group1[] = {3,5,6}; -+ int group2[] = {1,4}; -+ int *groups[] = {group0, group1, group2}; -+ int group_size[] = {3,3,2}; -+ -+ set_priority(p8, prio, 8); -+ set_tgt_node_name(p8, node_name, 8); -+ assert_int_equal(group_by_node_name(&mp8), 0); -+ verify_pathgroups(&mp8, p8, groups, group_size, 3); -+} -+ -+static void test_group_by_node_name_2_groups8(void **state) -+{ -+ char *node_name[] = {"a", "a", "b", "a", "b", "b", "b", "a"}; -+ int prio[] = {4,1,2,1,2,2,2,1}; -+ int group0[] = {2,4,5,6}; -+ int group1[] = {0,1,3,7}; -+ int *groups[] = {group0, group1}; -+ int group_size[] = {4,4}; -+ -+ set_priority(p8, prio, 8); -+ set_tgt_node_name(p8, node_name, 8); -+ assert_int_equal(group_by_node_name(&mp8), 0); -+ verify_pathgroups(&mp8, p8, groups, group_size, 2); -+} -+ -+static void test_group_by_node_name_3_groups4(void **state) -+{ -+ char *node_name[] = {"a","b","c","a"}; -+ int prio[] = {3,1,3,1}; -+ int group0[] = {2}; -+ int group1[] = {0,3}; -+ int group2[] = {1}; -+ int *groups[] = {group0, group1, group2}; -+ int group_size[] = {1,2,1}; -+ -+ set_priority(p4, prio, 4); -+ set_tgt_node_name(p4, node_name, 4); -+ assert_int_equal(group_by_node_name(&mp4), 0); -+ verify_pathgroups(&mp4, p4, groups, group_size, 3); -+} -+ -+static void test_group_by_node_name_2_groups4(void **state) -+{ -+ char *node_name[] = {"a","b","b","a"}; -+ int prio[] = {2,1,1,2}; -+ int group0[] = {0,3}; -+ int group1[] = {1,2}; -+ int *groups[] = {group0, group1}; -+ int group_size[] = {2,2}; -+ -+ set_priority(p4, prio, 4); -+ set_tgt_node_name(p4, node_name, 4); -+ assert_int_equal(group_by_node_name(&mp4), 0); -+ verify_pathgroups(&mp4, p4, groups, group_size, 2); -+} -+ -+static void test_group_by_node_name1(void **state) -+{ -+ char *node_name[] = {"a"}; -+ int paths[] = {0}; -+ int *groups[] = {paths}; -+ int group_size[] = {1}; -+ -+ set_tgt_node_name(p1, node_name, 1); -+ assert_int_equal(group_by_node_name(&mp1), 0); -+ verify_pathgroups(&mp1, p1, groups, group_size, 1); -+} -+ -+static void test_group_by_node_name0(void **state) -+{ -+ assert_int_equal(group_by_node_name(&mp0), 0); -+ verify_pathgroups(&mp0, NULL, NULL, NULL, 0); -+} -+ -+static void test_group_by_node_name_null(void **state) -+{ -+ assert_int_equal(group_by_node_name(&mp_null), 0); -+ verify_pathgroups(&mp_null, NULL, NULL, NULL, 0); -+} -+ -+static void test_group_by_serial_same8(void **state) -+{ -+ char *serial[] = {"1","1","1","1","1","1","1","1"}; -+ int paths[] = {0,1,2,3,4,5,6,7}; -+ int *groups[] = {paths}; -+ int group_size[] = {8}; -+ -+ set_serial(p8, serial, 8); -+ assert_int_equal(group_by_serial(&mp8), 0); -+ verify_pathgroups(&mp8, p8, groups, group_size, 1); -+} -+ -+static void test_group_by_serial_increasing8(void **state) -+{ -+ char *serial[] = {"1","2","3","4","5","6","7","8"}; -+ int prio[] = {1,2,3,4,5,6,7,8}; -+ int paths[] = {7,6,5,4,3,2,1,0}; -+ int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3], -+ &paths[4], &paths[5], &paths[6], &paths[7]}; -+ int group_size[] = {1,1,1,1,1,1,1,1}; -+ -+ set_priority(p8, prio, 8); -+ set_serial(p8, serial, 8); -+ assert_int_equal(group_by_serial(&mp8), 0); -+ verify_pathgroups(&mp8, p8, groups, group_size, 8); -+} -+ -+static void test_group_by_serial_3_groups8(void **state) -+{ -+ char *serial[] = {"1","2","1","3","2","3","2","1"}; -+ int prio[] = {4,1,4,3,1,3,1,4}; -+ int group0[] = {0,2,7}; -+ int group1[] = {3,5}; -+ int group2[] = {1,4,6}; -+ int *groups[] = {group0, group1, group2}; -+ int group_size[] = {3,2,3}; -+ -+ set_priority(p8, prio, 8); -+ set_serial(p8, serial, 8); -+ assert_int_equal(group_by_serial(&mp8), 0); -+ verify_pathgroups(&mp8, p8, groups, group_size, 3); -+} -+ -+static void test_group_by_serial_2_groups8(void **state) -+{ -+ char *serial[] = {"1", "2", "1", "1", "2", "2", "1", "2"}; -+ int prio[] = {3,2,2,1,2,2,1,2}; -+ int group0[] = {1,4,5,7}; -+ int group1[] = {0,2,3,6}; -+ int *groups[] = {group0, group1}; -+ int group_size[] = {4,4}; -+ -+ set_priority(p8, prio, 8); -+ set_serial(p8, serial, 8); -+ assert_int_equal(group_by_serial(&mp8), 0); -+ verify_pathgroups(&mp8, p8, groups, group_size, 2); -+} -+ -+static void test_group_by_serial_3_groups4(void **state) -+{ -+ char *serial[] = {"1","2","3","2"}; -+ int prio[] = {3,1,3,1}; -+ int group0[] = {0}; -+ int group1[] = {2}; -+ int group2[] = {1,3}; -+ int *groups[] = {group0, group1, group2}; -+ int group_size[] = {1,1,2}; -+ -+ set_priority(p4, prio, 4); -+ set_serial(p4, serial, 4); -+ assert_int_equal(group_by_serial(&mp4), 0); -+ verify_pathgroups(&mp4, p4, groups, group_size, 3); -+} -+ -+static void test_group_by_serial_2_groups4(void **state) -+{ -+ char *serial[] = {"1","2","1","2"}; -+ int prio[] = {3,1,3,1}; -+ int group0[] = {0,2}; -+ int group1[] = {1,3}; -+ int *groups[] = {group0, group1}; -+ int group_size[] = {2,2}; -+ -+ set_priority(p4, prio, 4); -+ set_serial(p4, serial, 4); -+ assert_int_equal(group_by_serial(&mp4), 0); -+ verify_pathgroups(&mp4, p4, groups, group_size, 2); -+} -+ -+static void test_group_by_serial1(void **state) -+{ -+ char *serial[1] = {"1"}; -+ int paths[1] = {0}; -+ int *groups[1] = {paths}; -+ int group_size[1] = {1}; -+ -+ set_serial(p1, serial, 1); -+ assert_int_equal(group_by_serial(&mp1), 0); -+ verify_pathgroups(&mp1, p1, groups, group_size, 1); -+} -+ -+static void test_group_by_serial0(void **state) -+{ -+ assert_int_equal(group_by_serial(&mp0), 0); -+ verify_pathgroups(&mp0, NULL, NULL, NULL, 0); -+} -+ -+static void test_group_by_serial_null(void **state) -+{ -+ assert_int_equal(group_by_serial(&mp_null), 0); -+ verify_pathgroups(&mp_null, NULL, NULL, NULL, 0); -+} -+ -+#define setup_test(name, nr) \ -+cmocka_unit_test_setup_teardown(name ## nr, setup ## nr, teardown ## nr) -+ -+int test_pgpolicies(void) -+{ -+ const struct CMUnitTest tests[] = { -+ setup_test(test_one_group, 8), -+ setup_test(test_one_group, 4), -+ setup_test(test_one_group, 1), -+ setup_test(test_one_group, 0), -+ setup_test(test_one_group, _null), -+ setup_test(test_one_path_per_group_same, 8), -+ setup_test(test_one_path_per_group_increasing, 8), -+ setup_test(test_one_path_per_group_decreasing, 8), -+ setup_test(test_one_path_per_group_mixed, 8), -+ setup_test(test_one_path_per_group, 4), -+ setup_test(test_one_path_per_group, 1), -+ setup_test(test_one_path_per_group, 0), -+ setup_test(test_one_path_per_group, _null), -+ setup_test(test_group_by_prio_same, 8), -+ setup_test(test_group_by_prio_increasing, 8), -+ setup_test(test_group_by_prio_decreasing, 8), -+ setup_test(test_group_by_prio_mixed, 8), -+ setup_test(test_group_by_prio_2_groups, 8), -+ setup_test(test_group_by_prio_mixed, 4), -+ setup_test(test_group_by_prio_2_groups, 4), -+ setup_test(test_group_by_prio, 1), -+ setup_test(test_group_by_prio, 0), -+ setup_test(test_group_by_prio, _null), -+ setup_test(test_group_by_node_name_same, 8), -+ setup_test(test_group_by_node_name_increasing, 8), -+ setup_test(test_group_by_node_name_3_groups, 8), -+ setup_test(test_group_by_node_name_2_groups, 8), -+ setup_test(test_group_by_node_name_3_groups, 4), -+ setup_test(test_group_by_node_name_2_groups, 4), -+ setup_test(test_group_by_node_name, 1), -+ setup_test(test_group_by_node_name, 0), -+ setup_test(test_group_by_node_name, _null), -+ setup_test(test_group_by_serial_same, 8), -+ setup_test(test_group_by_serial_increasing, 8), -+ setup_test(test_group_by_serial_3_groups, 8), -+ setup_test(test_group_by_serial_2_groups, 8), -+ setup_test(test_group_by_serial_3_groups, 4), -+ setup_test(test_group_by_serial_2_groups, 4), -+ setup_test(test_group_by_serial, 1), -+ setup_test(test_group_by_serial, 0), -+ setup_test(test_group_by_serial, _null), -+ }; -+ return cmocka_run_group_tests(tests, setup, NULL); -+} -+ -+int main(void) -+{ -+ int ret = 0; -+ -+ ret += test_pgpolicies(); -+ return ret; -+} --- -2.17.2 - diff --git a/0004-libmpathpersist-depend-on-libmultipath.patch b/0004-libmpathpersist-depend-on-libmultipath.patch new file mode 100644 index 0000000..47aad9b --- /dev/null +++ b/0004-libmpathpersist-depend-on-libmultipath.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Christian Hesse +Date: Wed, 6 May 2020 09:35:47 +0200 +Subject: [PATCH] libmpathpersist: depend on libmultipath + +Without this the build fails with: + +/usr/bin/ld: cannot find -lmultipath + +Signed-off-by: Christian Hesse +Signed-off-by: Benjamin Marzinski +--- + Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile b/Makefile +index 1dee3680..ba1d73ba 100644 +--- a/Makefile ++++ b/Makefile +@@ -28,7 +28,7 @@ all: $(BUILDDIRS) + $(BUILDDIRS): + $(MAKE) -C $@ + +-multipath multipathd mpathpersist: libmultipath ++libmpathpersist multipath multipathd mpathpersist: libmultipath + mpathpersist: libmpathpersist + + $(BUILDDIRS.clean): +-- +2.17.2 + diff --git a/0004-libmultipath-add-wrapper-function-around-pgpolicyfn.patch b/0004-libmultipath-add-wrapper-function-around-pgpolicyfn.patch deleted file mode 100644 index 2dac911..0000000 --- a/0004-libmultipath-add-wrapper-function-around-pgpolicyfn.patch +++ /dev/null @@ -1,260 +0,0 @@ -From cc1f4c53100ae50e0fba379c40ac8e1fe72c1fb1 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 2 Jul 2019 16:28:16 -0500 -Subject: [PATCH] libmultipath: add wrapper function around pgpolicyfn - -group_paths() is a wrapper around the pgpolicy functions, that pulls out -the common code from the beginning and the end. For this to work, -one_group() needs to change how it sets up the pathgroups vector to work -like the other pgpolicy functions. This does means that the pathgroups -in group_by_prio are now needlessly sorted afterwards. That will be -dealt with in a later patch. Also, since store_pathgroup() is only -called by add_pathgroup(), it doesn't need to exist as a seperate -function. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 2 +- - libmultipath/pgpolicies.c | 83 ++++++++++++++------------------------- - libmultipath/pgpolicies.h | 2 +- - libmultipath/structs.c | 16 ++------ - libmultipath/structs.h | 1 - - 5 files changed, 35 insertions(+), 69 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index b09ef529..3c309d64 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -387,7 +387,7 @@ int setup_map(struct multipath *mpp, char *params, int params_size, - vector_free(mpp->pg); - mpp->pg = NULL; - } -- if (mpp->pgpolicyfn && mpp->pgpolicyfn(mpp)) -+ if (group_paths(mpp)) - return 1; - - /* -diff --git a/libmultipath/pgpolicies.c b/libmultipath/pgpolicies.c -index 660768a4..1b59485c 100644 ---- a/libmultipath/pgpolicies.c -+++ b/libmultipath/pgpolicies.c -@@ -84,6 +84,26 @@ sort_pathgroups (struct multipath *mp) { - } - - -+int group_paths(struct multipath *mp) -+{ -+ if (!mp->pg) -+ mp->pg = vector_alloc(); -+ if (!mp->pg) -+ return 1; -+ -+ if (VECTOR_SIZE(mp->paths) > 0 && -+ (!mp->pgpolicyfn || mp->pgpolicyfn(mp))) { -+ vector_free(mp->pg); -+ mp->pg = NULL; -+ return 1; -+ } -+ -+ sort_pathgroups(mp); -+ vector_free(mp->paths); -+ mp->paths = NULL; -+ return 0; -+} -+ - /* - * One path group per unique tgt_node_name present in the path vector - */ -@@ -95,12 +115,6 @@ int group_by_node_name(struct multipath * mp) - struct pathgroup * pgp; - struct path * pp2; - -- if (!mp->pg) -- mp->pg = vector_alloc(); -- -- if (!mp->pg) -- return 1; -- - /* init the bitmap */ - bitmap = (int *)MALLOC(VECTOR_SIZE(mp->paths) * sizeof (int)); - -@@ -146,9 +160,6 @@ int group_by_node_name(struct multipath * mp) - } - } - FREE(bitmap); -- sort_pathgroups(mp); -- free_pathvec(mp->paths, KEEP_PATHS); -- mp->paths = NULL; - return 0; - out2: - free_pathgroup(pgp, KEEP_PATHS); -@@ -171,12 +182,6 @@ int group_by_serial(struct multipath * mp) - struct pathgroup * pgp; - struct path * pp2; - -- if (!mp->pg) -- mp->pg = vector_alloc(); -- -- if (!mp->pg) -- return 1; -- - /* init the bitmap */ - bitmap = (int *)MALLOC(VECTOR_SIZE(mp->paths) * sizeof (int)); - -@@ -221,9 +226,6 @@ int group_by_serial(struct multipath * mp) - } - } - FREE(bitmap); -- sort_pathgroups(mp); -- free_pathvec(mp->paths, KEEP_PATHS); -- mp->paths = NULL; - return 0; - out2: - free_pathgroup(pgp, KEEP_PATHS); -@@ -241,12 +243,6 @@ int one_path_per_group(struct multipath *mp) - struct path * pp; - struct pathgroup * pgp; - -- if (!mp->pg) -- mp->pg = vector_alloc(); -- -- if (!mp->pg) -- return 1; -- - for (i = 0; i < VECTOR_SIZE(mp->paths); i++) { - pp = VECTOR_SLOT(mp->paths, i); - pgp = alloc_pathgroup(); -@@ -260,9 +256,6 @@ int one_path_per_group(struct multipath *mp) - if (store_path(pgp->paths, pp)) - goto out1; - } -- sort_pathgroups(mp); -- free_pathvec(mp->paths, KEEP_PATHS); -- mp->paths = NULL; - return 0; - out1: - free_pathgroup(pgp, KEEP_PATHS); -@@ -274,32 +267,24 @@ out: - - int one_group(struct multipath *mp) /* aka multibus */ - { -+ int i; -+ struct path * pp; - struct pathgroup * pgp; - -- if (VECTOR_SIZE(mp->paths) < 0) -- return 0; -+ pgp = alloc_pathgroup(); - -- if (!mp->pg) -- mp->pg = vector_alloc(); -+ if (!pgp) -+ goto out; - -- if (!mp->pg) -- return 1; -+ if (add_pathgroup(mp, pgp)) -+ goto out1; - -- if (VECTOR_SIZE(mp->paths) > 0) { -- pgp = alloc_pathgroup(); -+ for (i = 0; i < VECTOR_SIZE(mp->paths); i++) { -+ pp = VECTOR_SLOT(mp->paths, i); - -- if (!pgp) -+ if (store_path(pgp->paths, pp)) - goto out; -- -- vector_free(pgp->paths); -- -- if (add_pathgroup(mp, pgp)) -- goto out1; -- -- pgp->paths = mp->paths; -- mp->paths = NULL; - } -- - return 0; - out1: - free_pathgroup(pgp, KEEP_PATHS); -@@ -317,12 +302,6 @@ int group_by_prio(struct multipath *mp) - struct pathgroup * pgp; - vector pathvec = NULL; - -- if (!mp->pg) -- mp->pg = vector_alloc(); -- -- if (!mp->pg) -- return 1; -- - pathvec = vector_alloc(); - if (!pathvec) - goto out; -@@ -387,8 +366,6 @@ int group_by_prio(struct multipath *mp) - } - } - free_pathvec(pathvec, KEEP_PATHS); -- free_pathvec(mp->paths, KEEP_PATHS); -- mp->paths = NULL; - return 0; - out2: - free_pathgroup(pgp, KEEP_PATHS); -diff --git a/libmultipath/pgpolicies.h b/libmultipath/pgpolicies.h -index c0eaa7f4..11834011 100644 ---- a/libmultipath/pgpolicies.h -+++ b/libmultipath/pgpolicies.h -@@ -21,7 +21,7 @@ enum iopolicies { - - int get_pgpolicy_id(char *); - int get_pgpolicy_name (char *, int, int); -- -+int group_paths(struct multipath *); - /* - * policies - */ -diff --git a/libmultipath/structs.c b/libmultipath/structs.c -index fee899bd..bf7fdd73 100644 ---- a/libmultipath/structs.c -+++ b/libmultipath/structs.c -@@ -318,23 +318,13 @@ store_path (vector pathvec, struct path * pp) - return 0; - } - --int --store_pathgroup (vector pgvec, struct pathgroup * pgp) -+int add_pathgroup(struct multipath *mpp, struct pathgroup *pgp) - { -- if (!vector_alloc_slot(pgvec)) -+ if (!vector_alloc_slot(mpp->pg)) - return 1; - -- vector_set_slot(pgvec, pgp); -- -- return 0; --} -- --int add_pathgroup(struct multipath *mpp, struct pathgroup *pgp) --{ -- int ret = store_pathgroup(mpp->pg, pgp); -+ vector_set_slot(mpp->pg, pgp); - -- if (ret) -- return ret; - pgp->mpp = mpp; - return 0; - } -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index 1a3d827b..893074eb 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -445,7 +445,6 @@ int store_adaptergroup(vector adapters, struct adapter_group *agp); - int store_hostgroup(vector hostgroupvec, struct host_group *hgp); - - int store_path (vector pathvec, struct path * pp); --int store_pathgroup (vector pgvec, struct pathgroup * pgp); - int add_pathgroup(struct multipath*, struct pathgroup *); - - struct multipath * find_mp_by_alias (const struct _vector *mp, const char *alias); --- -2.17.2 - diff --git a/0005-multipath-tools-Makefile-more-dependency-fixes-for-p.patch b/0005-multipath-tools-Makefile-more-dependency-fixes-for-p.patch new file mode 100644 index 0000000..c75ba30 --- /dev/null +++ b/0005-multipath-tools-Makefile-more-dependency-fixes-for-p.patch @@ -0,0 +1,34 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 12 May 2020 00:39:21 +0200 +Subject: [PATCH] multipath-tools: Makefile: more dependency fixes for parallel + build + +Extend the late fixes from Christian. + +Cc: Christian Hesse +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + Makefile | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/Makefile b/Makefile +index ba1d73ba..fec3b73b 100644 +--- a/Makefile ++++ b/Makefile +@@ -28,8 +28,9 @@ all: $(BUILDDIRS) + $(BUILDDIRS): + $(MAKE) -C $@ + +-libmpathpersist multipath multipathd mpathpersist: libmultipath +-mpathpersist: libmpathpersist ++libmultipath libdmmp: libmpathcmd ++libmpathpersist multipath multipathd: libmultipath ++mpathpersist multipathd: libmpathpersist + + $(BUILDDIRS.clean): + $(MAKE) -C ${@:.clean=} clean +-- +2.17.2 + diff --git a/0005-tests-update-pgpolicy-tests-to-work-with-group_paths.patch b/0005-tests-update-pgpolicy-tests-to-work-with-group_paths.patch deleted file mode 100644 index b304fcd..0000000 --- a/0005-tests-update-pgpolicy-tests-to-work-with-group_paths.patch +++ /dev/null @@ -1,420 +0,0 @@ -From 03741e7467fdef6cd2fc91457a406ad60047f50e Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 9 Jul 2019 17:41:32 -0500 -Subject: [PATCH] tests: update pgpolicy tests to work with group_paths() - -The pgpolicy unit tests now work again, using group_paths(). -test_one_group0(), which was skipped with the old path grouping code -because it failed, is now working correctly. - -Signed-off-by: Benjamin Marzinski ---- - tests/pgpolicy.c | 125 +++++++++++++++++++++++++++++++---------------- - 1 file changed, 83 insertions(+), 42 deletions(-) - -diff --git a/tests/pgpolicy.c b/tests/pgpolicy.c -index fbb8589e..04a77c4c 100644 ---- a/tests/pgpolicy.c -+++ b/tests/pgpolicy.c -@@ -92,6 +92,7 @@ static int setupX(struct multipath *mp, struct path *pp, int size) - vector_set_slot(mp->paths, &pp[i]); - } - set_priority(pp, prio, size); -+ mp->pgpolicyfn = NULL; - return 0; - } - -@@ -187,7 +188,8 @@ static void test_one_group8(void **state) - int *groups[] = {paths}; - int group_size[] = {8}; - -- assert_int_equal(one_group(&mp8), 0); -+ mp8.pgpolicyfn = one_group; -+ assert_int_equal(group_paths(&mp8), 0); - verify_pathgroups(&mp8, p8, groups, group_size, 1); - } - -@@ -197,7 +199,8 @@ static void test_one_group4(void **state) - int *groups[] = {paths}; - int group_size[] = {4}; - -- assert_int_equal(one_group(&mp4), 0); -+ mp4.pgpolicyfn = one_group; -+ assert_int_equal(group_paths(&mp4), 0); - verify_pathgroups(&mp4, p4, groups, group_size, 1); - } - -@@ -207,20 +210,22 @@ static void test_one_group1(void **state) - int *groups[] = {paths}; - int group_size[] = {1}; - -- assert_int_equal(one_group(&mp1), 0); -+ mp1.pgpolicyfn = one_group; -+ assert_int_equal(group_paths(&mp1), 0); - verify_pathgroups(&mp1, p1, groups, group_size, 1); - } - - static void test_one_group0(void **state) - { -- assert_int_equal(one_group(&mp0), 0); -- skip(); /* BROKEN */ -+ mp0.pgpolicyfn = one_group; -+ assert_int_equal(group_paths(&mp0), 0); - verify_pathgroups(&mp0, NULL, NULL, NULL, 0); - } - - static void test_one_group_null(void **state) - { -- assert_int_equal(one_group(&mp_null), 0); -+ mp_null.pgpolicyfn = one_group; -+ assert_int_equal(group_paths(&mp_null), 0); - verify_pathgroups(&mp_null, NULL, NULL, NULL, 0); - } - -@@ -231,7 +236,8 @@ static void test_one_path_per_group_same8(void **state) - &paths[4], &paths[5], &paths[6], &paths[7]}; - int group_size[] = {1,1,1,1,1,1,1,1}; - -- assert_int_equal(one_path_per_group(&mp8), 0); -+ mp8.pgpolicyfn = one_path_per_group; -+ assert_int_equal(group_paths(&mp8), 0); - verify_pathgroups(&mp8, p8, groups, group_size, 8); - } - -@@ -244,7 +250,8 @@ static void test_one_path_per_group_increasing8(void **state) - int group_size[] = {1,1,1,1,1,1,1,1}; - - set_priority(p8, prio, 8); -- assert_int_equal(one_path_per_group(&mp8), 0); -+ mp8.pgpolicyfn = one_path_per_group; -+ assert_int_equal(group_paths(&mp8), 0); - verify_pathgroups(&mp8, p8, groups, group_size, 8); - } - -@@ -257,7 +264,8 @@ static void test_one_path_per_group_decreasing8(void **state) - int group_size[] = {1,1,1,1,1,1,1,1}; - - set_priority(p8, prio, 8); -- assert_int_equal(one_path_per_group(&mp8), 0); -+ mp8.pgpolicyfn = one_path_per_group; -+ assert_int_equal(group_paths(&mp8), 0); - verify_pathgroups(&mp8, p8, groups, group_size, 8); - } - -@@ -270,7 +278,8 @@ static void test_one_path_per_group_mixed8(void **state) - int group_size[] = {1,1,1,1,1,1,1,1}; - - set_priority(p8, prio, 8); -- assert_int_equal(one_path_per_group(&mp8), 0); -+ mp8.pgpolicyfn = one_path_per_group; -+ assert_int_equal(group_paths(&mp8), 0); - verify_pathgroups(&mp8, p8, groups, group_size, 8); - } - -@@ -280,7 +289,8 @@ static void test_one_path_per_group4(void **state) - int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3]}; - int group_size[] = {1,1,1,1}; - -- assert_int_equal(one_path_per_group(&mp4), 0); -+ mp4.pgpolicyfn = one_path_per_group; -+ assert_int_equal(group_paths(&mp4), 0); - verify_pathgroups(&mp4, p4, groups, group_size, 4); - } - -@@ -290,19 +300,22 @@ static void test_one_path_per_group1(void **state) - int *groups[] = {paths}; - int group_size[] = {1}; - -- assert_int_equal(one_path_per_group(&mp1), 0); -+ mp1.pgpolicyfn = one_path_per_group; -+ assert_int_equal(group_paths(&mp1), 0); - verify_pathgroups(&mp1, p1, groups, group_size, 1); - } - - static void test_one_path_per_group0(void **state) - { -- assert_int_equal(one_path_per_group(&mp0), 0); -+ mp0.pgpolicyfn = one_path_per_group; -+ assert_int_equal(group_paths(&mp0), 0); - verify_pathgroups(&mp0, NULL, NULL, NULL, 0); - } - - static void test_one_path_per_group_null(void **state) - { -- assert_int_equal(one_path_per_group(&mp_null), 0); -+ mp_null.pgpolicyfn = one_path_per_group; -+ assert_int_equal(group_paths(&mp_null), 0); - verify_pathgroups(&mp_null, NULL, NULL, NULL, 0); - } - -@@ -312,7 +325,8 @@ static void test_group_by_prio_same8(void **state) - int *groups[] = {paths}; - int group_size[] = {8}; - -- assert_int_equal(group_by_prio(&mp8), 0); -+ mp8.pgpolicyfn = group_by_prio; -+ assert_int_equal(group_paths(&mp8), 0); - verify_pathgroups(&mp8, p8, groups, group_size, 1); - } - -@@ -325,7 +339,8 @@ static void test_group_by_prio_increasing8(void **state) - int group_size[] = {1,1,1,1,1,1,1,1}; - - set_priority(p8, prio, 8); -- assert_int_equal(group_by_prio(&mp8), 0); -+ mp8.pgpolicyfn = group_by_prio; -+ assert_int_equal(group_paths(&mp8), 0); - verify_pathgroups(&mp8, p8, groups, group_size, 8); - } - -@@ -338,7 +353,8 @@ static void test_group_by_prio_decreasing8(void **state) - int group_size[] = {1,1,1,1,1,1,1,1}; - - set_priority(p8, prio, 8); -- assert_int_equal(group_by_prio(&mp8), 0); -+ mp8.pgpolicyfn = group_by_prio; -+ assert_int_equal(group_paths(&mp8), 0); - verify_pathgroups(&mp8, p8, groups, group_size, 8); - } - -@@ -356,7 +372,8 @@ static void test_group_by_prio_mixed8(void **state) - int group_size[] = {1,1,1,2,2,1}; - - set_priority(p8, prio, 8); -- assert_int_equal(group_by_prio(&mp8), 0); -+ mp8.pgpolicyfn = group_by_prio; -+ assert_int_equal(group_paths(&mp8), 0); - verify_pathgroups(&mp8, p8, groups, group_size, 6); - } - -@@ -369,7 +386,8 @@ static void test_group_by_prio_2_groups8(void **state) - int group_size[] = {4,4}; - - set_priority(p8, prio, 8); -- assert_int_equal(group_by_prio(&mp8), 0); -+ mp8.pgpolicyfn = group_by_prio; -+ assert_int_equal(group_paths(&mp8), 0); - verify_pathgroups(&mp8, p8, groups, group_size, 2); - } - -@@ -383,7 +401,8 @@ static void test_group_by_prio_mixed4(void **state) - int group_size[] = {2,1,1}; - - set_priority(p4, prio, 4); -- assert_int_equal(group_by_prio(&mp4), 0); -+ mp4.pgpolicyfn = group_by_prio; -+ assert_int_equal(group_paths(&mp4), 0); - verify_pathgroups(&mp4, p4, groups, group_size, 3); - } - -@@ -396,7 +415,8 @@ static void test_group_by_prio_2_groups4(void **state) - int group_size[] = {2,2}; - - set_priority(p4, prio, 4); -- assert_int_equal(group_by_prio(&mp4), 0); -+ mp4.pgpolicyfn = group_by_prio; -+ assert_int_equal(group_paths(&mp4), 0); - verify_pathgroups(&mp4, p4, groups, group_size, 2); - } - -@@ -406,19 +426,22 @@ static void test_group_by_prio1(void **state) - int *groups[] = {paths}; - int group_size[] = {1}; - -- assert_int_equal(group_by_prio(&mp1), 0); -+ mp1.pgpolicyfn = group_by_prio; -+ assert_int_equal(group_paths(&mp1), 0); - verify_pathgroups(&mp1, p1, groups, group_size, 1); - } - - static void test_group_by_prio0(void **state) - { -- assert_int_equal(group_by_prio(&mp0), 0); -+ mp0.pgpolicyfn = group_by_prio; -+ assert_int_equal(group_paths(&mp0), 0); - verify_pathgroups(&mp0, NULL, NULL, NULL, 0); - } - - static void test_group_by_prio_null(void **state) - { -- assert_int_equal(group_by_prio(&mp_null), 0); -+ mp_null.pgpolicyfn = group_by_prio; -+ assert_int_equal(group_paths(&mp_null), 0); - verify_pathgroups(&mp_null, NULL, NULL, NULL, 0); - } - -@@ -430,7 +453,8 @@ static void test_group_by_node_name_same8(void **state) - int group_size[] = {8}; - - set_tgt_node_name(p8, node_name, 8); -- assert_int_equal(group_by_node_name(&mp8), 0); -+ mp8.pgpolicyfn = group_by_node_name; -+ assert_int_equal(group_paths(&mp8), 0); - verify_pathgroups(&mp8, p8, groups, group_size, 1); - } - -@@ -445,7 +469,8 @@ static void test_group_by_node_name_increasing8(void **state) - - set_priority(p8, prio, 8); - set_tgt_node_name(p8, node_name, 8); -- assert_int_equal(group_by_node_name(&mp8), 0); -+ mp8.pgpolicyfn = group_by_node_name; -+ assert_int_equal(group_paths(&mp8), 0); - verify_pathgroups(&mp8, p8, groups, group_size, 8); - } - -@@ -461,7 +486,8 @@ static void test_group_by_node_name_3_groups8(void **state) - - set_priority(p8, prio, 8); - set_tgt_node_name(p8, node_name, 8); -- assert_int_equal(group_by_node_name(&mp8), 0); -+ mp8.pgpolicyfn = group_by_node_name; -+ assert_int_equal(group_paths(&mp8), 0); - verify_pathgroups(&mp8, p8, groups, group_size, 3); - } - -@@ -476,7 +502,8 @@ static void test_group_by_node_name_2_groups8(void **state) - - set_priority(p8, prio, 8); - set_tgt_node_name(p8, node_name, 8); -- assert_int_equal(group_by_node_name(&mp8), 0); -+ mp8.pgpolicyfn = group_by_node_name; -+ assert_int_equal(group_paths(&mp8), 0); - verify_pathgroups(&mp8, p8, groups, group_size, 2); - } - -@@ -492,7 +519,8 @@ static void test_group_by_node_name_3_groups4(void **state) - - set_priority(p4, prio, 4); - set_tgt_node_name(p4, node_name, 4); -- assert_int_equal(group_by_node_name(&mp4), 0); -+ mp4.pgpolicyfn = group_by_node_name; -+ assert_int_equal(group_paths(&mp4), 0); - verify_pathgroups(&mp4, p4, groups, group_size, 3); - } - -@@ -507,7 +535,8 @@ static void test_group_by_node_name_2_groups4(void **state) - - set_priority(p4, prio, 4); - set_tgt_node_name(p4, node_name, 4); -- assert_int_equal(group_by_node_name(&mp4), 0); -+ mp4.pgpolicyfn = group_by_node_name; -+ assert_int_equal(group_paths(&mp4), 0); - verify_pathgroups(&mp4, p4, groups, group_size, 2); - } - -@@ -519,19 +548,22 @@ static void test_group_by_node_name1(void **state) - int group_size[] = {1}; - - set_tgt_node_name(p1, node_name, 1); -- assert_int_equal(group_by_node_name(&mp1), 0); -+ mp1.pgpolicyfn = group_by_node_name; -+ assert_int_equal(group_paths(&mp1), 0); - verify_pathgroups(&mp1, p1, groups, group_size, 1); - } - - static void test_group_by_node_name0(void **state) - { -- assert_int_equal(group_by_node_name(&mp0), 0); -+ mp0.pgpolicyfn = group_by_node_name; -+ assert_int_equal(group_paths(&mp0), 0); - verify_pathgroups(&mp0, NULL, NULL, NULL, 0); - } - - static void test_group_by_node_name_null(void **state) - { -- assert_int_equal(group_by_node_name(&mp_null), 0); -+ mp_null.pgpolicyfn = group_by_node_name; -+ assert_int_equal(group_paths(&mp_null), 0); - verify_pathgroups(&mp_null, NULL, NULL, NULL, 0); - } - -@@ -543,7 +575,8 @@ static void test_group_by_serial_same8(void **state) - int group_size[] = {8}; - - set_serial(p8, serial, 8); -- assert_int_equal(group_by_serial(&mp8), 0); -+ mp8.pgpolicyfn = group_by_serial; -+ assert_int_equal(group_paths(&mp8), 0); - verify_pathgroups(&mp8, p8, groups, group_size, 1); - } - -@@ -558,7 +591,8 @@ static void test_group_by_serial_increasing8(void **state) - - set_priority(p8, prio, 8); - set_serial(p8, serial, 8); -- assert_int_equal(group_by_serial(&mp8), 0); -+ mp8.pgpolicyfn = group_by_serial; -+ assert_int_equal(group_paths(&mp8), 0); - verify_pathgroups(&mp8, p8, groups, group_size, 8); - } - -@@ -574,7 +608,8 @@ static void test_group_by_serial_3_groups8(void **state) - - set_priority(p8, prio, 8); - set_serial(p8, serial, 8); -- assert_int_equal(group_by_serial(&mp8), 0); -+ mp8.pgpolicyfn = group_by_serial; -+ assert_int_equal(group_paths(&mp8), 0); - verify_pathgroups(&mp8, p8, groups, group_size, 3); - } - -@@ -589,7 +624,8 @@ static void test_group_by_serial_2_groups8(void **state) - - set_priority(p8, prio, 8); - set_serial(p8, serial, 8); -- assert_int_equal(group_by_serial(&mp8), 0); -+ mp8.pgpolicyfn = group_by_serial; -+ assert_int_equal(group_paths(&mp8), 0); - verify_pathgroups(&mp8, p8, groups, group_size, 2); - } - -@@ -605,7 +641,8 @@ static void test_group_by_serial_3_groups4(void **state) - - set_priority(p4, prio, 4); - set_serial(p4, serial, 4); -- assert_int_equal(group_by_serial(&mp4), 0); -+ mp4.pgpolicyfn = group_by_serial; -+ assert_int_equal(group_paths(&mp4), 0); - verify_pathgroups(&mp4, p4, groups, group_size, 3); - } - -@@ -620,7 +657,8 @@ static void test_group_by_serial_2_groups4(void **state) - - set_priority(p4, prio, 4); - set_serial(p4, serial, 4); -- assert_int_equal(group_by_serial(&mp4), 0); -+ mp4.pgpolicyfn = group_by_serial; -+ assert_int_equal(group_paths(&mp4), 0); - verify_pathgroups(&mp4, p4, groups, group_size, 2); - } - -@@ -632,19 +670,22 @@ static void test_group_by_serial1(void **state) - int group_size[1] = {1}; - - set_serial(p1, serial, 1); -- assert_int_equal(group_by_serial(&mp1), 0); -+ mp1.pgpolicyfn = group_by_serial; -+ assert_int_equal(group_paths(&mp1), 0); - verify_pathgroups(&mp1, p1, groups, group_size, 1); - } - - static void test_group_by_serial0(void **state) - { -- assert_int_equal(group_by_serial(&mp0), 0); -+ mp0.pgpolicyfn = group_by_serial; -+ assert_int_equal(group_paths(&mp0), 0); - verify_pathgroups(&mp0, NULL, NULL, NULL, 0); - } - - static void test_group_by_serial_null(void **state) - { -- assert_int_equal(group_by_serial(&mp_null), 0); -+ mp_null.pgpolicyfn = group_by_serial; -+ assert_int_equal(group_paths(&mp_null), 0); - verify_pathgroups(&mp_null, NULL, NULL, NULL, 0); - } - --- -2.17.2 - diff --git a/0006-libmultipath-fix-double-free-in-pgpolicyfn-error-pat.patch b/0006-libmultipath-fix-double-free-in-pgpolicyfn-error-pat.patch deleted file mode 100644 index d0f32d3..0000000 --- a/0006-libmultipath-fix-double-free-in-pgpolicyfn-error-pat.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 3209740e5a3e80b5f76dbc2ddaa63f2045aafd53 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 2 Jul 2019 17:30:32 -0500 -Subject: [PATCH] libmultipath: fix double free in pgpolicyfn error paths - -In the pgpolicy functions, if an error is encountered after -alloc_pathgroup() is called, but before the path group is added to a -multipath device with add_pathgroup(), the pathgroup needs to be cleaned -up by calling free_pathgroup(). However, after the pathgroup has been -added to the multipath device, calling free_pgvec() will clean it up. In -this case, if free_pathgroup() is called first, the recently added -pathgroup will be freed twice. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/pgpolicies.c | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - -diff --git a/libmultipath/pgpolicies.c b/libmultipath/pgpolicies.c -index 1b59485c..1af42f52 100644 ---- a/libmultipath/pgpolicies.c -+++ b/libmultipath/pgpolicies.c -@@ -139,7 +139,7 @@ int group_by_node_name(struct multipath * mp) - - /* feed the first path */ - if (store_path(pgp->paths, pp)) -- goto out2; -+ goto out1; - - bitmap[i] = 1; - -@@ -153,7 +153,7 @@ int group_by_node_name(struct multipath * mp) - if (!strncmp(pp->tgt_node_name, pp2->tgt_node_name, - NODE_NAME_SIZE)) { - if (store_path(pgp->paths, pp2)) -- goto out2; -+ goto out1; - - bitmap[j] = 1; - } -@@ -206,7 +206,7 @@ int group_by_serial(struct multipath * mp) - - /* feed the first path */ - if (store_path(pgp->paths, pp)) -- goto out2; -+ goto out1; - - bitmap[i] = 1; - -@@ -219,7 +219,7 @@ int group_by_serial(struct multipath * mp) - - if (0 == strcmp(pp->serial, pp2->serial)) { - if (store_path(pgp->paths, pp2)) -- goto out2; -+ goto out1; - - bitmap[j] = 1; - } -@@ -254,7 +254,7 @@ int one_path_per_group(struct multipath *mp) - goto out1; - - if (store_path(pgp->paths, pp)) -- goto out1; -+ goto out; - } - return 0; - out1: -@@ -358,7 +358,7 @@ int group_by_prio(struct multipath *mp) - vector_foreach_slot(pathvec, pp, i) { - if (pp->priority == prio) { - if (store_path(pgp->paths, pp)) -- goto out2; -+ goto out1; - - vector_del_slot(pathvec, i); - i--; --- -2.17.2 - diff --git a/0006-multipath-tools-Makefile.inc-set-Wno-error-clobbered.patch b/0006-multipath-tools-Makefile.inc-set-Wno-error-clobbered.patch new file mode 100644 index 0000000..1ad917f --- /dev/null +++ b/0006-multipath-tools-Makefile.inc-set-Wno-error-clobbered.patch @@ -0,0 +1,33 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 12 May 2020 00:39:24 +0200 +Subject: [PATCH] multipath-tools: Makefile.inc: set -Wno-error=clobbered + +We need to ignore -Wclobbered because gcc has trouble dealing with glibc's +implementation of pthread_cleanup_push(). + +For some variants of gcc, -Wno-clobbered alone isn't enough if -Werror is also +set. Compilation with -Wno-error=clobbered works, though. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile.inc b/Makefile.inc +index d4d1e0dd..9060ac9b 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -91,7 +91,7 @@ TEST_CC_OPTION = $(shell \ + + STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector) + ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers,) +-WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered,) ++WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered -Wno-error=clobbered,) + + OPTFLAGS = -O2 -g -pipe -Werror -Wall -Wextra -Wformat=2 -Werror=implicit-int \ + -Werror=implicit-function-declaration -Werror=format-security \ +-- +2.17.2 + diff --git a/0007-libmultipath-consolidate-group_by_-functions.patch b/0007-libmultipath-consolidate-group_by_-functions.patch deleted file mode 100644 index 98929d1..0000000 --- a/0007-libmultipath-consolidate-group_by_-functions.patch +++ /dev/null @@ -1,253 +0,0 @@ -From 9cccb06523154911282fd5b0840c6cfa6edd017e Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 3 Jul 2019 14:46:40 -0500 -Subject: [PATCH] libmultipath: consolidate group_by_* functions - -group_by_node_name() and group_by_serial() are exactly the same except -for how the paths are compared. group_by_prio() is different but its -pathvec solves the same issue as the bitmap from the other two -functions, and since we are always running sort_pathgroups() after -calling pgpriorityfn, there is no need to sort the pathgroups in -group_by_prio(). This means that all three functions can be replaced -with one function, group_by_match() that takes a match function as an -argument. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/pgpolicies.c | 189 +++++++++----------------------------- - 1 file changed, 41 insertions(+), 148 deletions(-) - -diff --git a/libmultipath/pgpolicies.c b/libmultipath/pgpolicies.c -index 1af42f52..2e4db74c 100644 ---- a/libmultipath/pgpolicies.c -+++ b/libmultipath/pgpolicies.c -@@ -4,6 +4,7 @@ - #include - #include - #include -+#include - - #include "checkers.h" - #include "util.h" -@@ -104,10 +105,29 @@ int group_paths(struct multipath *mp) - return 0; - } - --/* -- * One path group per unique tgt_node_name present in the path vector -- */ --int group_by_node_name(struct multipath * mp) -+typedef bool (path_match_fn)(struct path *pp1, struct path *pp2); -+ -+bool -+node_names_match(struct path *pp1, struct path *pp2) -+{ -+ return (strncmp(pp1->tgt_node_name, pp2->tgt_node_name, -+ NODE_NAME_SIZE) == 0); -+} -+ -+bool -+serials_match(struct path *pp1, struct path *pp2) -+{ -+ return (strncmp(pp1->serial, pp2->serial, SERIAL_SIZE) == 0); -+} -+ -+bool -+prios_match(struct path *pp1, struct path *pp2) -+{ -+ return (pp1->priority == pp2->priority); -+} -+ -+int group_by_match(struct multipath * mp, -+ bool (*path_match_fn)(struct path *, struct path *)) - { - int i, j; - int * bitmap; -@@ -150,8 +170,7 @@ int group_by_node_name(struct multipath * mp) - - pp2 = VECTOR_SLOT(mp->paths, j); - -- if (!strncmp(pp->tgt_node_name, pp2->tgt_node_name, -- NODE_NAME_SIZE)) { -+ if (path_match_fn(pp, pp2)) { - if (store_path(pgp->paths, pp2)) - goto out1; - -@@ -171,70 +190,28 @@ out: - return 1; - } - -+/* -+ * One path group per unique tgt_node_name present in the path vector -+ */ -+int group_by_node_name(struct multipath * mp) -+{ -+ return group_by_match(mp, node_names_match); -+} -+ - /* - * One path group per unique serial number present in the path vector - */ - int group_by_serial(struct multipath * mp) - { -- int i, j; -- int * bitmap; -- struct path * pp; -- struct pathgroup * pgp; -- struct path * pp2; -- -- /* init the bitmap */ -- bitmap = (int *)MALLOC(VECTOR_SIZE(mp->paths) * sizeof (int)); -- -- if (!bitmap) -- goto out; -- -- for (i = 0; i < VECTOR_SIZE(mp->paths); i++) { -- -- if (bitmap[i]) -- continue; -- -- pp = VECTOR_SLOT(mp->paths, i); -- -- /* here, we really got a new pg */ -- pgp = alloc_pathgroup(); -- -- if (!pgp) -- goto out1; -- -- if (add_pathgroup(mp, pgp)) -- goto out2; -- -- /* feed the first path */ -- if (store_path(pgp->paths, pp)) -- goto out1; -- -- bitmap[i] = 1; -- -- for (j = i + 1; j < VECTOR_SIZE(mp->paths); j++) { -- -- if (bitmap[j]) -- continue; -- -- pp2 = VECTOR_SLOT(mp->paths, j); -- -- if (0 == strcmp(pp->serial, pp2->serial)) { -- if (store_path(pgp->paths, pp2)) -- goto out1; -+ return group_by_match(mp, serials_match); -+} - -- bitmap[j] = 1; -- } -- } -- } -- FREE(bitmap); -- return 0; --out2: -- free_pathgroup(pgp, KEEP_PATHS); --out1: -- FREE(bitmap); --out: -- free_pgvec(mp->pg, KEEP_PATHS); -- mp->pg = NULL; -- return 1; -+/* -+ * One path group per priority present in the path vector -+ */ -+int group_by_prio(struct multipath *mp) -+{ -+ return group_by_match(mp, prios_match); - } - - int one_path_per_group(struct multipath *mp) -@@ -293,87 +270,3 @@ out: - mp->pg = NULL; - return 1; - } -- --int group_by_prio(struct multipath *mp) --{ -- int i; -- int prio; -- struct path * pp; -- struct pathgroup * pgp; -- vector pathvec = NULL; -- -- pathvec = vector_alloc(); -- if (!pathvec) -- goto out; -- -- vector_foreach_slot(mp->paths, pp, i) { -- if (!vector_alloc_slot(pathvec)) -- goto out1; -- vector_set_slot(pathvec, pp); -- } -- -- while (VECTOR_SIZE(pathvec) > 0) { -- pp = VECTOR_SLOT(pathvec, 0); -- prio = pp->priority; -- -- /* -- * Find the position to insert the new path group. All groups -- * are ordered by the priority value (higher value first). -- */ -- vector_foreach_slot(mp->pg, pgp, i) { -- pp = VECTOR_SLOT(pgp->paths, 0); -- -- if (prio > pp->priority) -- break; -- } -- -- /* -- * Initialize the new path group. -- */ -- pgp = alloc_pathgroup(); -- -- if (!pgp) -- goto out1; -- -- if (store_path(pgp->paths, VECTOR_SLOT(pathvec, 0))) -- goto out2; -- -- vector_del_slot(pathvec, 0); -- -- /* -- * Store the new path group into the vector. -- */ -- if (i < VECTOR_SIZE(mp->pg)) { -- if (!vector_insert_slot(mp->pg, i, pgp)) -- goto out2; -- pgp->mpp = mp; -- } else { -- if (add_pathgroup(mp, pgp)) -- goto out2; -- } -- -- /* -- * add the other paths with the same prio -- */ -- vector_foreach_slot(pathvec, pp, i) { -- if (pp->priority == prio) { -- if (store_path(pgp->paths, pp)) -- goto out1; -- -- vector_del_slot(pathvec, i); -- i--; -- } -- } -- } -- free_pathvec(pathvec, KEEP_PATHS); -- return 0; --out2: -- free_pathgroup(pgp, KEEP_PATHS); --out1: -- free_pathvec(pathvec, KEEP_PATHS); --out: -- free_pgvec(mp->pg, KEEP_PATHS); -- mp->pg = NULL; -- return 1; -- --} --- -2.17.2 - diff --git a/0007-libmultipath-discovery.c-use-z-qualifier-for-size_t.patch b/0007-libmultipath-discovery.c-use-z-qualifier-for-size_t.patch new file mode 100644 index 0000000..b24cca6 --- /dev/null +++ b/0007-libmultipath-discovery.c-use-z-qualifier-for-size_t.patch @@ -0,0 +1,91 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 12 May 2020 00:39:25 +0200 +Subject: [PATCH] libmultipath: discovery.c: use %z qualifier for size_t + +Otherwise compilation for 32bit targets spits out warnings. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/discovery.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index ee3290cd..ffec5162 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -986,7 +986,7 @@ parse_vpd_pg80(const unsigned char *in, char *out, size_t out_len) + } + + if (len >= out_len) { +- condlog(2, "vpd pg80 overflow, %lu/%lu bytes required", ++ condlog(2, "vpd pg80 overflow, %zu/%zu bytes required", + len + 1, out_len); + len = out_len - 1; + } +@@ -1087,7 +1087,7 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, + + len = sprintf(out, "%d", vpd_type); + if (2 * vpd_len >= out_len - len) { +- condlog(1, "%s: WWID overflow, type %d, %lu/%lu bytes required", ++ condlog(1, "%s: WWID overflow, type %d, %zu/%zu bytes required", + __func__, vpd_type, + 2 * vpd_len + len + 1, out_len); + vpd_len = (out_len - len - 1) / 2; +@@ -1096,7 +1096,7 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, + len += sprintf(out + len, + "%02x", vpd[i]); + } else if (vpd_type == 0x8 && vpd_len < 4) { +- condlog(1, "%s: VPD length %lu too small for designator type 8", ++ condlog(1, "%s: VPD length %zu too small for designator type 8", + __func__, vpd_len); + return -EINVAL; + } else if (vpd_type == 0x8) { +@@ -1112,7 +1112,7 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, + while (len > 2 && vpd[len - 2] == '\0') + --len; + if (len > out_len - 1) { +- condlog(1, "%s: WWID overflow, type 8/%c, %lu/%lu bytes required", ++ condlog(1, "%s: WWID overflow, type 8/%c, %zu/%zu bytes required", + __func__, out[0], len + 1, out_len); + len = out_len - 1; + } +@@ -1136,7 +1136,7 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, + while ((p = memchr(vpd, ' ', vpd_len))) { + p_len = p - vpd; + if (len + p_len > out_len - 1) { +- condlog(1, "%s: WWID overflow, type 1, %lu/%lu bytes required", ++ condlog(1, "%s: WWID overflow, type 1, %zu/%zu bytes required", + __func__, len + p_len, out_len); + p_len = out_len - len - 1; + } +@@ -1162,7 +1162,7 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, + p_len = vpd_len; + if (p_len > 0 && len < out_len - 1) { + if (len + p_len > out_len - 1) { +- condlog(1, "%s: WWID overflow, type 1, %lu/%lu bytes required", ++ condlog(1, "%s: WWID overflow, type 1, %zu/%zu bytes required", + __func__, len + p_len + 1, out_len); + p_len = out_len - len - 1; + } +@@ -1186,14 +1186,14 @@ parse_vpd_c0_hp3par(const unsigned char *in, size_t in_len, + + memset(out, 0x0, out_len); + if (in_len <= 4 || (in[4] > 3 && in_len < 44)) { +- condlog(3, "HP/3PAR vendor specific VPD page length too short: %lu", in_len); ++ condlog(3, "HP/3PAR vendor specific VPD page length too short: %zu", in_len); + return -EINVAL; + } + if (in[4] <= 3) /* revision must be > 3 to have Vomlume Name */ + return -ENODATA; + len = get_unaligned_be32(&in[40]); + if (len > out_len || len + 44 > in_len) { +- condlog(3, "HP/3PAR vendor specific Volume name too long: %lu", ++ condlog(3, "HP/3PAR vendor specific Volume name too long: %zu", + len); + return -EINVAL; + } +-- +2.17.2 + diff --git a/0008-libmultipath-eliminate-more-signed-unsigned-comparis.patch b/0008-libmultipath-eliminate-more-signed-unsigned-comparis.patch new file mode 100644 index 0000000..ac5b284 --- /dev/null +++ b/0008-libmultipath-eliminate-more-signed-unsigned-comparis.patch @@ -0,0 +1,185 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 12 May 2020 00:39:26 +0200 +Subject: [PATCH] libmultipath: eliminate more signed/unsigned comparisons + +Fix some more compiler warnings about signed/unsigned comparison. +I've observed these only on 32bit builds, therefore they went unnoticed +before. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/print.c | 12 ++++++------ + libmultipath/prioritizers/alua_spc3.h | 2 +- + multipathd/cli_handlers.c | 20 ++++++++++---------- + multipathd/main.c | 2 +- + 4 files changed, 18 insertions(+), 18 deletions(-) + +diff --git a/libmultipath/print.c b/libmultipath/print.c +index b944ef32..298b3764 100644 +--- a/libmultipath/print.c ++++ b/libmultipath/print.c +@@ -1958,25 +1958,25 @@ char *snprint_config(const struct config *conf, int *len, + } + + c = reply + snprint_defaults(conf, reply, maxlen); +- if ((c - reply) == maxlen) ++ if (c == reply + maxlen) + continue; + + c += snprint_blacklist(conf, c, reply + maxlen - c); +- if ((c - reply) == maxlen) ++ if (c == reply + maxlen) + continue; + + c += snprint_blacklist_except(conf, c, reply + maxlen - c); +- if ((c - reply) == maxlen) ++ if (c == reply + maxlen) + continue; + + c += snprint_hwtable(conf, c, reply + maxlen - c, + hwtable ? hwtable : conf->hwtable); +- if ((c - reply) == maxlen) ++ if (c == reply + maxlen) + continue; + + c += snprint_overrides(conf, c, reply + maxlen - c, + conf->overrides); +- if ((c - reply) == maxlen) ++ if (c == reply + maxlen) + continue; + + if (VECTOR_SIZE(conf->mptable) > 0 || +@@ -1984,7 +1984,7 @@ char *snprint_config(const struct config *conf, int *len, + c += snprint_mptable(conf, c, reply + maxlen - c, + mpvec); + +- if ((c - reply) < maxlen) { ++ if (c < reply + maxlen) { + if (len) + *len = c - reply; + return reply; +diff --git a/libmultipath/prioritizers/alua_spc3.h b/libmultipath/prioritizers/alua_spc3.h +index 18b495ef..7ba2cf4c 100644 +--- a/libmultipath/prioritizers/alua_spc3.h ++++ b/libmultipath/prioritizers/alua_spc3.h +@@ -284,7 +284,7 @@ struct rtpg_data { + #define RTPG_FOR_EACH_PORT_GROUP(p, g) \ + for( \ + g = &(p->data[0]); \ +- (((char *) g) - ((char *) p)) < get_unaligned_be32(p->length); \ ++ ((char *) g) < ((char *) p) + get_unaligned_be32(p->length); \ + g = (struct rtpg_tpg_dscr *) ( \ + ((char *) g) + \ + sizeof(struct rtpg_tpg_dscr) + \ +diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c +index 7d878c88..31c3d9fd 100644 +--- a/multipathd/cli_handlers.c ++++ b/multipathd/cli_handlers.c +@@ -66,7 +66,7 @@ show_paths (char ** r, int * len, struct vectors * vecs, char * style, + c += snprint_foreign_paths(c, reply + maxlen - c, + style, pretty); + +- again = ((c - reply) == (maxlen - 1)); ++ again = (c == reply + maxlen - 1); + + REALLOC_REPLY(reply, again, maxlen); + } +@@ -102,7 +102,7 @@ show_path (char ** r, int * len, struct vectors * vecs, struct path *pp, + + c += snprint_path(c, reply + maxlen - c, style, pp, 0); + +- again = ((c - reply) == (maxlen - 1)); ++ again = (c == reply + maxlen - 1); + + REALLOC_REPLY(reply, again, maxlen); + } +@@ -131,7 +131,7 @@ show_map_topology (char ** r, int * len, struct multipath * mpp, + c = reply; + + c += snprint_multipath_topology(c, reply + maxlen - c, mpp, 2); +- again = ((c - reply) == (maxlen - 1)); ++ again = (c == reply + maxlen - 1); + + REALLOC_REPLY(reply, again, maxlen); + } +@@ -171,7 +171,7 @@ show_maps_topology (char ** r, int * len, struct vectors * vecs) + } + c += snprint_foreign_topology(c, reply + maxlen - c, 2); + +- again = ((c - reply) == (maxlen - 1)); ++ again = (c == reply + maxlen - 1); + + REALLOC_REPLY(reply, again, maxlen); + } +@@ -209,7 +209,7 @@ show_maps_json (char ** r, int * len, struct vectors * vecs) + c = reply; + + c += snprint_multipath_topology_json(c, maxlen, vecs); +- again = ((c - reply) == maxlen); ++ again = (c == reply + maxlen); + + REALLOC_REPLY(reply, again, maxlen); + } +@@ -238,7 +238,7 @@ show_map_json (char ** r, int * len, struct multipath * mpp, + c = reply; + + c += snprint_multipath_map_json(c, maxlen, mpp); +- again = ((c - reply) == maxlen); ++ again = (c == reply + maxlen); + + REALLOC_REPLY(reply, again, maxlen); + } +@@ -487,7 +487,7 @@ show_map (char ** r, int *len, struct multipath * mpp, char * style, + c += snprint_multipath(c, reply + maxlen - c, style, + mpp, pretty); + +- again = ((c - reply) == (maxlen - 1)); ++ again = (c == reply + maxlen - 1); + + REALLOC_REPLY(reply, again, maxlen); + } +@@ -533,7 +533,7 @@ show_maps (char ** r, int *len, struct vectors * vecs, char * style, + } + c += snprint_foreign_multipaths(c, reply + maxlen - c, + style, pretty); +- again = ((c - reply) == (maxlen - 1)); ++ again = (c == reply + maxlen - 1); + + REALLOC_REPLY(reply, again, maxlen); + } +@@ -1297,7 +1297,7 @@ show_blacklist (char ** r, int * len) + + c = reply; + c += snprint_blacklist_report(conf, c, maxlen); +- again = ((c - reply) == maxlen); ++ again = (c == reply + maxlen); + REALLOC_REPLY(reply, again, maxlen); + } + pthread_cleanup_pop(1); +@@ -1339,7 +1339,7 @@ show_devices (char ** r, int * len, struct vectors *vecs) + + c = reply; + c += snprint_devices(conf, c, maxlen, vecs); +- again = ((c - reply) == maxlen); ++ again = (c == reply + maxlen); + REALLOC_REPLY(reply, again, maxlen); + } + pthread_cleanup_pop(1); +diff --git a/multipathd/main.c b/multipathd/main.c +index 8baf9abe..6b7db2c0 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -2374,7 +2374,7 @@ checkerloop (void *ap) + conf = get_multipath_config(); + max_checkint = conf->max_checkint; + put_multipath_config(conf); +- if (diff_time.tv_sec > max_checkint) ++ if (diff_time.tv_sec > (time_t)max_checkint) + condlog(1, "path checkers took longer " + "than %lu seconds, consider " + "increasing max_polling_interval", +-- +2.17.2 + diff --git a/0008-libmultipath-make-pgpolicyfn-take-a-paths-vector.patch b/0008-libmultipath-make-pgpolicyfn-take-a-paths-vector.patch deleted file mode 100644 index 35f96d7..0000000 --- a/0008-libmultipath-make-pgpolicyfn-take-a-paths-vector.patch +++ /dev/null @@ -1,174 +0,0 @@ -From 1e45eb6db98185ac8917c0c8feec69b7c0226230 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 11 Jul 2019 18:13:06 -0500 -Subject: [PATCH] libmultipath: make pgpolicyfn take a paths vector - -To enable future changes, mp->pgpolicyfn() now takes a vector of -paths instead of always using mp->paths. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/pgpolicies.c | 38 +++++++++++++++++++------------------- - libmultipath/pgpolicies.h | 10 +++++----- - libmultipath/structs.h | 2 +- - 3 files changed, 25 insertions(+), 25 deletions(-) - -diff --git a/libmultipath/pgpolicies.c b/libmultipath/pgpolicies.c -index 2e4db74c..2e7c0502 100644 ---- a/libmultipath/pgpolicies.c -+++ b/libmultipath/pgpolicies.c -@@ -93,7 +93,7 @@ int group_paths(struct multipath *mp) - return 1; - - if (VECTOR_SIZE(mp->paths) > 0 && -- (!mp->pgpolicyfn || mp->pgpolicyfn(mp))) { -+ (!mp->pgpolicyfn || mp->pgpolicyfn(mp, mp->paths))) { - vector_free(mp->pg); - mp->pg = NULL; - return 1; -@@ -126,7 +126,7 @@ prios_match(struct path *pp1, struct path *pp2) - return (pp1->priority == pp2->priority); - } - --int group_by_match(struct multipath * mp, -+int group_by_match(struct multipath * mp, vector paths, - bool (*path_match_fn)(struct path *, struct path *)) - { - int i, j; -@@ -136,17 +136,17 @@ int group_by_match(struct multipath * mp, - struct path * pp2; - - /* init the bitmap */ -- bitmap = (int *)MALLOC(VECTOR_SIZE(mp->paths) * sizeof (int)); -+ bitmap = (int *)MALLOC(VECTOR_SIZE(paths) * sizeof (int)); - - if (!bitmap) - goto out; - -- for (i = 0; i < VECTOR_SIZE(mp->paths); i++) { -+ for (i = 0; i < VECTOR_SIZE(paths); i++) { - - if (bitmap[i]) - continue; - -- pp = VECTOR_SLOT(mp->paths, i); -+ pp = VECTOR_SLOT(paths, i); - - /* here, we really got a new pg */ - pgp = alloc_pathgroup(); -@@ -163,12 +163,12 @@ int group_by_match(struct multipath * mp, - - bitmap[i] = 1; - -- for (j = i + 1; j < VECTOR_SIZE(mp->paths); j++) { -+ for (j = i + 1; j < VECTOR_SIZE(paths); j++) { - - if (bitmap[j]) - continue; - -- pp2 = VECTOR_SLOT(mp->paths, j); -+ pp2 = VECTOR_SLOT(paths, j); - - if (path_match_fn(pp, pp2)) { - if (store_path(pgp->paths, pp2)) -@@ -193,35 +193,35 @@ out: - /* - * One path group per unique tgt_node_name present in the path vector - */ --int group_by_node_name(struct multipath * mp) -+int group_by_node_name(struct multipath * mp, vector paths) - { -- return group_by_match(mp, node_names_match); -+ return group_by_match(mp, paths, node_names_match); - } - - /* - * One path group per unique serial number present in the path vector - */ --int group_by_serial(struct multipath * mp) -+int group_by_serial(struct multipath * mp, vector paths) - { -- return group_by_match(mp, serials_match); -+ return group_by_match(mp, paths, serials_match); - } - - /* - * One path group per priority present in the path vector - */ --int group_by_prio(struct multipath *mp) -+int group_by_prio(struct multipath *mp, vector paths) - { -- return group_by_match(mp, prios_match); -+ return group_by_match(mp, paths, prios_match); - } - --int one_path_per_group(struct multipath *mp) -+int one_path_per_group(struct multipath *mp, vector paths) - { - int i; - struct path * pp; - struct pathgroup * pgp; - -- for (i = 0; i < VECTOR_SIZE(mp->paths); i++) { -- pp = VECTOR_SLOT(mp->paths, i); -+ for (i = 0; i < VECTOR_SIZE(paths); i++) { -+ pp = VECTOR_SLOT(paths, i); - pgp = alloc_pathgroup(); - - if (!pgp) -@@ -242,7 +242,7 @@ out: - return 1; - } - --int one_group(struct multipath *mp) /* aka multibus */ -+int one_group(struct multipath *mp, vector paths) /* aka multibus */ - { - int i; - struct path * pp; -@@ -256,8 +256,8 @@ int one_group(struct multipath *mp) /* aka multibus */ - if (add_pathgroup(mp, pgp)) - goto out1; - -- for (i = 0; i < VECTOR_SIZE(mp->paths); i++) { -- pp = VECTOR_SLOT(mp->paths, i); -+ for (i = 0; i < VECTOR_SIZE(paths); i++) { -+ pp = VECTOR_SLOT(paths, i); - - if (store_path(pgp->paths, pp)) - goto out; -diff --git a/libmultipath/pgpolicies.h b/libmultipath/pgpolicies.h -index 11834011..7532d75f 100644 ---- a/libmultipath/pgpolicies.h -+++ b/libmultipath/pgpolicies.h -@@ -25,10 +25,10 @@ int group_paths(struct multipath *); - /* - * policies - */ --int one_path_per_group(struct multipath *); --int one_group(struct multipath *); --int group_by_serial(struct multipath *); --int group_by_prio(struct multipath *); --int group_by_node_name(struct multipath *); -+int one_path_per_group(struct multipath *, vector); -+int one_group(struct multipath *, vector); -+int group_by_serial(struct multipath *, vector); -+int group_by_prio(struct multipath *, vector); -+int group_by_node_name(struct multipath *, vector); - - #endif -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index 893074eb..a8b9d325 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -295,7 +295,7 @@ struct path { - struct gen_path generic_path; - }; - --typedef int (pgpolicyfn) (struct multipath *); -+typedef int (pgpolicyfn) (struct multipath *, vector); - - struct multipath { - char wwid[WWID_SIZE]; --- -2.17.2 - diff --git a/0009-libmultipath-make-group_paths-handle-marginal-paths.patch b/0009-libmultipath-make-group_paths-handle-marginal-paths.patch deleted file mode 100644 index 9791689..0000000 --- a/0009-libmultipath-make-group_paths-handle-marginal-paths.patch +++ /dev/null @@ -1,185 +0,0 @@ -From 227a9fceb8c20f153f4f136caeb28faff5bd80fe Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 12 Jul 2019 15:39:26 -0500 -Subject: [PATCH] libmultipath: make group_paths handle marginal paths - -group_paths() will now create seperate path groups for marginal and -normal paths, and place all of the marginal path groups after the normal -ones, in order by priority. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/pgpolicies.c | 83 +++++++++++++++++++++++++++++++++----- - libmultipath/switchgroup.c | 15 ++++++- - 2 files changed, 88 insertions(+), 10 deletions(-) - -diff --git a/libmultipath/pgpolicies.c b/libmultipath/pgpolicies.c -index 2e7c0502..6fb2d28a 100644 ---- a/libmultipath/pgpolicies.c -+++ b/libmultipath/pgpolicies.c -@@ -72,9 +72,11 @@ sort_pathgroups (struct multipath *mp) { - pgp2 = VECTOR_SLOT(mp->pg, j); - if (!pgp2) - continue; -- if (pgp2->priority > pgp1->priority || -- (pgp2->priority == pgp1->priority && -- pgp2->enabled_paths >= pgp1->enabled_paths)) { -+ if (pgp2->marginal < pgp1->marginal || -+ (pgp2->marginal == pgp1->marginal && -+ (pgp2->priority > pgp1->priority || -+ (pgp2->priority == pgp1->priority && -+ pgp2->enabled_paths >= pgp1->enabled_paths)))) { - vector_move_up(mp->pg, i, j + 1); - break; - } -@@ -84,25 +86,88 @@ sort_pathgroups (struct multipath *mp) { - } - } - -+static int -+split_marginal_paths(vector paths, vector *normal_p, vector *marginal_p) -+{ -+ int i; -+ int has_marginal = 0; -+ int has_normal = 0; -+ struct path *pp; -+ vector normal = NULL; -+ vector marginal = NULL; -+ -+ *normal_p = *marginal_p = NULL; -+ vector_foreach_slot(paths, pp, i) { -+ if (pp->marginal) -+ has_marginal = 1; -+ else -+ has_normal = 1; -+ } -+ -+ if (!has_marginal || !has_normal) -+ return -1; -+ -+ normal = vector_alloc(); -+ marginal = vector_alloc(); -+ if (!normal || !marginal) -+ goto fail; -+ -+ vector_foreach_slot(paths, pp, i) { -+ if (pp->marginal) { -+ if (store_path(marginal, pp)) -+ goto fail; -+ } -+ else { -+ if (store_path(normal, pp)) -+ goto fail; -+ } -+ } -+ *normal_p = normal; -+ *marginal_p = marginal; -+ return 0; -+fail: -+ vector_free(normal); -+ vector_free(marginal); -+ return -1; -+} - - int group_paths(struct multipath *mp) - { -+ vector normal, marginal; -+ - if (!mp->pg) - mp->pg = vector_alloc(); - if (!mp->pg) - return 1; - -- if (VECTOR_SIZE(mp->paths) > 0 && -- (!mp->pgpolicyfn || mp->pgpolicyfn(mp, mp->paths))) { -- vector_free(mp->pg); -- mp->pg = NULL; -- return 1; -+ if (VECTOR_SIZE(mp->paths) == 0) -+ goto out; -+ if (!mp->pgpolicyfn) -+ goto fail; -+ -+ if (split_marginal_paths(mp->paths, &normal, &marginal) != 0) { -+ if (mp->pgpolicyfn(mp, mp->paths) != 0) -+ goto fail; -+ } else { -+ if (mp->pgpolicyfn(mp, normal) != 0) -+ goto fail_marginal; -+ if (mp->pgpolicyfn(mp, marginal) != 0) -+ goto fail_marginal; -+ vector_free(normal); -+ vector_free(marginal); - } -- - sort_pathgroups(mp); -+out: - vector_free(mp->paths); - mp->paths = NULL; - return 0; -+fail_marginal: -+ vector_free(normal); -+ vector_free(marginal); -+fail: -+ vector_free(mp->pg); -+ mp->pg = NULL; -+ return 1; - } - - typedef bool (path_match_fn)(struct path *pp1, struct path *pp2); -diff --git a/libmultipath/switchgroup.c b/libmultipath/switchgroup.c -index 9632ce2d..6fdfcfa7 100644 ---- a/libmultipath/switchgroup.c -+++ b/libmultipath/switchgroup.c -@@ -11,6 +11,7 @@ void path_group_prio_update(struct pathgroup *pgp) - { - int i; - int priority = 0; -+ int marginal = 0; - struct path * pp; - - pgp->enabled_paths = 0; -@@ -19,6 +20,8 @@ void path_group_prio_update(struct pathgroup *pgp) - return; - } - vector_foreach_slot (pgp->paths, pp, i) { -+ if (pp->marginal) -+ marginal++; - if (pp->state == PATH_UP || - pp->state == PATH_GHOST) { - priority += pp->priority; -@@ -29,11 +32,14 @@ void path_group_prio_update(struct pathgroup *pgp) - pgp->priority = priority / pgp->enabled_paths; - else - pgp->priority = 0; -+ if (marginal && marginal == i) -+ pgp->marginal = 1; - } - - int select_path_group(struct multipath *mpp) - { - int i; -+ int normal_pgp = 0; - int max_priority = 0; - int bestpg = 1; - int max_enabled_paths = 1; -@@ -47,8 +53,15 @@ int select_path_group(struct multipath *mpp) - continue; - - path_group_prio_update(pgp); -+ if (pgp->marginal && normal_pgp) -+ continue; - if (pgp->enabled_paths) { -- if (pgp->priority > max_priority) { -+ if (!pgp->marginal && !normal_pgp) { -+ normal_pgp = 1; -+ max_priority = pgp->priority; -+ max_enabled_paths = pgp->enabled_paths; -+ bestpg = i + 1; -+ } else if (pgp->priority > max_priority) { - max_priority = pgp->priority; - max_enabled_paths = pgp->enabled_paths; - bestpg = i + 1; --- -2.17.2 - diff --git a/0009-libmultipath-set_uint-fix-parsing-for-32bit.patch b/0009-libmultipath-set_uint-fix-parsing-for-32bit.patch new file mode 100644 index 0000000..25f83c3 --- /dev/null +++ b/0009-libmultipath-set_uint-fix-parsing-for-32bit.patch @@ -0,0 +1,49 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 12 May 2020 00:39:27 +0200 +Subject: [PATCH] libmultipath: set_uint: fix parsing for 32bit + +On architectures where sizeof(long) == sizeof(int), the code wouldn't +work as intended. Use strtoul instead. As strtoul happily parses +negative numbers as input, require the number to begin with a digit. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/dict.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index 3e25e74f..0e9ea387 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -60,19 +60,22 @@ static int + set_uint(vector strvec, void *ptr) + { + unsigned int *uint_ptr = (unsigned int *)ptr; +- char *buff, *eptr; +- long res; ++ char *buff, *eptr, *p; ++ unsigned long res; + int rc; + + buff = set_value(strvec); + if (!buff) + return 1; + +- res = strtol(buff, &eptr, 10); ++ p = buff; ++ while (isspace(*p)) ++ p++; ++ res = strtoul(p, &eptr, 10); + if (eptr > buff) + while (isspace(*eptr)) + eptr++; +- if (*buff == '\0' || *eptr != '\0' || res < 0 || res > UINT_MAX) { ++ if (*buff == '\0' || *eptr != '\0' || !isdigit(*p) || res > UINT_MAX) { + condlog(1, "%s: invalid value for %s: \"%s\"", + __func__, (char*)VECTOR_SLOT(strvec, 0), buff); + rc = 1; +-- +2.17.2 + diff --git a/0010-multipath-tools-Makefile-add-install-dependency.patch b/0010-multipath-tools-Makefile-add-install-dependency.patch new file mode 100644 index 0000000..ee1da02 --- /dev/null +++ b/0010-multipath-tools-Makefile-add-install-dependency.patch @@ -0,0 +1,33 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 12 May 2020 22:38:22 +0200 +Subject: [PATCH] multipath-tools Makefile: add install dependency + +$(libdir) must exist before running "make install" on prioritizer, checker, +and foreign libraries. + +Cc: Christian Hesse +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + Makefile | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/Makefile b/Makefile +index fec3b73b..8bcaba66 100644 +--- a/Makefile ++++ b/Makefile +@@ -32,6 +32,10 @@ libmultipath libdmmp: libmpathcmd + libmpathpersist multipath multipathd: libmultipath + mpathpersist multipathd: libmpathpersist + ++libmultipath/checkers.install \ ++ libmultipath/prioritizers.install \ ++ libmultipath/foreign.install: libmultipath.install ++ + $(BUILDDIRS.clean): + $(MAKE) -C ${@:.clean=} clean + +-- +2.17.2 + diff --git a/0010-tests-add-tests-for-grouping-marginal-paths.patch b/0010-tests-add-tests-for-grouping-marginal-paths.patch deleted file mode 100644 index aba1563..0000000 --- a/0010-tests-add-tests-for-grouping-marginal-paths.patch +++ /dev/null @@ -1,701 +0,0 @@ -From ede846d1761709e2832c0a4c777369ae89692841 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 23 Jul 2019 13:21:12 -0500 -Subject: [PATCH] tests: add tests for grouping marginal paths. - -Signed-off-by: Benjamin Marzinski ---- - tests/pgpolicy.c | 337 +++++++++++++++++++++++++++++++++++++++++------ - 1 file changed, 295 insertions(+), 42 deletions(-) - -diff --git a/tests/pgpolicy.c b/tests/pgpolicy.c -index 04a77c4c..ab09f91c 100644 ---- a/tests/pgpolicy.c -+++ b/tests/pgpolicy.c -@@ -40,6 +40,15 @@ static void set_priority(struct path *pp, int *prio, int size) - } - } - -+static void set_marginal(struct path *pp, int *marginal, int size) -+{ -+ int i; -+ -+ for (i = 0; i < size; i++) { -+ pp[i].marginal = marginal[i]; -+ } -+} -+ - static void set_tgt_node_name(struct path *pp, char **tgt_node_name, int size) - { - int i; -@@ -82,6 +91,7 @@ static int setupX(struct multipath *mp, struct path *pp, int size) - { - int i; - int prio[8] = {10, 10, 10, 10, 10, 10, 10, 10}; -+ int marginal[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - - mp->paths = vector_alloc(); - if (!mp->paths) -@@ -92,6 +102,7 @@ static int setupX(struct multipath *mp, struct path *pp, int size) - vector_set_slot(mp->paths, &pp[i]); - } - set_priority(pp, prio, size); -+ set_marginal(pp, marginal, size); - mp->pgpolicyfn = NULL; - return 0; - } -@@ -155,7 +166,7 @@ static int teardown_null(void **state) - - static void - verify_pathgroups(struct multipath *mp, struct path *pp, int **groups, -- int *group_size, int size) -+ int *group_size, int *marginal, int size) - { - int i, j; - struct pathgroup *pgp; -@@ -168,6 +179,10 @@ verify_pathgroups(struct multipath *mp, struct path *pp, int **groups, - assert_non_null(pgp); - assert_non_null(pgp->paths); - assert_int_equal(VECTOR_SIZE(pgp->paths), group_size[i]); -+ if (marginal) -+ assert_int_equal(pgp->marginal, marginal[i]); -+ else -+ assert_int_equal(pgp->marginal, 0); - for (j = 0; j < group_size[i]; j++) { - int path_nr = groups[i][j]; - struct path *pgp_path = VECTOR_SLOT(pgp->paths, j); -@@ -190,7 +205,7 @@ static void test_one_group8(void **state) - - mp8.pgpolicyfn = one_group; - assert_int_equal(group_paths(&mp8), 0); -- verify_pathgroups(&mp8, p8, groups, group_size, 1); -+ verify_pathgroups(&mp8, p8, groups, group_size, NULL, 1); - } - - static void test_one_group4(void **state) -@@ -201,7 +216,7 @@ static void test_one_group4(void **state) - - mp4.pgpolicyfn = one_group; - assert_int_equal(group_paths(&mp4), 0); -- verify_pathgroups(&mp4, p4, groups, group_size, 1); -+ verify_pathgroups(&mp4, p4, groups, group_size, NULL, 1); - } - - static void test_one_group1(void **state) -@@ -212,21 +227,65 @@ static void test_one_group1(void **state) - - mp1.pgpolicyfn = one_group; - assert_int_equal(group_paths(&mp1), 0); -- verify_pathgroups(&mp1, p1, groups, group_size, 1); -+ verify_pathgroups(&mp1, p1, groups, group_size, NULL, 1); - } - - static void test_one_group0(void **state) - { - mp0.pgpolicyfn = one_group; - assert_int_equal(group_paths(&mp0), 0); -- verify_pathgroups(&mp0, NULL, NULL, NULL, 0); -+ verify_pathgroups(&mp0, NULL, NULL, NULL, NULL, 0); - } - - static void test_one_group_null(void **state) - { - mp_null.pgpolicyfn = one_group; - assert_int_equal(group_paths(&mp_null), 0); -- verify_pathgroups(&mp_null, NULL, NULL, NULL, 0); -+ verify_pathgroups(&mp_null, NULL, NULL, NULL, NULL, 0); -+} -+ -+static void test_one_group_all_marginal8(void **state) -+{ -+ int paths[] = {0,1,2,3,4,5,6,7}; -+ int marginal[] = {1,1,1,1,1,1,1,1}; -+ int *groups[] = {paths}; -+ int group_size[] = {8}; -+ int group_marginal[] = {1}; -+ -+ set_marginal(p8, marginal, 8); -+ mp8.pgpolicyfn = one_group; -+ assert_int_equal(group_paths(&mp8), 0); -+ verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 1); -+} -+ -+static void test_one_group_half_marginal8(void **state) -+{ -+ int marginal[] = {1,0,1,0,1,1,0,0}; -+ int group0[] = {1,3,6,7}; -+ int group1[] = {0,2,4,5}; -+ int *groups[] = {group0, group1}; -+ int group_size[] = {4,4}; -+ int group_marginal[] = {0,1}; -+ -+ set_marginal(p8, marginal, 8); -+ mp8.pgpolicyfn = one_group; -+ assert_int_equal(group_paths(&mp8), 0); -+ verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 2); -+} -+ -+static void test_one_group_one_marginal8(void **state) -+{ -+ int marginal[] = {0,0,0,0,0,1,0,0}; -+ int group0[] = {0,1,2,3,4,6,7}; -+ int group1[] = {5}; -+ int *groups[] = {group0, group1}; -+ int group_size[] = {7,1}; -+ int group_marginal[] = {0,1}; -+ -+ set_marginal(p8, marginal, 8); -+ mp8.pgpolicyfn = one_group; -+ assert_int_equal(group_paths(&mp8), 0); -+ verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 2); - } - - static void test_one_path_per_group_same8(void **state) -@@ -238,7 +297,7 @@ static void test_one_path_per_group_same8(void **state) - - mp8.pgpolicyfn = one_path_per_group; - assert_int_equal(group_paths(&mp8), 0); -- verify_pathgroups(&mp8, p8, groups, group_size, 8); -+ verify_pathgroups(&mp8, p8, groups, group_size, NULL, 8); - } - - static void test_one_path_per_group_increasing8(void **state) -@@ -252,7 +311,7 @@ static void test_one_path_per_group_increasing8(void **state) - set_priority(p8, prio, 8); - mp8.pgpolicyfn = one_path_per_group; - assert_int_equal(group_paths(&mp8), 0); -- verify_pathgroups(&mp8, p8, groups, group_size, 8); -+ verify_pathgroups(&mp8, p8, groups, group_size, NULL, 8); - } - - static void test_one_path_per_group_decreasing8(void **state) -@@ -266,7 +325,7 @@ static void test_one_path_per_group_decreasing8(void **state) - set_priority(p8, prio, 8); - mp8.pgpolicyfn = one_path_per_group; - assert_int_equal(group_paths(&mp8), 0); -- verify_pathgroups(&mp8, p8, groups, group_size, 8); -+ verify_pathgroups(&mp8, p8, groups, group_size, NULL, 8); - } - - static void test_one_path_per_group_mixed8(void **state) -@@ -280,7 +339,7 @@ static void test_one_path_per_group_mixed8(void **state) - set_priority(p8, prio, 8); - mp8.pgpolicyfn = one_path_per_group; - assert_int_equal(group_paths(&mp8), 0); -- verify_pathgroups(&mp8, p8, groups, group_size, 8); -+ verify_pathgroups(&mp8, p8, groups, group_size, NULL, 8); - } - - static void test_one_path_per_group4(void **state) -@@ -291,7 +350,7 @@ static void test_one_path_per_group4(void **state) - - mp4.pgpolicyfn = one_path_per_group; - assert_int_equal(group_paths(&mp4), 0); -- verify_pathgroups(&mp4, p4, groups, group_size, 4); -+ verify_pathgroups(&mp4, p4, groups, group_size, NULL, 4); - } - - static void test_one_path_per_group1(void **state) -@@ -302,21 +361,55 @@ static void test_one_path_per_group1(void **state) - - mp1.pgpolicyfn = one_path_per_group; - assert_int_equal(group_paths(&mp1), 0); -- verify_pathgroups(&mp1, p1, groups, group_size, 1); -+ verify_pathgroups(&mp1, p1, groups, group_size, NULL, 1); - } - - static void test_one_path_per_group0(void **state) - { - mp0.pgpolicyfn = one_path_per_group; - assert_int_equal(group_paths(&mp0), 0); -- verify_pathgroups(&mp0, NULL, NULL, NULL, 0); -+ verify_pathgroups(&mp0, NULL, NULL, NULL, NULL, 0); - } - - static void test_one_path_per_group_null(void **state) - { - mp_null.pgpolicyfn = one_path_per_group; - assert_int_equal(group_paths(&mp_null), 0); -- verify_pathgroups(&mp_null, NULL, NULL, NULL, 0); -+ verify_pathgroups(&mp_null, NULL, NULL, NULL, NULL, 0); -+} -+ -+static void test_one_path_per_group_mixed_all_marginal8(void **state) -+{ -+ int prio[] = {7,1,3,3,5,2,8,2}; -+ int marginal[] = {1,1,1,1,1,1,1,1}; -+ int paths[] = {6,0,4,2,3,5,7,1}; -+ int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3], -+ &paths[4], &paths[5], &paths[6], &paths[7]}; -+ int group_size[] = {1,1,1,1,1,1,1,1}; -+ int group_marginal[] = {1,1,1,1,1,1,1,1}; -+ -+ set_priority(p8, prio, 8); -+ set_marginal(p8, marginal, 8); -+ mp8.pgpolicyfn = one_path_per_group; -+ assert_int_equal(group_paths(&mp8), 0); -+ verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 8); -+} -+ -+static void test_one_path_per_group_mixed_half_marginal8(void **state) -+{ -+ int prio[] = {7,1,3,3,5,2,8,2}; -+ int marginal[] = {0,1,1,0,0,0,1,1}; -+ int paths[] = {0,4,3,5,6,2,7,1}; -+ int *groups[] = {&paths[0], &paths[1], &paths[2], &paths[3], -+ &paths[4], &paths[5], &paths[6], &paths[7]}; -+ int group_size[] = {1,1,1,1,1,1,1,1}; -+ int group_marginal[] = {0,0,0,0,1,1,1,1}; -+ -+ set_priority(p8, prio, 8); -+ set_marginal(p8, marginal, 8); -+ mp8.pgpolicyfn = one_path_per_group; -+ assert_int_equal(group_paths(&mp8), 0); -+ verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 8); - } - - static void test_group_by_prio_same8(void **state) -@@ -327,7 +420,7 @@ static void test_group_by_prio_same8(void **state) - - mp8.pgpolicyfn = group_by_prio; - assert_int_equal(group_paths(&mp8), 0); -- verify_pathgroups(&mp8, p8, groups, group_size, 1); -+ verify_pathgroups(&mp8, p8, groups, group_size, NULL, 1); - } - - static void test_group_by_prio_increasing8(void **state) -@@ -341,7 +434,7 @@ static void test_group_by_prio_increasing8(void **state) - set_priority(p8, prio, 8); - mp8.pgpolicyfn = group_by_prio; - assert_int_equal(group_paths(&mp8), 0); -- verify_pathgroups(&mp8, p8, groups, group_size, 8); -+ verify_pathgroups(&mp8, p8, groups, group_size, NULL, 8); - } - - static void test_group_by_prio_decreasing8(void **state) -@@ -355,7 +448,7 @@ static void test_group_by_prio_decreasing8(void **state) - set_priority(p8, prio, 8); - mp8.pgpolicyfn = group_by_prio; - assert_int_equal(group_paths(&mp8), 0); -- verify_pathgroups(&mp8, p8, groups, group_size, 8); -+ verify_pathgroups(&mp8, p8, groups, group_size, NULL, 8); - } - - static void test_group_by_prio_mixed8(void **state) -@@ -374,7 +467,7 @@ static void test_group_by_prio_mixed8(void **state) - set_priority(p8, prio, 8); - mp8.pgpolicyfn = group_by_prio; - assert_int_equal(group_paths(&mp8), 0); -- verify_pathgroups(&mp8, p8, groups, group_size, 6); -+ verify_pathgroups(&mp8, p8, groups, group_size, NULL, 6); - } - - static void test_group_by_prio_2_groups8(void **state) -@@ -388,7 +481,7 @@ static void test_group_by_prio_2_groups8(void **state) - set_priority(p8, prio, 8); - mp8.pgpolicyfn = group_by_prio; - assert_int_equal(group_paths(&mp8), 0); -- verify_pathgroups(&mp8, p8, groups, group_size, 2); -+ verify_pathgroups(&mp8, p8, groups, group_size, NULL, 2); - } - - static void test_group_by_prio_mixed4(void **state) -@@ -403,7 +496,7 @@ static void test_group_by_prio_mixed4(void **state) - set_priority(p4, prio, 4); - mp4.pgpolicyfn = group_by_prio; - assert_int_equal(group_paths(&mp4), 0); -- verify_pathgroups(&mp4, p4, groups, group_size, 3); -+ verify_pathgroups(&mp4, p4, groups, group_size, NULL, 3); - } - - static void test_group_by_prio_2_groups4(void **state) -@@ -417,7 +510,7 @@ static void test_group_by_prio_2_groups4(void **state) - set_priority(p4, prio, 4); - mp4.pgpolicyfn = group_by_prio; - assert_int_equal(group_paths(&mp4), 0); -- verify_pathgroups(&mp4, p4, groups, group_size, 2); -+ verify_pathgroups(&mp4, p4, groups, group_size, NULL, 2); - } - - static void test_group_by_prio1(void **state) -@@ -428,21 +521,89 @@ static void test_group_by_prio1(void **state) - - mp1.pgpolicyfn = group_by_prio; - assert_int_equal(group_paths(&mp1), 0); -- verify_pathgroups(&mp1, p1, groups, group_size, 1); -+ verify_pathgroups(&mp1, p1, groups, group_size, NULL, 1); - } - - static void test_group_by_prio0(void **state) - { - mp0.pgpolicyfn = group_by_prio; - assert_int_equal(group_paths(&mp0), 0); -- verify_pathgroups(&mp0, NULL, NULL, NULL, 0); -+ verify_pathgroups(&mp0, NULL, NULL, NULL, NULL, 0); - } - - static void test_group_by_prio_null(void **state) - { - mp_null.pgpolicyfn = group_by_prio; - assert_int_equal(group_paths(&mp_null), 0); -- verify_pathgroups(&mp_null, NULL, NULL, NULL, 0); -+ verify_pathgroups(&mp_null, NULL, NULL, NULL, NULL, 0); -+} -+ -+static void test_group_by_prio_mixed_all_marginal8(void **state) -+{ -+ int prio[] = {7,1,3,3,5,2,8,2}; -+ int marginal[] = {1,1,1,1,1,1,1,1}; -+ int group0[] = {6}; -+ int group1[] = {0}; -+ int group2[] = {4}; -+ int group3[] = {2,3}; -+ int group4[] = {5,7}; -+ int group5[] = {1}; -+ int *groups[] = {group0, group1, group2, group3, -+ group4, group5}; -+ int group_size[] = {1,1,1,2,2,1}; -+ int group_marginal[] = {1,1,1,1,1,1}; -+ -+ set_priority(p8, prio, 8); -+ set_marginal(p8, marginal, 8); -+ mp8.pgpolicyfn = group_by_prio; -+ assert_int_equal(group_paths(&mp8), 0); -+ verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 6); -+} -+ -+static void test_group_by_prio_mixed_half_marginal8(void **state) -+{ -+ int prio[] = {7,1,3,3,5,2,8,2}; -+ int marginal[] = {0,0,0,1,0,1,1,1}; -+ int group0[] = {0}; -+ int group1[] = {4}; -+ int group2[] = {2}; -+ int group3[] = {1}; -+ int group4[] = {6}; -+ int group5[] = {3}; -+ int group6[] = {5,7}; -+ int *groups[] = {group0, group1, group2, group3, -+ group4, group5, group6}; -+ int group_size[] = {1,1,1,1,1,1,2}; -+ int group_marginal[] = {0,0,0,0,1,1,1}; -+ -+ set_priority(p8, prio, 8); -+ set_marginal(p8, marginal, 8); -+ mp8.pgpolicyfn = group_by_prio; -+ assert_int_equal(group_paths(&mp8), 0); -+ verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 7); -+} -+ -+static void test_group_by_prio_mixed_one_marginal8(void **state) -+{ -+ int prio[] = {7,1,3,3,5,2,8,2}; -+ int marginal[] = {0,0,0,0,0,1,0,0}; -+ int group0[] = {6}; -+ int group1[] = {0}; -+ int group2[] = {4}; -+ int group3[] = {2,3}; -+ int group4[] = {7}; -+ int group5[] = {1}; -+ int group6[] = {5}; -+ int *groups[] = {group0, group1, group2, group3, -+ group4, group5, group6}; -+ int group_size[] = {1,1,1,2,1,1,1}; -+ int group_marginal[] = {0,0,0,0,0,0,1}; -+ -+ set_priority(p8, prio, 8); -+ set_marginal(p8, marginal, 8); -+ mp8.pgpolicyfn = group_by_prio; -+ assert_int_equal(group_paths(&mp8), 0); -+ verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 7); - } - - static void test_group_by_node_name_same8(void **state) -@@ -455,7 +616,7 @@ static void test_group_by_node_name_same8(void **state) - set_tgt_node_name(p8, node_name, 8); - mp8.pgpolicyfn = group_by_node_name; - assert_int_equal(group_paths(&mp8), 0); -- verify_pathgroups(&mp8, p8, groups, group_size, 1); -+ verify_pathgroups(&mp8, p8, groups, group_size, NULL, 1); - } - - static void test_group_by_node_name_increasing8(void **state) -@@ -471,7 +632,7 @@ static void test_group_by_node_name_increasing8(void **state) - set_tgt_node_name(p8, node_name, 8); - mp8.pgpolicyfn = group_by_node_name; - assert_int_equal(group_paths(&mp8), 0); -- verify_pathgroups(&mp8, p8, groups, group_size, 8); -+ verify_pathgroups(&mp8, p8, groups, group_size, NULL, 8); - } - - static void test_group_by_node_name_3_groups8(void **state) -@@ -488,7 +649,7 @@ static void test_group_by_node_name_3_groups8(void **state) - set_tgt_node_name(p8, node_name, 8); - mp8.pgpolicyfn = group_by_node_name; - assert_int_equal(group_paths(&mp8), 0); -- verify_pathgroups(&mp8, p8, groups, group_size, 3); -+ verify_pathgroups(&mp8, p8, groups, group_size, NULL, 3); - } - - static void test_group_by_node_name_2_groups8(void **state) -@@ -504,7 +665,7 @@ static void test_group_by_node_name_2_groups8(void **state) - set_tgt_node_name(p8, node_name, 8); - mp8.pgpolicyfn = group_by_node_name; - assert_int_equal(group_paths(&mp8), 0); -- verify_pathgroups(&mp8, p8, groups, group_size, 2); -+ verify_pathgroups(&mp8, p8, groups, group_size, NULL, 2); - } - - static void test_group_by_node_name_3_groups4(void **state) -@@ -521,7 +682,7 @@ static void test_group_by_node_name_3_groups4(void **state) - set_tgt_node_name(p4, node_name, 4); - mp4.pgpolicyfn = group_by_node_name; - assert_int_equal(group_paths(&mp4), 0); -- verify_pathgroups(&mp4, p4, groups, group_size, 3); -+ verify_pathgroups(&mp4, p4, groups, group_size, NULL, 3); - } - - static void test_group_by_node_name_2_groups4(void **state) -@@ -537,7 +698,7 @@ static void test_group_by_node_name_2_groups4(void **state) - set_tgt_node_name(p4, node_name, 4); - mp4.pgpolicyfn = group_by_node_name; - assert_int_equal(group_paths(&mp4), 0); -- verify_pathgroups(&mp4, p4, groups, group_size, 2); -+ verify_pathgroups(&mp4, p4, groups, group_size, NULL, 2); - } - - static void test_group_by_node_name1(void **state) -@@ -550,21 +711,61 @@ static void test_group_by_node_name1(void **state) - set_tgt_node_name(p1, node_name, 1); - mp1.pgpolicyfn = group_by_node_name; - assert_int_equal(group_paths(&mp1), 0); -- verify_pathgroups(&mp1, p1, groups, group_size, 1); -+ verify_pathgroups(&mp1, p1, groups, group_size, NULL, 1); - } - - static void test_group_by_node_name0(void **state) - { - mp0.pgpolicyfn = group_by_node_name; - assert_int_equal(group_paths(&mp0), 0); -- verify_pathgroups(&mp0, NULL, NULL, NULL, 0); -+ verify_pathgroups(&mp0, NULL, NULL, NULL, NULL, 0); - } - - static void test_group_by_node_name_null(void **state) - { - mp_null.pgpolicyfn = group_by_node_name; - assert_int_equal(group_paths(&mp_null), 0); -- verify_pathgroups(&mp_null, NULL, NULL, NULL, 0); -+ verify_pathgroups(&mp_null, NULL, NULL, NULL, NULL, 0); -+} -+ -+static void test_group_by_node_name_2_groups_all_marginal8(void **state) -+{ -+ char *node_name[] = {"a", "a", "b", "a", "b", "b", "b", "a"}; -+ int prio[] = {4,1,2,1,2,2,2,1}; -+ int marginal[] = {1,1,1,1,1,1,1,1}; -+ int group0[] = {2,4,5,6}; -+ int group1[] = {0,1,3,7}; -+ int *groups[] = {group0, group1}; -+ int group_size[] = {4,4}; -+ int group_marginal[] = {1,1}; -+ -+ set_priority(p8, prio, 8); -+ set_marginal(p8, marginal, 8); -+ set_tgt_node_name(p8, node_name, 8); -+ mp8.pgpolicyfn = group_by_node_name; -+ assert_int_equal(group_paths(&mp8), 0); -+ verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 2); -+} -+ -+static void test_group_by_node_name_2_groups_half_marginal8(void **state) -+{ -+ char *node_name[] = {"a", "a", "b", "a", "b", "b", "b", "a"}; -+ int prio[] = {4,1,2,1,2,2,2,1}; -+ int marginal[] = {1,0,1,1,0,1,0,0}; -+ int group0[] = {4,6}; -+ int group1[] = {1,7}; -+ int group2[] = {0,3}; -+ int group3[] = {2,5}; -+ int *groups[] = {group0, group1, group2, group3}; -+ int group_size[] = {2,2,2,2}; -+ int group_marginal[] = {0,0,1,1}; -+ -+ set_priority(p8, prio, 8); -+ set_marginal(p8, marginal, 8); -+ set_tgt_node_name(p8, node_name, 8); -+ mp8.pgpolicyfn = group_by_node_name; -+ assert_int_equal(group_paths(&mp8), 0); -+ verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 4); - } - - static void test_group_by_serial_same8(void **state) -@@ -577,7 +778,7 @@ static void test_group_by_serial_same8(void **state) - set_serial(p8, serial, 8); - mp8.pgpolicyfn = group_by_serial; - assert_int_equal(group_paths(&mp8), 0); -- verify_pathgroups(&mp8, p8, groups, group_size, 1); -+ verify_pathgroups(&mp8, p8, groups, group_size, NULL, 1); - } - - static void test_group_by_serial_increasing8(void **state) -@@ -593,7 +794,7 @@ static void test_group_by_serial_increasing8(void **state) - set_serial(p8, serial, 8); - mp8.pgpolicyfn = group_by_serial; - assert_int_equal(group_paths(&mp8), 0); -- verify_pathgroups(&mp8, p8, groups, group_size, 8); -+ verify_pathgroups(&mp8, p8, groups, group_size, NULL, 8); - } - - static void test_group_by_serial_3_groups8(void **state) -@@ -610,7 +811,7 @@ static void test_group_by_serial_3_groups8(void **state) - set_serial(p8, serial, 8); - mp8.pgpolicyfn = group_by_serial; - assert_int_equal(group_paths(&mp8), 0); -- verify_pathgroups(&mp8, p8, groups, group_size, 3); -+ verify_pathgroups(&mp8, p8, groups, group_size, NULL, 3); - } - - static void test_group_by_serial_2_groups8(void **state) -@@ -626,7 +827,7 @@ static void test_group_by_serial_2_groups8(void **state) - set_serial(p8, serial, 8); - mp8.pgpolicyfn = group_by_serial; - assert_int_equal(group_paths(&mp8), 0); -- verify_pathgroups(&mp8, p8, groups, group_size, 2); -+ verify_pathgroups(&mp8, p8, groups, group_size, NULL, 2); - } - - static void test_group_by_serial_3_groups4(void **state) -@@ -643,7 +844,7 @@ static void test_group_by_serial_3_groups4(void **state) - set_serial(p4, serial, 4); - mp4.pgpolicyfn = group_by_serial; - assert_int_equal(group_paths(&mp4), 0); -- verify_pathgroups(&mp4, p4, groups, group_size, 3); -+ verify_pathgroups(&mp4, p4, groups, group_size, NULL, 3); - } - - static void test_group_by_serial_2_groups4(void **state) -@@ -659,7 +860,7 @@ static void test_group_by_serial_2_groups4(void **state) - set_serial(p4, serial, 4); - mp4.pgpolicyfn = group_by_serial; - assert_int_equal(group_paths(&mp4), 0); -- verify_pathgroups(&mp4, p4, groups, group_size, 2); -+ verify_pathgroups(&mp4, p4, groups, group_size, NULL, 2); - } - - static void test_group_by_serial1(void **state) -@@ -672,21 +873,61 @@ static void test_group_by_serial1(void **state) - set_serial(p1, serial, 1); - mp1.pgpolicyfn = group_by_serial; - assert_int_equal(group_paths(&mp1), 0); -- verify_pathgroups(&mp1, p1, groups, group_size, 1); -+ verify_pathgroups(&mp1, p1, groups, group_size, NULL, 1); - } - - static void test_group_by_serial0(void **state) - { - mp0.pgpolicyfn = group_by_serial; - assert_int_equal(group_paths(&mp0), 0); -- verify_pathgroups(&mp0, NULL, NULL, NULL, 0); -+ verify_pathgroups(&mp0, NULL, NULL, NULL, NULL, 0); - } - - static void test_group_by_serial_null(void **state) - { - mp_null.pgpolicyfn = group_by_serial; - assert_int_equal(group_paths(&mp_null), 0); -- verify_pathgroups(&mp_null, NULL, NULL, NULL, 0); -+ verify_pathgroups(&mp_null, NULL, NULL, NULL, NULL, 0); -+} -+ -+static void test_group_by_serial_2_groups8_all_marginal8(void **state) -+{ -+ char *serial[] = {"1", "2", "1", "1", "2", "2", "1", "2"}; -+ int marginal[] = {1,1,1,1,1,1,1,1}; -+ int prio[] = {3,2,2,1,2,2,1,2}; -+ int group0[] = {1,4,5,7}; -+ int group1[] = {0,2,3,6}; -+ int *groups[] = {group0, group1}; -+ int group_size[] = {4,4}; -+ int group_marginal[] = {1,1}; -+ -+ set_priority(p8, prio, 8); -+ set_serial(p8, serial, 8); -+ set_marginal(p8, marginal, 8); -+ mp8.pgpolicyfn = group_by_serial; -+ assert_int_equal(group_paths(&mp8), 0); -+ verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 2); -+} -+ -+static void test_group_by_serial_2_groups8_half_marginal8(void **state) -+{ -+ char *serial[] = {"1", "2", "1", "1", "2", "2", "1", "2"}; -+ int marginal[] = {0,0,1,1,1,1,0,0}; -+ int prio[] = {3,2,2,1,2,2,1,2}; -+ int group0[] = {0,6}; -+ int group1[] = {1,7}; -+ int group2[] = {4,5}; -+ int group3[] = {2,3}; -+ int *groups[] = {group0, group1, group2, group3}; -+ int group_size[] = {2,2,2,2}; -+ int group_marginal[] = {0,0,1,1}; -+ -+ set_priority(p8, prio, 8); -+ set_serial(p8, serial, 8); -+ set_marginal(p8, marginal, 8); -+ mp8.pgpolicyfn = group_by_serial; -+ assert_int_equal(group_paths(&mp8), 0); -+ verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 4); - } - - #define setup_test(name, nr) \ -@@ -700,6 +941,9 @@ int test_pgpolicies(void) - setup_test(test_one_group, 1), - setup_test(test_one_group, 0), - setup_test(test_one_group, _null), -+ setup_test(test_one_group_all_marginal, 8), -+ setup_test(test_one_group_half_marginal, 8), -+ setup_test(test_one_group_one_marginal, 8), - setup_test(test_one_path_per_group_same, 8), - setup_test(test_one_path_per_group_increasing, 8), - setup_test(test_one_path_per_group_decreasing, 8), -@@ -708,6 +952,8 @@ int test_pgpolicies(void) - setup_test(test_one_path_per_group, 1), - setup_test(test_one_path_per_group, 0), - setup_test(test_one_path_per_group, _null), -+ setup_test(test_one_path_per_group_mixed_all_marginal, 8), -+ setup_test(test_one_path_per_group_mixed_half_marginal, 8), - setup_test(test_group_by_prio_same, 8), - setup_test(test_group_by_prio_increasing, 8), - setup_test(test_group_by_prio_decreasing, 8), -@@ -718,6 +964,9 @@ int test_pgpolicies(void) - setup_test(test_group_by_prio, 1), - setup_test(test_group_by_prio, 0), - setup_test(test_group_by_prio, _null), -+ setup_test(test_group_by_prio_mixed_all_marginal, 8), -+ setup_test(test_group_by_prio_mixed_half_marginal, 8), -+ setup_test(test_group_by_prio_mixed_one_marginal, 8), - setup_test(test_group_by_node_name_same, 8), - setup_test(test_group_by_node_name_increasing, 8), - setup_test(test_group_by_node_name_3_groups, 8), -@@ -727,6 +976,8 @@ int test_pgpolicies(void) - setup_test(test_group_by_node_name, 1), - setup_test(test_group_by_node_name, 0), - setup_test(test_group_by_node_name, _null), -+ setup_test(test_group_by_node_name_2_groups_all_marginal, 8), -+ setup_test(test_group_by_node_name_2_groups_half_marginal, 8), - setup_test(test_group_by_serial_same, 8), - setup_test(test_group_by_serial_increasing, 8), - setup_test(test_group_by_serial_3_groups, 8), -@@ -736,6 +987,8 @@ int test_pgpolicies(void) - setup_test(test_group_by_serial, 1), - setup_test(test_group_by_serial, 0), - setup_test(test_group_by_serial, _null), -+ setup_test(test_group_by_serial_2_groups8_all_marginal, 8), -+ setup_test(test_group_by_serial_2_groups8_half_marginal, 8), - }; - return cmocka_run_group_tests(tests, setup, NULL); - } --- -2.17.2 - diff --git a/0032-add-support-for-upcoming-json-c-0.14.0.patch b/0011-libdmmp-Add-support-for-upcoming-json-c-0.14.0.patch similarity index 83% rename from 0032-add-support-for-upcoming-json-c-0.14.0.patch rename to 0011-libdmmp-Add-support-for-upcoming-json-c-0.14.0.patch index 34d02f7..7c03c34 100644 --- a/0032-add-support-for-upcoming-json-c-0.14.0.patch +++ b/0011-libdmmp-Add-support-for-upcoming-json-c-0.14.0.patch @@ -1,11 +1,13 @@ -From 8438a9cd8d7ed88645fa8e6a8f19c0fd9ae872a7 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= Date: Mon, 13 Apr 2020 19:22:02 +0200 -Subject: [PATCH] Add support for upcoming json-c 0.14.0. +Subject: [PATCH] libdmmp: Add support for upcoming json-c 0.14.0. TRUE/FALSE are not defined anymore. 1 and 0 are used instead. This is backwards compatible, as earlier versions of json-c are using the same integer values in their present definitions. + +Signed-off-by: Benjamin Marzinski --- libdmmp/libdmmp_private.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) @@ -24,5 +26,5 @@ index ac85b63f..4378962b 100644 "key '%s' not found", key); \ rc = DMMP_ERR_IPC_ERROR; \ -- -2.26.0 +2.17.2 diff --git a/0011-libmultipath-add-marginal_pathgroups-config-option.patch b/0011-libmultipath-add-marginal_pathgroups-config-option.patch deleted file mode 100644 index 3558922..0000000 --- a/0011-libmultipath-add-marginal_pathgroups-config-option.patch +++ /dev/null @@ -1,642 +0,0 @@ -From febf9b26fcc67d94ad06f06fc599f0ef90d84132 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 24 Jul 2019 10:04:40 -0500 -Subject: [PATCH] libmultipath: add marginal_pathgroups config option - -group_paths now gets passed this to determine whether to enable -marginal pathgroups. The unit tests have also been updated. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/config.h | 1 + - libmultipath/configure.c | 5 +- - libmultipath/dict.c | 3 + - libmultipath/pgpolicies.c | 5 +- - libmultipath/pgpolicies.h | 2 +- - tests/pgpolicy.c | 140 +++++++++++++++++++++++--------------- - 6 files changed, 98 insertions(+), 58 deletions(-) - -diff --git a/libmultipath/config.h b/libmultipath/config.h -index ff2b4e86..0b978970 100644 ---- a/libmultipath/config.h -+++ b/libmultipath/config.h -@@ -186,6 +186,7 @@ struct config { - int max_sectors_kb; - int ghost_delay; - int find_multipaths_timeout; -+ int marginal_pathgroups; - unsigned int version[3]; - - char * multipath_dir; -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 3c309d64..3238d485 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -297,7 +297,7 @@ int setup_map(struct multipath *mpp, char *params, int params_size, - { - struct pathgroup * pgp; - struct config *conf; -- int i, n_paths; -+ int i, n_paths, marginal_pathgroups; - - /* - * don't bother if devmap size is unknown -@@ -357,6 +357,7 @@ int setup_map(struct multipath *mpp, char *params, int params_size, - select_flush_on_last_del(conf, mpp); - - sysfs_set_scsi_tmo(mpp, conf->checkint); -+ marginal_pathgroups = conf->marginal_pathgroups; - pthread_cleanup_pop(1); - - if (marginal_path_check_enabled(mpp)) { -@@ -387,7 +388,7 @@ int setup_map(struct multipath *mpp, char *params, int params_size, - vector_free(mpp->pg); - mpp->pg = NULL; - } -- if (group_paths(mpp)) -+ if (group_paths(mpp, marginal_pathgroups)) - return 1; - - /* -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index c6eba0f6..b5feb884 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -1339,6 +1339,8 @@ 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) - -+declare_def_handler(marginal_pathgroups, set_yes_no) -+declare_def_snprint(marginal_pathgroups, print_yes_no) - - static int - def_uxsock_timeout_handler(struct config *conf, vector strvec) -@@ -1710,6 +1712,7 @@ init_keywords(vector keywords) - install_keyword("find_multipaths_timeout", - &def_find_multipaths_timeout_handler, - &snprint_def_find_multipaths_timeout); -+ install_keyword("marginal_pathgroups", &def_marginal_pathgroups_handler, &snprint_def_marginal_pathgroups); - __deprecated install_keyword("default_selector", &def_selector_handler, NULL); - __deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL); - __deprecated install_keyword("default_uid_attribute", &def_uid_attribute_handler, NULL); -diff --git a/libmultipath/pgpolicies.c b/libmultipath/pgpolicies.c -index 6fb2d28a..8f7c6b13 100644 ---- a/libmultipath/pgpolicies.c -+++ b/libmultipath/pgpolicies.c -@@ -131,7 +131,7 @@ fail: - return -1; - } - --int group_paths(struct multipath *mp) -+int group_paths(struct multipath *mp, int marginal_pathgroups) - { - vector normal, marginal; - -@@ -145,7 +145,8 @@ int group_paths(struct multipath *mp) - if (!mp->pgpolicyfn) - goto fail; - -- if (split_marginal_paths(mp->paths, &normal, &marginal) != 0) { -+ if (!marginal_pathgroups || -+ split_marginal_paths(mp->paths, &normal, &marginal) != 0) { - if (mp->pgpolicyfn(mp, mp->paths) != 0) - goto fail; - } else { -diff --git a/libmultipath/pgpolicies.h b/libmultipath/pgpolicies.h -index 7532d75f..15927610 100644 ---- a/libmultipath/pgpolicies.h -+++ b/libmultipath/pgpolicies.h -@@ -21,7 +21,7 @@ enum iopolicies { - - int get_pgpolicy_id(char *); - int get_pgpolicy_name (char *, int, int); --int group_paths(struct multipath *); -+int group_paths(struct multipath *, int); - /* - * policies - */ -diff --git a/tests/pgpolicy.c b/tests/pgpolicy.c -index ab09f91c..3f61b123 100644 ---- a/tests/pgpolicy.c -+++ b/tests/pgpolicy.c -@@ -204,7 +204,7 @@ static void test_one_group8(void **state) - int group_size[] = {8}; - - mp8.pgpolicyfn = one_group; -- assert_int_equal(group_paths(&mp8), 0); -+ assert_int_equal(group_paths(&mp8, 0), 0); - verify_pathgroups(&mp8, p8, groups, group_size, NULL, 1); - } - -@@ -215,7 +215,7 @@ static void test_one_group4(void **state) - int group_size[] = {4}; - - mp4.pgpolicyfn = one_group; -- assert_int_equal(group_paths(&mp4), 0); -+ assert_int_equal(group_paths(&mp4, 0), 0); - verify_pathgroups(&mp4, p4, groups, group_size, NULL, 1); - } - -@@ -226,21 +226,21 @@ static void test_one_group1(void **state) - int group_size[] = {1}; - - mp1.pgpolicyfn = one_group; -- assert_int_equal(group_paths(&mp1), 0); -+ assert_int_equal(group_paths(&mp1, 0), 0); - verify_pathgroups(&mp1, p1, groups, group_size, NULL, 1); - } - - static void test_one_group0(void **state) - { - mp0.pgpolicyfn = one_group; -- assert_int_equal(group_paths(&mp0), 0); -+ assert_int_equal(group_paths(&mp0, 0), 0); - verify_pathgroups(&mp0, NULL, NULL, NULL, NULL, 0); - } - - static void test_one_group_null(void **state) - { - mp_null.pgpolicyfn = one_group; -- assert_int_equal(group_paths(&mp_null), 0); -+ assert_int_equal(group_paths(&mp_null, 0), 0); - verify_pathgroups(&mp_null, NULL, NULL, NULL, NULL, 0); - } - -@@ -254,7 +254,7 @@ static void test_one_group_all_marginal8(void **state) - - set_marginal(p8, marginal, 8); - mp8.pgpolicyfn = one_group; -- assert_int_equal(group_paths(&mp8), 0); -+ assert_int_equal(group_paths(&mp8, 1), 0); - verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 1); - } - -@@ -269,10 +269,23 @@ static void test_one_group_half_marginal8(void **state) - - set_marginal(p8, marginal, 8); - mp8.pgpolicyfn = one_group; -- assert_int_equal(group_paths(&mp8), 0); -+ assert_int_equal(group_paths(&mp8, 1), 0); - verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 2); - } - -+static void test_one_group_ignore_marginal8(void **state) -+{ -+ int marginal[] = {1,0,1,0,1,1,0,0}; -+ int paths[] = {0,1,2,3,4,5,6,7}; -+ int *groups[] = {paths}; -+ int group_size[] = {8}; -+ -+ set_marginal(p8, marginal, 8); -+ mp8.pgpolicyfn = one_group; -+ assert_int_equal(group_paths(&mp8, 0), 0); -+ verify_pathgroups(&mp8, p8, groups, group_size, NULL, 1); -+} -+ - static void test_one_group_one_marginal8(void **state) - { - int marginal[] = {0,0,0,0,0,1,0,0}; -@@ -284,7 +297,7 @@ static void test_one_group_one_marginal8(void **state) - - set_marginal(p8, marginal, 8); - mp8.pgpolicyfn = one_group; -- assert_int_equal(group_paths(&mp8), 0); -+ assert_int_equal(group_paths(&mp8, 1), 0); - verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 2); - } - -@@ -296,7 +309,7 @@ static void test_one_path_per_group_same8(void **state) - int group_size[] = {1,1,1,1,1,1,1,1}; - - mp8.pgpolicyfn = one_path_per_group; -- assert_int_equal(group_paths(&mp8), 0); -+ assert_int_equal(group_paths(&mp8, 0), 0); - verify_pathgroups(&mp8, p8, groups, group_size, NULL, 8); - } - -@@ -310,7 +323,7 @@ static void test_one_path_per_group_increasing8(void **state) - - set_priority(p8, prio, 8); - mp8.pgpolicyfn = one_path_per_group; -- assert_int_equal(group_paths(&mp8), 0); -+ assert_int_equal(group_paths(&mp8, 0), 0); - verify_pathgroups(&mp8, p8, groups, group_size, NULL, 8); - } - -@@ -324,7 +337,7 @@ static void test_one_path_per_group_decreasing8(void **state) - - set_priority(p8, prio, 8); - mp8.pgpolicyfn = one_path_per_group; -- assert_int_equal(group_paths(&mp8), 0); -+ assert_int_equal(group_paths(&mp8, 0), 0); - verify_pathgroups(&mp8, p8, groups, group_size, NULL, 8); - } - -@@ -338,7 +351,7 @@ static void test_one_path_per_group_mixed8(void **state) - - set_priority(p8, prio, 8); - mp8.pgpolicyfn = one_path_per_group; -- assert_int_equal(group_paths(&mp8), 0); -+ assert_int_equal(group_paths(&mp8, 0), 0); - verify_pathgroups(&mp8, p8, groups, group_size, NULL, 8); - } - -@@ -349,7 +362,7 @@ static void test_one_path_per_group4(void **state) - int group_size[] = {1,1,1,1}; - - mp4.pgpolicyfn = one_path_per_group; -- assert_int_equal(group_paths(&mp4), 0); -+ assert_int_equal(group_paths(&mp4, 0), 0); - verify_pathgroups(&mp4, p4, groups, group_size, NULL, 4); - } - -@@ -360,21 +373,21 @@ static void test_one_path_per_group1(void **state) - int group_size[] = {1}; - - mp1.pgpolicyfn = one_path_per_group; -- assert_int_equal(group_paths(&mp1), 0); -+ assert_int_equal(group_paths(&mp1, 0), 0); - verify_pathgroups(&mp1, p1, groups, group_size, NULL, 1); - } - - static void test_one_path_per_group0(void **state) - { - mp0.pgpolicyfn = one_path_per_group; -- assert_int_equal(group_paths(&mp0), 0); -+ assert_int_equal(group_paths(&mp0, 0), 0); - verify_pathgroups(&mp0, NULL, NULL, NULL, NULL, 0); - } - - static void test_one_path_per_group_null(void **state) - { - mp_null.pgpolicyfn = one_path_per_group; -- assert_int_equal(group_paths(&mp_null), 0); -+ assert_int_equal(group_paths(&mp_null, 0), 0); - verify_pathgroups(&mp_null, NULL, NULL, NULL, NULL, 0); - } - -@@ -391,7 +404,7 @@ static void test_one_path_per_group_mixed_all_marginal8(void **state) - set_priority(p8, prio, 8); - set_marginal(p8, marginal, 8); - mp8.pgpolicyfn = one_path_per_group; -- assert_int_equal(group_paths(&mp8), 0); -+ assert_int_equal(group_paths(&mp8, 1), 0); - verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 8); - } - -@@ -408,7 +421,7 @@ static void test_one_path_per_group_mixed_half_marginal8(void **state) - set_priority(p8, prio, 8); - set_marginal(p8, marginal, 8); - mp8.pgpolicyfn = one_path_per_group; -- assert_int_equal(group_paths(&mp8), 0); -+ assert_int_equal(group_paths(&mp8, 1), 0); - verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 8); - } - -@@ -419,7 +432,7 @@ static void test_group_by_prio_same8(void **state) - int group_size[] = {8}; - - mp8.pgpolicyfn = group_by_prio; -- assert_int_equal(group_paths(&mp8), 0); -+ assert_int_equal(group_paths(&mp8, 0), 0); - verify_pathgroups(&mp8, p8, groups, group_size, NULL, 1); - } - -@@ -433,7 +446,7 @@ static void test_group_by_prio_increasing8(void **state) - - set_priority(p8, prio, 8); - mp8.pgpolicyfn = group_by_prio; -- assert_int_equal(group_paths(&mp8), 0); -+ assert_int_equal(group_paths(&mp8, 0), 0); - verify_pathgroups(&mp8, p8, groups, group_size, NULL, 8); - } - -@@ -447,7 +460,7 @@ static void test_group_by_prio_decreasing8(void **state) - - set_priority(p8, prio, 8); - mp8.pgpolicyfn = group_by_prio; -- assert_int_equal(group_paths(&mp8), 0); -+ assert_int_equal(group_paths(&mp8, 0), 0); - verify_pathgroups(&mp8, p8, groups, group_size, NULL, 8); - } - -@@ -466,7 +479,26 @@ static void test_group_by_prio_mixed8(void **state) - - set_priority(p8, prio, 8); - mp8.pgpolicyfn = group_by_prio; -- assert_int_equal(group_paths(&mp8), 0); -+ assert_int_equal(group_paths(&mp8, 0), 0); -+ verify_pathgroups(&mp8, p8, groups, group_size, NULL, 6); -+} -+ -+static void test_group_by_prio_mixed_no_marginal8(void **state) -+{ -+ int prio[] = {7,1,3,3,5,2,8,2}; -+ int group0[] = {6}; -+ int group1[] = {0}; -+ int group2[] = {4}; -+ int group3[] = {2,3}; -+ int group4[] = {5,7}; -+ int group5[] = {1}; -+ int *groups[] = {group0, group1, group2, group3, -+ group4, group5}; -+ int group_size[] = {1,1,1,2,2,1}; -+ -+ set_priority(p8, prio, 8); -+ mp8.pgpolicyfn = group_by_prio; -+ assert_int_equal(group_paths(&mp8, 1), 0); - verify_pathgroups(&mp8, p8, groups, group_size, NULL, 6); - } - -@@ -480,7 +512,7 @@ static void test_group_by_prio_2_groups8(void **state) - - set_priority(p8, prio, 8); - mp8.pgpolicyfn = group_by_prio; -- assert_int_equal(group_paths(&mp8), 0); -+ assert_int_equal(group_paths(&mp8, 0), 0); - verify_pathgroups(&mp8, p8, groups, group_size, NULL, 2); - } - -@@ -495,7 +527,7 @@ static void test_group_by_prio_mixed4(void **state) - - set_priority(p4, prio, 4); - mp4.pgpolicyfn = group_by_prio; -- assert_int_equal(group_paths(&mp4), 0); -+ assert_int_equal(group_paths(&mp4, 0), 0); - verify_pathgroups(&mp4, p4, groups, group_size, NULL, 3); - } - -@@ -509,7 +541,7 @@ static void test_group_by_prio_2_groups4(void **state) - - set_priority(p4, prio, 4); - mp4.pgpolicyfn = group_by_prio; -- assert_int_equal(group_paths(&mp4), 0); -+ assert_int_equal(group_paths(&mp4, 0), 0); - verify_pathgroups(&mp4, p4, groups, group_size, NULL, 2); - } - -@@ -520,21 +552,21 @@ static void test_group_by_prio1(void **state) - int group_size[] = {1}; - - mp1.pgpolicyfn = group_by_prio; -- assert_int_equal(group_paths(&mp1), 0); -+ assert_int_equal(group_paths(&mp1, 0), 0); - verify_pathgroups(&mp1, p1, groups, group_size, NULL, 1); - } - - static void test_group_by_prio0(void **state) - { - mp0.pgpolicyfn = group_by_prio; -- assert_int_equal(group_paths(&mp0), 0); -+ assert_int_equal(group_paths(&mp0, 0), 0); - verify_pathgroups(&mp0, NULL, NULL, NULL, NULL, 0); - } - - static void test_group_by_prio_null(void **state) - { - mp_null.pgpolicyfn = group_by_prio; -- assert_int_equal(group_paths(&mp_null), 0); -+ assert_int_equal(group_paths(&mp_null, 0), 0); - verify_pathgroups(&mp_null, NULL, NULL, NULL, NULL, 0); - } - -@@ -556,7 +588,7 @@ static void test_group_by_prio_mixed_all_marginal8(void **state) - set_priority(p8, prio, 8); - set_marginal(p8, marginal, 8); - mp8.pgpolicyfn = group_by_prio; -- assert_int_equal(group_paths(&mp8), 0); -+ assert_int_equal(group_paths(&mp8, 1), 0); - verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 6); - } - -@@ -579,7 +611,7 @@ static void test_group_by_prio_mixed_half_marginal8(void **state) - set_priority(p8, prio, 8); - set_marginal(p8, marginal, 8); - mp8.pgpolicyfn = group_by_prio; -- assert_int_equal(group_paths(&mp8), 0); -+ assert_int_equal(group_paths(&mp8, 1), 0); - verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 7); - } - -@@ -602,7 +634,7 @@ static void test_group_by_prio_mixed_one_marginal8(void **state) - set_priority(p8, prio, 8); - set_marginal(p8, marginal, 8); - mp8.pgpolicyfn = group_by_prio; -- assert_int_equal(group_paths(&mp8), 0); -+ assert_int_equal(group_paths(&mp8, 1), 0); - verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 7); - } - -@@ -615,7 +647,7 @@ static void test_group_by_node_name_same8(void **state) - - set_tgt_node_name(p8, node_name, 8); - mp8.pgpolicyfn = group_by_node_name; -- assert_int_equal(group_paths(&mp8), 0); -+ assert_int_equal(group_paths(&mp8, 0), 0); - verify_pathgroups(&mp8, p8, groups, group_size, NULL, 1); - } - -@@ -631,7 +663,7 @@ static void test_group_by_node_name_increasing8(void **state) - set_priority(p8, prio, 8); - set_tgt_node_name(p8, node_name, 8); - mp8.pgpolicyfn = group_by_node_name; -- assert_int_equal(group_paths(&mp8), 0); -+ assert_int_equal(group_paths(&mp8, 0), 0); - verify_pathgroups(&mp8, p8, groups, group_size, NULL, 8); - } - -@@ -648,7 +680,7 @@ static void test_group_by_node_name_3_groups8(void **state) - set_priority(p8, prio, 8); - set_tgt_node_name(p8, node_name, 8); - mp8.pgpolicyfn = group_by_node_name; -- assert_int_equal(group_paths(&mp8), 0); -+ assert_int_equal(group_paths(&mp8, 0), 0); - verify_pathgroups(&mp8, p8, groups, group_size, NULL, 3); - } - -@@ -664,7 +696,7 @@ static void test_group_by_node_name_2_groups8(void **state) - set_priority(p8, prio, 8); - set_tgt_node_name(p8, node_name, 8); - mp8.pgpolicyfn = group_by_node_name; -- assert_int_equal(group_paths(&mp8), 0); -+ assert_int_equal(group_paths(&mp8, 0), 0); - verify_pathgroups(&mp8, p8, groups, group_size, NULL, 2); - } - -@@ -681,7 +713,7 @@ static void test_group_by_node_name_3_groups4(void **state) - set_priority(p4, prio, 4); - set_tgt_node_name(p4, node_name, 4); - mp4.pgpolicyfn = group_by_node_name; -- assert_int_equal(group_paths(&mp4), 0); -+ assert_int_equal(group_paths(&mp4, 0), 0); - verify_pathgroups(&mp4, p4, groups, group_size, NULL, 3); - } - -@@ -697,7 +729,7 @@ static void test_group_by_node_name_2_groups4(void **state) - set_priority(p4, prio, 4); - set_tgt_node_name(p4, node_name, 4); - mp4.pgpolicyfn = group_by_node_name; -- assert_int_equal(group_paths(&mp4), 0); -+ assert_int_equal(group_paths(&mp4, 0), 0); - verify_pathgroups(&mp4, p4, groups, group_size, NULL, 2); - } - -@@ -710,21 +742,21 @@ static void test_group_by_node_name1(void **state) - - set_tgt_node_name(p1, node_name, 1); - mp1.pgpolicyfn = group_by_node_name; -- assert_int_equal(group_paths(&mp1), 0); -+ assert_int_equal(group_paths(&mp1,0), 0); - verify_pathgroups(&mp1, p1, groups, group_size, NULL, 1); - } - - static void test_group_by_node_name0(void **state) - { - mp0.pgpolicyfn = group_by_node_name; -- assert_int_equal(group_paths(&mp0), 0); -+ assert_int_equal(group_paths(&mp0, 0), 0); - verify_pathgroups(&mp0, NULL, NULL, NULL, NULL, 0); - } - - static void test_group_by_node_name_null(void **state) - { - mp_null.pgpolicyfn = group_by_node_name; -- assert_int_equal(group_paths(&mp_null), 0); -+ assert_int_equal(group_paths(&mp_null, 0), 0); - verify_pathgroups(&mp_null, NULL, NULL, NULL, NULL, 0); - } - -@@ -743,7 +775,7 @@ static void test_group_by_node_name_2_groups_all_marginal8(void **state) - set_marginal(p8, marginal, 8); - set_tgt_node_name(p8, node_name, 8); - mp8.pgpolicyfn = group_by_node_name; -- assert_int_equal(group_paths(&mp8), 0); -+ assert_int_equal(group_paths(&mp8, 1), 0); - verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 2); - } - -@@ -764,7 +796,7 @@ static void test_group_by_node_name_2_groups_half_marginal8(void **state) - set_marginal(p8, marginal, 8); - set_tgt_node_name(p8, node_name, 8); - mp8.pgpolicyfn = group_by_node_name; -- assert_int_equal(group_paths(&mp8), 0); -+ assert_int_equal(group_paths(&mp8, 1), 0); - verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 4); - } - -@@ -777,7 +809,7 @@ static void test_group_by_serial_same8(void **state) - - set_serial(p8, serial, 8); - mp8.pgpolicyfn = group_by_serial; -- assert_int_equal(group_paths(&mp8), 0); -+ assert_int_equal(group_paths(&mp8, 0), 0); - verify_pathgroups(&mp8, p8, groups, group_size, NULL, 1); - } - -@@ -793,7 +825,7 @@ static void test_group_by_serial_increasing8(void **state) - set_priority(p8, prio, 8); - set_serial(p8, serial, 8); - mp8.pgpolicyfn = group_by_serial; -- assert_int_equal(group_paths(&mp8), 0); -+ assert_int_equal(group_paths(&mp8, 0), 0); - verify_pathgroups(&mp8, p8, groups, group_size, NULL, 8); - } - -@@ -810,7 +842,7 @@ static void test_group_by_serial_3_groups8(void **state) - set_priority(p8, prio, 8); - set_serial(p8, serial, 8); - mp8.pgpolicyfn = group_by_serial; -- assert_int_equal(group_paths(&mp8), 0); -+ assert_int_equal(group_paths(&mp8, 0), 0); - verify_pathgroups(&mp8, p8, groups, group_size, NULL, 3); - } - -@@ -826,7 +858,7 @@ static void test_group_by_serial_2_groups8(void **state) - set_priority(p8, prio, 8); - set_serial(p8, serial, 8); - mp8.pgpolicyfn = group_by_serial; -- assert_int_equal(group_paths(&mp8), 0); -+ assert_int_equal(group_paths(&mp8, 0), 0); - verify_pathgroups(&mp8, p8, groups, group_size, NULL, 2); - } - -@@ -843,7 +875,7 @@ static void test_group_by_serial_3_groups4(void **state) - set_priority(p4, prio, 4); - set_serial(p4, serial, 4); - mp4.pgpolicyfn = group_by_serial; -- assert_int_equal(group_paths(&mp4), 0); -+ assert_int_equal(group_paths(&mp4, 0), 0); - verify_pathgroups(&mp4, p4, groups, group_size, NULL, 3); - } - -@@ -859,7 +891,7 @@ static void test_group_by_serial_2_groups4(void **state) - set_priority(p4, prio, 4); - set_serial(p4, serial, 4); - mp4.pgpolicyfn = group_by_serial; -- assert_int_equal(group_paths(&mp4), 0); -+ assert_int_equal(group_paths(&mp4, 0), 0); - verify_pathgroups(&mp4, p4, groups, group_size, NULL, 2); - } - -@@ -872,21 +904,21 @@ static void test_group_by_serial1(void **state) - - set_serial(p1, serial, 1); - mp1.pgpolicyfn = group_by_serial; -- assert_int_equal(group_paths(&mp1), 0); -+ assert_int_equal(group_paths(&mp1, 0), 0); - verify_pathgroups(&mp1, p1, groups, group_size, NULL, 1); - } - - static void test_group_by_serial0(void **state) - { - mp0.pgpolicyfn = group_by_serial; -- assert_int_equal(group_paths(&mp0), 0); -+ assert_int_equal(group_paths(&mp0, 0), 0); - verify_pathgroups(&mp0, NULL, NULL, NULL, NULL, 0); - } - - static void test_group_by_serial_null(void **state) - { - mp_null.pgpolicyfn = group_by_serial; -- assert_int_equal(group_paths(&mp_null), 0); -+ assert_int_equal(group_paths(&mp_null, 0), 0); - verify_pathgroups(&mp_null, NULL, NULL, NULL, NULL, 0); - } - -@@ -905,7 +937,7 @@ static void test_group_by_serial_2_groups8_all_marginal8(void **state) - set_serial(p8, serial, 8); - set_marginal(p8, marginal, 8); - mp8.pgpolicyfn = group_by_serial; -- assert_int_equal(group_paths(&mp8), 0); -+ assert_int_equal(group_paths(&mp8, 1), 0); - verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 2); - } - -@@ -926,7 +958,7 @@ static void test_group_by_serial_2_groups8_half_marginal8(void **state) - set_serial(p8, serial, 8); - set_marginal(p8, marginal, 8); - mp8.pgpolicyfn = group_by_serial; -- assert_int_equal(group_paths(&mp8), 0); -+ assert_int_equal(group_paths(&mp8, 1), 0); - verify_pathgroups(&mp8, p8, groups, group_size, group_marginal, 4); - } - -@@ -943,6 +975,7 @@ int test_pgpolicies(void) - setup_test(test_one_group, _null), - setup_test(test_one_group_all_marginal, 8), - setup_test(test_one_group_half_marginal, 8), -+ setup_test(test_one_group_ignore_marginal, 8), - setup_test(test_one_group_one_marginal, 8), - setup_test(test_one_path_per_group_same, 8), - setup_test(test_one_path_per_group_increasing, 8), -@@ -958,6 +991,7 @@ int test_pgpolicies(void) - setup_test(test_group_by_prio_increasing, 8), - setup_test(test_group_by_prio_decreasing, 8), - setup_test(test_group_by_prio_mixed, 8), -+ setup_test(test_group_by_prio_mixed_no_marginal, 8), - setup_test(test_group_by_prio_2_groups, 8), - setup_test(test_group_by_prio_mixed, 4), - setup_test(test_group_by_prio_2_groups, 4), --- -2.17.2 - diff --git a/0012-libmultipath-fix-condlog-NULL-argument-in-uevent_get.patch b/0012-libmultipath-fix-condlog-NULL-argument-in-uevent_get.patch new file mode 100644 index 0000000..5d2750d --- /dev/null +++ b/0012-libmultipath-fix-condlog-NULL-argument-in-uevent_get.patch @@ -0,0 +1,46 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Fri, 29 May 2020 15:13:59 -0500 +Subject: [PATCH] libmultipath: fix condlog NULL argument in uevent_get_env_var + +uevent_get_env_var() could call condlog with p == NULL. On gcc 10, +this triggers warnings like: + +In file included from uevent.c:47: +In function 'uevent_get_env_var', + inlined from 'uevent_get_wwid' at uevent.c:170:8: +debug.h:13:2: error: '%s' directive argument is null +[-Werror=format-overflow=] + 13 | dlog(logsink, prio, fmt "\n", ##args) + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +uevent.c:132:2: note: in expansion of macro 'condlog' + 132 | condlog(4, "%s: %s -> '%s'", __func__, attr, p); + | ^~~~~~~ +uevent.c: In function 'uevent_get_wwid': +uevent.c:132:25: note: format string is defined here + 132 | condlog(4, "%s: %s -> '%s'", __func__, attr, p); + | ^~ + +If p is NULL, use "(null)" instead. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/uevent.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmultipath/uevent.c b/libmultipath/uevent.c +index d38e8a7f..e0d13b11 100644 +--- a/libmultipath/uevent.c ++++ b/libmultipath/uevent.c +@@ -129,7 +129,7 @@ static const char* uevent_get_env_var(const struct uevent *uev, + } + } + +- condlog(4, "%s: %s -> '%s'", __func__, attr, p); ++ condlog(4, "%s: %s -> '%s'", __func__, attr, p ?: "(null)"); + return p; + + invalid: +-- +2.17.2 + diff --git a/0012-libmutipath-deprecate-delay_-_checks.patch b/0012-libmutipath-deprecate-delay_-_checks.patch deleted file mode 100644 index 55f4ca1..0000000 --- a/0012-libmutipath-deprecate-delay_-_checks.patch +++ /dev/null @@ -1,381 +0,0 @@ -From ef0b288867f20b4a1a532d693ac7b64e088b235a Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 30 Jul 2019 11:09:07 -0500 -Subject: [PATCH] libmutipath: deprecate delay_*_checks - -The delay_checks shaky paths detection method works the same way as the -san_path_err method, but not as well, with less configurability, and -with the code spread all over check_path(). The only real difference is -that marks the path as marginal for a certain number of path checks -instead of for a specific time. This patch deprecates the delay_checks -method and maps it to the the san_path_err method. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 18 +------- - libmultipath/propsel.c | 89 ++++++++++++++++++++++++++++---------- - libmultipath/propsel.h | 3 +- - libmultipath/structs.h | 10 ----- - multipath/multipath.conf.5 | 40 +++++++++-------- - multipathd/main.c | 34 ++------------- - 6 files changed, 96 insertions(+), 98 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 3238d485..9897cc37 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -342,8 +342,6 @@ int setup_map(struct multipath *mpp, char *params, int params_size, - select_dev_loss(conf, mpp); - select_reservation_key(conf, mpp); - select_deferred_remove(conf, mpp); -- select_delay_watch_checks(conf, mpp); -- select_delay_wait_checks(conf, mpp); - select_marginal_path_err_sample_time(conf, mpp); - select_marginal_path_err_rate_threshold(conf, mpp); - select_marginal_path_err_recheck_gap_time(conf, mpp); -@@ -351,6 +349,7 @@ int setup_map(struct multipath *mpp, char *params, int params_size, - select_san_path_err_threshold(conf, mpp); - select_san_path_err_forget_rate(conf, mpp); - select_san_path_err_recovery_time(conf, mpp); -+ select_delay_checks(conf, mpp); - select_skip_kpartx(conf, mpp); - select_max_sectors_kb(conf, mpp); - select_ghost_delay(conf, mpp); -@@ -360,21 +359,8 @@ int setup_map(struct multipath *mpp, char *params, int params_size, - marginal_pathgroups = conf->marginal_pathgroups; - pthread_cleanup_pop(1); - -- if (marginal_path_check_enabled(mpp)) { -- if (delay_check_enabled(mpp)) { -- condlog(1, "%s: WARNING: both marginal_path and delay_checks error detection selected", -- mpp->alias); -- condlog(0, "%s: unexpected behavior may occur!", -- mpp->alias); -- } -+ if (marginal_path_check_enabled(mpp)) - start_io_err_stat_thread(vecs); -- } -- if (san_path_check_enabled(mpp) && delay_check_enabled(mpp)) { -- condlog(1, "%s: WARNING: both san_path_err and delay_checks error detection selected", -- mpp->alias); -- condlog(0, "%s: unexpected behavior may occur!", -- mpp->alias); -- } - - n_paths = VECTOR_SIZE(mpp->paths); - /* -diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c -index 6af2513d..27e8d68a 100644 ---- a/libmultipath/propsel.c -+++ b/libmultipath/propsel.c -@@ -85,6 +85,10 @@ static const char autodetect_origin[] = - "(setting: storage device autodetected)"; - static const char marginal_path_origin[] = - "(setting: implied by marginal_path check)"; -+static const char delay_watch_origin[] = -+ "(setting: implied by delay_watch_checks)"; -+static const char delay_wait_origin[] = -+ "(setting: implied by delay_wait_checks)"; - - #define do_default(dest, value) \ - do { \ -@@ -877,39 +881,80 @@ out: - return 0; - } - --int select_delay_watch_checks(struct config *conf, struct multipath *mp) -+static inline int san_path_check_options_set(const struct multipath *mp) - { -- const char *origin; -+ return mp->san_path_err_threshold > 0 || -+ mp->san_path_err_forget_rate > 0 || -+ mp->san_path_err_recovery_time > 0; -+} -+ -+static int -+use_delay_watch_checks(struct config *conf, struct multipath *mp) -+{ -+ int value = NU_UNDEF; -+ const char *origin = default_origin; - char buff[12]; - -- mp_set_mpe(delay_watch_checks); -- mp_set_ovr(delay_watch_checks); -- mp_set_hwe(delay_watch_checks); -- mp_set_conf(delay_watch_checks); -- mp_set_default(delay_watch_checks, DEFAULT_DELAY_CHECKS); -+ do_set(delay_watch_checks, mp->mpe, value, multipaths_origin); -+ do_set(delay_watch_checks, conf->overrides, value, overrides_origin); -+ do_set_from_hwe(delay_watch_checks, mp, value, hwe_origin); -+ do_set(delay_watch_checks, conf, value, conf_origin); - out: -- if (print_off_int_undef(buff, 12, mp->delay_watch_checks) != 0) -- condlog(3, "%s: delay_watch_checks = %s %s", -- mp->alias, buff, origin); -- return 0; -+ if (print_off_int_undef(buff, 12, value) != 0) -+ condlog(3, "%s: delay_watch_checks = %s %s", mp->alias, buff, -+ origin); -+ return value; - } - --int select_delay_wait_checks(struct config *conf, struct multipath *mp) -+static int -+use_delay_wait_checks(struct config *conf, struct multipath *mp) - { -- const char *origin; -+ int value = NU_UNDEF; -+ const char *origin = default_origin; - char buff[12]; - -- mp_set_mpe(delay_wait_checks); -- mp_set_ovr(delay_wait_checks); -- mp_set_hwe(delay_wait_checks); -- mp_set_conf(delay_wait_checks); -- mp_set_default(delay_wait_checks, DEFAULT_DELAY_CHECKS); -+ do_set(delay_wait_checks, mp->mpe, value, multipaths_origin); -+ do_set(delay_wait_checks, conf->overrides, value, overrides_origin); -+ do_set_from_hwe(delay_wait_checks, mp, value, hwe_origin); -+ do_set(delay_wait_checks, conf, value, conf_origin); - out: -- if (print_off_int_undef(buff, 12, mp->delay_wait_checks) != 0) -- condlog(3, "%s: delay_wait_checks = %s %s", -- mp->alias, buff, origin); -- return 0; -+ if (print_off_int_undef(buff, 12, value) != 0) -+ condlog(3, "%s: delay_wait_checks = %s %s", mp->alias, buff, -+ origin); -+ return value; -+} -+ -+int select_delay_checks(struct config *conf, struct multipath *mp) -+{ -+ int watch_checks, wait_checks; -+ char buff[12]; - -+ watch_checks = use_delay_watch_checks(conf, mp); -+ wait_checks = use_delay_wait_checks(conf, mp); -+ if (watch_checks <= 0 && wait_checks <= 0) -+ return 0; -+ if (san_path_check_options_set(mp)) { -+ condlog(3, "%s: both marginal_path and delay_checks error detection options selected", mp->alias); -+ condlog(3, "%s: ignoring delay_checks options", mp->alias); -+ return 0; -+ } -+ mp->san_path_err_threshold = 1; -+ condlog(3, "%s: san_path_err_threshold = 1 %s", mp->alias, -+ (watch_checks > 0)? delay_watch_origin : delay_wait_origin); -+ if (watch_checks > 0) { -+ mp->san_path_err_forget_rate = watch_checks; -+ print_off_int_undef(buff, 12, mp->san_path_err_forget_rate); -+ condlog(3, "%s: san_path_err_forget_rate = %s %s", mp->alias, -+ buff, delay_watch_origin); -+ } -+ if (wait_checks > 0) { -+ mp->san_path_err_recovery_time = wait_checks * -+ conf->max_checkint; -+ print_off_int_undef(buff, 12, mp->san_path_err_recovery_time); -+ condlog(3, "%s: san_path_err_recovery_time = %s %s", mp->alias, -+ buff, delay_wait_origin); -+ } -+ return 0; - } - - static int san_path_deprecated_warned; -diff --git a/libmultipath/propsel.h b/libmultipath/propsel.h -index b352c16a..ddfd6262 100644 ---- a/libmultipath/propsel.h -+++ b/libmultipath/propsel.h -@@ -22,8 +22,7 @@ int select_retain_hwhandler (struct config *conf, struct multipath * mp); - int select_detect_prio(struct config *conf, struct path * pp); - int select_detect_checker(struct config *conf, struct path * pp); - int select_deferred_remove(struct config *conf, struct multipath *mp); --int select_delay_watch_checks (struct config *conf, struct multipath * mp); --int select_delay_wait_checks (struct config *conf, struct multipath * mp); -+int select_delay_checks(struct config *conf, struct multipath * mp); - int select_skip_kpartx (struct config *conf, struct multipath * mp); - int select_max_sectors_kb (struct config *conf, struct multipath * mp); - int select_san_path_err_forget_rate(struct config *conf, struct multipath *mp); -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index a8b9d325..a3adf906 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -268,8 +268,6 @@ struct path { - int pgindex; - int detect_prio; - int detect_checker; -- int watch_checks; -- int wait_checks; - int tpgs; - char * uid_attribute; - char * getuid; -@@ -321,8 +319,6 @@ struct multipath { - int fast_io_fail; - int retain_hwhandler; - int deferred_remove; -- int delay_watch_checks; -- int delay_wait_checks; - int san_path_err_threshold; - int san_path_err_forget_rate; - int san_path_err_recovery_time; -@@ -393,12 +389,6 @@ static inline int san_path_check_enabled(const struct multipath *mpp) - mpp->san_path_err_recovery_time > 0; - } - --static inline int delay_check_enabled(const struct multipath *mpp) --{ -- return mpp->delay_watch_checks != NU_NO || -- mpp->delay_wait_checks != NU_NO; --} -- - struct pathgroup { - long id; - int status; -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index f7d21b4c..08297a41 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -1013,10 +1013,12 @@ The default is: \fBno\fR - . - .TP - .B delay_watch_checks --If set to a value greater than 0, multipathd will watch paths that have --recently become valid for this many checks. If they fail again while they are --being watched, when they next become valid, they will not be used until they --have stayed up for \fIdelay_wait_checks\fR checks. See "Shaky paths detection" below. -+This option is \fBdeprecated\fR, and mapped to \fIsan_path_err_forget_rate\fR. -+If this is set to a value greater than 0 and no \fIsan_path_err\fR options -+are set, \fIsan_path_err_forget_rate\fR will be set to the value of -+\fIdelay_watch_checks\fR and \fIsan_path_err_threshold\fR will be set to 1. -+See the \fIsan_path_err_forget_rate\fR and \fIsan_path_err_threshold\fR -+options, and "Shaky paths detection" below for more information. - .RS - .TP - The default is: \fBno\fR -@@ -1025,10 +1027,14 @@ The default is: \fBno\fR - . - .TP - .B delay_wait_checks --If set to a value greater than 0, when a device that has recently come back --online fails again within \fIdelay_watch_checks\fR checks, the next time it --comes back online, it will marked and delayed, and not used until it has passed --\fIdelay_wait_checks\fR checks. See "Shaky paths detection" below. -+This option is \fBdeprecated\fR, and mapped to \fIsan_path_err_recovery_time\fR. -+If this is set to a value greater than 0 and no \fIsan_path_err\fR options -+are set, \fIsan_path_err_recovery_time\fR will be set to the value of -+\fIdelay_wait_checks\fR times \fImax_polling_interval\fR. This will give -+approximately the same wait time as delay_wait_checks previously did. -+Also, \fIsan_path_err_threshold\fR will be set to 1. See the -+\fIsan_path_err_recovery_time\fR and \fIsan_path_err_threshold\fR -+options, and "Shaky paths detection" below for more information. - .RS - .TP - The default is: \fBno\fR -@@ -1689,13 +1695,10 @@ if the healthy state appears to be stable. The logic of determining - differs between the three methods. - .TP 8 - .B \(dqdelay_checks\(dq failure tracking --If a path fails again within a --\fIdelay_watch_checks\fR interval after a failure, don't --reinstate it until it passes a \fIdelay_wait_checks\fR interval --in always good status. --The intervals are measured in \(dqticks\(dq, i.e. the --time between path checks by multipathd, which is variable and controlled by the --\fIpolling_interval\fR and \fImax_polling_interval\fR parameters. -+This method is \fBdeprecated\fR and mapped to the \(dqsan_path_err\(dq method. -+See the \fIdelay_watch_checks\fR and \fIdelay_wait_checks\fR options above -+for more information. -+ - .TP - .B \(dqmarginal_path\(dq failure tracking - If a second failure event (good->bad transition) occurs within -@@ -1712,12 +1715,13 @@ in seconds. - .B \(dqsan_path_err\(dq failure tracking - multipathd counts path failures for each path. Once the number of failures - exceeds the value given by \fIsan_path_err_threshold\fR, the path is not --reinstated for \fIsan_path_err_recovery_time\fR ticks. While counting -+reinstated for \fIsan_path_err_recovery_time\fR seconds. While counting - failures, multipathd \(dqforgets\(dq one past failure every - \(dqsan_path_err_forget_rate\(dq ticks; thus if errors don't occur more - often then once in the forget rate interval, the failure count doesn't --increase and the threshold is never reached. As for the \fIdelay_xy\fR method, --intervals are measured in \(dqticks\(dq. -+increase and the threshold is never reached. Ticks are the time between -+path checks by multipathd, which is variable and controlled by the -+\fIpolling_interval\fR and \fImax_polling_interval\fR parameters. - . - .RS 8 - .LP -diff --git a/multipathd/main.c b/multipathd/main.c -index 7db15736..dca2214c 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -2122,16 +2122,6 @@ check_path (struct vectors * vecs, struct path * pp, int ticks) - return 1; - } - -- if ((newstate == PATH_UP || newstate == PATH_GHOST) && -- pp->wait_checks > 0) { -- if (pp->mpp->nr_active > 0) { -- pp->state = PATH_DELAYED; -- pp->wait_checks--; -- return 1; -- } else -- pp->wait_checks = 0; -- } -- - /* - * don't reinstate failed path, if its in stand-by - * and if target supports only implicit tpgs mode. -@@ -2162,19 +2152,10 @@ check_path (struct vectors * vecs, struct path * pp, int ticks) - * proactively fail path in the DM - */ - if (oldstate == PATH_UP || -- oldstate == PATH_GHOST) { -+ oldstate == PATH_GHOST) - fail_path(pp, 1); -- if (pp->mpp->delay_wait_checks > 0 && -- pp->watch_checks > 0) { -- pp->wait_checks = pp->mpp->delay_wait_checks; -- pp->watch_checks = 0; -- } -- } else { -+ else - fail_path(pp, 0); -- if (pp->wait_checks > 0) -- pp->wait_checks = -- pp->mpp->delay_wait_checks; -- } - - /* - * cancel scheduled failback -@@ -2200,15 +2181,10 @@ check_path (struct vectors * vecs, struct path * pp, int ticks) - * reinstate this path - */ - if (oldstate != PATH_UP && -- oldstate != PATH_GHOST) { -- if (pp->mpp->delay_watch_checks > 0) -- pp->watch_checks = pp->mpp->delay_watch_checks; -+ oldstate != PATH_GHOST) - add_active = 1; -- } else { -- if (pp->watch_checks > 0) -- pp->watch_checks--; -+ else - add_active = 0; -- } - if (!disable_reinstate && reinstate_path(pp, add_active)) { - condlog(3, "%s: reload map", pp->dev); - ev_add_path(pp, vecs, 1); -@@ -2253,8 +2229,6 @@ check_path (struct vectors * vecs, struct path * pp, int ticks) - condlog(4, "%s: delay next check %is", - pp->dev_t, pp->checkint); - } -- if (pp->watch_checks > 0) -- pp->watch_checks--; - pp->tick = pp->checkint; - } - } --- -2.17.2 - diff --git a/0021-RH-fixup-udev-rules-for-redhat.patch b/0013-RH-fixup-udev-rules-for-redhat.patch similarity index 95% rename from 0021-RH-fixup-udev-rules-for-redhat.patch rename to 0013-RH-fixup-udev-rules-for-redhat.patch index 444f5cf..1a8e108 100644 --- a/0021-RH-fixup-udev-rules-for-redhat.patch +++ b/0013-RH-fixup-udev-rules-for-redhat.patch @@ -1,4 +1,4 @@ -From c1df27f4efd0c36d6ceecf5c850a68859e7d5fe5 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 13 Apr 2017 07:22:23 -0500 Subject: [PATCH] RH: fixup udev rules for redhat @@ -15,7 +15,7 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 56c3eda0..2e8946ca 100644 +index 9060ac9b..034752d9 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -53,7 +53,7 @@ endif diff --git a/0013-multipathd-use-marginal_pathgroups.patch b/0013-multipathd-use-marginal_pathgroups.patch deleted file mode 100644 index 86cbc49..0000000 --- a/0013-multipathd-use-marginal_pathgroups.patch +++ /dev/null @@ -1,111 +0,0 @@ -From d43ffc1112c0385737f88bab1c884e4ff4c316f5 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 31 Jul 2019 18:11:41 -0500 -Subject: [PATCH] multipathd: use marginal_pathgroups - -This commit makes the marginal_pathgroups option work with the -existing methods for determining marginal paths. It also merges the -code for the marginal_path and sand_path_err methods. This has the -side effect of making the marginal_path code set a marginal path's state -to "delayed" instead of "shaky" like it previously did. - -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 53 +++++++++++++++++++++++++++++++++-------------- - 1 file changed, 38 insertions(+), 15 deletions(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index dca2214c..04b2b56a 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -1960,6 +1960,18 @@ reinstate_path: - return 0; - } - -+static int -+should_skip_path(struct path *pp){ -+ if (marginal_path_check_enabled(pp->mpp)) { -+ if (pp->io_err_disable_reinstate && need_io_err_check(pp)) -+ return 1; -+ } else if (san_path_check_enabled(pp->mpp)) { -+ if (check_path_reinstate_state(pp)) -+ return 1; -+ } -+ return 0; -+} -+ - /* - * Returns '1' if the path has been checked, '-1' if it was blacklisted - * and '0' otherwise -@@ -1975,6 +1987,7 @@ check_path (struct vectors * vecs, struct path * pp, int ticks) - int oldchkrstate = pp->chkrstate; - int retrigger_tries, checkint, max_checkint, verbosity; - struct config *conf; -+ int marginal_pathgroups, marginal_changed = 0; - int ret; - - if ((pp->initialized == INIT_OK || -@@ -1991,6 +2004,7 @@ check_path (struct vectors * vecs, struct path * pp, int ticks) - checkint = conf->checkint; - max_checkint = conf->max_checkint; - verbosity = conf->verbosity; -+ marginal_pathgroups = conf->marginal_pathgroups; - put_multipath_config(conf); - - if (pp->checkint == CHECKINT_UNDEF) { -@@ -2106,20 +2120,27 @@ check_path (struct vectors * vecs, struct path * pp, int ticks) - set_no_path_retry(pp->mpp); - - if ((newstate == PATH_UP || newstate == PATH_GHOST) && -- check_path_reinstate_state(pp)) { -- pp->state = PATH_DELAYED; -- return 1; -- } -- -- if ((newstate == PATH_UP || newstate == PATH_GHOST) && -- pp->io_err_disable_reinstate && need_io_err_check(pp)) { -- pp->state = PATH_SHAKY; -- /* -- * to reschedule as soon as possible,so that this path can -- * be recoverd in time -- */ -- pp->tick = 1; -- return 1; -+ (san_path_check_enabled(pp->mpp) || -+ marginal_path_check_enabled(pp->mpp))) { -+ int was_marginal = pp->marginal; -+ if (should_skip_path(pp)) { -+ if (!marginal_pathgroups) { -+ if (marginal_path_check_enabled(pp->mpp)) -+ /* to reschedule as soon as possible, -+ * so that this path can be recovered -+ * in time */ -+ pp->tick = 1; -+ pp->state = PATH_DELAYED; -+ return 1; -+ } -+ if (!was_marginal) { -+ pp->marginal = 1; -+ marginal_changed = 1; -+ } -+ } else if (marginal_pathgroups && was_marginal) { -+ pp->marginal = 0; -+ marginal_changed = 1; -+ } - } - - /* -@@ -2258,7 +2279,9 @@ check_path (struct vectors * vecs, struct path * pp, int ticks) - */ - condlog(4, "path prio refresh"); - -- if (update_prio(pp, new_path_up) && -+ if (marginal_changed) -+ update_path_groups(pp->mpp, vecs, 1); -+ else if (update_prio(pp, new_path_up) && - (pp->mpp->pgpolicyfn == (pgpolicyfn *)group_by_prio) && - pp->mpp->pgfailback == -FAILBACK_IMMEDIATE) - update_path_groups(pp->mpp, vecs, !new_path_up); --- -2.17.2 - diff --git a/0022-RH-Remove-the-property-blacklist-exception-builtin.patch b/0014-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 87% rename from 0022-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0014-RH-Remove-the-property-blacklist-exception-builtin.patch index 925aab9..10cc1b3 100644 --- a/0022-RH-Remove-the-property-blacklist-exception-builtin.patch +++ b/0014-RH-Remove-the-property-blacklist-exception-builtin.patch @@ -1,4 +1,4 @@ -From 46cfd1a474d1c3e2724782c493d0ea72c8438807 Mon Sep 17 00:00:00 2001 +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 @@ -14,9 +14,9 @@ it. Signed-off-by: Benjamin Marzinski --- libmultipath/blacklist.c | 9 ++------- - multipath/multipath.conf.5 | 12 ++++++------ + multipath/multipath.conf.5 | 11 ++++++----- tests/blacklist.c | 6 ++---- - 3 files changed, 10 insertions(+), 17 deletions(-) + 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c index 00e8dbdb..d9691b17 100644 @@ -46,10 +46,10 @@ index 00e8dbdb..d9691b17 100644 udev_device_get_properties_list_entry(udev)) { diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 101e1a88..b4837b15 100644 +index 05a5e8ff..3455b1cc 100644 --- a/multipath/multipath.conf.5 +++ b/multipath/multipath.conf.5 -@@ -1287,9 +1287,14 @@ keywords. Both are regular expressions. For a full description of these keywords +@@ -1286,9 +1286,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, @@ -65,7 +65,7 @@ index 101e1a88..b4837b15 100644 . .RS .PP -@@ -1300,11 +1305,6 @@ Blacklisting by missing properties is only applied to devices which do have the +@@ -1299,10 +1304,6 @@ Blacklisting by missing properties is only applied to devices which do have the property specified by \fIuid_attribute\fR (e.g. \fIID_SERIAL\fR) set. Previously, it was applied to every device, possibly causing devices to be blacklisted because of temporary I/O error conditions. @@ -73,15 +73,14 @@ index 101e1a88..b4837b15 100644 -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 + .RE .TP .B protocol - Regular expression for the protocol of a device to be excluded/included. diff --git a/tests/blacklist.c b/tests/blacklist.c -index 362c44d9..ea284939 100644 +index 6e7c1864..cc8a9a4a 100644 --- a/tests/blacklist.c +++ b/tests/blacklist.c -@@ -291,7 +291,7 @@ static void test_property_missing(void **state) +@@ -271,7 +271,7 @@ static void test_property_missing(void **state) conf.blist_property = blist_property_wwn; expect_condlog(3, "sdb: blacklisted, udev property missing\n"); assert_int_equal(filter_property(&conf, &udev, 3, "ID_SERIAL"), @@ -90,7 +89,7 @@ index 362c44d9..ea284939 100644 assert_int_equal(filter_property(&conf, &udev, 3, "ID_BLAH"), MATCH_NOTHING); assert_int_equal(filter_property(&conf, &udev, 3, ""), -@@ -383,9 +383,7 @@ static void test_filter_path_missing1(void **state) +@@ -363,9 +363,7 @@ static void test_filter_path_missing1(void **state) conf.blist_device = blist_device_foo_bar; conf.blist_protocol = blist_protocol_fcp; conf.blist_wwid = blist_wwid_xyzzy; diff --git a/0014-multipath-update-man-pages.patch b/0014-multipath-update-man-pages.patch deleted file mode 100644 index 6c7261b..0000000 --- a/0014-multipath-update-man-pages.patch +++ /dev/null @@ -1,99 +0,0 @@ -From 0992a545413cf2bcbde18c90f04b9e5b1077fd62 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 1 Aug 2019 16:29:41 -0500 -Subject: [PATCH] multipath: update man pages - -Add documentation for the marginal_pathgroups option and the -(un)setmarginal commands. - -Signed-off-by: Benjamin Marzinski ---- - multipath/multipath.conf.5 | 34 ++++++++++++++++++++++++++++++---- - multipathd/multipathd.8 | 19 +++++++++++++++++++ - 2 files changed, 49 insertions(+), 4 deletions(-) - -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 08297a41..ac8eadd0 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -1042,6 +1042,28 @@ The default is: \fBno\fR - . - . - .TP -+.B marginal_pathgroups -+If set to \fIno\fR, the \fIdelay_*_checks\fR, \fImarginal_path_*\fR, and -+\fIsan_path_err_*\fR options will keep marginal, or \(dqshaky\(dq, paths from -+being reinstated until they have been monitored for some time. This can cause -+situations where all non-marginal paths are down, and no paths are usable -+until multipathd detects this and reinstates a marginal path. If the multipath -+device is not configured to queue IO in this case, it can cause IO errors to -+occur, even though there are marginal paths available. However, if this -+option is set to \fIyes\fR, when one of the marginal path detecting methods -+determines that a path is marginal, it will be reinstated and placed in a -+seperate pathgroup that will only be used after all the non-marginal pathgroups -+have been tried first. This prevents the possibility of IO errors occuring -+while marginal paths are still usable. After the path has been monitored -+for the configured time, and is declared healthy, it will be returned to its -+normal pathgroup. See "Shaky paths detection" below for more information. -+.RS -+.TP -+The default is: \fBno\fR -+.RE -+. -+. -+.TP - .B find_multipaths - This option controls whether multipath and multipathd try to create multipath - maps over non-blacklisted devices they encounter. This matters a) when a device is -@@ -1689,10 +1711,14 @@ events. \fImultipathd\fR supports three different methods for detecting this - situation and dealing with it. All methods share the same basic mode of - operation: If a path is found to be \(dqshaky\(dq or \(dqflipping\(dq, - and appears to be in healthy status, it is not reinstated (put back to use) --immediately. Instead, it is watched for some time, and only reinstated --if the healthy state appears to be stable. The logic of determining --\(dqshaky\(dq condition, as well as the logic when to reinstate, --differs between the three methods. -+immediately. Instead, it is placed in the \(dqdelayed\(dq state and watched -+for some time, and only reinstated if the healthy state appears to be stable. -+If the \fImarginal_pathgroups\fR option is set, the path will reinstated -+immediately, but placed in a special pathgroup for marginal paths. Marginal -+pathgroups will not be used until all other pathgroups have been tried. At the -+time when the path would normally be reinstated, it will be returned to its -+normal pathgroup. The logic of determining \(dqshaky\(dq condition, as well as -+the logic when to reinstate, differs between the three methods. - .TP 8 - .B \(dqdelay_checks\(dq failure tracking - This method is \fBdeprecated\fR and mapped to the \(dqsan_path_err\(dq method. -diff --git a/multipathd/multipathd.8 b/multipathd/multipathd.8 -index edac7a92..048a838d 100644 ---- a/multipathd/multipathd.8 -+++ b/multipathd/multipathd.8 -@@ -277,6 +277,25 @@ Remove the persistent reservation key associated with $map from the - \fIreservation_key\fR is set to \fBfile\fR in \fI/etc/multipath.conf\fR. - . - .TP -+.B path $path setmarginal -+move $path to a marginal pathgroup. The path will remain in the marginal -+path group until \fIunsetmarginal\fR is called. This command will only -+work if \fImarginal_pathgroups\fR is enabled and there is no Shaky paths -+detection method configured (see the multipath.conf man page for details). -+. -+.TP -+.B path $path unsetmarginal -+return marginal path $path to its normal pathgroup. This command will only -+work if \fImarginal_pathgroups\fR is enabled and there is no Shaky paths -+detection method configured (see the multipath.conf man page for details). -+. -+.TP -+.B map $map unsetmarginal -+return all marginal paths in $map to their normal pathgroups. This command -+will only work if \fImarginal_pathgroups\fR is enabled and there is no Shaky -+paths detection method configured (see the multipath.conf man page for details). -+. -+.TP - .B quit|exit - End interactive session. - . --- -2.17.2 - diff --git a/0023-RH-don-t-start-without-a-config-file.patch b/0015-RH-don-t-start-without-a-config-file.patch similarity index 95% rename from 0023-RH-don-t-start-without-a-config-file.patch rename to 0015-RH-don-t-start-without-a-config-file.patch index 7d5fe18..86cdf68 100644 --- a/0023-RH-don-t-start-without-a-config-file.patch +++ b/0015-RH-don-t-start-without-a-config-file.patch @@ -1,4 +1,4 @@ -From 4e4c589657eecfe5d37636ce91eb2945f63fc0a6 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Wed, 15 Oct 2014 10:39:30 -0500 Subject: [PATCH] RH: don't start without a config file @@ -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 20e3b8bf..c36bc69c 100644 +index b4d87689..b36778b0 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c @@ -26,6 +26,7 @@ @@ -31,7 +31,7 @@ index 20e3b8bf..c36bc69c 100644 static int hwe_strmatch (const struct hwentry *hwe1, const struct hwentry *hwe2) -@@ -743,6 +744,20 @@ load_config (char * file) +@@ -778,6 +779,20 @@ load_config (char * file) goto out; } factorize_hwtable(conf->hwtable, builtin_hwtable_size, file); @@ -53,7 +53,7 @@ index 20e3b8bf..c36bc69c 100644 conf->processed_main_config = 1; diff --git a/libmultipath/config.h b/libmultipath/config.h -index ffec3103..6dbf553d 100644 +index ceecff2d..3368d8c9 100644 --- a/libmultipath/config.h +++ b/libmultipath/config.h @@ -9,6 +9,7 @@ diff --git a/0015-multipath.conf-add-enable_foreign-parameter.patch b/0015-multipath.conf-add-enable_foreign-parameter.patch deleted file mode 100644 index 97ef17c..0000000 --- a/0015-multipath.conf-add-enable_foreign-parameter.patch +++ /dev/null @@ -1,230 +0,0 @@ -From 959cf306b6ad0bbfc73e7745161ef4edfa821a47 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 15 Aug 2019 14:46:54 +0000 -Subject: [PATCH] multipath.conf: add "enable_foreign" parameter - -This new configuration parameter can be used to selectively -enable foreign libraries. The value is a regular expression, -against which foreign library names such as "nvme" are matched. -By setting this to a value that matches no foreign library -(e.g. "^$" or "NONE"), foreign code is completely disabled. -By default, all available foreign libraries are loaded. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/config.h | 1 + - libmultipath/defaults.h | 2 ++ - libmultipath/dict.c | 6 +++++ - libmultipath/foreign.c | 53 +++++++++++++++++++++++++++++++++++++---- - libmultipath/foreign.h | 3 ++- - multipath/main.c | 2 +- - multipathd/main.c | 2 +- - 7 files changed, 62 insertions(+), 7 deletions(-) - -diff --git a/libmultipath/config.h b/libmultipath/config.h -index 0b978970..ffec3103 100644 ---- a/libmultipath/config.h -+++ b/libmultipath/config.h -@@ -225,6 +225,7 @@ struct config { - vector elist_device; - vector elist_property; - vector elist_protocol; -+ char *enable_foreign; - }; - - extern struct udev * udev; -diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h -index decc9335..4dfe007c 100644 ---- a/libmultipath/defaults.h -+++ b/libmultipath/defaults.h -@@ -48,6 +48,8 @@ - #define DEFAULT_FIND_MULTIPATHS_TIMEOUT -10 - #define DEFAULT_UNKNOWN_FIND_MULTIPATHS_TIMEOUT 1 - #define DEFAULT_ALL_TG_PT ALL_TG_PT_OFF -+/* Enable all foreign libraries by default */ -+#define DEFAULT_ENABLE_FOREIGN "" - - #define CHECKINT_UNDEF (~0U) - #define DEFAULT_CHECKINT 5 -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index b5feb884..1b3d0373 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -610,6 +610,10 @@ declare_def_handler(find_multipaths_timeout, set_int) - declare_def_snprint_defint(find_multipaths_timeout, print_int, - DEFAULT_FIND_MULTIPATHS_TIMEOUT) - -+declare_def_handler(enable_foreign, set_str) -+declare_def_snprint_defstr(enable_foreign, print_str, -+ DEFAULT_ENABLE_FOREIGN) -+ - static int - def_config_dir_handler(struct config *conf, vector strvec) - { -@@ -1713,6 +1717,8 @@ init_keywords(vector keywords) - &def_find_multipaths_timeout_handler, - &snprint_def_find_multipaths_timeout); - install_keyword("marginal_pathgroups", &def_marginal_pathgroups_handler, &snprint_def_marginal_pathgroups); -+ install_keyword("enable_foreign", &def_enable_foreign_handler, -+ &snprint_def_enable_foreign); - __deprecated install_keyword("default_selector", &def_selector_handler, NULL); - __deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL); - __deprecated install_keyword("default_uid_attribute", &def_uid_attribute_handler, NULL); -diff --git a/libmultipath/foreign.c b/libmultipath/foreign.c -index 48e8d247..4b34e141 100644 ---- a/libmultipath/foreign.c -+++ b/libmultipath/foreign.c -@@ -16,6 +16,7 @@ - */ - - #include -+#include - #include - #include - #include -@@ -25,6 +26,7 @@ - #include - #include - #include -+#include - #include "vector.h" - #include "debug.h" - #include "util.h" -@@ -111,17 +113,45 @@ static int select_foreign_libs(const struct dirent *di) - return fnmatch(foreign_pattern, di->d_name, FNM_FILE_NAME) == 0; - } - --static int _init_foreign(const char *multipath_dir) -+static void free_pre(void *arg) -+{ -+ regex_t **pre = arg; -+ -+ if (pre != NULL && *pre != NULL) { -+ regfree(*pre); -+ free(*pre); -+ *pre = NULL; -+ } -+} -+ -+static int _init_foreign(const char *multipath_dir, const char *enable) - { - char pathbuf[PATH_MAX]; - struct dirent **di; - struct scandir_result sr; - int r, i; -+ regex_t *enable_re = NULL; - - foreigns = vector_alloc(); - if (foreigns == NULL) - return -ENOMEM; - -+ pthread_cleanup_push(free_pre, &enable_re); -+ enable_re = calloc(1, sizeof(*enable_re)); -+ if (enable_re) { -+ const char *str = enable ? enable : DEFAULT_ENABLE_FOREIGN; -+ -+ r = regcomp(enable_re, str, REG_EXTENDED|REG_NOSUB); -+ if (r != 0) { -+ char errbuf[64]; -+ -+ (void)regerror(r, enable_re, errbuf, sizeof(errbuf)); -+ condlog (2, "%s: error compiling enable_foreign = \"%s\": \"%s\"", -+ __func__, str, errbuf); -+ free_pre(&enable_re); -+ } -+ } -+ - r = scandir(multipath_dir, &di, select_foreign_libs, alphasort); - - if (r == 0) { -@@ -163,6 +193,20 @@ static int _init_foreign(const char *multipath_dir) - memset(fgn, 0, sizeof(*fgn)); - strlcpy((char*)fgn + offsetof(struct foreign, name), c, namesz); - -+ if (enable_re != NULL) { -+ int ret = regexec(enable_re, fgn->name, 0, NULL, 0); -+ -+ if (ret == REG_NOMATCH) { -+ condlog(3, "%s: foreign library \"%s\" is not enabled", -+ __func__, fgn->name); -+ free(fgn); -+ continue; -+ } else if (ret != 0) -+ /* assume it matches */ -+ condlog(2, "%s: error %d in regexec() for %s", -+ __func__, ret, fgn->name); -+ } -+ - snprintf(pathbuf, sizeof(pathbuf), "%s/%s", multipath_dir, fn); - fgn->handle = dlopen(pathbuf, RTLD_NOW|RTLD_LOCAL); - msg = dlerror(); -@@ -205,11 +249,12 @@ static int _init_foreign(const char *multipath_dir) - dl_err: - free_foreign(fgn); - } -- pthread_cleanup_pop(1); -+ pthread_cleanup_pop(1); /* free_scandir_result */ -+ pthread_cleanup_pop(1); /* free_pre */ - return 0; - } - --int init_foreign(const char *multipath_dir) -+int init_foreign(const char *multipath_dir, const char *enable) - { - int ret; - -@@ -222,7 +267,7 @@ int init_foreign(const char *multipath_dir) - } - - pthread_cleanup_push(unlock_foreigns, NULL); -- ret = _init_foreign(multipath_dir); -+ ret = _init_foreign(multipath_dir, enable); - pthread_cleanup_pop(1); - - return ret; -diff --git a/libmultipath/foreign.h b/libmultipath/foreign.h -index 697f12f8..acd33601 100644 ---- a/libmultipath/foreign.h -+++ b/libmultipath/foreign.h -@@ -195,9 +195,10 @@ struct foreign { - * init_foreign(dir) - * load and initialize foreign multipath libraries in dir (libforeign-*.so). - * @param dir: directory to search -+ * @param enable: regex to match foreign library name ("*" above) against - * @returns: 0 on success, negative value on failure. - */ --int init_foreign(const char *multipath_dir); -+int init_foreign(const char *multipath_dir, const char *enable); - - /** - * cleanup_foreign(dir) -diff --git a/multipath/main.c b/multipath/main.c -index 96a11468..4f4d8e89 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -1050,7 +1050,7 @@ main (int argc, char *argv[]) - goto out; - } - /* Failing here is non-fatal */ -- init_foreign(conf->multipath_dir); -+ init_foreign(conf->multipath_dir, conf->enable_foreign); - if (cmd == CMD_USABLE_PATHS) { - r = check_usable_paths(conf, dev, dev_type) ? - RTVL_FAIL : RTVL_OK; -diff --git a/multipathd/main.c b/multipathd/main.c -index 04b2b56a..8826620d 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -2848,7 +2848,7 @@ child (void * param) - } - /* Failing this is non-fatal */ - -- init_foreign(conf->multipath_dir); -+ init_foreign(conf->multipath_dir, conf->enable_foreign); - - if (poll_dmevents) - poll_dmevents = dmevent_poll_supported(); --- -2.17.2 - diff --git a/0024-RH-use-rpm-optflags-if-present.patch b/0016-RH-use-rpm-optflags-if-present.patch similarity index 52% rename from 0024-RH-use-rpm-optflags-if-present.patch rename to 0016-RH-use-rpm-optflags-if-present.patch index 8721a82..be1af2e 100644 --- a/0024-RH-use-rpm-optflags-if-present.patch +++ b/0016-RH-use-rpm-optflags-if-present.patch @@ -1,4 +1,4 @@ -From e08dd1d6abe62714c484b046a68c95c3803716dd Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Wed, 19 Apr 2017 06:10:01 -0500 Subject: [PATCH] RH: use rpm optflags if present @@ -9,45 +9,56 @@ still being generic. Signed-off-by: Benjamin Marzinski --- - Makefile.inc | 24 ++++++++++++++++-------- - 1 file changed, 16 insertions(+), 8 deletions(-) + Makefile.inc | 29 +++++++++++++++++++++-------- + 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 2e8946ca..1b2f47a8 100644 +index 034752d9..c2abd301 100644 --- a/Makefile.inc +++ b/Makefile.inc -@@ -88,15 +88,23 @@ TEST_CC_OPTION = $(shell \ +@@ -89,16 +89,29 @@ TEST_CC_OPTION = $(shell \ echo "$(2)"; \ fi) -STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector) ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers,) -- --OPTFLAGS = -O2 -g -pipe -Wall -Wextra -Wformat=2 -Werror=implicit-int \ -- -Werror=implicit-function-declaration -Werror=format-security \ -- -Wno-sign-compare -Wno-unused-parameter -Wno-clobbered \ -- -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) \ -- -Wp,-D_FORTIFY_SOURCE=2 $(STACKPROT) \ -- --param=ssp-buffer-size=4 + WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered -Wno-error=clobbered,) +ifndef RPM_OPT_FLAGS + STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector) + OPTFLAGS = -O2 -g -pipe -Wall -Werror=format-security \ + -Wp,-D_FORTIFY_SOURCE=2 -fexceptions \ -+ $(STACKPROT) --param=ssp-buffer-size=4 \ -+ -grecord-gcc-switches ++ $(STACKPROT) -grecord-gcc-switches \ ++ -fasynchronous-unwind-tables + ifeq ($(shell test -f /usr/lib/rpm/redhat/redhat-hardened-cc1 && echo 1),1) + OPTFLAGS += -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 + endif ++ ifeq ($(shell test -f /usr/lib/rpm/redhat/redhat-annobin-cc1 && echo 1),1) ++ OPTFLAGS += -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 ++ endif +else + OPTFLAGS = $(RPM_OPT_FLAGS) +endif -+OPTFLAGS += -Wextra -Wstrict-prototypes -Wformat=2 -Werror=implicit-int \ -+ -Werror=implicit-function-declaration -Wno-sign-compare \ -+ -Wno-unused-parameter $(ERROR_DISCARDED_QUALIFIERS) \ -+ -Werror=cast-qual ++OPTFLAGS += -Werror -Wextra -Wstrict-prototypes -Wformat=2 \ ++ -Werror=implicit-int -Werror=implicit-function-declaration \ ++ $(WNOCLOBBERED) \ ++ -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) \ ++ --param=ssp-buffer-size=4 +-OPTFLAGS = -O2 -g -pipe -Werror -Wall -Wextra -Wformat=2 -Werror=implicit-int \ +- -Werror=implicit-function-declaration -Werror=format-security \ +- $(WNOCLOBBERED) \ +- -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) \ +- $(STACKPROT) --param=ssp-buffer-size=4 +-CPPFLAGS := -Wp,-D_FORTIFY_SOURCE=2 CFLAGS := $(OPTFLAGS) -DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" \ -MMD -MP $(CFLAGS) + BIN_CFLAGS = -fPIE -DPIE +@@ -135,4 +148,4 @@ check_file = $(shell \ + + %.o: %.c + @echo building $@ because of $? +- $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< ++ $(CC) $(CFLAGS) -c -o $@ $< -- 2.17.2 diff --git a/0016-multipath.conf.5-document-foreign-library-support.patch b/0016-multipath.conf.5-document-foreign-library-support.patch deleted file mode 100644 index 4988e4d..0000000 --- a/0016-multipath.conf.5-document-foreign-library-support.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 1439bf7acc88b6a398e1a390045dcac9e3163e53 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 15 Aug 2019 14:46:56 +0000 -Subject: [PATCH] multipath.conf.5: document foreign library support - -Add documentation for foreign library support, and for the -"enable_foreign" parameter. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - multipath/multipath.conf.5 | 40 ++++++++++++++++++++++++++++++++++++++ - 1 file changed, 40 insertions(+) - -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index ac8eadd0..101e1a88 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -1222,6 +1222,21 @@ makes multipath immediately mark a device with only ghost paths as ready. - The default is: \fBno\fR - .RE - . -+. -+.TP -+.B enable_foreign -+Enables or disables foreign libraries (see section -+.I FOREIGN MULTIPATH SUPPORT -+below). The value is a regular expression; foreign libraries are loaded -+if their name (e.g. \(dqnvme\(dq) matches the expression. By default, -+all foreign libraries are enabled. -+.RS -+.TP -+The default is: \fB\(dq\(dq\fR (the empty regular expression) -+.RE -+. -+. -+ - . - .\" ---------------------------------------------------------------------------- - .SH "blacklist and blacklist_exceptions sections" -@@ -1765,6 +1780,31 @@ unpredictable ways. If the \(dqmarginal_path\(dq method is active, the - . - . - .\" ---------------------------------------------------------------------------- -+.SH "FOREIGN MULTIPATH SUPPORT" -+.\" ---------------------------------------------------------------------------- -+. -+multipath and multipathd can load \(dqforeign\(dq libraries to add -+support for other multipathing technologies besides the Linux device mapper. -+Currently this support is limited to printing detected information about -+multipath setup. In topology output, the names of foreign maps are prefixed by -+the foreign library name in square brackets, as in this example: -+. -+.P -+.EX -+# multipath -ll -+uuid.fedcba98-3579-4567-8765-123456789abc [nvme]:nvme4n9 NVMe,Some NVMe controller,FFFFFFFF -+size=167772160 features='n/a' hwhandler='ANA' wp=rw -+|-+- policy='n/a' prio=50 status=optimized -+| `- 4:38:1 nvme4c38n1 0:0 n/a optimized live -+`-+- policy='n/a' prio=50 status=optimized -+ `- 4:39:1 nvme4c39n1 0:0 n/a optimized live -+.EE -+. -+.P -+The \(dqnvme\(dq foreign library provides support for NVMe native multipathing -+in the kernel. It is part of the standard multipath package. -+. -+.\" ---------------------------------------------------------------------------- - .SH "KNOWN ISSUES" - .\" ---------------------------------------------------------------------------- - . --- -2.17.2 - diff --git a/0025-RH-add-mpathconf.patch b/0017-RH-add-mpathconf.patch similarity index 78% rename from 0025-RH-add-mpathconf.patch rename to 0017-RH-add-mpathconf.patch index 3f3c570..009a033 100644 --- a/0025-RH-add-mpathconf.patch +++ b/0017-RH-add-mpathconf.patch @@ -1,4 +1,4 @@ -From 64b336a47365eb0ee91a917d6b98c6c695775a36 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 16 Oct 2014 15:49:01 -0500 Subject: [PATCH] RH: add mpathconf @@ -14,17 +14,17 @@ Signed-off-by: Benjamin Marzinski --- libmultipath/config.c | 2 + multipath/Makefile | 5 + - multipath/mpathconf | 464 ++++++++++++++++++++++++++++++++++++++++++ - multipath/mpathconf.8 | 119 +++++++++++ - 4 files changed, 590 insertions(+) + multipath/mpathconf | 555 ++++++++++++++++++++++++++++++++++++++++++ + multipath/mpathconf.8 | 135 ++++++++++ + 4 files changed, 697 insertions(+) create mode 100644 multipath/mpathconf create mode 100644 multipath/mpathconf.8 diff --git a/libmultipath/config.c b/libmultipath/config.c -index c36bc69c..fcd17dd4 100644 +index b36778b0..26f8e050 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c -@@ -746,6 +746,8 @@ load_config (char * file) +@@ -781,6 +781,8 @@ load_config (char * file) factorize_hwtable(conf->hwtable, builtin_hwtable_size, file); } else { condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices."); @@ -69,10 +69,10 @@ index b9bbb3cf..e720c7f6 100644 $(RM) core *.o $(EXEC) *.gz diff --git a/multipath/mpathconf b/multipath/mpathconf new file mode 100644 -index 00000000..e8391347 +index 00000000..f34003c9 --- /dev/null +++ b/multipath/mpathconf -@@ -0,0 +1,464 @@ +@@ -0,0 +1,555 @@ +#!/bin/bash +# +# Copyright (C) 2010 Red Hat, Inc. All rights reserved. @@ -92,7 +92,7 @@ index 00000000..e8391347 +# This program was largely ripped off from lvmconf +# + -+unset ENABLE FIND FRIENDLY MODULE MULTIPATHD HAVE_DISABLE HAVE_WWID_DISABLE HAVE_FIND HAVE_BLACKLIST HAVE_EXCEPTIONS HAVE_DEFAULTS HAVE_FRIENDLY HAVE_MULTIPATHD HAVE_MODULE HAVE_OUTFILE SHOW_STATUS CHANGED_CONFIG WWID_LIST ++unset ENABLE FIND FRIENDLY PROPERTY FOREIGN MODULE MULTIPATHD HAVE_DISABLE HAVE_WWID_DISABLE HAVE_FIND HAVE_BLACKLIST HAVE_EXCEPTIONS HAVE_DEFAULTS HAVE_FRIENDLY HAVE_PROPERTY HAVE_FOREIGN HAVE_MULTIPATHD HAVE_MODULE HAVE_OUTFILE SHOW_STATUS CHANGED_CONFIG WWID_LIST + +DEFAULT_CONFIG="# device-mapper-multipath configuration file + @@ -107,6 +107,7 @@ index 00000000..e8391347 +defaults { + user_friendly_names yes + find_multipaths yes ++ enable_foreign \"^$\" +} + +blacklist_exceptions { @@ -129,6 +130,8 @@ index 00000000..e8391347 + echo "Only allow certain wwids (instead of enable): --allow " + echo "Set user_friendly_names (Default y): --user_friendly_names " + echo "Set find_multipaths (Default y): --find_multipaths " ++ echo "Set default property blacklist (Default y): --property_blacklist " ++ echo "Set enable_foreign to show foreign devices (Default n): --enable_foreign " + echo "Load the dm-multipath modules on enable (Default y): --with_module " + echo "start/stop/reload multipathd (Default n): --with_multipathd " + echo "select output file (Default /etc/multipath.conf): --outfile " @@ -230,6 +233,24 @@ index 00000000..e8391347 + exit 1 + fi + ;; ++ --property_blacklist) ++ if [ -n "$2" ]; then ++ PROPERTY=$2 ++ shift 2 ++ else ++ usage ++ exit 1 ++ fi ++ ;; ++ --enable_foreign) ++ if [ -n "$2" ]; then ++ FOREIGN=$2 ++ shift 2 ++ else ++ usage ++ exit 1 ++ fi ++ ;; + --with_module) + if [ -n "$2" ]; then + MODULE=$2 @@ -267,10 +288,11 @@ index 00000000..e8391347 + +function validate_args +{ -+ if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$MODULE" ]; then ++ if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$PROPERTY" -o -n "$MODULE" ]; then + echo "ignoring extra parameters on disable" + FRIENDLY="" + FIND="" ++ PROPERTY="" + MODULE="" + fi + if [ -n "$FRIENDLY" ] && [ "$FRIENDLY" != "y" -a "$FRIENDLY" != "n" ]; then @@ -281,7 +303,15 @@ index 00000000..e8391347 + echo "--find_multipaths must be either 'y' or 'n'" + exit 1 + fi -+ if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" ]; then ++ if [ -n "$PROPERTY" ] && [ "$PROPERTY" != "y" -a "$PROPERTY" != "n" ]; then ++ echo "--property_blacklist must be either 'y' or 'n'" ++ exit 1 ++ fi ++ if [ -n "$FOREIGN" ] && [ "$FOREIGN" != "y" -a "$FOREIGN" != "n" ]; then ++ echo "--enable_foreign must be either 'y' or 'n'" ++ exit 1 ++ fi ++ if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" -a -z "$PROPERTY" ]; then + SHOW_STATUS=1 + fi + if [ -n "$MODULE" ] && [ "$MODULE" != "y" -a "$MODULE" != "n" ]; then @@ -382,6 +412,21 @@ index 00000000..e8391347 + elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]]*\(no\|0\)" ; then + HAVE_FRIENDLY=0 + fi ++ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*enable_foreign" ; then ++ HAVE_FOREIGN=0 ++ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]]*\"\^\$\"" ; then ++ HAVE_FOREIGN=1 ++ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign" ; then ++ HAVE_FOREIGN=2 ++ fi ++fi ++ ++if [ "$HAVE_EXCEPTIONS" = "1" ]; then ++ if sed -n '/^blacklist_exceptions[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"" ; then ++ HAVE_PROPERTY=1 ++ elif sed -n '/^blacklist_exceptions[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"" ; then ++ HAVE_PROPERTY=0 ++ fi +fi + +if [ -n "$SHOW_STATUS" ]; then @@ -400,6 +445,18 @@ index 00000000..e8391347 + else + echo "user_friendly_names is enabled" + fi ++ if [ -z "$HAVE_PROPERTY" -o "$HAVE_PROPERTY" = 0 ]; then ++ echo "default property blacklist is disabled" ++ else ++ echo "default property blacklist is enabled" ++ fi ++ if [ -z "$HAVE_FOREIGN" -o "$HAVE_FOREIGN" = 0 ]; then ++ echo "enable_foreign is not set (all foreign multipath devices will be shown)" ++ elif [ "$HAVE_FOREIGN" = 1 ]; then ++ echo "enable_foreign is set (no foreign multipath devices will be shown)" ++ else ++ echo "enable_foreign is set (foreign multipath devices may not be shown)" ++ fi + if [ -n "$HAVE_MODULE" ]; then + if [ "$HAVE_MODULE" = 1 ]; then + echo "dm_multipath module is loaded" @@ -507,6 +564,40 @@ index 00000000..e8391347 + fi +fi + ++if [ "$PROPERTY" = "n" ]; then ++ if [ "$HAVE_PROPERTY" = 1 ]; then ++ sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/# property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE ++ CHANGED_CONFIG=1 ++ fi ++elif [ "$PROPERTY" = "y" ]; then ++ if [ -z "$HAVE_PROPERTY" ]; then ++ sed -i '/^blacklist_exceptions[[:space:]]*{/ a\ ++ property "(SCSI_IDENT_|ID_WWN)" ++' $TMPFILE ++ CHANGED_CONFIG=1 ++ elif [ "$HAVE_PROPERTY" = 0 ]; then ++ sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/ property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE ++ CHANGED_CONFIG=1 ++ fi ++fi ++ ++if [ "$FOREIGN" = "y" ]; then ++ if [ "$HAVE_FOREIGN" = 1 -o "$HAVE_FOREIGN" = 2 ]; then ++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*enable_foreign/# enable_foreign/' $TMPFILE ++ CHANGED_CONFIG=1 ++ fi ++elif [ "$FOREIGN" = "n" ]; then ++ if [ -z "$HAVE_FOREIGN" ]; then ++ sed -i '/^defaults[[:space:]]*{/ a\ ++ enable_foreign "^$" ++' $TMPFILE ++ CHANGED_CONFIG=1 ++ elif [ "$HAVE_FOREIGN" = 0 -o "$HAVE_FOREIGN" = 2 ]; then ++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*#\?[[:space:]]*enable_foreign.*$/ enable_foreign "^$"/' $TMPFILE ++ CHANGED_CONFIG=1 ++ fi ++fi ++ +if [ -f "$OUTPUTFILE" ]; then + cp $OUTPUTFILE $OUTPUTFILE.old + if [ $? != 0 ]; then @@ -539,10 +630,10 @@ index 00000000..e8391347 +fi diff --git a/multipath/mpathconf.8 b/multipath/mpathconf.8 new file mode 100644 -index 00000000..5b7ae0c3 +index 00000000..b82961d6 --- /dev/null +++ b/multipath/mpathconf.8 -@@ -0,0 +1,119 @@ +@@ -0,0 +1,135 @@ +.TH MPATHCONF 8 "June 2010" "" "Linux Administrator's Manual" +.SH NAME +mpathconf - A tool for configuring device-mapper-multipath @@ -614,7 +705,7 @@ index 00000000..5b7ae0c3 +mpathconf will not be able to revert back to its previous state. Because +of this, \fB--outfile\fP is required when using \fB--allow\fP. +.TP -+.B --user_friendly_name \fP { \fBy\fP | \fBn\fP } ++.B --user_friendly_names \fP { \fBy\fP | \fBn\fP } +If set to \fBy\fP, this adds the line +.B user_friendly_names yes +to the @@ -628,7 +719,23 @@ index 00000000..5b7ae0c3 +to the +.B /etc/multipath.conf +defaults section. If set to \fBn\fP, this removes the line, if present. This -+command can be used aldong with any other command. ++command can be used along with any other command. ++.TP ++.B --property_blacklist \fP { \fBy\fP | \fBn\fP } ++If set to \fBy\fP, this adds the line ++.B property "(SCSI_IDENT_|ID_WWN)" ++to the ++.B /etc/multipath.conf ++blacklist_exceptions section. If set to \fBn\fP, this removes the line, if ++present. This command can be used along with any other command. ++.TP ++.B --enable_foreign\fP { \fBy\fP | \fBn\fP } ++If set to \fBn\fP, this adds the line ++.B enable_foreign "^$" ++to the ++.B /etc/multipath.conf ++defaults section. if set to \fBy\fP, this removes the line, if present. This ++command can be used along with any other command. +.TP +.B --outfile \fB\fP +Write the resulting multipath configuration to \fB\fP instead of diff --git a/0017-mpathpersist-remove-broken-unused-code.patch b/0017-mpathpersist-remove-broken-unused-code.patch deleted file mode 100644 index 82d1341..0000000 --- a/0017-mpathpersist-remove-broken-unused-code.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 826c100b0cbe72c5d770614cea8898afec09628c Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 9 Sep 2019 16:18:33 -0500 -Subject: [PATCH] mpathpersist: remove broken/unused code - -The test for an empty pp->dev in updatepaths() dates back to when -disassemble_map() didn't fill in pp->dev for newly added paths, and it -was meant to catch paths that got added by disassemble_map(). With the -mpathpersist speedup code, all paths get added by disassemble_map(). -However, disassemble_map() now calls devt2devname() to set pp->dev if -possible. This means that there is no point in calling devt2devname() -again in updatepaths(). If for some reason it did return success, the -current code would still fail, since it doesn't set pp->udev in this -code path. The best thing to do if disassemble_map() couldn't set -pp->dev is simply to fail the path. - -Signed-off-by: Benjamin Marzinski ---- - libmpathpersist/mpath_persist.c | 16 ++++------------ - 1 file changed, 4 insertions(+), 12 deletions(-) - -diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c -index 53022f5b..603cfc3b 100644 ---- a/libmpathpersist/mpath_persist.c -+++ b/libmpathpersist/mpath_persist.c -@@ -82,18 +82,10 @@ updatepaths (struct multipath * mpp) - - vector_foreach_slot (pgp->paths, pp, j){ - if (!strlen(pp->dev)){ -- if (devt2devname(pp->dev, FILE_NAME_SIZE, -- pp->dev_t)){ -- /* -- * path is not in sysfs anymore -- */ -- pp->state = PATH_DOWN; -- continue; -- } -- pp->mpp = mpp; -- conf = get_multipath_config(); -- pathinfo(pp, conf, DI_ALL); -- put_multipath_config(conf); -+ /* -+ * path is not in sysfs anymore -+ */ -+ pp->state = PATH_DOWN; - continue; - } - pp->mpp = mpp; --- -2.17.2 - diff --git a/0026-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0018-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 94% rename from 0026-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0018-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch index 5446efa..fb0d281 100644 --- a/0026-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +++ b/0018-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch @@ -1,4 +1,4 @@ -From bba3bc3cfd910921ab5887acdc9503610e7efa18 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Fri, 17 Oct 2014 11:20:34 -0500 Subject: [PATCH] RH: add wwids from kernel cmdline mpath.wwids with -A @@ -22,10 +22,10 @@ Signed-off-by: Benjamin Marzinski 5 files changed, 60 insertions(+), 3 deletions(-) diff --git a/libmultipath/wwids.c b/libmultipath/wwids.c -index ef748125..349da8b7 100644 +index 28a2150d..fab6fc8f 100644 --- a/libmultipath/wwids.c +++ b/libmultipath/wwids.c -@@ -444,3 +444,47 @@ int op ## _wwid(const char *wwid) \ +@@ -454,3 +454,47 @@ int op ## _wwid(const char *wwid) \ declare_failed_wwid_op(is_failed, false) declare_failed_wwid_op(mark_failed, true) declare_failed_wwid_op(unmark_failed, true) @@ -86,7 +86,7 @@ index 0c6ee54d..e32a0b0e 100644 enum { WWID_IS_NOT_FAILED = 0, diff --git a/multipath/main.c b/multipath/main.c -index 4f4d8e89..22aff7be 100644 +index cf9d2a28..78822ee1 100644 --- a/multipath/main.c +++ b/multipath/main.c @@ -138,7 +138,7 @@ usage (char * progname) @@ -107,16 +107,16 @@ index 4f4d8e89..22aff7be 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" -@@ -905,7 +907,7 @@ main (int argc, char *argv[]) - exit(RTVL_FAIL); +@@ -907,7 +909,7 @@ main (int argc, char *argv[]) multipath_conf = conf; conf->retrigger_tries = 0; + conf->force_sync = 1; - while ((arg = getopt(argc, argv, ":adcChl::FfM:v:p:b:BrR:itTquUwW")) != EOF ) { + while ((arg = getopt(argc, argv, ":aAdcChl::FfM:v:p:b:BrR:itTquUwW")) != EOF ) { switch(arg) { case 1: printf("optarg : %s\n",optarg); break; -@@ -975,6 +977,10 @@ main (int argc, char *argv[]) +@@ -977,6 +979,10 @@ main (int argc, char *argv[]) case 'T': cmd = CMD_DUMP_CONFIG; break; diff --git a/0018-libmultipath-EMC-PowerMax-NVMe-device-config.patch b/0018-libmultipath-EMC-PowerMax-NVMe-device-config.patch deleted file mode 100644 index 68d5852..0000000 --- a/0018-libmultipath-EMC-PowerMax-NVMe-device-config.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 16116095d5a11c5134e0696398a9908dafc415bc Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 9 Sep 2019 17:18:08 -0500 -Subject: [PATCH] libmultipath: EMC PowerMax NVMe device config - -Got this config from Dell. - -Cc: heyi -Signed-off-by: Benjamin Marzinski ---- - libmultipath/hwtable.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index 96e8b25d..ca217e65 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -360,6 +360,12 @@ static struct hwentry default_hw[] = { - .pgfailback = -FAILBACK_IMMEDIATE, - .no_path_retry = 30, - }, -+ { -+ /* EMC PowerMax NVMe */ -+ .vendor = "NVME", -+ .product = "^EMC PowerMax_", -+ .pgpolicy = MULTIBUS, -+ }, - /* - * Fujitsu - */ --- -2.17.2 - diff --git a/0027-RH-warn-on-invalid-regex-instead-of-failing.patch b/0019-RH-warn-on-invalid-regex-instead-of-failing.patch similarity index 89% rename from 0027-RH-warn-on-invalid-regex-instead-of-failing.patch rename to 0019-RH-warn-on-invalid-regex-instead-of-failing.patch index 5250415..18dd530 100644 --- a/0027-RH-warn-on-invalid-regex-instead-of-failing.patch +++ b/0019-RH-warn-on-invalid-regex-instead-of-failing.patch @@ -1,4 +1,4 @@ -From 779d51dcaff09fc8910d5a71e74d735f573ece9e Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Mon, 6 Nov 2017 21:39:28 -0600 Subject: [PATCH] RH: warn on invalid regex instead of failing @@ -16,10 +16,10 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index 1b3d0373..695c8404 100644 +index 0e9ea387..184d4b22 100644 --- a/libmultipath/dict.c +++ b/libmultipath/dict.c -@@ -58,6 +58,21 @@ set_str(vector strvec, void *ptr) +@@ -103,6 +103,21 @@ set_str(vector strvec, void *ptr) return 0; } @@ -41,7 +41,7 @@ index 1b3d0373..695c8404 100644 static int set_yes_no(vector strvec, void *ptr) { -@@ -1422,7 +1437,7 @@ ble_ ## option ## _handler (struct config *conf, vector strvec) \ +@@ -1504,7 +1519,7 @@ ble_ ## option ## _handler (struct config *conf, vector strvec) \ if (!conf->option) \ return 1; \ \ @@ -50,7 +50,7 @@ index 1b3d0373..695c8404 100644 if (!buff) \ return 1; \ \ -@@ -1438,7 +1453,7 @@ ble_ ## option ## _ ## name ## _handler (struct config *conf, vector strvec) \ +@@ -1520,7 +1535,7 @@ ble_ ## option ## _ ## name ## _handler (struct config *conf, vector strvec) \ if (!conf->option) \ return 1; \ \ @@ -59,7 +59,7 @@ index 1b3d0373..695c8404 100644 if (!buff) \ return 1; \ \ -@@ -1541,16 +1556,16 @@ device_handler(struct config *conf, vector strvec) +@@ -1623,16 +1638,16 @@ device_handler(struct config *conf, vector strvec) return 0; } @@ -81,7 +81,7 @@ index 1b3d0373..695c8404 100644 declare_hw_handler(hwhandler, set_str) diff --git a/libmultipath/parser.c b/libmultipath/parser.c -index e00c5fff..15495d26 100644 +index d478b177..a184511b 100644 --- a/libmultipath/parser.c +++ b/libmultipath/parser.c @@ -382,6 +382,19 @@ oom: diff --git a/0019-mpathpersist-fix-leaks.patch b/0019-mpathpersist-fix-leaks.patch deleted file mode 100644 index 8610633..0000000 --- a/0019-mpathpersist-fix-leaks.patch +++ /dev/null @@ -1,132 +0,0 @@ -From 385f0a62f83af67eb0b4b67f3af43e149619c0af Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 10 Sep 2019 10:44:50 -0500 -Subject: [PATCH] mpathpersist: fix leaks - -If handle_args() fails while looping through the argument list, it needs -to free batch_fn, if it has been set. Also handle_args() needs to make -sure to free the file descriptor after it has been opened. - -Signed-off-by: Benjamin Marzinski ---- - mpathpersist/main.c | 31 ++++++++++++++++++++----------- - 1 file changed, 20 insertions(+), 11 deletions(-) - -diff --git a/mpathpersist/main.c b/mpathpersist/main.c -index 5ad06a97..2368b429 100644 ---- a/mpathpersist/main.c -+++ b/mpathpersist/main.c -@@ -155,7 +155,8 @@ static int do_batch_file(const char *batch_fn) - - static int handle_args(int argc, char * argv[], int nline) - { -- int fd, c; -+ int c; -+ int fd = -1; - const char *device_name = NULL; - int num_prin_sa = 0; - int num_prout_sa = 0; -@@ -213,7 +214,8 @@ static int handle_args(int argc, char * argv[], int nline) - if (nline == 0 && 1 != sscanf (optarg, "%d", &loglevel)) - { - fprintf (stderr, "bad argument to '--verbose'\n"); -- return MPATH_PR_SYNTAX_ERROR; -+ ret = MPATH_PR_SYNTAX_ERROR; -+ goto out; - } - break; - -@@ -228,6 +230,7 @@ static int handle_args(int argc, char * argv[], int nline) - - case 'h': - usage (); -+ free(batch_fn); - return 0; - - case 'H': -@@ -254,7 +257,8 @@ static int handle_args(int argc, char * argv[], int nline) - if (1 != sscanf (optarg, "%" SCNx64 "", ¶m_rk)) - { - fprintf (stderr, "bad argument to '--param-rk'\n"); -- return MPATH_PR_SYNTAX_ERROR; -+ ret = MPATH_PR_SYNTAX_ERROR; -+ goto out; - } - ++num_prout_param; - break; -@@ -263,7 +267,8 @@ static int handle_args(int argc, char * argv[], int nline) - if (1 != sscanf (optarg, "%" SCNx64 "", ¶m_sark)) - { - fprintf (stderr, "bad argument to '--param-sark'\n"); -- return MPATH_PR_SYNTAX_ERROR; -+ ret = MPATH_PR_SYNTAX_ERROR; -+ goto out; - } - ++num_prout_param; - break; -@@ -282,7 +287,8 @@ static int handle_args(int argc, char * argv[], int nline) - if (1 != sscanf (optarg, "%x", &prout_type)) - { - fprintf (stderr, "bad argument to '--prout-type'\n"); -- return MPATH_PR_SYNTAX_ERROR; -+ ret = MPATH_PR_SYNTAX_ERROR; -+ goto out; - } - ++num_prout_param; - break; -@@ -330,7 +336,8 @@ static int handle_args(int argc, char * argv[], int nline) - case 'X': - if (0 != construct_transportid(optarg, transportids, num_transport)) { - fprintf(stderr, "bad argument to '--transport-id'\n"); -- return MPATH_PR_SYNTAX_ERROR; -+ ret = MPATH_PR_SYNTAX_ERROR; -+ goto out; - } - - ++num_transport; -@@ -339,11 +346,13 @@ static int handle_args(int argc, char * argv[], int nline) - case 'l': - if (1 != sscanf(optarg, "%u", &mpath_mx_alloc_len)) { - fprintf(stderr, "bad argument to '--alloc-length'\n"); -- return MPATH_PR_SYNTAX_ERROR; -+ ret = MPATH_PR_SYNTAX_ERROR; -+ goto out; - } else if (MPATH_MAX_PARAM_LEN < mpath_mx_alloc_len) { - fprintf(stderr, "'--alloc-length' argument exceeds maximum" - " limit(%d)\n", MPATH_MAX_PARAM_LEN); -- return MPATH_PR_SYNTAX_ERROR; -+ ret = MPATH_PR_SYNTAX_ERROR; -+ goto out; - } - break; - -@@ -481,14 +490,14 @@ static int handle_args(int argc, char * argv[], int nline) - { - fprintf (stderr, "failed to allocate PRIN response buffer\n"); - ret = MPATH_PR_OTHER; -- goto out; -+ goto out_fd; - } - - ret = __mpath_persistent_reserve_in (fd, prin_sa, resp, noisy); - if (ret != MPATH_PR_SUCCESS ) - { - fprintf (stderr, "Persistent Reserve IN command failed\n"); -- goto out; -+ goto out_fd; - } - - switch(prin_sa) -@@ -568,8 +577,8 @@ static int handle_args(int argc, char * argv[], int nline) - printf("PR out: command failed\n"); - } - -+out_fd: - close (fd); -- - out : - if (ret == MPATH_PR_SYNTAX_ERROR) { - free(batch_fn); --- -2.17.2 - diff --git a/0028-RH-reset-default-find_mutipaths-value-to-off.patch b/0020-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 88% rename from 0028-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0020-RH-reset-default-find_mutipaths-value-to-off.patch index 2ea9db8..2e53cd9 100644 --- a/0028-RH-reset-default-find_mutipaths-value-to-off.patch +++ b/0020-RH-reset-default-find_mutipaths-value-to-off.patch @@ -1,4 +1,4 @@ -From 1f5156bc77ef05f5d93e7a9df6e270a587eb6a30 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 7 Jun 2018 17:43:52 -0500 Subject: [PATCH] RH: reset default find_mutipaths value to off @@ -12,10 +12,10 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h -index 4dfe007c..d910da51 100644 +index e5ee6afe..52fe05b9 100644 --- a/libmultipath/defaults.h +++ b/libmultipath/defaults.h -@@ -20,7 +20,7 @@ +@@ -22,7 +22,7 @@ #define DEFAULT_NO_PATH_RETRY NO_PATH_RETRY_UNDEF #define DEFAULT_VERBOSITY 2 #define DEFAULT_REASSIGN_MAPS 0 diff --git a/0020-libmultipath-fix-mpcontext-initialization.patch b/0020-libmultipath-fix-mpcontext-initialization.patch deleted file mode 100644 index 1ed3a7b..0000000 --- a/0020-libmultipath-fix-mpcontext-initialization.patch +++ /dev/null @@ -1,232 +0,0 @@ -From 33a6f6b05d7041716142f080a2708db351c92eaa Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 10 Sep 2019 15:46:28 -0500 -Subject: [PATCH] libmultipath: fix mpcontext initialization - -If a path is discovered before there is a multipath device for it to -belong to, the checker will not have its mpcontext initialized, even if -that path later belongs to a multipath device. A checker's mpcontext is -only set when the checker is selected, and is set to NULL if there is no -multipath device associated with the path. This only impacts the emc -checker. However, it makes the emc checker unable to determine if a -passive path is connected to an inactive snapshot or not. - -This can be solved by adding a new checker class function, mp_init(). -This is called when the checker is first initialized, and whenever the -checker is called, if the checker's mpcontext hasn't been initialized. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/checkers.c | 29 ++++++++++++++++++++++++++-- - libmultipath/checkers.h | 1 + - libmultipath/checkers/cciss_tur.c | 5 +++++ - libmultipath/checkers/directio.c | 5 +++++ - libmultipath/checkers/emc_clariion.c | 7 +++++++ - libmultipath/checkers/hp_sw.c | 5 +++++ - libmultipath/checkers/rdac.c | 5 +++++ - libmultipath/checkers/readsector0.c | 5 +++++ - libmultipath/checkers/tur.c | 5 +++++ - libmultipath/discovery.c | 2 ++ - 10 files changed, 67 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/checkers.c b/libmultipath/checkers.c -index f4fdcae9..240b0f29 100644 ---- a/libmultipath/checkers.c -+++ b/libmultipath/checkers.c -@@ -16,6 +16,7 @@ struct checker_class { - char name[CHECKER_NAME_LEN]; - int (*check)(struct checker *); - int (*init)(struct checker *); /* to allocate the context */ -+ int (*mp_init)(struct checker *); /* to allocate the mpcontext */ - void (*free)(struct checker *); /* to free the context */ - const char **msgtable; - short msgtable_size; -@@ -140,6 +141,13 @@ static struct checker_class *add_checker_class(const char *multipath_dir, - if (!c->init) - goto out; - -+ c->mp_init = (int (*)(struct checker *)) dlsym(c->handle, "libcheck_mp_init"); -+ errstr = dlerror(); -+ if (errstr != NULL) -+ condlog(0, "A dynamic linking error occurred: (%s)", errstr); -+ if (!c->mp_init) -+ goto out; -+ - c->free = (void (*)(struct checker *)) dlsym(c->handle, "libcheck_free"); - errstr = dlerror(); - if (errstr != NULL) -@@ -212,8 +220,25 @@ int checker_init (struct checker * c, void ** mpctxt_addr) - if (!c || !c->cls) - return 1; - c->mpcontext = mpctxt_addr; -- if (c->cls->init) -- return c->cls->init(c); -+ if (c->cls->init && c->cls->init(c) != 0) -+ return 1; -+ if (mpctxt_addr && *mpctxt_addr == NULL && c->cls->mp_init && -+ c->cls->mp_init(c) != 0) /* continue even if mp_init fails */ -+ c->mpcontext = NULL; -+ return 0; -+} -+ -+int checker_mp_init(struct checker * c, void ** mpctxt_addr) -+{ -+ if (!c || !c->cls) -+ return 1; -+ if (c->cls->mp_init && !c->mpcontext && mpctxt_addr) { -+ c->mpcontext = mpctxt_addr; -+ if (c->cls->mp_init(c) != 0) { -+ c->mpcontext = NULL; -+ return 1; -+ } -+ } - return 0; - } - -diff --git a/libmultipath/checkers.h b/libmultipath/checkers.h -index dab197f9..5237e7ec 100644 ---- a/libmultipath/checkers.h -+++ b/libmultipath/checkers.h -@@ -138,6 +138,7 @@ const char *checker_state_name(int); - int init_checkers(const char *); - void cleanup_checkers (void); - int checker_init (struct checker *, void **); -+int checker_mp_init(struct checker *, void **); - void checker_clear (struct checker *); - void checker_put (struct checker *); - void checker_reset (struct checker *); -diff --git a/libmultipath/checkers/cciss_tur.c b/libmultipath/checkers/cciss_tur.c -index ea843742..b570ed65 100644 ---- a/libmultipath/checkers/cciss_tur.c -+++ b/libmultipath/checkers/cciss_tur.c -@@ -51,6 +51,11 @@ int libcheck_init (struct checker * c) - return 0; - } - -+int libcheck_mp_init (struct checker * c) -+{ -+ return 0; -+} -+ - void libcheck_free (struct checker * c) - { - return; -diff --git a/libmultipath/checkers/directio.c b/libmultipath/checkers/directio.c -index 1b00b775..96f223b2 100644 ---- a/libmultipath/checkers/directio.c -+++ b/libmultipath/checkers/directio.c -@@ -103,6 +103,11 @@ out: - return 1; - } - -+int libcheck_mp_init(struct checker * c) -+{ -+ return 0; -+} -+ - void libcheck_free (struct checker * c) - { - struct directio_context * ct = (struct directio_context *)c->context; -diff --git a/libmultipath/checkers/emc_clariion.c b/libmultipath/checkers/emc_clariion.c -index 6fc89113..5cd63aca 100644 ---- a/libmultipath/checkers/emc_clariion.c -+++ b/libmultipath/checkers/emc_clariion.c -@@ -107,11 +107,18 @@ int libcheck_init (struct checker * c) - return 1; - ((struct emc_clariion_checker_path_context *)c->context)->wwn_set = 0; - -+ return 0; -+} -+ -+int libcheck_mp_init (struct checker * c) -+{ - /* - * Allocate and initialize the multi-path global context. - */ - if (c->mpcontext && *c->mpcontext == NULL) { - void * mpctxt = malloc(sizeof(int)); -+ if (!mpctxt) -+ return 1; - *c->mpcontext = mpctxt; - CLR_INACTIVE_SNAP(c); - } -diff --git a/libmultipath/checkers/hp_sw.c b/libmultipath/checkers/hp_sw.c -index 1a820223..35aca204 100644 ---- a/libmultipath/checkers/hp_sw.c -+++ b/libmultipath/checkers/hp_sw.c -@@ -37,6 +37,11 @@ int libcheck_init (struct checker * c) - return 0; - } - -+int libcheck_mp_init(struct checker * c) -+{ -+ return 0; -+} -+ - void libcheck_free (struct checker * c) - { - return; -diff --git a/libmultipath/checkers/rdac.c b/libmultipath/checkers/rdac.c -index 8a3b73ec..805d153e 100644 ---- a/libmultipath/checkers/rdac.c -+++ b/libmultipath/checkers/rdac.c -@@ -133,6 +133,11 @@ out: - return 0; - } - -+int libcheck_mp_init(struct checker * c) -+{ -+ return 0; -+} -+ - void libcheck_free (struct checker * c) - { - return; -diff --git a/libmultipath/checkers/readsector0.c b/libmultipath/checkers/readsector0.c -index cf79e067..71db9f80 100644 ---- a/libmultipath/checkers/readsector0.c -+++ b/libmultipath/checkers/readsector0.c -@@ -15,6 +15,11 @@ int libcheck_init (struct checker * c) - return 0; - } - -+int libcheck_mp_init(struct checker * c) -+{ -+ return 0; -+} -+ - void libcheck_free (struct checker * c) - { - return; -diff --git a/libmultipath/checkers/tur.c b/libmultipath/checkers/tur.c -index 6b08dbbb..138b9e58 100644 ---- a/libmultipath/checkers/tur.c -+++ b/libmultipath/checkers/tur.c -@@ -79,6 +79,11 @@ int libcheck_init (struct checker * c) - return 0; - } - -+int libcheck_mp_init(struct checker * c) -+{ -+ return 0; -+} -+ - static void cleanup_context(struct tur_checker_context *ct) - { - pthread_mutex_destroy(&ct->lock); -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index acca466c..72f455e8 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -1608,6 +1608,8 @@ get_state (struct path * pp, struct config *conf, int daemon, int oldstate) - return PATH_UNCHECKED; - } - } -+ if (pp->mpp && !c->mpcontext) -+ checker_mp_init(c, &pp->mpp->mpcontext); - checker_clear_message(c); - if (daemon) { - if (conf->force_sync == 0) --- -2.17.2 - diff --git a/0029-RH-Fix-nvme-compilation-warning.patch b/0021-RH-Fix-nvme-compilation-warning.patch similarity index 92% rename from 0029-RH-Fix-nvme-compilation-warning.patch rename to 0021-RH-Fix-nvme-compilation-warning.patch index f0308a7..fc6ccd7 100644 --- a/0029-RH-Fix-nvme-compilation-warning.patch +++ b/0021-RH-Fix-nvme-compilation-warning.patch @@ -1,4 +1,4 @@ -From 938d211bf5e8d96849bfbf4d2707507adc7f718e Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Fri, 25 Jan 2019 14:54:56 -0600 Subject: [PATCH] RH: Fix nvme compilation warning diff --git a/0030-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0022-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 83% rename from 0030-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0022-RH-attempt-to-get-ANA-info-via-sysfs-first.patch index b85edca..14b3367 100644 --- a/0030-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +++ b/0022-RH-attempt-to-get-ANA-info-via-sysfs-first.patch @@ -1,4 +1,4 @@ -From cff4e6981d8b168cabd81b3de6f9f97735de7e1a Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 11 Apr 2019 13:25:42 -0500 Subject: [PATCH] RH: attempt to get ANA info via sysfs first @@ -13,7 +13,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/libmultipath/prioritizers/ana.c b/libmultipath/prioritizers/ana.c -index 2673d9d9..f34ade28 100644 +index b5c7873d..e139360c 100644 --- a/libmultipath/prioritizers/ana.c +++ b/libmultipath/prioritizers/ana.c @@ -24,6 +24,7 @@ @@ -40,11 +40,11 @@ index 2673d9d9..f34ade28 100644 }; static const char *anas_string[] = { -@@ -106,6 +109,27 @@ static int get_ana_state(__u32 nsid, __u32 anagrpid, void *ana_log, +@@ -107,6 +110,27 @@ static int get_ana_state(__u32 nsid, __u32 anagrpid, void *ana_log, return -ANA_ERR_GETANAS_NOTFOUND; } -+int get_ana_info_sysfs(struct path *pp) ++static int get_ana_info_sysfs(struct path *pp) +{ + char state[32]; + @@ -65,19 +65,19 @@ index 2673d9d9..f34ade28 100644 + return -ANA_ERR_INVALID_STATE; +} + - int get_ana_info(struct path * pp, unsigned int timeout) + static int get_ana_info(struct path * pp) { int rc; -@@ -208,8 +232,11 @@ int getprio(struct path *pp, char *args, unsigned int timeout) +@@ -210,8 +234,11 @@ int getprio(struct path *pp, __attribute__((unused)) char *args, if (pp->fd < 0) rc = -ANA_ERR_NO_INFORMATION; - else -- rc = get_ana_info(pp, timeout); +- rc = get_ana_info(pp); + else { + rc = get_ana_info_sysfs(pp); + if (rc < 0) -+ rc = get_ana_info(pp, timeout); ++ rc = get_ana_info(pp); + } switch (rc) { diff --git a/0023-RH-work-around-gcc-10-format-truncation-issue.patch b/0023-RH-work-around-gcc-10-format-truncation-issue.patch new file mode 100644 index 0000000..f03c1a6 --- /dev/null +++ b/0023-RH-work-around-gcc-10-format-truncation-issue.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Fri, 29 May 2020 17:21:21 -0500 +Subject: [PATCH] RH: work around gcc 10 format-truncation issue + +gcc 10 was returning false positives on some architectures, when trying +to determine if a snprintf() function could silently truncate its +output. Instead of changing the code to pretend that this is possible, +make these warnings, instead of errors. + +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile.inc b/Makefile.inc +index c2abd301..bb642931 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -108,7 +108,7 @@ else + endif + OPTFLAGS += -Werror -Wextra -Wstrict-prototypes -Wformat=2 \ + -Werror=implicit-int -Werror=implicit-function-declaration \ +- $(WNOCLOBBERED) \ ++ $(WNOCLOBBERED) -Wno-error=format-truncation \ + -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) \ + --param=ssp-buffer-size=4 + +-- +2.17.2 + diff --git a/0031-multipath-fix-issues-found-by-compiling-with-gcc-10.patch b/0031-multipath-fix-issues-found-by-compiling-with-gcc-10.patch deleted file mode 100644 index b55e393..0000000 --- a/0031-multipath-fix-issues-found-by-compiling-with-gcc-10.patch +++ /dev/null @@ -1,119 +0,0 @@ -From b665961ce1acc273b936ef8593e328c413d35ba7 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 11 Feb 2020 17:01:08 -0600 -Subject: [PATCH] multipath: fix issues found by compiling with gcc 10 - -Compiling with gcc 10 raised a number of warings about buffer sizes, -and an error based on declaring ___error1___ in multiple c files, -do to it being in structs.h. fix these - -Signed-off-by: Benjamin Marzinski ---- - kpartx/dasd.c | 6 +++--- - libmultipath/print.c | 3 ++- - libmultipath/structs.c | 6 ++++++ - libmultipath/structs.h | 5 ----- - multipath/main.c | 2 +- - 5 files changed, 12 insertions(+), 10 deletions(-) - -diff --git a/kpartx/dasd.c b/kpartx/dasd.c -index d95d8ca0..42986e78 100644 ---- a/kpartx/dasd.c -+++ b/kpartx/dasd.c -@@ -188,7 +188,7 @@ read_dasd_pt(int fd, struct slice all, struct slice *sp, int ns) - goto out; - } - -- if ((!info.FBA_layout) && (!strcmp(info.type, "ECKD"))) -+ if ((!info.FBA_layout) && (!strncmp(info.type, "ECKD", 4))) - memcpy (&vlabel, data, sizeof(vlabel)); - else { - bzero(&vlabel,4); -@@ -218,7 +218,7 @@ read_dasd_pt(int fd, struct slice all, struct slice *sp, int ns) - sp[0].size = size - sp[0].start; - retval = 1; - } else if ((strncmp(type, "VOL1", 4) == 0) && -- (!info.FBA_layout) && (!strcmp(info.type, "ECKD"))) { -+ (!info.FBA_layout) && (!strncmp(info.type, "ECKD",4))) { - /* - * New style VOL1 labeled disk - */ -@@ -267,7 +267,7 @@ read_dasd_pt(int fd, struct slice all, struct slice *sp, int ns) - if (vlabel.ldl_version == 0xf2) { - fmt_size = sectors512(vlabel.formatted_blocks, - blocksize); -- } else if (!strcmp(info.type, "ECKD")) { -+ } else if (!strncmp(info.type, "ECKD",4)) { - /* formatted w/o large volume support */ - fmt_size = geo.cylinders * geo.heads - * geo.sectors * (blocksize >> 9); -diff --git a/libmultipath/print.c b/libmultipath/print.c -index 907469ad..61e123de 100644 ---- a/libmultipath/print.c -+++ b/libmultipath/print.c -@@ -29,6 +29,7 @@ - #include "uevent.h" - #include "debug.h" - #include "discovery.h" -+#include "util.h" - - #define MAX(x,y) (((x) > (y)) ? (x) : (y)) - #define MIN(x,y) (((x) > (y)) ? (y) : (x)) -@@ -2028,7 +2029,7 @@ int snprint_devices(struct config *conf, char * buff, int len, - - devptr = devpath + 11; - *devptr = '\0'; -- strncat(devptr, blkdev->d_name, PATH_MAX-12); -+ strlcpy(devptr, blkdev->d_name, PATH_MAX-11); - if (stat(devpath, &statbuf) < 0) - continue; - -diff --git a/libmultipath/structs.c b/libmultipath/structs.c -index bf7fdd73..46e8bb18 100644 ---- a/libmultipath/structs.c -+++ b/libmultipath/structs.c -@@ -20,6 +20,12 @@ - #include "prioritizers/alua_spc3.h" - #include "dm-generic.h" - -+/* -+ * _FIND_MULTIPATHS_F must have the same value as YNU_YES. -+ * Generate a compile time error if that isn't the case. -+ */ -+char ___error1___[-(_FIND_MULTIPATHS_F != YNU_YES)]; -+ - struct adapter_group * - alloc_adaptergroup(void) - { -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index a3adf906..191a5945 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -102,11 +102,6 @@ enum yes_no_undef_states { - #define _FIND_MULTIPATHS_F (1 << 1) - #define _FIND_MULTIPATHS_I (1 << 2) - #define _FIND_MULTIPATHS_N (1 << 3) --/* -- * _FIND_MULTIPATHS_F must have the same value as YNU_YES. -- * Generate a compile time error if that isn't the case. -- */ --char ___error1___[-(_FIND_MULTIPATHS_F != YNU_YES)]; - - #define find_multipaths_on(conf) \ - (!!((conf)->find_multipaths & _FIND_MULTIPATHS_F)) -diff --git a/multipath/main.c b/multipath/main.c -index 22aff7be..ed214183 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -1029,7 +1029,7 @@ main (int argc, char *argv[]) - if (!dev) - goto out; - -- strncpy(dev, argv[optind], FILE_NAME_SIZE); -+ strlcpy(dev, argv[optind], FILE_NAME_SIZE); - if (dev_type != DEV_UEVENT) - dev_type = get_dev_type(dev); - if (dev_type == DEV_NONE) { --- -2.17.2 - diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 7c4945f..f6b5f85 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,47 +1,38 @@ Name: device-mapper-multipath -Version: 0.8.2 -Release: 6%{?dist} +Version: 0.8.4 +Release: 1%{?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.8.2;sf=tgz" -o multipath-tools-0.8.2.tgz -Source0: multipath-tools-0.8.2.tgz +# curl "https://git.opensvc.com/?p=multipath-tools/.git;a=snapshot;h=refs/tags/0.8.4;sf=tgz" -o multipath-tools-0.8.4.tgz +Source0: multipath-tools-0.8.4.tgz Source1: multipath.conf -Patch0001: 0001-libmultipath-make-vector_foreach_slot_backwards-work.patch -Patch0002: 0002-libmultipath-add-marginal-paths-and-groups-infrastru.patch -Patch0003: 0003-tests-add-path-grouping-policy-unit-tests.patch -Patch0004: 0004-libmultipath-add-wrapper-function-around-pgpolicyfn.patch -Patch0005: 0005-tests-update-pgpolicy-tests-to-work-with-group_paths.patch -Patch0006: 0006-libmultipath-fix-double-free-in-pgpolicyfn-error-pat.patch -Patch0007: 0007-libmultipath-consolidate-group_by_-functions.patch -Patch0008: 0008-libmultipath-make-pgpolicyfn-take-a-paths-vector.patch -Patch0009: 0009-libmultipath-make-group_paths-handle-marginal-paths.patch -Patch0010: 0010-tests-add-tests-for-grouping-marginal-paths.patch -Patch0011: 0011-libmultipath-add-marginal_pathgroups-config-option.patch -Patch0012: 0012-libmutipath-deprecate-delay_-_checks.patch -Patch0013: 0013-multipathd-use-marginal_pathgroups.patch -Patch0014: 0014-multipath-update-man-pages.patch -Patch0015: 0015-multipath.conf-add-enable_foreign-parameter.patch -Patch0016: 0016-multipath.conf.5-document-foreign-library-support.patch -Patch0017: 0017-mpathpersist-remove-broken-unused-code.patch -Patch0018: 0018-libmultipath-EMC-PowerMax-NVMe-device-config.patch -Patch0019: 0019-mpathpersist-fix-leaks.patch -Patch0020: 0020-libmultipath-fix-mpcontext-initialization.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 -Patch0029: 0029-RH-Fix-nvme-compilation-warning.patch -Patch0030: 0030-RH-attempt-to-get-ANA-info-via-sysfs-first.patch -Patch0031: 0031-multipath-fix-issues-found-by-compiling-with-gcc-10.patch -Patch0032: 0032-add-support-for-upcoming-json-c-0.14.0.patch +Patch0001:0001-libmultipath-assign-variable-to-make-gcc-happy.patch +Patch0002: 0002-libmutipath-don-t-close-fd-on-dm_lib_release.patch +Patch0003: 0003-libmultipath-allow-force-reload-with-no-active-paths.patch +Patch0004: 0004-libmpathpersist-depend-on-libmultipath.patch +Patch0005: 0005-multipath-tools-Makefile-more-dependency-fixes-for-p.patch +Patch0006: 0006-multipath-tools-Makefile.inc-set-Wno-error-clobbered.patch +Patch0007: 0007-libmultipath-discovery.c-use-z-qualifier-for-size_t.patch +Patch0008: 0008-libmultipath-eliminate-more-signed-unsigned-comparis.patch +Patch0009: 0009-libmultipath-set_uint-fix-parsing-for-32bit.patch +Patch0010: 0010-multipath-tools-Makefile-add-install-dependency.patch +Patch0011: 0011-libdmmp-Add-support-for-upcoming-json-c-0.14.0.patch +Patch0012: 0012-libmultipath-fix-condlog-NULL-argument-in-uevent_get.patch +Patch0013: 0013-RH-fixup-udev-rules-for-redhat.patch +Patch0014: 0014-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0015: 0015-RH-don-t-start-without-a-config-file.patch +Patch0016: 0016-RH-use-rpm-optflags-if-present.patch +Patch0017: 0017-RH-add-mpathconf.patch +Patch0018: 0018-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0019: 0019-RH-warn-on-invalid-regex-instead-of-failing.patch +Patch0020: 0020-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0021: 0021-RH-Fix-nvme-compilation-warning.patch +Patch0022: 0022-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0023: 0023-RH-work-around-gcc-10-format-truncation-issue.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -124,7 +115,7 @@ This package contains the files needed to develop applications that use device-mapper-multipath's libdmmp C API library %prep -%autosetup -n multipath-tools-0.8.2 -p1 +%autosetup -n multipath-tools-0.8.4 -p1 cp %{SOURCE1} . %build @@ -236,6 +227,25 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Fri May 29 2020 Benjamin Marzinski - 0.8.4-1 +- Update Source to upstream version 0.8.2 + * Previoud patches 0001-0020 & 0031 are included in this commit +- Rename files + * Previous patches 0021-0032 are now patches 0012-0022 +- Add 0001-libmultipath-assign-variable-to-make-gcc-happy.patch +- Add 0002-libmutipath-don-t-close-fd-on-dm_lib_release.patch +- Add 0003-libmultipath-allow-force-reload-with-no-active-paths.patch +- Add 0004-libmpathpersist-depend-on-libmultipath.patch +- Add 0005-multipath-tools-Makefile-more-dependency-fixes-for-p.patch +- Add 0006-multipath-tools-Makefile.inc-set-Wno-error-clobbered.patch +- Add 0007-libmultipath-discovery.c-use-z-qualifier-for-size_t.patch +- Add 0008-libmultipath-eliminate-more-signed-unsigned-comparis.patch +- Add 0009-libmultipath-set_uint-fix-parsing-for-32bit.patch +- Add 0010-multipath-tools-Makefile-add-install-dependency.patch +- Add 0012-libmultipath-fix-condlog-NULL-argument-in-uevent_get.patch +- Add 0023-RH-work-around-gcc-10-format-truncation-issue.patch + * The above 10 patches have been submitted upstream + * Tue Apr 21 2020 Björn Esser - 0.8.2-6 - Rebuild (json-c) diff --git a/sources b/sources index 1e3c506..1e028ad 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (multipath-tools-0.8.2.tgz) = 31cc4054a2f645fa40b7a16aa8715871b848167a32bf3f34e1c900714f61a46f5d79cbda373bda7f8a8fd2280b96e045c1fd27f4b87aa84fc5305097d72edcd6 +SHA512 (multipath-tools-0.8.4.tgz) = 130308e61d6dce31085fc2763219f4df0f3ad9153e0e6e7a5a1c3c948a2305cff9413699025c28f9b81dd24d2a9263f9fa825253060e44232c3bb6600cd1f07f SHA512 (multipath.conf) = 71953dce5a68adcf60a942305f5a66023e6f4c4baf53b1bfdb4edf65ed5b8e03db804363c36d1dcfd85591f4766f52b515269904c53b84d7b076da0b80b09942 From 2b0cd7ccebbd827ec2dae28bde342fd117052c5e Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Wed, 8 Jul 2020 23:16:57 -0500 Subject: [PATCH 04/67] device-mapper-multipath-0.8.4-2 Rebased on top of Martin Wilck's queue of ACKed upstream commits * https://github.com/openSUSE/multipath-tools/tree/upstream-queue * All previous patches have been reordered, with the exception of 0011-libdmmp-Add-support-for-upcoming-json-c-0.14.0.patch which has been replaced with 0029-fix-boolean-value-with-json-c-0.14.patch Modify 0054-RH-add-mpathconf.patch * remove default enable_foreign and property blacklist_exceptions settings, and deal with the builtin default change from 0031-libmultipath-set-enable_foreign-to-NONE-by-default.patch. Fixes bz #1853668 Add 0048-Makefile.inc-trim-extra-information-from-systemd-ver.patch Add 0049-kpartx-fix-Wsign-compare-error.patch * The above two patches have been submitted upstream --- ...limit-PRIN-allocation-length-to-8192.patch | 35 + ...format_transportids-avoid-PROUT-over.patch | 93 +++ ...mpath_format_readfullstatus-use-real.patch | 54 ++ ...th-assign-variable-to-make-gcc-happy.patch | 2 +- ...ath-don-t-close-fd-on-dm_lib_release.patch | 2 +- ...ow-force-reload-with-no-active-paths.patch | 2 +- ...nor-DM_UDEV_DISABLE_OTHER_RULES_FLAG.patch | 30 + ...ck-for-skip_kpartx-on-synthetic-ueve.patch | 43 + ...bmpathpersist-depend-on-libmultipath.patch | 0 ...Makefile-more-dependency-fixes-for-p.patch | 3 +- ...d-support-for-upcoming-json-c-0.14.0.patch | 30 - ...s-Makefile.inc-separate-out-OPTFLAGS.patch | 44 + ...Makefile.inc-allow-user-settings-for.patch | 33 + ...Makefile.inc-set-Wno-error-clobbered.patch | 9 +- ...scovery.c-use-z-qualifier-for-size_t.patch | 3 +- ...minate-more-signed-unsigned-comparis.patch | 19 +- ...ipath-set_uint-fix-parsing-for-32bit.patch | 3 +- ...tests-Makefile-add-lmpathcmd-to-LIBD.patch | 28 + ...tests-Makefile-Fix-OBJDEPS-for-hwtab.patch | 34 + ...tests-test-lib.c-drop-__wrap_is_clai.patch | 33 + ...tests-directio-fix-Wmaybe-uninitaliz.patch | 29 + ...ltipath-move-libsg-into-libmultipath.patch | 83 ++ ...ools-Makefile-add-install-dependency.patch | 3 +- ...ultipath-make-libmp_dm_init-optional.patch | 89 ++ ...e-sysfs_is_multipathed-able-to-retur.patch | 108 +++ ...multipath-centralize-validation-code.patch | 777 ++++++++++++++++++ 0026-Unit-tests-for-is_path_valid.patch | 530 ++++++++++++ ...bmultipath-simplify-failed-wwid-code.patch | 205 +++++ ...se-atomic-linkat-in-mark_failed_wwid.patch | 96 +++ 0029-fix-boolean-value-with-json-c-0.14.patch | 41 + ...-condlog-NULL-argument-in-uevent_get.patch | 2 +- ...et-enable_foreign-to-NONE-by-default.patch | 49 ++ ...e-option-to-enable-foreign-libraries.patch | 89 ++ ...move-_blacklist_exceptions-functions.patch | 139 ++++ ...-parser-issue-with-comments-in-strin.patch | 95 +++ ...ert-regexes-that-start-with-exclamat.patch | 435 ++++++++++ ...mpiler-warnings-when-built-without-s.patch | 111 +++ ...ipath-fix-sysfs-dev_loss_tmo-parsing.patch | 43 + 0038-kpartx-read-devices-with-direct-IO.patch | 267 ++++++ ...dle-alternate-bsd-disklabel-location.patch | 53 ++ ...x-checker-detection-for-nvme-devices.patch | 62 ++ ...e-dm_get_map-status-return-codes-sym.patch | 322 ++++++++ ...x-check_path-errors-with-removed-map.patch | 116 +++ ...e-dm_flush_maps-only-return-0-on-suc.patch | 46 ++ ...athd-add-del-maps-multipathd-command.patch | 161 ++++ ...lushing-maps-work-like-other-command.patch | 104 +++ ...delegate-flushing-maps-to-multipathd.patch | 64 ++ ...option-to-skip-multipathd-delegation.patch | 63 ++ ...m-extra-information-from-systemd-ver.patch | 30 + 0049-kpartx-fix-Wsign-compare-error.patch | 26 + ... 0050-RH-fixup-udev-rules-for-redhat.patch | 6 +- ...property-blacklist-exception-builtin.patch | 18 +- ...RH-don-t-start-without-a-config-file.patch | 4 +- ... 0053-RH-use-rpm-optflags-if-present.patch | 44 +- ...hconf.patch => 0054-RH-add-mpathconf.patch | 60 +- ...om-kernel-cmdline-mpath.wwids-with-A.patch | 26 +- ...-on-invalid-regex-instead-of-failing.patch | 4 +- ...-default-find_mutipaths-value-to-off.patch | 2 +- ...0058-RH-Fix-nvme-compilation-warning.patch | 0 ...empt-to-get-ANA-info-via-sysfs-first.patch | 0 ...round-gcc-10-format-truncation-issue.patch | 20 +- device-mapper-multipath.spec | 105 ++- 62 files changed, 4862 insertions(+), 165 deletions(-) create mode 100644 0001-libmpathpersist-limit-PRIN-allocation-length-to-8192.patch create mode 100644 0002-libmpathpersist-format_transportids-avoid-PROUT-over.patch create mode 100644 0003-libmpathpersist-mpath_format_readfullstatus-use-real.patch rename 0001-libmultipath-assign-variable-to-make-gcc-happy.patch => 0004-libmultipath-assign-variable-to-make-gcc-happy.patch (97%) rename 0002-libmutipath-don-t-close-fd-on-dm_lib_release.patch => 0005-libmutipath-don-t-close-fd-on-dm_lib_release.patch (98%) rename 0003-libmultipath-allow-force-reload-with-no-active-paths.patch => 0006-libmultipath-allow-force-reload-with-no-active-paths.patch (98%) create mode 100644 0007-kpartx.rules-honor-DM_UDEV_DISABLE_OTHER_RULES_FLAG.patch create mode 100644 0008-kpartx.rules-check-for-skip_kpartx-on-synthetic-ueve.patch rename 0004-libmpathpersist-depend-on-libmultipath.patch => 0009-libmpathpersist-depend-on-libmultipath.patch (100%) rename 0005-multipath-tools-Makefile-more-dependency-fixes-for-p.patch => 0010-multipath-tools-Makefile-more-dependency-fixes-for-p.patch (91%) delete mode 100644 0011-libdmmp-Add-support-for-upcoming-json-c-0.14.0.patch create mode 100644 0011-multipath-tools-Makefile.inc-separate-out-OPTFLAGS.patch create mode 100644 0012-multipath-tools-Makefile.inc-allow-user-settings-for.patch rename 0006-multipath-tools-Makefile.inc-set-Wno-error-clobbered.patch => 0013-multipath-tools-Makefile.inc-set-Wno-error-clobbered.patch (79%) rename 0007-libmultipath-discovery.c-use-z-qualifier-for-size_t.patch => 0014-libmultipath-discovery.c-use-z-qualifier-for-size_t.patch (97%) rename 0008-libmultipath-eliminate-more-signed-unsigned-comparis.patch => 0015-libmultipath-eliminate-more-signed-unsigned-comparis.patch (88%) rename 0009-libmultipath-set_uint-fix-parsing-for-32bit.patch => 0016-libmultipath-set_uint-fix-parsing-for-32bit.patch (94%) create mode 100644 0017-multipath-tools-tests-Makefile-add-lmpathcmd-to-LIBD.patch create mode 100644 0018-multipath-tools-tests-Makefile-Fix-OBJDEPS-for-hwtab.patch create mode 100644 0019-multipath-tools-tests-test-lib.c-drop-__wrap_is_clai.patch create mode 100644 0020-multipath-tools-tests-directio-fix-Wmaybe-uninitaliz.patch create mode 100644 0021-libmultipath-move-libsg-into-libmultipath.patch rename 0010-multipath-tools-Makefile-add-install-dependency.patch => 0022-multipath-tools-Makefile-add-install-dependency.patch (91%) create mode 100644 0023-libmultipath-make-libmp_dm_init-optional.patch create mode 100644 0024-libmultipath-make-sysfs_is_multipathed-able-to-retur.patch create mode 100644 0025-multipath-centralize-validation-code.patch create mode 100644 0026-Unit-tests-for-is_path_valid.patch create mode 100644 0027-libmultipath-simplify-failed-wwid-code.patch create mode 100644 0028-libmultipath-use-atomic-linkat-in-mark_failed_wwid.patch create mode 100644 0029-fix-boolean-value-with-json-c-0.14.patch rename 0012-libmultipath-fix-condlog-NULL-argument-in-uevent_get.patch => 0030-libmultipath-fix-condlog-NULL-argument-in-uevent_get.patch (97%) create mode 100644 0031-libmultipath-set-enable_foreign-to-NONE-by-default.patch create mode 100644 0032-multipath-add-e-option-to-enable-foreign-libraries.patch create mode 100644 0033-libmultipath-remove-_blacklist_exceptions-functions.patch create mode 100644 0034-libmultipath-fix-parser-issue-with-comments-in-strin.patch create mode 100644 0035-libmultipath-invert-regexes-that-start-with-exclamat.patch create mode 100644 0036-multipath-Fix-compiler-warnings-when-built-without-s.patch create mode 100644 0037-libmultipath-fix-sysfs-dev_loss_tmo-parsing.patch create mode 100644 0038-kpartx-read-devices-with-direct-IO.patch create mode 100644 0039-kpartx-handle-alternate-bsd-disklabel-location.patch create mode 100644 0040-libmultipath-fix-checker-detection-for-nvme-devices.patch create mode 100644 0041-libmultipath-make-dm_get_map-status-return-codes-sym.patch create mode 100644 0042-multipathd-fix-check_path-errors-with-removed-map.patch create mode 100644 0043-libmultipath-make-dm_flush_maps-only-return-0-on-suc.patch create mode 100644 0044-multipathd-add-del-maps-multipathd-command.patch create mode 100644 0045-multipath-make-flushing-maps-work-like-other-command.patch create mode 100644 0046-multipath-delegate-flushing-maps-to-multipathd.patch create mode 100644 0047-multipath-add-option-to-skip-multipathd-delegation.patch create mode 100644 0048-Makefile.inc-trim-extra-information-from-systemd-ver.patch create mode 100644 0049-kpartx-fix-Wsign-compare-error.patch rename 0013-RH-fixup-udev-rules-for-redhat.patch => 0050-RH-fixup-udev-rules-for-redhat.patch (95%) rename 0014-RH-Remove-the-property-blacklist-exception-builtin.patch => 0051-RH-Remove-the-property-blacklist-exception-builtin.patch (89%) rename 0015-RH-don-t-start-without-a-config-file.patch => 0052-RH-don-t-start-without-a-config-file.patch (98%) rename 0016-RH-use-rpm-optflags-if-present.patch => 0053-RH-use-rpm-optflags-if-present.patch (55%) rename 0017-RH-add-mpathconf.patch => 0054-RH-add-mpathconf.patch (94%) rename 0018-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch => 0055-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch (88%) rename 0019-RH-warn-on-invalid-regex-instead-of-failing.patch => 0056-RH-warn-on-invalid-regex-instead-of-failing.patch (98%) rename 0020-RH-reset-default-find_mutipaths-value-to-off.patch => 0057-RH-reset-default-find_mutipaths-value-to-off.patch (96%) rename 0021-RH-Fix-nvme-compilation-warning.patch => 0058-RH-Fix-nvme-compilation-warning.patch (100%) rename 0022-RH-attempt-to-get-ANA-info-via-sysfs-first.patch => 0059-RH-attempt-to-get-ANA-info-via-sysfs-first.patch (100%) rename 0023-RH-work-around-gcc-10-format-truncation-issue.patch => 0060-RH-work-around-gcc-10-format-truncation-issue.patch (58%) diff --git a/0001-libmpathpersist-limit-PRIN-allocation-length-to-8192.patch b/0001-libmpathpersist-limit-PRIN-allocation-length-to-8192.patch new file mode 100644 index 0000000..d40166a --- /dev/null +++ b/0001-libmpathpersist-limit-PRIN-allocation-length-to-8192.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 6 Mar 2020 21:50:30 +0100 +Subject: [PATCH] libmpathpersist: limit PRIN allocation length to 8192 bytes + +Some targets (notably the qemu-pr-helper) don't support PERSISTENT +RESERVE IN commands with more than 8192 bytes allocation length. +While I have found no explicit requirement in the SCSI specs that +the allocation lengh may not exceed 8k, an 8k limit is also enforced +by sg_persist(8), and actually by mpathpersist itself for the +--allocation-length option, but not for the auto-determined length. + +Fix that. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmpathpersist/mpath_pr_ioctl.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/libmpathpersist/mpath_pr_ioctl.c b/libmpathpersist/mpath_pr_ioctl.c +index 74b26b0c..1a28cba7 100644 +--- a/libmpathpersist/mpath_pr_ioctl.c ++++ b/libmpathpersist/mpath_pr_ioctl.c +@@ -543,5 +543,7 @@ int get_prin_length(int rq_servact) + mx_resp_len = 0; + break; + } ++ if (mx_resp_len > MPATH_MAX_PARAM_LEN) ++ mx_resp_len = MPATH_MAX_PARAM_LEN; + return mx_resp_len; + } +-- +2.17.2 + diff --git a/0002-libmpathpersist-format_transportids-avoid-PROUT-over.patch b/0002-libmpathpersist-format_transportids-avoid-PROUT-over.patch new file mode 100644 index 0000000..6164b26 --- /dev/null +++ b/0002-libmpathpersist-format_transportids-avoid-PROUT-over.patch @@ -0,0 +1,93 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 6 Mar 2020 23:33:04 +0100 +Subject: [PATCH] libmpathpersist: format_transportids(): avoid PROUT overflow + +This limits the PERSISTENT RESERVE OUT data size to max. 8192 bytes. + +Signed-off-by: Benjamin Marzinski +--- + libmpathpersist/mpath_pr_ioctl.c | 31 +++++++++++++++++++++++++++++-- + 1 file changed, 29 insertions(+), 2 deletions(-) + +diff --git a/libmpathpersist/mpath_pr_ioctl.c b/libmpathpersist/mpath_pr_ioctl.c +index 1a28cba7..c78e8000 100644 +--- a/libmpathpersist/mpath_pr_ioctl.c ++++ b/libmpathpersist/mpath_pr_ioctl.c +@@ -1,5 +1,6 @@ + #include + #include ++#include + + #include + #include +@@ -138,38 +139,64 @@ retry : + return status; + } + ++/* ++ * Helper macro to avoid overflow of prout_param_descriptor in ++ * format_transportids(). Data must not be written past ++ * MPATH_MAX_PARAM_LEN bytes from struct prout_param_descriptor. ++ */ ++#define check_overflow(ofs, n, start, label) \ ++ do { \ ++ if ((ofs) + (n) + \ ++ offsetof(struct prout_param_descriptor, private_buffer) \ ++ > MPATH_MAX_PARAM_LEN) \ ++ { \ ++ (ofs) = (start); \ ++ goto label; \ ++ } \ ++ } while(0) ++ + uint32_t format_transportids(struct prout_param_descriptor *paramp) + { + unsigned int i = 0, len; + uint32_t buff_offset = 4; +- memset(paramp->private_buffer, 0, MPATH_MAX_PARAM_LEN); ++ memset(paramp->private_buffer, 0, sizeof(paramp->private_buffer)); + for (i=0; i < paramp->num_transportid; i++ ) + { ++ uint32_t start_offset = buff_offset; ++ ++ check_overflow(buff_offset, 1, start_offset, end_loop); + paramp->private_buffer[buff_offset] = (uint8_t)((paramp->trnptid_list[i]->format_code & 0xff)| + (paramp->trnptid_list[i]->protocol_id & 0xff)); + buff_offset += 1; + switch(paramp->trnptid_list[i]->protocol_id) + { + case MPATH_PROTOCOL_ID_FC: ++ check_overflow(buff_offset, 7 + 8 + 8, ++ start_offset, end_loop); + buff_offset += 7; + memcpy(¶mp->private_buffer[buff_offset], ¶mp->trnptid_list[i]->n_port_name, 8); + buff_offset +=8 ; + buff_offset +=8 ; + break; + case MPATH_PROTOCOL_ID_SAS: ++ check_overflow(buff_offset, 3 + 12, ++ start_offset, end_loop); + buff_offset += 3; + memcpy(¶mp->private_buffer[buff_offset], ¶mp->trnptid_list[i]->sas_address, 8); + buff_offset += 12; + break; + case MPATH_PROTOCOL_ID_ISCSI: +- buff_offset += 1; + len = (paramp->trnptid_list[i]->iscsi_name[1] & 0xff)+2; ++ check_overflow(buff_offset, 1 + len, ++ start_offset, end_loop); ++ buff_offset += 1; + memcpy(¶mp->private_buffer[buff_offset], ¶mp->trnptid_list[i]->iscsi_name,len); + buff_offset += len ; + break; + } + + } ++end_loop: + buff_offset -= 4; + paramp->private_buffer[0] = (unsigned char)((buff_offset >> 24) & 0xff); + paramp->private_buffer[1] = (unsigned char)((buff_offset >> 16) & 0xff); +-- +2.17.2 + diff --git a/0003-libmpathpersist-mpath_format_readfullstatus-use-real.patch b/0003-libmpathpersist-mpath_format_readfullstatus-use-real.patch new file mode 100644 index 0000000..6d0cf1e --- /dev/null +++ b/0003-libmpathpersist-mpath_format_readfullstatus-use-real.patch @@ -0,0 +1,54 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 6 Mar 2020 23:46:47 +0100 +Subject: [PATCH] libmpathpersist: mpath_format_readfullstatus(): use real + buffer size + +This changes no semantics, but it will allow changing the size of +prin_readfd.private_buffer in a follow-up patch. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmpathpersist/mpath_pr_ioctl.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/libmpathpersist/mpath_pr_ioctl.c b/libmpathpersist/mpath_pr_ioctl.c +index c78e8000..fadc9e10 100644 +--- a/libmpathpersist/mpath_pr_ioctl.c ++++ b/libmpathpersist/mpath_pr_ioctl.c +@@ -238,6 +238,8 @@ static void mpath_format_readfullstatus(struct prin_resp *pr_buff) + uint32_t additional_length, k, tid_len_len = 0; + char tempbuff[MPATH_MAX_PARAM_LEN]; + struct prin_fulldescr fdesc; ++ static const int pbuf_size = ++ sizeof(pr_buff->prin_descriptor.prin_readfd.private_buffer); + + convert_be32_to_cpu(&pr_buff->prin_descriptor.prin_readfd.prgeneration); + convert_be32_to_cpu(&pr_buff->prin_descriptor.prin_readfd.number_of_descriptor); +@@ -249,16 +251,18 @@ static void mpath_format_readfullstatus(struct prin_resp *pr_buff) + } + + additional_length = pr_buff->prin_descriptor.prin_readfd.number_of_descriptor; +- if (additional_length > MPATH_MAX_PARAM_LEN) { ++ if (additional_length > pbuf_size) { + condlog(3, "PRIN length %u exceeds max length %d", additional_length, +- MPATH_MAX_PARAM_LEN); ++ pbuf_size); + return; + } + + memset(&fdesc, 0, sizeof(struct prin_fulldescr)); + +- memcpy( tempbuff, pr_buff->prin_descriptor.prin_readfd.private_buffer,MPATH_MAX_PARAM_LEN ); +- memset(&pr_buff->prin_descriptor.prin_readfd.private_buffer, 0, MPATH_MAX_PARAM_LEN); ++ memcpy( tempbuff, pr_buff->prin_descriptor.prin_readfd.private_buffer, ++ pbuf_size); ++ memset(&pr_buff->prin_descriptor.prin_readfd.private_buffer, 0, ++ pbuf_size); + + p =(unsigned char *)tempbuff; + ppbuff = (char *)pr_buff->prin_descriptor.prin_readfd.private_buffer; +-- +2.17.2 + diff --git a/0001-libmultipath-assign-variable-to-make-gcc-happy.patch b/0004-libmultipath-assign-variable-to-make-gcc-happy.patch similarity index 97% rename from 0001-libmultipath-assign-variable-to-make-gcc-happy.patch rename to 0004-libmultipath-assign-variable-to-make-gcc-happy.patch index 06de678..8db8dd9 100644 --- a/0001-libmultipath-assign-variable-to-make-gcc-happy.patch +++ b/0004-libmultipath-assign-variable-to-make-gcc-happy.patch @@ -1,6 +1,6 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski -Date: Tue, 17 Mar 2020 17:28:24 -0500 +Date: Wed, 25 Mar 2020 23:22:46 -0500 Subject: [PATCH] libmultipath: assign variable to make gcc happy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 diff --git a/0002-libmutipath-don-t-close-fd-on-dm_lib_release.patch b/0005-libmutipath-don-t-close-fd-on-dm_lib_release.patch similarity index 98% rename from 0002-libmutipath-don-t-close-fd-on-dm_lib_release.patch rename to 0005-libmutipath-don-t-close-fd-on-dm_lib_release.patch index 9a1ce41..dd4af7e 100644 --- a/0002-libmutipath-don-t-close-fd-on-dm_lib_release.patch +++ b/0005-libmutipath-don-t-close-fd-on-dm_lib_release.patch @@ -1,6 +1,6 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski -Date: Sat, 21 Mar 2020 23:49:59 -0500 +Date: Wed, 25 Mar 2020 23:22:47 -0500 Subject: [PATCH] libmutipath: don't close fd on dm_lib_release If dm_hold_control_open() isn't set, when dm_lib_release() is called, it diff --git a/0003-libmultipath-allow-force-reload-with-no-active-paths.patch b/0006-libmultipath-allow-force-reload-with-no-active-paths.patch similarity index 98% rename from 0003-libmultipath-allow-force-reload-with-no-active-paths.patch rename to 0006-libmultipath-allow-force-reload-with-no-active-paths.patch index a6efaaa..77d5474 100644 --- a/0003-libmultipath-allow-force-reload-with-no-active-paths.patch +++ b/0006-libmultipath-allow-force-reload-with-no-active-paths.patch @@ -1,6 +1,6 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski -Date: Thu, 19 Mar 2020 22:17:51 -0500 +Date: Wed, 25 Mar 2020 23:22:48 -0500 Subject: [PATCH] libmultipath: allow force reload with no active paths If the partition information has changed on multipath devices (say, diff --git a/0007-kpartx.rules-honor-DM_UDEV_DISABLE_OTHER_RULES_FLAG.patch b/0007-kpartx.rules-honor-DM_UDEV_DISABLE_OTHER_RULES_FLAG.patch new file mode 100644 index 0000000..6c33439 --- /dev/null +++ b/0007-kpartx.rules-honor-DM_UDEV_DISABLE_OTHER_RULES_FLAG.patch @@ -0,0 +1,30 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 3 Apr 2020 13:03:01 +0200 +Subject: [PATCH] kpartx.rules: honor DM_UDEV_DISABLE_OTHER_RULES_FLAG + +10-dm.rules sets DM_UDEV_DISABLE_OTHER_RULES_FLAG for spurious +events that should be ignored by other layers. This means devices +with DISK_RO set, and devices that have never been set up properly +by device-mapper before. This flag should be respected by kpartx. + +Signed-off-by: Benjamin Marzinski +--- + kpartx/kpartx.rules | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules +index 8f990494..f1bf31ca 100644 +--- a/kpartx/kpartx.rules ++++ b/kpartx/kpartx.rules +@@ -7,6 +7,7 @@ + KERNEL!="dm-*", GOTO="kpartx_end" + ACTION!="add|change", GOTO="kpartx_end" + ENV{DM_UUID}!="?*", GOTO="kpartx_end" ++ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}=="1", GOTO="kpartx_end" + + # Create dm tables for partitions on multipath devices. + ENV{DM_UUID}!="mpath-?*", GOTO="mpath_kpartx_end" +-- +2.17.2 + diff --git a/0008-kpartx.rules-check-for-skip_kpartx-on-synthetic-ueve.patch b/0008-kpartx.rules-check-for-skip_kpartx-on-synthetic-ueve.patch new file mode 100644 index 0000000..2a18b15 --- /dev/null +++ b/0008-kpartx.rules-check-for-skip_kpartx-on-synthetic-ueve.patch @@ -0,0 +1,43 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 2 Apr 2020 18:12:48 +0200 +Subject: [PATCH] kpartx.rules: check for skip_kpartx on synthetic uevents + +The current test to detect "spurious" uevents, and thus whether to +import DM_SUBSYSTEM_UDEV_FLAG1 (the flag for the "skip_kpartx" option) +from the udev db is wrong. In 10-dm.rules, DM_UDEV_PRIMARY_SOURCE_FLAG +is imported from the db if it isn't set, meaning that it's always 1 +for active maps. The only events for which DM_SUBSYSTEM_UDEV_FLAG1 +must not be loaded from the db are the real "primary" events, which +are "change" events with DM_ACTIVATION=="1". + +11-dm-mpath.rules resets DM_ACTIVATION to 0 if nothing should change in upper +layers. In this case importing DM_SUBSYSTEM_UDEV_FLAG1 is correct, too. kpartx +will not be called anyway, because 11-dm-mpath.rules also sets MPATH_UNCHANGED=1. + +Signed-off-by: Benjamin Marzinski +--- + kpartx/kpartx.rules | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules +index f1bf31ca..d7527d7d 100644 +--- a/kpartx/kpartx.rules ++++ b/kpartx/kpartx.rules +@@ -13,8 +13,11 @@ ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}=="1", GOTO="kpartx_end" + ENV{DM_UUID}!="mpath-?*", GOTO="mpath_kpartx_end" + + # DM_SUBSYSTEM_UDEV_FLAG1 is the "skip_kpartx" flag. +-# For events not generated by libdevmapper, we need to fetch it from db. +-ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}!="1", IMPORT{db}="DM_SUBSYSTEM_UDEV_FLAG1" ++# For events not generated by libdevmapper, we need to fetch it from db: ++# - "change" events with DM_ACTIVATION!="1" (e.g. partition table changes) ++# - "add" events for which rules are not disabled ("coldplug" case) ++ENV{DM_ACTIVATION}!="1", IMPORT{db}="DM_SUBSYSTEM_UDEV_FLAG1" ++ACTION=="add", IMPORT{db}="DM_SUBSYSTEM_UDEV_FLAG1" + ENV{DM_SUBSYSTEM_UDEV_FLAG1}=="1", GOTO="mpath_kpartx_end" + + # 11-dm-mpath.rules sets MPATH_UNCHANGED for events that can be ignored. +-- +2.17.2 + diff --git a/0004-libmpathpersist-depend-on-libmultipath.patch b/0009-libmpathpersist-depend-on-libmultipath.patch similarity index 100% rename from 0004-libmpathpersist-depend-on-libmultipath.patch rename to 0009-libmpathpersist-depend-on-libmultipath.patch diff --git a/0005-multipath-tools-Makefile-more-dependency-fixes-for-p.patch b/0010-multipath-tools-Makefile-more-dependency-fixes-for-p.patch similarity index 91% rename from 0005-multipath-tools-Makefile-more-dependency-fixes-for-p.patch rename to 0010-multipath-tools-Makefile-more-dependency-fixes-for-p.patch index c75ba30..c4f0b3e 100644 --- a/0005-multipath-tools-Makefile-more-dependency-fixes-for-p.patch +++ b/0010-multipath-tools-Makefile-more-dependency-fixes-for-p.patch @@ -1,13 +1,12 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Martin Wilck -Date: Tue, 12 May 2020 00:39:21 +0200 +Date: Mon, 11 May 2020 14:24:37 +0200 Subject: [PATCH] multipath-tools: Makefile: more dependency fixes for parallel build Extend the late fixes from Christian. Cc: Christian Hesse -Signed-off-by: Martin Wilck Signed-off-by: Benjamin Marzinski --- Makefile | 5 +++-- diff --git a/0011-libdmmp-Add-support-for-upcoming-json-c-0.14.0.patch b/0011-libdmmp-Add-support-for-upcoming-json-c-0.14.0.patch deleted file mode 100644 index 7c03c34..0000000 --- a/0011-libdmmp-Add-support-for-upcoming-json-c-0.14.0.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= -Date: Mon, 13 Apr 2020 19:22:02 +0200 -Subject: [PATCH] libdmmp: Add support for upcoming json-c 0.14.0. - -TRUE/FALSE are not defined anymore. 1 and 0 are used instead. -This is backwards compatible, as earlier versions of json-c are -using the same integer values in their present definitions. - -Signed-off-by: Benjamin Marzinski ---- - libdmmp/libdmmp_private.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libdmmp/libdmmp_private.h b/libdmmp/libdmmp_private.h -index ac85b63f..4378962b 100644 ---- a/libdmmp/libdmmp_private.h -+++ b/libdmmp/libdmmp_private.h -@@ -82,7 +82,7 @@ static out_type func_name(struct dmmp_context *ctx, const char *var_name) { \ - do { \ - json_type j_type = json_type_null; \ - json_object *j_obj_tmp = NULL; \ -- if (json_object_object_get_ex(j_obj, key, &j_obj_tmp) != TRUE) { \ -+ if (json_object_object_get_ex(j_obj, key, &j_obj_tmp) != 1) { \ - _error(ctx, "Invalid JSON output from multipathd IPC: " \ - "key '%s' not found", key); \ - rc = DMMP_ERR_IPC_ERROR; \ --- -2.17.2 - diff --git a/0011-multipath-tools-Makefile.inc-separate-out-OPTFLAGS.patch b/0011-multipath-tools-Makefile.inc-separate-out-OPTFLAGS.patch new file mode 100644 index 0000000..2082970 --- /dev/null +++ b/0011-multipath-tools-Makefile.inc-separate-out-OPTFLAGS.patch @@ -0,0 +1,44 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 11 May 2020 15:27:34 +0200 +Subject: [PATCH] multipath-tools: Makefile.inc: separate out OPTFLAGS + +OPTFLAGS is what distribution builds would typically override. That +should not include the warning flags we use. + +Moreover, in the definition of CFLAGS, put $(CFLAGS) first to make it +easier for the user to spot her input in the build logs. + +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index d4d1e0dd..7a59db85 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -93,14 +93,14 @@ STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector) + ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers,) + WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered,) + +-OPTFLAGS = -O2 -g -pipe -Werror -Wall -Wextra -Wformat=2 -Werror=implicit-int \ ++OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 ++WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 -Werror=implicit-int \ + -Werror=implicit-function-declaration -Werror=format-security \ +- $(WNOCLOBBERED) \ +- -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) \ +- $(STACKPROT) --param=ssp-buffer-size=4 ++ $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) + CPPFLAGS := -Wp,-D_FORTIFY_SOURCE=2 +-CFLAGS := $(OPTFLAGS) -DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" \ +- -MMD -MP $(CFLAGS) ++CFLAGS := $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ ++ -DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" \ ++ -MMD -MP + BIN_CFLAGS = -fPIE -DPIE + LIB_CFLAGS = -fPIC + SHARED_FLAGS = -shared +-- +2.17.2 + diff --git a/0012-multipath-tools-Makefile.inc-allow-user-settings-for.patch b/0012-multipath-tools-Makefile.inc-allow-user-settings-for.patch new file mode 100644 index 0000000..ba2ec42 --- /dev/null +++ b/0012-multipath-tools-Makefile.inc-allow-user-settings-for.patch @@ -0,0 +1,33 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 11 May 2020 16:00:04 +0200 +Subject: [PATCH] multipath-tools: Makefile.inc: allow user settings for + LDFLAGS + +This allows e.g. setting LDFLAGS="-m32 -Wl,-b,elf32-i386" to compile +for a 32bit target on a 64bit system. + +Note that, like CFLAGS, the variable needs to be set in the environment, +not on the "make" command line. + +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 7a59db85..671dd1ca 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -104,7 +104,7 @@ CFLAGS := $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ + BIN_CFLAGS = -fPIE -DPIE + LIB_CFLAGS = -fPIC + SHARED_FLAGS = -shared +-LDFLAGS = -Wl,-z,relro -Wl,-z,now ++LDFLAGS := $(LDFLAGS) -Wl,-z,relro -Wl,-z,now + BIN_LDFLAGS = -pie + + # Check whether a function with name $1 has been declared in header file $2. +-- +2.17.2 + diff --git a/0006-multipath-tools-Makefile.inc-set-Wno-error-clobbered.patch b/0013-multipath-tools-Makefile.inc-set-Wno-error-clobbered.patch similarity index 79% rename from 0006-multipath-tools-Makefile.inc-set-Wno-error-clobbered.patch rename to 0013-multipath-tools-Makefile.inc-set-Wno-error-clobbered.patch index 1ad917f..3de6cb6 100644 --- a/0006-multipath-tools-Makefile.inc-set-Wno-error-clobbered.patch +++ b/0013-multipath-tools-Makefile.inc-set-Wno-error-clobbered.patch @@ -1,6 +1,6 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Martin Wilck -Date: Tue, 12 May 2020 00:39:24 +0200 +Date: Mon, 11 May 2020 17:19:37 +0200 Subject: [PATCH] multipath-tools: Makefile.inc: set -Wno-error=clobbered We need to ignore -Wclobbered because gcc has trouble dealing with glibc's @@ -9,14 +9,13 @@ implementation of pthread_cleanup_push(). For some variants of gcc, -Wno-clobbered alone isn't enough if -Werror is also set. Compilation with -Wno-error=clobbered works, though. -Signed-off-by: Martin Wilck Signed-off-by: Benjamin Marzinski --- Makefile.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc -index d4d1e0dd..9060ac9b 100644 +index 671dd1ca..e7256e3a 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -91,7 +91,7 @@ TEST_CC_OPTION = $(shell \ @@ -26,8 +25,8 @@ index d4d1e0dd..9060ac9b 100644 -WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered,) +WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered -Wno-error=clobbered,) - OPTFLAGS = -O2 -g -pipe -Werror -Wall -Wextra -Wformat=2 -Werror=implicit-int \ - -Werror=implicit-function-declaration -Werror=format-security \ + OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 + WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 -Werror=implicit-int \ -- 2.17.2 diff --git a/0007-libmultipath-discovery.c-use-z-qualifier-for-size_t.patch b/0014-libmultipath-discovery.c-use-z-qualifier-for-size_t.patch similarity index 97% rename from 0007-libmultipath-discovery.c-use-z-qualifier-for-size_t.patch rename to 0014-libmultipath-discovery.c-use-z-qualifier-for-size_t.patch index b24cca6..749bef2 100644 --- a/0007-libmultipath-discovery.c-use-z-qualifier-for-size_t.patch +++ b/0014-libmultipath-discovery.c-use-z-qualifier-for-size_t.patch @@ -1,11 +1,10 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Martin Wilck -Date: Tue, 12 May 2020 00:39:25 +0200 +Date: Mon, 11 May 2020 16:02:25 +0200 Subject: [PATCH] libmultipath: discovery.c: use %z qualifier for size_t Otherwise compilation for 32bit targets spits out warnings. -Signed-off-by: Martin Wilck Signed-off-by: Benjamin Marzinski --- libmultipath/discovery.c | 16 ++++++++-------- diff --git a/0008-libmultipath-eliminate-more-signed-unsigned-comparis.patch b/0015-libmultipath-eliminate-more-signed-unsigned-comparis.patch similarity index 88% rename from 0008-libmultipath-eliminate-more-signed-unsigned-comparis.patch rename to 0015-libmultipath-eliminate-more-signed-unsigned-comparis.patch index ac5b284..a97c202 100644 --- a/0008-libmultipath-eliminate-more-signed-unsigned-comparis.patch +++ b/0015-libmultipath-eliminate-more-signed-unsigned-comparis.patch @@ -1,21 +1,34 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Martin Wilck -Date: Tue, 12 May 2020 00:39:26 +0200 +Date: Mon, 11 May 2020 16:03:58 +0200 Subject: [PATCH] libmultipath: eliminate more signed/unsigned comparisons Fix some more compiler warnings about signed/unsigned comparison. I've observed these only on 32bit builds, therefore they went unnoticed before. -Signed-off-by: Martin Wilck Signed-off-by: Benjamin Marzinski --- + libmpathpersist/mpath_pr_ioctl.c | 2 +- libmultipath/print.c | 12 ++++++------ libmultipath/prioritizers/alua_spc3.h | 2 +- multipathd/cli_handlers.c | 20 ++++++++++---------- multipathd/main.c | 2 +- - 4 files changed, 18 insertions(+), 18 deletions(-) + 5 files changed, 19 insertions(+), 19 deletions(-) +diff --git a/libmpathpersist/mpath_pr_ioctl.c b/libmpathpersist/mpath_pr_ioctl.c +index fadc9e10..126601c3 100644 +--- a/libmpathpersist/mpath_pr_ioctl.c ++++ b/libmpathpersist/mpath_pr_ioctl.c +@@ -238,7 +238,7 @@ static void mpath_format_readfullstatus(struct prin_resp *pr_buff) + uint32_t additional_length, k, tid_len_len = 0; + char tempbuff[MPATH_MAX_PARAM_LEN]; + struct prin_fulldescr fdesc; +- static const int pbuf_size = ++ static const unsigned int pbuf_size = + sizeof(pr_buff->prin_descriptor.prin_readfd.private_buffer); + + convert_be32_to_cpu(&pr_buff->prin_descriptor.prin_readfd.prgeneration); diff --git a/libmultipath/print.c b/libmultipath/print.c index b944ef32..298b3764 100644 --- a/libmultipath/print.c diff --git a/0009-libmultipath-set_uint-fix-parsing-for-32bit.patch b/0016-libmultipath-set_uint-fix-parsing-for-32bit.patch similarity index 94% rename from 0009-libmultipath-set_uint-fix-parsing-for-32bit.patch rename to 0016-libmultipath-set_uint-fix-parsing-for-32bit.patch index 25f83c3..c621937 100644 --- a/0009-libmultipath-set_uint-fix-parsing-for-32bit.patch +++ b/0016-libmultipath-set_uint-fix-parsing-for-32bit.patch @@ -1,13 +1,12 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Martin Wilck -Date: Tue, 12 May 2020 00:39:27 +0200 +Date: Mon, 11 May 2020 22:22:25 +0200 Subject: [PATCH] libmultipath: set_uint: fix parsing for 32bit On architectures where sizeof(long) == sizeof(int), the code wouldn't work as intended. Use strtoul instead. As strtoul happily parses negative numbers as input, require the number to begin with a digit. -Signed-off-by: Martin Wilck Signed-off-by: Benjamin Marzinski --- libmultipath/dict.c | 11 +++++++---- diff --git a/0017-multipath-tools-tests-Makefile-add-lmpathcmd-to-LIBD.patch b/0017-multipath-tools-tests-Makefile-add-lmpathcmd-to-LIBD.patch new file mode 100644 index 0000000..282aa38 --- /dev/null +++ b/0017-multipath-tools-tests-Makefile-add-lmpathcmd-to-LIBD.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 11 May 2020 18:24:19 +0200 +Subject: [PATCH] multipath-tools tests/Makefile: add -lmpathcmd to LIBDEPS + +Make sure the linker finds libmpathcmd. + +Signed-off-by: Benjamin Marzinski +--- + tests/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tests/Makefile b/tests/Makefile +index 77ff3249..028c9ea7 100644 +--- a/tests/Makefile ++++ b/tests/Makefile +@@ -10,7 +10,7 @@ W_MISSING_INITIALIZERS := $(call TEST_MISSING_INITIALIZERS) + + CFLAGS += $(BIN_CFLAGS) -I$(multipathdir) -I$(mpathcmddir) \ + -Wno-unused-parameter $(W_MISSING_INITIALIZERS) +-LIBDEPS += -L$(multipathdir) -lmultipath -lcmocka ++LIBDEPS += -L$(multipathdir) -L$(mpathcmddir) -lmultipath -lmpathcmd -lcmocka + + TESTS := uevent parser util dmevents hwtable blacklist unaligned vpd pgpolicy \ + alias directio +-- +2.17.2 + diff --git a/0018-multipath-tools-tests-Makefile-Fix-OBJDEPS-for-hwtab.patch b/0018-multipath-tools-tests-Makefile-Fix-OBJDEPS-for-hwtab.patch new file mode 100644 index 0000000..5835089 --- /dev/null +++ b/0018-multipath-tools-tests-Makefile-Fix-OBJDEPS-for-hwtab.patch @@ -0,0 +1,34 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 11 May 2020 23:44:19 +0200 +Subject: [PATCH] multipath tools tests/Makefile: Fix OBJDEPS for hwtable-test + +OBJDEPS needs to list object files that _call_ functions we want +to wrap, but it should _not_ list the object files where these +functions are defined; otherwise the linker might resolve these +symbols before they can be wrapped. + +(Observed on i586 with gcc 9.3.1, ld 2.34.0, where wrapping +prio_getprio() doesn't work with prio.o in OBJDEPS). + +Signed-off-by: Benjamin Marzinski +--- + tests/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tests/Makefile b/tests/Makefile +index 028c9ea7..1b8706a7 100644 +--- a/tests/Makefile ++++ b/tests/Makefile +@@ -41,7 +41,7 @@ endif + dmevents-test_LIBDEPS = -lpthread -ldevmapper -lurcu + hwtable-test_TESTDEPS := test-lib.o + hwtable-test_OBJDEPS := ../libmultipath/discovery.o ../libmultipath/blacklist.o \ +- ../libmultipath/prio.o ../libmultipath/callout.o ../libmultipath/structs.o ++ ../libmultipath/structs.o + hwtable-test_LIBDEPS := -ludev -lpthread -ldl + blacklist-test_TESTDEPS := test-log.o + blacklist-test_OBJDEPS := ../libmultipath/blacklist.o +-- +2.17.2 + diff --git a/0019-multipath-tools-tests-test-lib.c-drop-__wrap_is_clai.patch b/0019-multipath-tools-tests-test-lib.c-drop-__wrap_is_clai.patch new file mode 100644 index 0000000..e5882f6 --- /dev/null +++ b/0019-multipath-tools-tests-test-lib.c-drop-__wrap_is_clai.patch @@ -0,0 +1,33 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 11 May 2020 23:43:02 +0200 +Subject: [PATCH] multipath-tools tests/test-lib.c: drop + __wrap_is_claimed_by_foreign + +is_claimed_by_foreign() is an inline function and can't be wrapped. + +Signed-off-by: Benjamin Marzinski +--- + tests/test-lib.c | 6 ------ + 1 file changed, 6 deletions(-) + +diff --git a/tests/test-lib.c b/tests/test-lib.c +index 59275163..00bae58e 100644 +--- a/tests/test-lib.c ++++ b/tests/test-lib.c +@@ -56,12 +56,6 @@ int __wrap_execute_program(char *path, char *value, int len) + return 0; + } + +-bool __wrap_is_claimed_by_foreign(struct udev_device *ud) +-{ +- condlog(5, "%s: %p", __func__, ud); +- return false; +-} +- + struct udev_list_entry + *__wrap_udev_device_get_properties_list_entry(struct udev_device *ud) + { +-- +2.17.2 + diff --git a/0020-multipath-tools-tests-directio-fix-Wmaybe-uninitaliz.patch b/0020-multipath-tools-tests-directio-fix-Wmaybe-uninitaliz.patch new file mode 100644 index 0000000..3bf6f75 --- /dev/null +++ b/0020-multipath-tools-tests-directio-fix-Wmaybe-uninitaliz.patch @@ -0,0 +1,29 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 12 May 2020 00:11:39 +0200 +Subject: [PATCH] multipath-tools tests/directio: fix -Wmaybe-uninitalized + warning + +Initialize aio_grp to satisfy gcc. + +Signed-off-by: Benjamin Marzinski +--- + tests/directio.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tests/directio.c b/tests/directio.c +index 3cd7a520..66aaf0eb 100644 +--- a/tests/directio.c ++++ b/tests/directio.c +@@ -316,7 +316,7 @@ static void test_init_free(void **state) + { + int i, count = 0; + struct checker c[4096] = {0}; +- struct aio_group *aio_grp; ++ struct aio_group *aio_grp = NULL; + + assert_true(list_empty(&aio_grp_list)); + will_return(__wrap_io_setup, 0); +-- +2.17.2 + diff --git a/0021-libmultipath-move-libsg-into-libmultipath.patch b/0021-libmultipath-move-libsg-into-libmultipath.patch new file mode 100644 index 0000000..e7cf278 --- /dev/null +++ b/0021-libmultipath-move-libsg-into-libmultipath.patch @@ -0,0 +1,83 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 12 May 2020 16:46:15 +0200 +Subject: [PATCH] libmultipath: move libsg into libmultipath + +sg_read() is called from readsector0 and emc_clariion. Move it +to libmultipath/, where all common code resides. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/Makefile | 3 ++- + libmultipath/checkers/Makefile | 6 +++--- + libmultipath/{checkers => }/libsg.c | 0 + libmultipath/{checkers => }/libsg.h | 0 + libmultipath/prioritizers/Makefile | 2 +- + 5 files changed, 6 insertions(+), 5 deletions(-) + rename libmultipath/{checkers => }/libsg.c (100%) + rename libmultipath/{checkers => }/libsg.h (100%) + +diff --git a/libmultipath/Makefile b/libmultipath/Makefile +index ad690a49..f19b7ad2 100644 +--- a/libmultipath/Makefile ++++ b/libmultipath/Makefile +@@ -47,7 +47,8 @@ OBJS = memory.o parser.o vector.o devmapper.o callout.o \ + switchgroup.o uxsock.o print.o alias.o log_pthread.o \ + log.o configure.o structs_vec.o sysfs.o prio.o checkers.o \ + lock.o file.o wwids.o prioritizers/alua_rtpg.o prkey.o \ +- io_err_stat.o dm-generic.o generic.o foreign.o nvme-lib.o ++ io_err_stat.o dm-generic.o generic.o foreign.o nvme-lib.o \ ++ libsg.o + + all: $(LIBS) + +diff --git a/libmultipath/checkers/Makefile b/libmultipath/checkers/Makefile +index 02caea64..01c04510 100644 +--- a/libmultipath/checkers/Makefile ++++ b/libmultipath/checkers/Makefile +@@ -17,10 +17,10 @@ LIBS= \ + + all: $(LIBS) + +-libcheckdirectio.so: libsg.o directio.o ++libcheckdirectio.so: directio.o + $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ -laio + +-libcheck%.so: libsg.o %.o ++libcheck%.so: %.o + $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ + + install: +@@ -32,7 +32,7 @@ uninstall: + clean: dep_clean + $(RM) core *.a *.o *.gz *.so + +-OBJS := $(LIBS:libcheck%.so=%.o) libsg.o directio.o ++OBJS := $(LIBS:libcheck%.so=%.o) + .SECONDARY: $(OBJS) + + include $(wildcard $(OBJS:.o=.d)) +diff --git a/libmultipath/checkers/libsg.c b/libmultipath/libsg.c +similarity index 100% +rename from libmultipath/checkers/libsg.c +rename to libmultipath/libsg.c +diff --git a/libmultipath/checkers/libsg.h b/libmultipath/libsg.h +similarity index 100% +rename from libmultipath/checkers/libsg.h +rename to libmultipath/libsg.h +diff --git a/libmultipath/prioritizers/Makefile b/libmultipath/prioritizers/Makefile +index 9d0fe03c..fc6e0e0c 100644 +--- a/libmultipath/prioritizers/Makefile ++++ b/libmultipath/prioritizers/Makefile +@@ -28,7 +28,7 @@ endif + + all: $(LIBS) + +-libpriopath_latency.so: path_latency.o ../checkers/libsg.o ++libpriopath_latency.so: path_latency.o + $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ -lm + + libprio%.so: %.o +-- +2.17.2 + diff --git a/0010-multipath-tools-Makefile-add-install-dependency.patch b/0022-multipath-tools-Makefile-add-install-dependency.patch similarity index 91% rename from 0010-multipath-tools-Makefile-add-install-dependency.patch rename to 0022-multipath-tools-Makefile-add-install-dependency.patch index ee1da02..95c80fd 100644 --- a/0010-multipath-tools-Makefile-add-install-dependency.patch +++ b/0022-multipath-tools-Makefile-add-install-dependency.patch @@ -1,13 +1,12 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Martin Wilck -Date: Tue, 12 May 2020 22:38:22 +0200 +Date: Tue, 12 May 2020 22:13:51 +0200 Subject: [PATCH] multipath-tools Makefile: add install dependency $(libdir) must exist before running "make install" on prioritizer, checker, and foreign libraries. Cc: Christian Hesse -Signed-off-by: Martin Wilck Signed-off-by: Benjamin Marzinski --- Makefile | 4 ++++ diff --git a/0023-libmultipath-make-libmp_dm_init-optional.patch b/0023-libmultipath-make-libmp_dm_init-optional.patch new file mode 100644 index 0000000..588fd87 --- /dev/null +++ b/0023-libmultipath-make-libmp_dm_init-optional.patch @@ -0,0 +1,89 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 19 May 2020 12:08:40 -0500 +Subject: [PATCH] libmultipath: make libmp_dm_init optional + +Move dm_initialized out of libmp_dm_task_create(), and add +a function skip_libmp_dm_init() so that users of libmultipath can skip +initializing device-mapper. This is needed for other programs that +use libmultipath (or a library that depends on it) but want to control +how device-mapper is set up. + +Also make dm_prereq a global function. + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/devmapper.c | 17 +++++++++++++---- + libmultipath/devmapper.h | 3 ++- + 2 files changed, 15 insertions(+), 5 deletions(-) + +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index 13a1cf53..7ed494a1 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -33,6 +33,8 @@ + #define MAX_WAIT 5 + #define LOOPS_PER_SEC 5 + ++static pthread_once_t dm_initialized = PTHREAD_ONCE_INIT; ++ + static int dm_conf_verbosity; + + #ifdef LIBDM_API_DEFERRED +@@ -229,7 +231,7 @@ dm_tgt_prereq (unsigned int *ver) + return 1; + } + +-static int dm_prereq(unsigned int *v) ++int dm_prereq(unsigned int *v) + { + if (dm_lib_prereq()) + return 1; +@@ -243,7 +245,7 @@ void libmp_udev_set_sync_support(int on) + libmp_dm_udev_sync = !!on; + } + +-void libmp_dm_init(void) ++static void libmp_dm_init(void) + { + struct config *conf; + int verbosity; +@@ -262,11 +264,18 @@ void libmp_dm_init(void) + dm_udev_set_sync_support(libmp_dm_udev_sync); + } + ++static void _do_skip_libmp_dm_init(void) ++{ ++} ++ ++void skip_libmp_dm_init(void) ++{ ++ pthread_once(&dm_initialized, _do_skip_libmp_dm_init); ++} ++ + struct dm_task* + libmp_dm_task_create(int task) + { +- static pthread_once_t dm_initialized = PTHREAD_ONCE_INIT; +- + pthread_once(&dm_initialized, libmp_dm_init); + return dm_task_create(task); + } +diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h +index 7557a86b..17fc9faf 100644 +--- a/libmultipath/devmapper.h ++++ b/libmultipath/devmapper.h +@@ -28,7 +28,8 @@ + #define UUID_PREFIX_LEN (sizeof(UUID_PREFIX) - 1) + + void dm_init(int verbosity); +-void libmp_dm_init(void); ++int dm_prereq(unsigned int *v); ++void skip_libmp_dm_init(void); + void libmp_udev_set_sync_support(int on); + struct dm_task *libmp_dm_task_create(int task); + int dm_drv_version (unsigned int * version); +-- +2.17.2 + diff --git a/0024-libmultipath-make-sysfs_is_multipathed-able-to-retur.patch b/0024-libmultipath-make-sysfs_is_multipathed-able-to-retur.patch new file mode 100644 index 0000000..47c7a80 --- /dev/null +++ b/0024-libmultipath-make-sysfs_is_multipathed-able-to-retur.patch @@ -0,0 +1,108 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 19 May 2020 12:08:41 -0500 +Subject: [PATCH] libmultipath: make sysfs_is_multipathed able to return wwid + +sysfs_is_multipathed reads the wwid of the dm device holding a path to +check if its a multipath device. Add code to optinally set pp->wwid to +that wwid. This will be used by a future patch. + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/sysfs.c | 24 +++++++++++++++++++----- + libmultipath/sysfs.h | 2 +- + multipath/main.c | 7 ++++--- + 3 files changed, 24 insertions(+), 9 deletions(-) + +diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c +index 62ec2ed7..12a82d95 100644 +--- a/libmultipath/sysfs.c ++++ b/libmultipath/sysfs.c +@@ -295,7 +295,7 @@ static int select_dm_devs(const struct dirent *di) + return fnmatch("dm-*", di->d_name, FNM_FILE_NAME) == 0; + } + +-bool sysfs_is_multipathed(const struct path *pp) ++bool sysfs_is_multipathed(struct path *pp, bool set_wwid) + { + char pathbuf[PATH_MAX]; + struct scandir_result sr; +@@ -325,7 +325,7 @@ bool sysfs_is_multipathed(const struct path *pp) + for (i = 0; i < r && !found; i++) { + long fd; + int nr; +- char uuid[6]; ++ char uuid[WWID_SIZE + UUID_PREFIX_LEN]; + + if (safe_snprintf(pathbuf + n, sizeof(pathbuf) - n, + "/%s/dm/uuid", di[i]->d_name)) +@@ -339,12 +339,26 @@ bool sysfs_is_multipathed(const struct path *pp) + + pthread_cleanup_push(close_fd, (void *)fd); + nr = read(fd, uuid, sizeof(uuid)); +- if (nr == sizeof(uuid) && !memcmp(uuid, "mpath-", sizeof(uuid))) ++ if (nr > (int)UUID_PREFIX_LEN && ++ !memcmp(uuid, UUID_PREFIX, UUID_PREFIX_LEN)) + found = true; + else if (nr < 0) { +- condlog(1, "%s: error reading from %s: %s", +- __func__, pathbuf, strerror(errno)); ++ condlog(1, "%s: error reading from %s: %m", ++ __func__, pathbuf); + } ++ if (found && set_wwid) { ++ nr -= UUID_PREFIX_LEN; ++ memcpy(pp->wwid, uuid + UUID_PREFIX_LEN, nr); ++ if (nr == WWID_SIZE) { ++ condlog(4, "%s: overflow while reading from %s", ++ __func__, pathbuf); ++ pp->wwid[0] = '\0'; ++ } else { ++ pp->wwid[nr] = '\0'; ++ strchop(pp->wwid); ++ } ++ } ++ + pthread_cleanup_pop(1); + } + pthread_cleanup_pop(1); +diff --git a/libmultipath/sysfs.h b/libmultipath/sysfs.h +index 9ae30b39..72b39ab2 100644 +--- a/libmultipath/sysfs.h ++++ b/libmultipath/sysfs.h +@@ -14,5 +14,5 @@ ssize_t sysfs_bin_attr_get_value(struct udev_device *dev, const char *attr_name, + unsigned char * value, size_t value_len); + int sysfs_get_size (struct path *pp, unsigned long long * size); + int sysfs_check_holders(char * check_devt, char * new_devt); +-bool sysfs_is_multipathed(const struct path *pp); ++bool sysfs_is_multipathed(struct path *pp, bool set_wwid); + #endif +diff --git a/multipath/main.c b/multipath/main.c +index cf9d2a28..545ead87 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -638,7 +638,8 @@ configure (struct config *conf, enum mpath_cmds cmd, + * Shortcut for find_multipaths smart: + * Quick check if path is already multipathed. + */ +- if (sysfs_is_multipathed(VECTOR_SLOT(pathvec, 0))) { ++ if (sysfs_is_multipathed(VECTOR_SLOT(pathvec, 0), ++ false)) { + r = RTVL_YES; + goto print_valid; + } +@@ -747,8 +748,8 @@ configure (struct config *conf, enum mpath_cmds cmd, + /* + * Check if we raced with multipathd + */ +- r = sysfs_is_multipathed(VECTOR_SLOT(pathvec, 0)) ? +- RTVL_YES : RTVL_NO; ++ r = sysfs_is_multipathed(VECTOR_SLOT(pathvec, 0), ++ false) ? RTVL_YES : RTVL_NO; + } + goto print_valid; + } +-- +2.17.2 + diff --git a/0025-multipath-centralize-validation-code.patch b/0025-multipath-centralize-validation-code.patch new file mode 100644 index 0000000..c8f862c --- /dev/null +++ b/0025-multipath-centralize-validation-code.patch @@ -0,0 +1,777 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 19 May 2020 12:08:42 -0500 +Subject: [PATCH] multipath: centralize validation code + +This code pulls the multipath path validation code out of configure(), +and puts it into its own function, check_path_valid(). This function +calls a new libmultipath function, is_path_valid() to check just path +requested. This seperation exists so that is_path_valid() can be reused +by future code. This code will give almost the same answer as the +existing code, with the exception that now, if a device is currently +multipathed, it will always be a valid multipath path. + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/Makefile | 2 +- + libmultipath/devmapper.c | 45 ++++++ + libmultipath/devmapper.h | 1 + + libmultipath/structs.h | 24 +--- + libmultipath/valid.c | 118 ++++++++++++++++ + libmultipath/valid.h | 42 ++++++ + libmultipath/wwids.c | 10 +- + multipath/main.c | 296 +++++++++++++++++---------------------- + 8 files changed, 343 insertions(+), 195 deletions(-) + create mode 100644 libmultipath/valid.c + create mode 100644 libmultipath/valid.h + +diff --git a/libmultipath/Makefile b/libmultipath/Makefile +index f19b7ad2..e5dac5ea 100644 +--- a/libmultipath/Makefile ++++ b/libmultipath/Makefile +@@ -48,7 +48,7 @@ OBJS = memory.o parser.o vector.o devmapper.o callout.o \ + log.o configure.o structs_vec.o sysfs.o prio.o checkers.o \ + lock.o file.o wwids.o prioritizers/alua_rtpg.o prkey.o \ + io_err_stat.o dm-generic.o generic.o foreign.o nvme-lib.o \ +- libsg.o ++ libsg.o valid.o + + all: $(LIBS) + +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index 7ed494a1..27d52398 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -770,6 +770,51 @@ out: + return r; + } + ++/* ++ * Return ++ * 1 : map with uuid exists ++ * 0 : map with uuid doesn't exist ++ * -1 : error ++ */ ++int ++dm_map_present_by_uuid(const char *uuid) ++{ ++ struct dm_task *dmt; ++ struct dm_info info; ++ char prefixed_uuid[WWID_SIZE + UUID_PREFIX_LEN]; ++ int r = -1; ++ ++ if (!uuid || uuid[0] == '\0') ++ return 0; ++ ++ if (safe_sprintf(prefixed_uuid, UUID_PREFIX "%s", uuid)) ++ goto out; ++ ++ if (!(dmt = dm_task_create(DM_DEVICE_INFO))) ++ goto out; ++ ++ dm_task_no_open_count(dmt); ++ ++ if (!dm_task_set_uuid(dmt, prefixed_uuid)) ++ goto out_task; ++ ++ if (!dm_task_run(dmt)) ++ goto out_task; ++ ++ if (!dm_task_get_info(dmt, &info)) ++ goto out_task; ++ ++ r = !!info.exists; ++ ++out_task: ++ dm_task_destroy(dmt); ++out: ++ if (r < 0) ++ condlog(3, "%s: dm command failed in %s: %s", uuid, ++ __FUNCTION__, strerror(errno)); ++ return r; ++} ++ + static int + dm_dev_t (const char * mapname, char * dev_t, int len) + { +diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h +index 17fc9faf..5ed7edc5 100644 +--- a/libmultipath/devmapper.h ++++ b/libmultipath/devmapper.h +@@ -39,6 +39,7 @@ int dm_simplecmd_noflush (int, const char *, uint16_t); + int dm_addmap_create (struct multipath *mpp, char *params); + int dm_addmap_reload (struct multipath *mpp, char *params, int flush); + int dm_map_present (const char *); ++int dm_map_present_by_uuid(const char *uuid); + int dm_get_map(const char *, unsigned long long *, char *); + int dm_get_status(const char *, char *); + int dm_type(const char *, char *); +diff --git a/libmultipath/structs.h b/libmultipath/structs.h +index 9bd39eb1..d69bc2e9 100644 +--- a/libmultipath/structs.h ++++ b/libmultipath/structs.h +@@ -101,29 +101,13 @@ enum yes_no_undef_states { + YNU_YES, + }; + +-#define _FIND_MULTIPATHS_F (1 << 1) +-#define _FIND_MULTIPATHS_I (1 << 2) +-#define _FIND_MULTIPATHS_N (1 << 3) +-/* +- * _FIND_MULTIPATHS_F must have the same value as YNU_YES. +- * Generate a compile time error if that isn't the case. +- */ +-extern char ___error1___[-(_FIND_MULTIPATHS_F != YNU_YES)]; +- +-#define find_multipaths_on(conf) \ +- (!!((conf)->find_multipaths & _FIND_MULTIPATHS_F)) +-#define ignore_wwids_on(conf) \ +- (!!((conf)->find_multipaths & _FIND_MULTIPATHS_I)) +-#define ignore_new_devs_on(conf) \ +- (!!((conf)->find_multipaths & _FIND_MULTIPATHS_N)) +- + enum find_multipaths_states { + FIND_MULTIPATHS_UNDEF = YNU_UNDEF, + FIND_MULTIPATHS_OFF = YNU_NO, +- FIND_MULTIPATHS_ON = _FIND_MULTIPATHS_F, +- FIND_MULTIPATHS_GREEDY = _FIND_MULTIPATHS_I, +- FIND_MULTIPATHS_SMART = _FIND_MULTIPATHS_F|_FIND_MULTIPATHS_I, +- FIND_MULTIPATHS_STRICT = _FIND_MULTIPATHS_F|_FIND_MULTIPATHS_N, ++ FIND_MULTIPATHS_ON = YNU_YES, ++ FIND_MULTIPATHS_GREEDY, ++ FIND_MULTIPATHS_SMART, ++ FIND_MULTIPATHS_STRICT, + __FIND_MULTIPATHS_LAST, + }; + +diff --git a/libmultipath/valid.c b/libmultipath/valid.c +new file mode 100644 +index 00000000..456b1f6e +--- /dev/null ++++ b/libmultipath/valid.c +@@ -0,0 +1,118 @@ ++/* ++ Copyright (c) 2020 Benjamin Marzinski, IBM ++ ++ This program is free software; you can redistribute it and/or ++ modify it under the terms of the GNU General Public License ++ as published by the Free Software Foundation; either version 2 ++ of the License, or (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . ++ */ ++#include ++#include ++#include ++ ++#include "vector.h" ++#include "config.h" ++#include "debug.h" ++#include "util.h" ++#include "devmapper.h" ++#include "discovery.h" ++#include "wwids.h" ++#include "sysfs.h" ++#include "blacklist.h" ++#include "mpath_cmd.h" ++#include "valid.h" ++ ++int ++is_path_valid(const char *name, struct config *conf, struct path *pp, ++ bool check_multipathd) ++{ ++ int r; ++ int fd; ++ ++ if (!pp || !name || !conf) ++ return PATH_IS_ERROR; ++ ++ if (conf->find_multipaths <= FIND_MULTIPATHS_UNDEF || ++ conf->find_multipaths >= __FIND_MULTIPATHS_LAST) ++ return PATH_IS_ERROR; ++ ++ if (safe_sprintf(pp->dev, "%s", name)) ++ return PATH_IS_ERROR; ++ ++ if (sysfs_is_multipathed(pp, true)) { ++ if (pp->wwid[0] == '\0') ++ return PATH_IS_ERROR; ++ return PATH_IS_VALID_NO_CHECK; ++ } ++ ++ /* ++ * "multipath -u" may be run before the daemon is started. In this ++ * case, systemd might own the socket but might delay multipathd ++ * startup until some other unit (udev settle!) has finished ++ * starting. With many LUNs, the listen backlog may be exceeded, which ++ * would cause connect() to block. This causes udev workers calling ++ * "multipath -u" to hang, and thus creates a deadlock, until "udev ++ * settle" times out. To avoid this, call connect() in non-blocking ++ * mode here, and take EAGAIN as indication for a filled-up systemd ++ * backlog. ++ */ ++ ++ if (check_multipathd) { ++ fd = __mpath_connect(1); ++ if (fd < 0) { ++ if (errno != EAGAIN && !systemd_service_enabled(name)) { ++ condlog(3, "multipathd not running or enabled"); ++ return PATH_IS_NOT_VALID; ++ } ++ } else ++ mpath_disconnect(fd); ++ } ++ ++ pp->udev = udev_device_new_from_subsystem_sysname(udev, "block", name); ++ if (!pp->udev) ++ return PATH_IS_ERROR; ++ ++ r = pathinfo(pp, conf, DI_SYSFS | DI_WWID | DI_BLACKLIST); ++ if (r == PATHINFO_SKIPPED) ++ return PATH_IS_NOT_VALID; ++ else if (r) ++ return PATH_IS_ERROR; ++ ++ if (pp->wwid[0] == '\0') ++ return PATH_IS_NOT_VALID; ++ ++ if (pp->udev && pp->uid_attribute && ++ filter_property(conf, pp->udev, 3, pp->uid_attribute) > 0) ++ return PATH_IS_NOT_VALID; ++ ++ r = is_failed_wwid(pp->wwid); ++ if (r != WWID_IS_NOT_FAILED) { ++ if (r == WWID_IS_FAILED) ++ return PATH_IS_NOT_VALID; ++ return PATH_IS_ERROR; ++ } ++ ++ if (conf->find_multipaths == FIND_MULTIPATHS_GREEDY) ++ return PATH_IS_VALID; ++ ++ if (check_wwids_file(pp->wwid, 0) == 0) ++ return PATH_IS_VALID_NO_CHECK; ++ ++ if (dm_map_present_by_uuid(pp->wwid) == 1) ++ return PATH_IS_VALID; ++ ++ /* all these act like FIND_MULTIPATHS_STRICT for finding if a ++ * path is valid */ ++ if (conf->find_multipaths != FIND_MULTIPATHS_SMART) ++ return PATH_IS_NOT_VALID; ++ ++ return PATH_IS_MAYBE_VALID; ++} +diff --git a/libmultipath/valid.h b/libmultipath/valid.h +new file mode 100644 +index 00000000..ce1c7cbf +--- /dev/null ++++ b/libmultipath/valid.h +@@ -0,0 +1,42 @@ ++/* ++ Copyright (c) 2020 Benjamin Marzinski, IBM ++ ++ This program is free software; you can redistribute it and/or ++ modify it under the terms of the GNU General Public License ++ as published by the Free Software Foundation; either version 2 ++ of the License, or (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . ++ */ ++#ifndef _VALID_H ++#define _VALID_H ++ ++/* ++ * PATH_IS_VALID_NO_CHECK is returned when multipath should claim ++ * the path, regardless of whether is has been released to systemd ++ * already. ++ * PATH_IS_VALID is returned by is_path_valid, when the path is ++ * valid only if it hasn't been released to systemd already. ++ * PATH_IS_MAYBE_VALID is returned when the the path would be valid ++ * if other paths with the same wwid existed. It is up to the caller ++ * to check for these other paths. ++ */ ++enum is_path_valid_result { ++ PATH_IS_ERROR = -1, ++ PATH_IS_NOT_VALID, ++ PATH_IS_VALID, ++ PATH_IS_VALID_NO_CHECK, ++ PATH_IS_MAYBE_VALID, ++ PATH_MAX_VALID_RESULT, /* only for bounds checking */ ++}; ++ ++int is_path_valid(const char *name, struct config *conf, struct path *pp, ++ bool check_multipathd); ++ ++#endif /* _VALID_D */ +diff --git a/libmultipath/wwids.c b/libmultipath/wwids.c +index 28a2150d..637cb0ab 100644 +--- a/libmultipath/wwids.c ++++ b/libmultipath/wwids.c +@@ -289,19 +289,19 @@ out: + int + should_multipath(struct path *pp1, vector pathvec, vector mpvec) + { +- int i, ignore_new_devs, find_multipaths; ++ int i, find_multipaths; + struct path *pp2; + struct config *conf; + + conf = get_multipath_config(); +- ignore_new_devs = ignore_new_devs_on(conf); +- find_multipaths = find_multipaths_on(conf); ++ find_multipaths = conf->find_multipaths; + put_multipath_config(conf); +- if (!find_multipaths && !ignore_new_devs) ++ if (find_multipaths == FIND_MULTIPATHS_OFF || ++ find_multipaths == FIND_MULTIPATHS_GREEDY) + return 1; + + condlog(4, "checking if %s should be multipathed", pp1->dev); +- if (!ignore_new_devs) { ++ if (find_multipaths != FIND_MULTIPATHS_STRICT) { + char tmp_wwid[WWID_SIZE]; + struct multipath *mp = find_mp_by_wwid(mpvec, pp1->wwid); + +diff --git a/multipath/main.c b/multipath/main.c +index 545ead87..953fab27 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -63,21 +63,18 @@ + #include "propsel.h" + #include "time-util.h" + #include "file.h" ++#include "valid.h" + + int logsink; + struct udev *udev; + struct config *multipath_conf; + + /* +- * Return values of configure(), print_cmd_valid(), and main(). +- * RTVL_{YES,NO} are synonyms for RTVL_{OK,FAIL} for the CMD_VALID_PATH case. ++ * Return values of configure(), check_path_valid(), and main(). + */ + enum { + RTVL_OK = 0, +- RTVL_YES = RTVL_OK, + RTVL_FAIL = 1, +- RTVL_NO = RTVL_FAIL, +- RTVL_MAYBE, /* only used internally, never returned */ + RTVL_RETRY, /* returned by configure(), not by main() */ + }; + +@@ -269,9 +266,6 @@ get_dm_mpvec (enum mpath_cmds cmd, vector curmp, vector pathvec, char * refwwid) + continue; + } + +- if (cmd == CMD_VALID_PATH) +- continue; +- + dm_get_map(mpp->alias, &mpp->size, params); + condlog(3, "params = %s", params); + dm_get_status(mpp->alias, status); +@@ -491,10 +485,11 @@ static int print_cmd_valid(int k, const vector pathvec, + struct timespec until; + struct path *pp; + +- if (k != RTVL_YES && k != RTVL_NO && k != RTVL_MAYBE) +- return RTVL_NO; ++ if (k != PATH_IS_VALID && k != PATH_IS_NOT_VALID && ++ k != PATH_IS_MAYBE_VALID) ++ return PATH_IS_NOT_VALID; + +- if (k == RTVL_MAYBE) { ++ if (k == PATH_IS_MAYBE_VALID) { + /* + * Caller ensures that pathvec[0] is the path to + * examine. +@@ -504,7 +499,7 @@ static int print_cmd_valid(int k, const vector pathvec, + wait = find_multipaths_check_timeout( + pp, pp->find_multipaths_timeout, &until); + if (wait != FIND_MULTIPATHS_WAITING) +- k = RTVL_NO; ++ k = PATH_IS_NOT_VALID; + } else if (pathvec != NULL && (pp = VECTOR_SLOT(pathvec, 0))) + wait = find_multipaths_check_timeout(pp, 0, &until); + if (wait == FIND_MULTIPATHS_WAITING) +@@ -513,9 +508,9 @@ static int print_cmd_valid(int k, const vector pathvec, + else if (wait == FIND_MULTIPATHS_WAIT_DONE) + printf("FIND_MULTIPATHS_WAIT_UNTIL=\"0\"\n"); + printf("DM_MULTIPATH_DEVICE_PATH=\"%d\"\n", +- k == RTVL_MAYBE ? 2 : k == RTVL_YES ? 1 : 0); ++ k == PATH_IS_MAYBE_VALID ? 2 : k == PATH_IS_VALID ? 1 : 0); + /* Never return RTVL_MAYBE */ +- return k == RTVL_NO ? RTVL_NO : RTVL_YES; ++ return k == PATH_IS_NOT_VALID ? PATH_IS_NOT_VALID : PATH_IS_VALID; + } + + /* +@@ -548,7 +543,6 @@ configure (struct config *conf, enum mpath_cmds cmd, + int di_flag = 0; + char * refwwid = NULL; + char * dev = NULL; +- bool released = released_to_systemd(); + + /* + * allocate core vectors to store paths and multipaths +@@ -573,7 +567,7 @@ configure (struct config *conf, enum mpath_cmds cmd, + cmd != CMD_REMOVE_WWID && + (filter_devnode(conf->blist_devnode, + conf->elist_devnode, dev) > 0)) { +- goto print_valid; ++ goto out; + } + + /* +@@ -581,14 +575,10 @@ configure (struct config *conf, enum mpath_cmds cmd, + * failing the translation is fatal (by policy) + */ + if (devpath) { +- int failed = get_refwwid(cmd, devpath, dev_type, +- pathvec, &refwwid); ++ get_refwwid(cmd, devpath, dev_type, pathvec, &refwwid); + if (!refwwid) { + condlog(4, "%s: failed to get wwid", devpath); +- if (failed == 2 && cmd == CMD_VALID_PATH) +- goto print_valid; +- else +- condlog(3, "scope is null"); ++ condlog(3, "scope is null"); + goto out; + } + if (cmd == CMD_REMOVE_WWID) { +@@ -614,53 +604,6 @@ configure (struct config *conf, enum mpath_cmds cmd, + goto out; + } + condlog(3, "scope limited to %s", refwwid); +- /* If you are ignoring the wwids file and find_multipaths is +- * set, you need to actually check if there are two available +- * paths to determine if this path should be multipathed. To +- * do this, we put off the check until after discovering all +- * the paths. +- * Paths listed in the wwids file are always considered valid. +- */ +- if (cmd == CMD_VALID_PATH) { +- if (is_failed_wwid(refwwid) == WWID_IS_FAILED) { +- r = RTVL_NO; +- goto print_valid; +- } +- if ((!find_multipaths_on(conf) && +- ignore_wwids_on(conf)) || +- check_wwids_file(refwwid, 0) == 0) +- r = RTVL_YES; +- if (!ignore_wwids_on(conf)) +- goto print_valid; +- /* At this point, either r==0 or find_multipaths_on. */ +- +- /* +- * Shortcut for find_multipaths smart: +- * Quick check if path is already multipathed. +- */ +- if (sysfs_is_multipathed(VECTOR_SLOT(pathvec, 0), +- false)) { +- r = RTVL_YES; +- goto print_valid; +- } +- +- /* +- * DM_MULTIPATH_DEVICE_PATH=="0" means that we have +- * been called for this device already, and have +- * released it to systemd. Unless the device is now +- * already multipathed (see above), we can't try to +- * grab it, because setting SYSTEMD_READY=0 would +- * cause file systems to be unmounted. +- * Leave DM_MULTIPATH_DEVICE_PATH="0". +- */ +- if (released) { +- r = RTVL_NO; +- goto print_valid; +- } +- if (r == RTVL_YES) +- goto print_valid; +- /* find_multipaths_on: Fall through to path detection */ +- } + } + + /* +@@ -701,59 +644,6 @@ configure (struct config *conf, enum mpath_cmds cmd, + goto out; + } + +- if (cmd == CMD_VALID_PATH) { +- struct path *pp; +- int fd; +- +- /* This only happens if find_multipaths and +- * ignore_wwids is set, and the path is not in WWIDs +- * file, not currently multipathed, and has +- * never been released to systemd. +- * If there is currently a multipath device matching +- * the refwwid, or there is more than one path matching +- * the refwwid, then the path is valid */ +- if (VECTOR_SIZE(curmp) != 0) { +- r = RTVL_YES; +- goto print_valid; +- } else if (VECTOR_SIZE(pathvec) > 1) +- r = RTVL_YES; +- else +- r = RTVL_MAYBE; +- +- /* +- * If opening the path with O_EXCL fails, the path +- * is in use (e.g. mounted during initramfs processing). +- * We know that it's not used by dm-multipath. +- * We may not set SYSTEMD_READY=0 on such devices, it +- * might cause systemd to umount the device. +- * Use O_RDONLY, because udevd would trigger another +- * uevent for close-after-write. +- * +- * The O_EXCL check is potentially dangerous, because it may +- * race with other tasks trying to access the device. Therefore +- * this code is only executed if the path hasn't been released +- * to systemd earlier (see above). +- * +- * get_refwwid() above stores the path we examine in slot 0. +- */ +- pp = VECTOR_SLOT(pathvec, 0); +- fd = open(udev_device_get_devnode(pp->udev), +- O_RDONLY|O_EXCL); +- if (fd >= 0) +- close(fd); +- else { +- condlog(3, "%s: path %s is in use: %s", +- __func__, pp->dev, +- strerror(errno)); +- /* +- * Check if we raced with multipathd +- */ +- r = sysfs_is_multipathed(VECTOR_SLOT(pathvec, 0), +- false) ? RTVL_YES : RTVL_NO; +- } +- goto print_valid; +- } +- + if (cmd != CMD_CREATE && cmd != CMD_DRY_RUN) { + r = RTVL_OK; + goto out; +@@ -766,10 +656,6 @@ configure (struct config *conf, enum mpath_cmds cmd, + conf->force_reload, cmd); + r = rc == CP_RETRY ? RTVL_RETRY : rc == CP_OK ? RTVL_OK : RTVL_FAIL; + +-print_valid: +- if (cmd == CMD_VALID_PATH) +- r = print_cmd_valid(r, pathvec, conf); +- + out: + if (refwwid) + FREE(refwwid); +@@ -780,6 +666,112 @@ out: + return r; + } + ++static int ++check_path_valid(const char *name, struct config *conf, bool is_uevent) ++{ ++ int fd, r = PATH_IS_ERROR; ++ struct path *pp = NULL; ++ vector pathvec = NULL; ++ ++ pp = alloc_path(); ++ if (!pp) ++ return RTVL_FAIL; ++ ++ r = is_path_valid(name, conf, pp, is_uevent); ++ if (r <= PATH_IS_ERROR || r >= PATH_MAX_VALID_RESULT) ++ goto fail; ++ ++ /* set path values if is_path_valid() didn't */ ++ if (!pp->udev) ++ pp->udev = udev_device_new_from_subsystem_sysname(udev, "block", ++ name); ++ if (!pp->udev) ++ goto fail; ++ ++ if (!strlen(pp->dev_t)) { ++ dev_t devt = udev_device_get_devnum(pp->udev); ++ if (major(devt) == 0 && minor(devt) == 0) ++ goto fail; ++ snprintf(pp->dev_t, BLK_DEV_SIZE, "%d:%d", major(devt), ++ minor(devt)); ++ } ++ ++ pathvec = vector_alloc(); ++ if (!pathvec) ++ goto fail; ++ ++ if (store_path(pathvec, pp) != 0) { ++ free_path(pp); ++ goto fail; ++ } ++ ++ if ((r == PATH_IS_VALID || r == PATH_IS_MAYBE_VALID) && ++ released_to_systemd()) ++ r = PATH_IS_NOT_VALID; ++ ++ /* This state is only used to skip the released_to_systemd() check */ ++ if (r == PATH_IS_VALID_NO_CHECK) ++ r = PATH_IS_VALID; ++ ++ if (r != PATH_IS_MAYBE_VALID) ++ goto out; ++ ++ /* ++ * If opening the path with O_EXCL fails, the path ++ * is in use (e.g. mounted during initramfs processing). ++ * We know that it's not used by dm-multipath. ++ * We may not set SYSTEMD_READY=0 on such devices, it ++ * might cause systemd to umount the device. ++ * Use O_RDONLY, because udevd would trigger another ++ * uevent for close-after-write. ++ * ++ * The O_EXCL check is potentially dangerous, because it may ++ * race with other tasks trying to access the device. Therefore ++ * this code is only executed if the path hasn't been released ++ * to systemd earlier (see above). ++ */ ++ fd = open(udev_device_get_devnode(pp->udev), O_RDONLY|O_EXCL); ++ if (fd >= 0) ++ close(fd); ++ else { ++ condlog(3, "%s: path %s is in use: %m", __func__, pp->dev); ++ /* Check if we raced with multipathd */ ++ if (sysfs_is_multipathed(pp, false)) ++ r = PATH_IS_VALID; ++ else ++ r = PATH_IS_NOT_VALID; ++ goto out; ++ } ++ ++ /* For find_multipaths = SMART, if there is more than one path ++ * matching the refwwid, then the path is valid */ ++ if (path_discovery(pathvec, DI_SYSFS | DI_WWID) < 0) ++ goto fail; ++ filter_pathvec(pathvec, pp->wwid); ++ if (VECTOR_SIZE(pathvec) > 1) ++ r = PATH_IS_VALID; ++ else ++ r = PATH_IS_MAYBE_VALID; ++ ++out: ++ r = print_cmd_valid(r, pathvec, conf); ++ free_pathvec(pathvec, FREE_PATHS); ++ /* ++ * multipath -u must exit with status 0, otherwise udev won't ++ * import its output. ++ */ ++ if (!is_uevent && r == PATH_IS_NOT_VALID) ++ return RTVL_FAIL; ++ return RTVL_OK; ++ ++fail: ++ if (pathvec) ++ free_pathvec(pathvec, FREE_PATHS); ++ else ++ free_path(pp); ++ return RTVL_FAIL; ++} ++ + static int + get_dev_type(char *dev) { + struct stat buf; +@@ -861,32 +853,6 @@ out: + return r; + } + +-static int test_multipathd_socket(void) +-{ +- int fd; +- /* +- * "multipath -u" may be run before the daemon is started. In this +- * case, systemd might own the socket but might delay multipathd +- * startup until some other unit (udev settle!) has finished +- * starting. With many LUNs, the listen backlog may be exceeded, which +- * would cause connect() to block. This causes udev workers calling +- * "multipath -u" to hang, and thus creates a deadlock, until "udev +- * settle" times out. To avoid this, call connect() in non-blocking +- * mode here, and take EAGAIN as indication for a filled-up systemd +- * backlog. +- */ +- +- fd = __mpath_connect(1); +- if (fd == -1) { +- if (errno == EAGAIN) +- condlog(3, "daemon backlog exceeded"); +- else +- return 0; +- } else +- close(fd); +- return 1; +-} +- + int + main (int argc, char *argv[]) + { +@@ -970,7 +936,11 @@ main (int argc, char *argv[]) + conf->force_reload = FORCE_RELOAD_YES; + break; + case 'i': +- conf->find_multipaths |= _FIND_MULTIPATHS_I; ++ if (conf->find_multipaths == FIND_MULTIPATHS_ON || ++ conf->find_multipaths == FIND_MULTIPATHS_STRICT) ++ conf->find_multipaths = FIND_MULTIPATHS_SMART; ++ else if (conf->find_multipaths == FIND_MULTIPATHS_OFF) ++ conf->find_multipaths = FIND_MULTIPATHS_GREEDY; + break; + case 't': + r = dump_config(conf, NULL, NULL) ? RTVL_FAIL : RTVL_OK; +@@ -1064,15 +1034,10 @@ main (int argc, char *argv[]) + condlog(0, "the -c option requires a path to check"); + goto out; + } +- if (cmd == CMD_VALID_PATH && +- dev_type == DEV_UEVENT) { +- if (!test_multipathd_socket()) { +- condlog(3, "%s: daemon is not running", dev); +- if (!systemd_service_enabled(dev)) { +- r = print_cmd_valid(RTVL_NO, NULL, conf); +- goto out; +- } +- } ++ if (cmd == CMD_VALID_PATH) { ++ char * name = convert_dev(dev, (dev_type == DEV_DEVNODE)); ++ r = check_path_valid(name, conf, dev_type == DEV_UEVENT); ++ goto out; + } + + if (cmd == CMD_REMOVE_WWID && !dev) { +@@ -1136,13 +1101,6 @@ out: + cleanup_prio(); + cleanup_checkers(); + +- /* +- * multipath -u must exit with status 0, otherwise udev won't +- * import its output. +- */ +- if (cmd == CMD_VALID_PATH && dev_type == DEV_UEVENT && r == RTVL_NO) +- r = RTVL_OK; +- + if (dev_type == DEV_UEVENT) + closelog(); + +-- +2.17.2 + diff --git a/0026-Unit-tests-for-is_path_valid.patch b/0026-Unit-tests-for-is_path_valid.patch new file mode 100644 index 0000000..9ada368 --- /dev/null +++ b/0026-Unit-tests-for-is_path_valid.patch @@ -0,0 +1,530 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 19 May 2020 12:08:43 -0500 +Subject: [PATCH] Unit tests for is_path_valid() + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + tests/Makefile | 4 +- + tests/valid.c | 486 +++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 489 insertions(+), 1 deletion(-) + create mode 100644 tests/valid.c + +diff --git a/tests/Makefile b/tests/Makefile +index 1b8706a7..125553b8 100644 +--- a/tests/Makefile ++++ b/tests/Makefile +@@ -13,7 +13,7 @@ CFLAGS += $(BIN_CFLAGS) -I$(multipathdir) -I$(mpathcmddir) \ + LIBDEPS += -L$(multipathdir) -L$(mpathcmddir) -lmultipath -lmpathcmd -lcmocka + + TESTS := uevent parser util dmevents hwtable blacklist unaligned vpd pgpolicy \ +- alias directio ++ alias directio valid + + .SILENT: $(TESTS:%=%.o) + .PRECIOUS: $(TESTS:%=%-test) +@@ -50,6 +50,8 @@ vpd-test_OBJDEPS := ../libmultipath/discovery.o + vpd-test_LIBDEPS := -ludev -lpthread -ldl + alias-test_TESTDEPS := test-log.o + alias-test_LIBDEPS := -lpthread -ldl ++valid-test_OBJDEPS := ../libmultipath/valid.o ++valid-test_LIBDEPS := -ludev -lpthread -ldl + ifneq ($(DIO_TEST_DEV),) + directio-test_LIBDEPS := -laio + endif +diff --git a/tests/valid.c b/tests/valid.c +new file mode 100644 +index 00000000..693c72c5 +--- /dev/null ++++ b/tests/valid.c +@@ -0,0 +1,486 @@ ++/* ++ * Copyright (c) 2020 Benjamin Marzinski, Redhat ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2 ++ * of the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see . ++ * ++ */ ++ ++#define _GNU_SOURCE ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "globals.c" ++#include "util.h" ++#include "discovery.h" ++#include "wwids.h" ++#include "blacklist.h" ++#include "valid.h" ++ ++int test_fd; ++struct udev_device { ++ int unused; ++} test_udev; ++ ++bool __wrap_sysfs_is_multipathed(struct path *pp, bool set_wwid) ++{ ++ bool is_multipathed = mock_type(bool); ++ assert_non_null(pp); ++ assert_int_not_equal(strlen(pp->dev), 0); ++ if (is_multipathed && set_wwid) ++ strlcpy(pp->wwid, mock_ptr_type(char *), WWID_SIZE); ++ return is_multipathed; ++} ++ ++int __wrap___mpath_connect(int nonblocking) ++{ ++ bool connected = mock_type(bool); ++ assert_int_equal(nonblocking, 1); ++ if (connected) ++ return test_fd; ++ errno = mock_type(int); ++ return -1; ++} ++ ++int __wrap_systemd_service_enabled(const char *dev) ++{ ++ return (int)mock_type(bool); ++} ++ ++/* There's no point in checking the return value here */ ++int __wrap_mpath_disconnect(int fd) ++{ ++ assert_int_equal(fd, test_fd); ++ return 0; ++} ++ ++struct udev_device *__wrap_udev_device_new_from_subsystem_sysname(struct udev *udev, const char *subsystem, const char *sysname) ++{ ++ bool passed = mock_type(bool); ++ assert_string_equal(sysname, mock_ptr_type(char *)); ++ if (passed) ++ return &test_udev; ++ return NULL; ++} ++ ++int __wrap_pathinfo(struct path *pp, struct config *conf, int mask) ++{ ++ int ret = mock_type(int); ++ assert_string_equal(pp->dev, mock_ptr_type(char *)); ++ assert_int_equal(mask, DI_SYSFS | DI_WWID | DI_BLACKLIST); ++ if (ret == PATHINFO_OK) { ++ pp->uid_attribute = "ID_TEST"; ++ strlcpy(pp->wwid, mock_ptr_type(char *), WWID_SIZE); ++ } else ++ memset(pp->wwid, 0, WWID_SIZE); ++ return ret; ++} ++ ++int __wrap_filter_property(struct config *conf, struct udev_device *udev, ++ int lvl, const char *uid_attribute) ++{ ++ int ret = mock_type(int); ++ assert_string_equal(uid_attribute, "ID_TEST"); ++ return ret; ++} ++ ++int __wrap_is_failed_wwid(const char *wwid) ++{ ++ int ret = mock_type(int); ++ assert_string_equal(wwid, mock_ptr_type(char *)); ++ return ret; ++} ++ ++int __wrap_check_wwids_file(char *wwid, int write_wwid) ++{ ++ bool passed = mock_type(bool); ++ assert_int_equal(write_wwid, 0); ++ assert_string_equal(wwid, mock_ptr_type(char *)); ++ if (passed) ++ return 0; ++ else ++ return -1; ++} ++ ++int __wrap_dm_map_present_by_uuid(const char *uuid) ++{ ++ int ret = mock_type(int); ++ assert_string_equal(uuid, mock_ptr_type(char *)); ++ return ret; ++} ++ ++enum { ++ STAGE_IS_MULTIPATHED, ++ STAGE_CHECK_MULTIPATHD, ++ STAGE_GET_UDEV_DEVICE, ++ STAGE_PATHINFO, ++ STAGE_FILTER_PROPERTY, ++ STAGE_IS_FAILED, ++ STAGE_CHECK_WWIDS, ++ STAGE_UUID_PRESENT, ++}; ++ ++enum { ++ CHECK_MPATHD_RUNNING, ++ CHECK_MPATHD_EAGAIN, ++ CHECK_MPATHD_ENABLED, ++ CHECK_MPATHD_SKIP, ++}; ++ ++/* setup the test to continue past the given stage in is_path_valid() */ ++static void setup_passing(char *name, char *wwid, unsigned int check_multipathd, ++ unsigned int stage) ++{ ++ will_return(__wrap_sysfs_is_multipathed, false); ++ if (stage == STAGE_IS_MULTIPATHED) ++ return; ++ if (check_multipathd == CHECK_MPATHD_RUNNING) ++ will_return(__wrap___mpath_connect, true); ++ else if (check_multipathd == CHECK_MPATHD_EAGAIN) { ++ will_return(__wrap___mpath_connect, false); ++ will_return(__wrap___mpath_connect, EAGAIN); ++ } else if (check_multipathd == CHECK_MPATHD_ENABLED) { ++ will_return(__wrap___mpath_connect, false); ++ will_return(__wrap___mpath_connect, ECONNREFUSED); ++ will_return(__wrap_systemd_service_enabled, true); ++ } ++ /* nothing for CHECK_MPATHD_SKIP */ ++ if (stage == STAGE_CHECK_MULTIPATHD) ++ return; ++ will_return(__wrap_udev_device_new_from_subsystem_sysname, true); ++ will_return(__wrap_udev_device_new_from_subsystem_sysname, ++ name); ++ if (stage == STAGE_GET_UDEV_DEVICE) ++ return; ++ will_return(__wrap_pathinfo, PATHINFO_OK); ++ will_return(__wrap_pathinfo, name); ++ will_return(__wrap_pathinfo, wwid); ++ if (stage == STAGE_PATHINFO) ++ return; ++ will_return(__wrap_filter_property, MATCH_PROPERTY_BLIST_EXCEPT); ++ if (stage == STAGE_FILTER_PROPERTY) ++ return; ++ will_return(__wrap_is_failed_wwid, WWID_IS_NOT_FAILED); ++ will_return(__wrap_is_failed_wwid, wwid); ++ if (stage == STAGE_IS_FAILED) ++ return; ++ will_return(__wrap_check_wwids_file, false); ++ will_return(__wrap_check_wwids_file, wwid); ++ if (stage == STAGE_CHECK_WWIDS) ++ return; ++ will_return(__wrap_dm_map_present_by_uuid, 0); ++ will_return(__wrap_dm_map_present_by_uuid, wwid); ++} ++ ++static void test_bad_arguments(void **state) ++{ ++ struct path pp; ++ char too_long[FILE_NAME_SIZE + 1]; ++ ++ memset(&pp, 0, sizeof(pp)); ++ /* test NULL pointers */ ++ assert_int_equal(is_path_valid("test", &conf, NULL, true), ++ PATH_IS_ERROR); ++ assert_int_equal(is_path_valid("test", NULL, &pp, true), ++ PATH_IS_ERROR); ++ assert_int_equal(is_path_valid(NULL, &conf, &pp, true), ++ PATH_IS_ERROR); ++ /* test undefined find_multipaths */ ++ conf.find_multipaths = FIND_MULTIPATHS_UNDEF; ++ assert_int_equal(is_path_valid("test", &conf, &pp, true), ++ PATH_IS_ERROR); ++ /* test name too long */ ++ memset(too_long, 'x', sizeof(too_long)); ++ too_long[sizeof(too_long) - 1] = '\0'; ++ conf.find_multipaths = FIND_MULTIPATHS_STRICT; ++ assert_int_equal(is_path_valid(too_long, &conf, &pp, true), ++ PATH_IS_ERROR); ++} ++ ++static void test_sysfs_is_multipathed(void **state) ++{ ++ struct path pp; ++ char *name = "test"; ++ char *wwid = "test_wwid"; ++ ++ memset(&pp, 0, sizeof(pp)); ++ conf.find_multipaths = FIND_MULTIPATHS_STRICT; ++ /* test for already existing multiapthed device */ ++ will_return(__wrap_sysfs_is_multipathed, true); ++ will_return(__wrap_sysfs_is_multipathed, wwid); ++ assert_int_equal(is_path_valid(name, &conf, &pp, true), ++ PATH_IS_VALID_NO_CHECK); ++ assert_string_equal(pp.dev, name); ++ assert_string_equal(pp.wwid, wwid); ++ /* test for wwid device with empty wwid */ ++ will_return(__wrap_sysfs_is_multipathed, true); ++ will_return(__wrap_sysfs_is_multipathed, ""); ++ assert_int_equal(is_path_valid(name, &conf, &pp, true), ++ PATH_IS_ERROR); ++} ++ ++static void test_check_multipathd(void **state) ++{ ++ struct path pp; ++ char *name = "test"; ++ ++ memset(&pp, 0, sizeof(pp)); ++ conf.find_multipaths = FIND_MULTIPATHS_STRICT; ++ /* test failed check to see if multipathd is active */ ++ will_return(__wrap_sysfs_is_multipathed, false); ++ will_return(__wrap___mpath_connect, false); ++ will_return(__wrap___mpath_connect, ECONNREFUSED); ++ will_return(__wrap_systemd_service_enabled, false); ++ assert_int_equal(is_path_valid(name, &conf, &pp, true), ++ PATH_IS_NOT_VALID); ++ assert_string_equal(pp.dev, name); ++ /* test pass because service is enabled. fail getting udev */ ++ memset(&pp, 0, sizeof(pp)); ++ setup_passing(name, NULL, CHECK_MPATHD_ENABLED, STAGE_CHECK_MULTIPATHD); ++ will_return(__wrap_udev_device_new_from_subsystem_sysname, false); ++ will_return(__wrap_udev_device_new_from_subsystem_sysname, ++ name); ++ assert_int_equal(is_path_valid(name, &conf, &pp, true), ++ PATH_IS_ERROR); ++ assert_string_equal(pp.dev, name); ++ /* test pass because connect returned EAGAIN. fail getting udev */ ++ setup_passing(name, NULL, CHECK_MPATHD_EAGAIN, STAGE_CHECK_MULTIPATHD); ++ will_return(__wrap_udev_device_new_from_subsystem_sysname, false); ++ will_return(__wrap_udev_device_new_from_subsystem_sysname, ++ name); ++ assert_int_equal(is_path_valid(name, &conf, &pp, true), ++ PATH_IS_ERROR); ++ /* test pass because connect succeeded. fail getting udev */ ++ memset(&pp, 0, sizeof(pp)); ++ setup_passing(name, NULL, CHECK_MPATHD_RUNNING, STAGE_CHECK_MULTIPATHD); ++ will_return(__wrap_udev_device_new_from_subsystem_sysname, false); ++ will_return(__wrap_udev_device_new_from_subsystem_sysname, ++ name); ++ assert_int_equal(is_path_valid(name, &conf, &pp, true), ++ PATH_IS_ERROR); ++ assert_string_equal(pp.dev, name); ++} ++ ++static void test_pathinfo(void **state) ++{ ++ struct path pp; ++ char *name = "test"; ++ ++ memset(&pp, 0, sizeof(pp)); ++ conf.find_multipaths = FIND_MULTIPATHS_STRICT; ++ /* Test pathinfo blacklisting device */ ++ setup_passing(name, NULL, CHECK_MPATHD_SKIP, STAGE_GET_UDEV_DEVICE); ++ will_return(__wrap_pathinfo, PATHINFO_SKIPPED); ++ will_return(__wrap_pathinfo, name); ++ assert_int_equal(is_path_valid(name, &conf, &pp, false), ++ PATH_IS_NOT_VALID); ++ assert_string_equal(pp.dev, name); ++ assert_ptr_equal(pp.udev, &test_udev); ++ /* Test pathinfo failing */ ++ memset(&pp, 0, sizeof(pp)); ++ setup_passing(name, NULL, CHECK_MPATHD_SKIP, STAGE_GET_UDEV_DEVICE); ++ will_return(__wrap_pathinfo, PATHINFO_FAILED); ++ will_return(__wrap_pathinfo, name); ++ assert_int_equal(is_path_valid(name, &conf, &pp, false), ++ PATH_IS_ERROR); ++ /* Test blank wwid */ ++ memset(&pp, 0, sizeof(pp)); ++ setup_passing(name, NULL, CHECK_MPATHD_SKIP, STAGE_GET_UDEV_DEVICE); ++ will_return(__wrap_pathinfo, PATHINFO_OK); ++ will_return(__wrap_pathinfo, name); ++ will_return(__wrap_pathinfo, ""); ++ assert_int_equal(is_path_valid(name, &conf, &pp, false), ++ PATH_IS_NOT_VALID); ++} ++ ++static void test_filter_property(void **state) ++{ ++ struct path pp; ++ char *name = "test"; ++ char *wwid = "test-wwid"; ++ ++ /* test blacklist property */ ++ memset(&pp, 0, sizeof(pp)); ++ conf.find_multipaths = FIND_MULTIPATHS_STRICT; ++ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_PATHINFO); ++ will_return(__wrap_filter_property, MATCH_PROPERTY_BLIST); ++ assert_int_equal(is_path_valid(name, &conf, &pp, false), ++ PATH_IS_NOT_VALID); ++ assert_ptr_equal(pp.udev, &test_udev); ++ assert_string_equal(pp.wwid, wwid); ++ /* test missing property */ ++ memset(&pp, 0, sizeof(pp)); ++ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_PATHINFO); ++ will_return(__wrap_filter_property, MATCH_PROPERTY_BLIST_MISSING); ++ assert_int_equal(is_path_valid(name, &conf, &pp, false), ++ PATH_IS_NOT_VALID); ++ /* test MATCH_NOTHING fail on is_failed_wwid */ ++ memset(&pp, 0, sizeof(pp)); ++ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_PATHINFO); ++ will_return(__wrap_filter_property, MATCH_NOTHING); ++ will_return(__wrap_is_failed_wwid, WWID_IS_FAILED); ++ will_return(__wrap_is_failed_wwid, wwid); ++ assert_int_equal(is_path_valid(name, &conf, &pp, false), ++ PATH_IS_NOT_VALID); ++} ++ ++static void test_is_failed_wwid(void **state) ++{ ++ struct path pp; ++ char *name = "test"; ++ char *wwid = "test-wwid"; ++ ++ memset(&pp, 0, sizeof(pp)); ++ conf.find_multipaths = FIND_MULTIPATHS_STRICT; ++ /* Test wwid failed */ ++ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_FILTER_PROPERTY); ++ will_return(__wrap_is_failed_wwid, WWID_IS_FAILED); ++ will_return(__wrap_is_failed_wwid, wwid); ++ assert_int_equal(is_path_valid(name, &conf, &pp, false), ++ PATH_IS_NOT_VALID); ++ assert_string_equal(pp.dev, name); ++ assert_ptr_equal(pp.udev, &test_udev); ++ assert_string_equal(pp.wwid, wwid); ++ /* test is_failed_wwid error */ ++ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_FILTER_PROPERTY); ++ will_return(__wrap_is_failed_wwid, WWID_FAILED_ERROR); ++ will_return(__wrap_is_failed_wwid, wwid); ++ assert_int_equal(is_path_valid(name, &conf, &pp, false), ++ PATH_IS_ERROR); ++} ++ ++static void test_greedy(void **state) ++{ ++ struct path pp; ++ char *name = "test"; ++ char *wwid = "test-wwid"; ++ ++ /* test greedy success with checking multipathd */ ++ memset(&pp, 0, sizeof(pp)); ++ conf.find_multipaths = FIND_MULTIPATHS_GREEDY; ++ setup_passing(name, wwid, CHECK_MPATHD_RUNNING, STAGE_IS_FAILED); ++ assert_int_equal(is_path_valid(name, &conf, &pp, true), ++ PATH_IS_VALID); ++ assert_string_equal(pp.dev, name); ++ assert_ptr_equal(pp.udev, &test_udev); ++ assert_string_equal(pp.wwid, wwid); ++ /* test greedy success without checking multiapthd */ ++ memset(&pp, 0, sizeof(pp)); ++ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_IS_FAILED); ++ assert_int_equal(is_path_valid(name, &conf, &pp, false), ++ PATH_IS_VALID); ++} ++ ++static void test_check_wwids(void **state) ++{ ++ struct path pp; ++ char *name = "test"; ++ char *wwid = "test-wwid"; ++ ++ memset(&pp, 0, sizeof(pp)); ++ conf.find_multipaths = FIND_MULTIPATHS_STRICT; ++ setup_passing(name, wwid, CHECK_MPATHD_EAGAIN, STAGE_IS_FAILED); ++ will_return(__wrap_check_wwids_file, true); ++ will_return(__wrap_check_wwids_file, wwid); ++ assert_int_equal(is_path_valid(name, &conf, &pp, true), ++ PATH_IS_VALID_NO_CHECK); ++ assert_string_equal(pp.dev, name); ++ assert_ptr_equal(pp.udev, &test_udev); ++ assert_string_equal(pp.wwid, wwid); ++} ++ ++static void test_check_uuid_present(void **state) ++{ ++ struct path pp; ++ char *name = "test"; ++ char *wwid = "test-wwid"; ++ ++ memset(&pp, 0, sizeof(pp)); ++ conf.find_multipaths = FIND_MULTIPATHS_STRICT; ++ setup_passing(name, wwid, CHECK_MPATHD_ENABLED, STAGE_CHECK_WWIDS); ++ will_return(__wrap_dm_map_present_by_uuid, 1); ++ will_return(__wrap_dm_map_present_by_uuid, wwid); ++ assert_int_equal(is_path_valid(name, &conf, &pp, true), ++ PATH_IS_VALID); ++ assert_string_equal(pp.dev, name); ++ assert_ptr_equal(pp.udev, &test_udev); ++ assert_string_equal(pp.wwid, wwid); ++} ++ ++ ++static void test_find_multipaths(void **state) ++{ ++ struct path pp; ++ char *name = "test"; ++ char *wwid = "test-wwid"; ++ ++ /* test find_multipaths = FIND_MULTIPATHS_STRICT */ ++ memset(&pp, 0, sizeof(pp)); ++ conf.find_multipaths = FIND_MULTIPATHS_STRICT; ++ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_UUID_PRESENT); ++ assert_int_equal(is_path_valid(name, &conf, &pp, false), ++ PATH_IS_NOT_VALID); ++ assert_string_equal(pp.dev, name); ++ assert_ptr_equal(pp.udev, &test_udev); ++ assert_string_equal(pp.wwid, wwid); ++ /* test find_multipaths = FIND_MULTIPATHS_OFF */ ++ memset(&pp, 0, sizeof(pp)); ++ conf.find_multipaths = FIND_MULTIPATHS_OFF; ++ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_UUID_PRESENT); ++ assert_int_equal(is_path_valid(name, &conf, &pp, false), ++ PATH_IS_NOT_VALID); ++ /* test find_multipaths = FIND_MULTIPATHS_ON */ ++ memset(&pp, 0, sizeof(pp)); ++ conf.find_multipaths = FIND_MULTIPATHS_ON; ++ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_UUID_PRESENT); ++ assert_int_equal(is_path_valid(name, &conf, &pp, false), ++ PATH_IS_NOT_VALID); ++ /* test find_multipaths = FIND_MULTIPATHS_SMART */ ++ memset(&pp, 0, sizeof(pp)); ++ conf.find_multipaths = FIND_MULTIPATHS_SMART; ++ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_UUID_PRESENT); ++ assert_int_equal(is_path_valid(name, &conf, &pp, false), ++ PATH_IS_MAYBE_VALID); ++ assert_string_equal(pp.dev, name); ++ assert_ptr_equal(pp.udev, &test_udev); ++ assert_string_equal(pp.wwid, wwid); ++} ++ ++int test_valid(void) ++{ ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test(test_bad_arguments), ++ cmocka_unit_test(test_sysfs_is_multipathed), ++ cmocka_unit_test(test_check_multipathd), ++ cmocka_unit_test(test_pathinfo), ++ cmocka_unit_test(test_filter_property), ++ cmocka_unit_test(test_is_failed_wwid), ++ cmocka_unit_test(test_greedy), ++ cmocka_unit_test(test_check_wwids), ++ cmocka_unit_test(test_check_uuid_present), ++ cmocka_unit_test(test_find_multipaths), ++ }; ++ return cmocka_run_group_tests(tests, NULL, NULL); ++} ++ ++int main(void) ++{ ++ int ret = 0; ++ ret += test_valid(); ++ return ret; ++} +-- +2.17.2 + diff --git a/0027-libmultipath-simplify-failed-wwid-code.patch b/0027-libmultipath-simplify-failed-wwid-code.patch new file mode 100644 index 0000000..bb60d21 --- /dev/null +++ b/0027-libmultipath-simplify-failed-wwid-code.patch @@ -0,0 +1,205 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 19 May 2020 12:08:44 -0500 +Subject: [PATCH] libmultipath: simplify failed wwid code + +The (is|mark|unmark)_failed_wwid code is needlessly complicated. +Locking a file is necssary if multiple processes could otherwise be +writing to it at the same time. That is not the case with the +failed_wwids files. They can simply be empty files in a directory. Even +with all the locking in place, two processes accessing or modifying a +file at the same time will still race. And even without the locking, if +two processes try to access or modify a file at the same time, they will +both see a reasonable result, and will leave the files in a valid state +afterwards. + +Instead of doing all the locking work (which made it necessary to write +a file, even just to check if a file existed), simply check for files +with lstat(), create them with open(), and remove them with unlink(). + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/wwids.c | 131 ++++++++++++++++++------------------------- + 1 file changed, 56 insertions(+), 75 deletions(-) + +diff --git a/libmultipath/wwids.c b/libmultipath/wwids.c +index 637cb0ab..aab5da8a 100644 +--- a/libmultipath/wwids.c ++++ b/libmultipath/wwids.c +@@ -6,6 +6,7 @@ + #include + #include + #include ++#include + + #include "util.h" + #include "checkers.h" +@@ -348,109 +349,89 @@ remember_wwid(char *wwid) + } + + static const char shm_dir[] = MULTIPATH_SHM_BASE "failed_wwids"; +-static const char shm_lock[] = ".lock"; +-static const char shm_header[] = "multipath shm lock file, don't edit"; +-static char _shm_lock_path[sizeof(shm_dir)+sizeof(shm_lock)]; +-static const char *shm_lock_path = &_shm_lock_path[0]; + +-static void init_shm_paths(void) ++static void print_failed_wwid_result(const char * msg, const char *wwid, int r) + { +- snprintf(_shm_lock_path, sizeof(_shm_lock_path), +- "%s/%s", shm_dir, shm_lock); ++ switch(r) { ++ case WWID_FAILED_ERROR: ++ condlog(1, "%s: %s: %m", msg, wwid); ++ return; ++ case WWID_IS_FAILED: ++ case WWID_IS_NOT_FAILED: ++ condlog(4, "%s: %s is %s", msg, wwid, ++ r == WWID_IS_FAILED ? "failed" : "good"); ++ return; ++ case WWID_FAILED_CHANGED: ++ condlog(3, "%s: %s", msg, wwid); ++ } + } + +-static pthread_once_t shm_path_once = PTHREAD_ONCE_INIT; +- +-static int multipath_shm_open(bool rw) ++int is_failed_wwid(const char *wwid) + { +- int fd; +- int can_write; +- +- pthread_once(&shm_path_once, init_shm_paths); +- fd = open_file(shm_lock_path, &can_write, shm_header); ++ struct stat st; ++ char path[PATH_MAX]; ++ int r; + +- if (fd >= 0 && rw && !can_write) { +- close(fd); +- condlog(1, "failed to open %s for writing", shm_dir); ++ if (safe_sprintf(path, "%s/%s", shm_dir, wwid)) { ++ condlog(1, "%s: path name overflow", __func__); + return -1; + } + +- return fd; +-} +- +-static void multipath_shm_close(void *arg) +-{ +- long fd = (long)arg; ++ if (lstat(path, &st) == 0) ++ r = WWID_IS_FAILED; ++ else if (errno == ENOENT) ++ r = WWID_IS_NOT_FAILED; ++ else ++ r = WWID_FAILED_ERROR; + +- close(fd); +- unlink(shm_lock_path); ++ print_failed_wwid_result("is_failed", wwid, r); ++ return r; + } + +-static int _failed_wwid_op(const char *wwid, bool rw, +- int (*func)(const char *), const char *msg) ++int mark_failed_wwid(const char *wwid) + { + char path[PATH_MAX]; +- long lockfd; +- int r = -1; ++ int r, fd; + + if (safe_sprintf(path, "%s/%s", shm_dir, wwid)) { + condlog(1, "%s: path name overflow", __func__); + return -1; + } +- +- lockfd = multipath_shm_open(rw); +- if (lockfd == -1) ++ if (ensure_directories_exist(path, 0700) < 0) { ++ condlog(1, "%s: can't setup directories", __func__); + return -1; ++ } + +- pthread_cleanup_push(multipath_shm_close, (void *)lockfd); +- r = func(path); +- pthread_cleanup_pop(1); +- +- if (r == WWID_FAILED_ERROR) +- condlog(1, "%s: %s: %s", msg, wwid, strerror(errno)); +- else if (r == WWID_FAILED_CHANGED) +- condlog(3, "%s: %s", msg, wwid); +- else if (!rw) +- condlog(4, "%s: %s is %s", msg, wwid, +- r == WWID_IS_FAILED ? "failed" : "good"); ++ fd = open(path, O_RDONLY | O_CREAT | O_EXCL, S_IRUSR); ++ if (fd >= 0) { ++ close(fd); ++ r = WWID_FAILED_CHANGED; ++ } else if (errno == EEXIST) ++ r = WWID_FAILED_UNCHANGED; ++ else ++ r = WWID_FAILED_ERROR; + ++ print_failed_wwid_result("mark_failed", wwid, r); + return r; + } + +-static int _is_failed(const char *path) ++int unmark_failed_wwid(const char *wwid) + { +- struct stat st; ++ char path[PATH_MAX]; ++ int r; + +- if (lstat(path, &st) == 0) +- return WWID_IS_FAILED; ++ if (safe_sprintf(path, "%s/%s", shm_dir, wwid)) { ++ condlog(1, "%s: path name overflow", __func__); ++ return -1; ++ } ++ ++ if (unlink(path) == 0) ++ r = WWID_FAILED_CHANGED; + else if (errno == ENOENT) +- return WWID_IS_NOT_FAILED; ++ r = WWID_FAILED_UNCHANGED; + else +- return WWID_FAILED_ERROR; +-} +- +-static int _mark_failed(const char *path) +-{ +- /* Called from _failed_wwid_op: we know that shm_lock_path exists */ +- if (_is_failed(path) == WWID_IS_FAILED) +- return WWID_FAILED_UNCHANGED; +- return (link(shm_lock_path, path) == 0 ? WWID_FAILED_CHANGED : +- WWID_FAILED_ERROR); +-} ++ r = WWID_FAILED_ERROR; + +-static int _unmark_failed(const char *path) +-{ +- if (_is_failed(path) == WWID_IS_NOT_FAILED) +- return WWID_FAILED_UNCHANGED; +- return (unlink(path) == 0 ? WWID_FAILED_CHANGED : WWID_FAILED_ERROR); +-} +- +-#define declare_failed_wwid_op(op, rw) \ +-int op ## _wwid(const char *wwid) \ +-{ \ +- return _failed_wwid_op(wwid, (rw), _ ## op, #op); \ ++ print_failed_wwid_result("unmark_failed", wwid, r); ++ return r; + } +- +-declare_failed_wwid_op(is_failed, false) +-declare_failed_wwid_op(mark_failed, true) +-declare_failed_wwid_op(unmark_failed, true) +-- +2.17.2 + diff --git a/0028-libmultipath-use-atomic-linkat-in-mark_failed_wwid.patch b/0028-libmultipath-use-atomic-linkat-in-mark_failed_wwid.patch new file mode 100644 index 0000000..6b9941a --- /dev/null +++ b/0028-libmultipath-use-atomic-linkat-in-mark_failed_wwid.patch @@ -0,0 +1,96 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 19 May 2020 12:08:45 -0500 +Subject: [PATCH] libmultipath: use atomic linkat() in mark_failed_wwid() + +This keeps (almost) the simplicity of the previous patch, while +making sure that the return value of mark_failed_wwid() +(WWID_FAILED_CHANGED vs. WWID_FAILED_UNCHANGED) is correct, even +if several processes access this WWID at the same time. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/wwids.c | 42 +++++++++++++++++++++++++++++------------- + 1 file changed, 29 insertions(+), 13 deletions(-) + +diff --git a/libmultipath/wwids.c b/libmultipath/wwids.c +index aab5da8a..61d9c39e 100644 +--- a/libmultipath/wwids.c ++++ b/libmultipath/wwids.c +@@ -374,7 +374,7 @@ int is_failed_wwid(const char *wwid) + + if (safe_sprintf(path, "%s/%s", shm_dir, wwid)) { + condlog(1, "%s: path name overflow", __func__); +- return -1; ++ return WWID_FAILED_ERROR; + } + + if (lstat(path, &st) == 0) +@@ -390,27 +390,43 @@ int is_failed_wwid(const char *wwid) + + int mark_failed_wwid(const char *wwid) + { +- char path[PATH_MAX]; +- int r, fd; ++ char tmpfile[WWID_SIZE + 2 * sizeof(long) + 1]; ++ int r = WWID_FAILED_ERROR, fd, dfd; + +- if (safe_sprintf(path, "%s/%s", shm_dir, wwid)) { +- condlog(1, "%s: path name overflow", __func__); +- return -1; ++ dfd = open(shm_dir, O_RDONLY|O_DIRECTORY); ++ if (dfd == -1 && errno == ENOENT) { ++ char path[sizeof(shm_dir) + 2]; ++ ++ /* arg for ensure_directories_exist() must not end with "/" */ ++ safe_sprintf(path, "%s/_", shm_dir); ++ ensure_directories_exist(path, 0700); ++ dfd = open(shm_dir, O_RDONLY|O_DIRECTORY); + } +- if (ensure_directories_exist(path, 0700) < 0) { +- condlog(1, "%s: can't setup directories", __func__); +- return -1; ++ if (dfd == -1) { ++ condlog(1, "%s: can't setup %s: %m", __func__, shm_dir); ++ return WWID_FAILED_ERROR; + } + +- fd = open(path, O_RDONLY | O_CREAT | O_EXCL, S_IRUSR); +- if (fd >= 0) { ++ safe_sprintf(tmpfile, "%s.%lx", wwid, (long)getpid()); ++ fd = openat(dfd, tmpfile, O_RDONLY | O_CREAT | O_EXCL, S_IRUSR); ++ if (fd >= 0) + close(fd); ++ else ++ goto out_closedir; ++ ++ if (linkat(dfd, tmpfile, dfd, wwid, 0) == 0) + r = WWID_FAILED_CHANGED; +- } else if (errno == EEXIST) ++ else if (errno == EEXIST) + r = WWID_FAILED_UNCHANGED; + else + r = WWID_FAILED_ERROR; + ++ if (unlinkat(dfd, tmpfile, 0) == -1) ++ condlog(2, "%s: failed to unlink %s/%s: %m", ++ __func__, shm_dir, tmpfile); ++ ++out_closedir: ++ close(dfd); + print_failed_wwid_result("mark_failed", wwid, r); + return r; + } +@@ -422,7 +438,7 @@ int unmark_failed_wwid(const char *wwid) + + if (safe_sprintf(path, "%s/%s", shm_dir, wwid)) { + condlog(1, "%s: path name overflow", __func__); +- return -1; ++ return WWID_FAILED_ERROR; + } + + if (unlink(path) == 0) +-- +2.17.2 + diff --git a/0029-fix-boolean-value-with-json-c-0.14.patch b/0029-fix-boolean-value-with-json-c-0.14.patch new file mode 100644 index 0000000..29bb90b --- /dev/null +++ b/0029-fix-boolean-value-with-json-c-0.14.patch @@ -0,0 +1,41 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: "mail@eworm.de" +Date: Sat, 25 Apr 2020 21:11:13 +0200 +Subject: [PATCH] fix boolean value with json-c 0.14 + +Upstream json-c removed the TRUE and FALSE defines in commit +0992aac61f8b087efd7094e9ac2b84fa9c040fcd. + +[mwilck]: Use stdbool.h, and keep the log message unchanged. + +Signed-off-by: Christian Hesse +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libdmmp/libdmmp_private.h | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/libdmmp/libdmmp_private.h b/libdmmp/libdmmp_private.h +index ac85b63f..b1a6ddea 100644 +--- a/libdmmp/libdmmp_private.h ++++ b/libdmmp/libdmmp_private.h +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include + #include + + #include "libdmmp/libdmmp.h" +@@ -82,7 +83,7 @@ static out_type func_name(struct dmmp_context *ctx, const char *var_name) { \ + do { \ + json_type j_type = json_type_null; \ + json_object *j_obj_tmp = NULL; \ +- if (json_object_object_get_ex(j_obj, key, &j_obj_tmp) != TRUE) { \ ++ if (json_object_object_get_ex(j_obj, key, &j_obj_tmp) != true) { \ + _error(ctx, "Invalid JSON output from multipathd IPC: " \ + "key '%s' not found", key); \ + rc = DMMP_ERR_IPC_ERROR; \ +-- +2.17.2 + diff --git a/0012-libmultipath-fix-condlog-NULL-argument-in-uevent_get.patch b/0030-libmultipath-fix-condlog-NULL-argument-in-uevent_get.patch similarity index 97% rename from 0012-libmultipath-fix-condlog-NULL-argument-in-uevent_get.patch rename to 0030-libmultipath-fix-condlog-NULL-argument-in-uevent_get.patch index 5d2750d..d8ae27d 100644 --- a/0012-libmultipath-fix-condlog-NULL-argument-in-uevent_get.patch +++ b/0030-libmultipath-fix-condlog-NULL-argument-in-uevent_get.patch @@ -1,6 +1,6 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski -Date: Fri, 29 May 2020 15:13:59 -0500 +Date: Thu, 4 Jun 2020 18:20:06 -0500 Subject: [PATCH] libmultipath: fix condlog NULL argument in uevent_get_env_var uevent_get_env_var() could call condlog with p == NULL. On gcc 10, diff --git a/0031-libmultipath-set-enable_foreign-to-NONE-by-default.patch b/0031-libmultipath-set-enable_foreign-to-NONE-by-default.patch new file mode 100644 index 0000000..7d2b886 --- /dev/null +++ b/0031-libmultipath-set-enable_foreign-to-NONE-by-default.patch @@ -0,0 +1,49 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 21 Aug 2019 16:07:12 +0200 +Subject: [PATCH] libmultipath: set "enable_foreign" to NONE by default + +This has been requested by NetApp. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/defaults.h | 4 ++-- + multipath/multipath.conf.5 | 5 +++-- + 2 files changed, 5 insertions(+), 4 deletions(-) + +diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h +index e5ee6afe..01a501bd 100644 +--- a/libmultipath/defaults.h ++++ b/libmultipath/defaults.h +@@ -50,8 +50,8 @@ + #define DEFAULT_FIND_MULTIPATHS_TIMEOUT -10 + #define DEFAULT_UNKNOWN_FIND_MULTIPATHS_TIMEOUT 1 + #define DEFAULT_ALL_TG_PT ALL_TG_PT_OFF +-/* Enable all foreign libraries by default */ +-#define DEFAULT_ENABLE_FOREIGN "" ++/* Enable no foreign libraries by default */ ++#define DEFAULT_ENABLE_FOREIGN "NONE" + + #define CHECKINT_UNDEF UINT_MAX + #define DEFAULT_CHECKINT 5 +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 +index 05a5e8ff..28cea88c 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5 +@@ -1228,10 +1228,11 @@ Enables or disables foreign libraries (see section + .I FOREIGN MULTIPATH SUPPORT + below). The value is a regular expression; foreign libraries are loaded + if their name (e.g. \(dqnvme\(dq) matches the expression. By default, +-all foreign libraries are enabled. ++no foreign libraries are enabled. Set this to \(dqnvme\(dq to enable NVMe native ++multipath support, or \(dq.*\(dq to enable all foreign libraries. + .RS + .TP +-The default is: \fB\(dq\(dq\fR (the empty regular expression) ++The default is: \fB\(dqNONE\(dq\fR + .RE + . + . +-- +2.17.2 + diff --git a/0032-multipath-add-e-option-to-enable-foreign-libraries.patch b/0032-multipath-add-e-option-to-enable-foreign-libraries.patch new file mode 100644 index 0000000..6e07152 --- /dev/null +++ b/0032-multipath-add-e-option-to-enable-foreign-libraries.patch @@ -0,0 +1,89 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 2 Mar 2020 22:43:27 +0100 +Subject: [PATCH] multipath: add "-e" option to enable foreign libraries + +As we have set "enable_foreign" to "NONE" now by default, users +may find it useful to be able to switch on foreign multipath display +with an extra command line option even if foreign libraries are +not enabled in multipath.conf. Currently this makes only sense +with "multipath -ll", as the nvme library (and foreign libraries +in general) support only the display of status information. + +Suggested-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/main.c | 11 ++++++++++- + multipath/multipath.8 | 6 ++++++ + 2 files changed, 16 insertions(+), 1 deletion(-) + +diff --git a/multipath/main.c b/multipath/main.c +index 953fab27..c4740fab 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -145,6 +145,7 @@ usage (char * progname) + " -h print this usage text\n" + " -l show multipath topology (sysfs and DM info)\n" + " -ll show multipath topology (maximum info)\n" ++ " -e enable foreign libraries with -l/-ll\n" + " -f flush a multipath device map\n" + " -F flush all multipath device maps\n" + " -a add a device wwid to the wwids file\n" +@@ -865,6 +866,7 @@ main (int argc, char *argv[]) + char *dev = NULL; + struct config *conf; + int retries = -1; ++ bool enable_foreign = false; + + udev = udev_new(); + logsink = 0; +@@ -874,7 +876,7 @@ main (int argc, char *argv[]) + multipath_conf = conf; + conf->retrigger_tries = 0; + conf->force_sync = 1; +- while ((arg = getopt(argc, argv, ":adcChl::FfM:v:p:b:BrR:itTquUwW")) != EOF ) { ++ while ((arg = getopt(argc, argv, ":adcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { + switch(arg) { + case 1: printf("optarg : %s\n",optarg); + break; +@@ -971,6 +973,9 @@ main (int argc, char *argv[]) + case 'R': + retries = atoi(optarg); + break; ++ case 'e': ++ enable_foreign = true; ++ break; + case ':': + fprintf(stderr, "Missing option argument\n"); + usage(argv[0]); +@@ -1022,6 +1027,10 @@ main (int argc, char *argv[]) + condlog(0, "failed to initialize prioritizers"); + goto out; + } ++ ++ if ((cmd == CMD_LIST_SHORT || cmd == CMD_LIST_LONG) && enable_foreign) ++ conf->enable_foreign = ""; ++ + /* Failing here is non-fatal */ + init_foreign(conf->multipath_dir, conf->enable_foreign); + if (cmd == CMD_USABLE_PATHS) { +diff --git a/multipath/multipath.8 b/multipath/multipath.8 +index 9cdd05a3..6fb8645a 100644 +--- a/multipath/multipath.8 ++++ b/multipath/multipath.8 +@@ -223,6 +223,12 @@ The verbosity level also controls the level of log and debug messages printed to + Dry run, do not create or update devmaps. + . + .TP ++.B \-e ++Enable all foreign libraries. This overrides the ++.I enable_foreign ++option from \fBmultipath.conf(5)\fR. ++. ++.TP + .B \-i + Ignore WWIDs file when processing devices. If + \fIfind_multipaths strict\fR or \fIfind_multipaths no\fR is set in +-- +2.17.2 + diff --git a/0033-libmultipath-remove-_blacklist_exceptions-functions.patch b/0033-libmultipath-remove-_blacklist_exceptions-functions.patch new file mode 100644 index 0000000..5fa6539 --- /dev/null +++ b/0033-libmultipath-remove-_blacklist_exceptions-functions.patch @@ -0,0 +1,139 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 9 Jun 2020 16:35:27 -0500 +Subject: [PATCH] libmultipath: remove _blacklist_exceptions functions + +_blacklist_exceptions() and _blacklist_exceptions_device() are exactly +the same as _blacklist() and _blacklist_device(), so remove them, and +give the remaining functions to a more general name. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/blacklist.c | 62 ++++++++++------------------------------ + 1 file changed, 15 insertions(+), 47 deletions(-) + +diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c +index 00e8dbdb..c21a0e27 100644 +--- a/libmultipath/blacklist.c ++++ b/libmultipath/blacklist.c +@@ -101,21 +101,8 @@ int set_ble_device(vector blist, char * vendor, char * product, int origin) + return 0; + } + +-int +-_blacklist_exceptions (vector elist, const char * str) +-{ +- int i; +- struct blentry * ele; +- +- vector_foreach_slot (elist, ele, i) { +- if (!regexec(&ele->regex, str, 0, NULL, 0)) +- return 1; +- } +- return 0; +-} +- +-int +-_blacklist (vector blist, const char * str) ++static int ++match_reglist (vector blist, const char * str) + { + int i; + struct blentry * ble; +@@ -127,28 +114,9 @@ _blacklist (vector blist, const char * str) + return 0; + } + +-int +-_blacklist_exceptions_device(const struct _vector *elist, const char * vendor, +- const char * product) +-{ +- int i; +- struct blentry_device * ble; +- +- vector_foreach_slot (elist, ble, i) { +- if (!ble->vendor && !ble->product) +- continue; +- if ((!ble->vendor || +- !regexec(&ble->vendor_reg, vendor, 0, NULL, 0)) && +- (!ble->product || +- !regexec(&ble->product_reg, product, 0, NULL, 0))) +- return 1; +- } +- return 0; +-} +- +-int +-_blacklist_device (const struct _vector *blist, const char * vendor, +- const char * product) ++static int ++match_reglist_device (const struct _vector *blist, const char * vendor, ++ const char * product) + { + int i; + struct blentry_device * ble; +@@ -300,9 +268,9 @@ filter_device (vector blist, vector elist, char * vendor, char * product, + int r = MATCH_NOTHING; + + if (vendor && product) { +- if (_blacklist_exceptions_device(elist, vendor, product)) ++ if (match_reglist_device(elist, vendor, product)) + r = MATCH_DEVICE_BLIST_EXCEPT; +- else if (_blacklist_device(blist, vendor, product)) ++ else if (match_reglist_device(blist, vendor, product)) + r = MATCH_DEVICE_BLIST; + } + +@@ -316,9 +284,9 @@ filter_devnode (vector blist, vector elist, char * dev) + int r = MATCH_NOTHING; + + if (dev) { +- if (_blacklist_exceptions(elist, dev)) ++ if (match_reglist(elist, dev)) + r = MATCH_DEVNODE_BLIST_EXCEPT; +- else if (_blacklist(blist, dev)) ++ else if (match_reglist(blist, dev)) + r = MATCH_DEVNODE_BLIST; + } + +@@ -332,9 +300,9 @@ filter_wwid (vector blist, vector elist, char * wwid, char * dev) + int r = MATCH_NOTHING; + + if (wwid) { +- if (_blacklist_exceptions(elist, wwid)) ++ if (match_reglist(elist, wwid)) + r = MATCH_WWID_BLIST_EXCEPT; +- else if (_blacklist(blist, wwid)) ++ else if (match_reglist(blist, wwid)) + r = MATCH_WWID_BLIST; + } + +@@ -351,9 +319,9 @@ filter_protocol(vector blist, vector elist, struct path * pp) + if (pp) { + snprint_path_protocol(buf, sizeof(buf), pp); + +- if (_blacklist_exceptions(elist, buf)) ++ if (match_reglist(elist, buf)) + r = MATCH_PROTOCOL_BLIST_EXCEPT; +- else if (_blacklist(blist, buf)) ++ else if (match_reglist(blist, buf)) + r = MATCH_PROTOCOL_BLIST; + } + +@@ -422,11 +390,11 @@ filter_property(struct config *conf, struct udev_device *udev, int lvl, + if (check_missing_prop && !strcmp(env, uid_attribute)) + uid_attr_seen = true; + +- if (_blacklist_exceptions(conf->elist_property, env)) { ++ if (match_reglist(conf->elist_property, env)) { + r = MATCH_PROPERTY_BLIST_EXCEPT; + break; + } +- if (_blacklist(conf->blist_property, env)) { ++ if (match_reglist(conf->blist_property, env)) { + r = MATCH_PROPERTY_BLIST; + break; + } +-- +2.17.2 + diff --git a/0034-libmultipath-fix-parser-issue-with-comments-in-strin.patch b/0034-libmultipath-fix-parser-issue-with-comments-in-strin.patch new file mode 100644 index 0000000..22cc22c --- /dev/null +++ b/0034-libmultipath-fix-parser-issue-with-comments-in-strin.patch @@ -0,0 +1,95 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 9 Jun 2020 16:35:28 -0500 +Subject: [PATCH] libmultipath: fix parser issue with comments in strings + +If a quoted string starts with '#' or '!', the parser will stop +parsing the line, thinking that it's a comment. It should only +be checking for comments outside of quoted strings. Fixed this and +added unit tests to verify it. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/parser.c | 4 +++- + tests/parser.c | 42 ++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 45 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/parser.c b/libmultipath/parser.c +index d478b177..11a6168c 100644 +--- a/libmultipath/parser.c ++++ b/libmultipath/parser.c +@@ -300,8 +300,10 @@ alloc_strvec(char *string) + (isspace((int) *cp) || !isascii((int) *cp))) + && *cp != '\0') + cp++; +- if (*cp == '\0' || *cp == '!' || *cp == '#') ++ if (*cp == '\0' || ++ (!in_string && (*cp == '!' || *cp == '#'))) { + return strvec; ++ } + } + out: + vector_free(strvec); +diff --git a/tests/parser.c b/tests/parser.c +index 29859dac..5772391e 100644 +--- a/tests/parser.c ++++ b/tests/parser.c +@@ -440,6 +440,46 @@ static void test18(void **state) + free_strvec(v); + } + ++static void test19(void **state) ++{ ++#define QUOTED19 "!value" ++ vector v = alloc_strvec("key \"" QUOTED19 "\""); ++ char *val; ++ ++ assert_int_equal(VECTOR_SIZE(v), 4); ++ assert_string_equal(VECTOR_SLOT(v, 0), "key"); ++ assert_true(is_quote(VECTOR_SLOT(v, 1))); ++ assert_string_equal(VECTOR_SLOT(v, 2), QUOTED19); ++ assert_true(is_quote(VECTOR_SLOT(v, 3))); ++ assert_int_equal(validate_config_strvec(v, test_file), 0); ++ ++ val = set_value(v); ++ assert_string_equal(val, QUOTED19); ++ ++ free(val); ++ free_strvec(v); ++} ++ ++static void test20(void **state) ++{ ++#define QUOTED20 "#value" ++ vector v = alloc_strvec("key \"" QUOTED20 "\""); ++ char *val; ++ ++ assert_int_equal(VECTOR_SIZE(v), 4); ++ assert_string_equal(VECTOR_SLOT(v, 0), "key"); ++ assert_true(is_quote(VECTOR_SLOT(v, 1))); ++ assert_string_equal(VECTOR_SLOT(v, 2), QUOTED20); ++ assert_true(is_quote(VECTOR_SLOT(v, 3))); ++ assert_int_equal(validate_config_strvec(v, test_file), 0); ++ ++ val = set_value(v); ++ assert_string_equal(val, QUOTED20); ++ ++ free(val); ++ free_strvec(v); ++} ++ + int test_config_parser(void) + { + const struct CMUnitTest tests[] = { +@@ -461,6 +501,8 @@ int test_config_parser(void) + cmocka_unit_test(test16), + cmocka_unit_test(test17), + cmocka_unit_test(test18), ++ cmocka_unit_test(test19), ++ cmocka_unit_test(test20), + }; + return cmocka_run_group_tests(tests, setup, teardown); + } +-- +2.17.2 + diff --git a/0035-libmultipath-invert-regexes-that-start-with-exclamat.patch b/0035-libmultipath-invert-regexes-that-start-with-exclamat.patch new file mode 100644 index 0000000..ff1331d --- /dev/null +++ b/0035-libmultipath-invert-regexes-that-start-with-exclamat.patch @@ -0,0 +1,435 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 9 Jun 2020 16:35:29 -0500 +Subject: [PATCH] libmultipath: invert regexes that start with exclamation + point + +The number of devices that multipath needs to blacklist keeps growing, +and the udev rules already have + +KERNEL!="sd*|dasd*|nvme*", GOTO="end_mpath" + +so they only work correctly with these device types. Instead of +individually blacklisting every type of device that can't be +multipathed, multipath's default blacklist should work like the udev +rule, and blacklist all devices that aren't scsi, dasd, or nvme. +Unfortunately, the c regex library doesn't support negative lookahead. +Instead, multipath should treat "!" at the beginning of +blacklist/exceptions regexes as inverse matching the rest of the regex. +If users need to match a literal '!' as the first character of their +regex, they can use "\!" instead. This allows multipath to change the +default devnode blacklist regex to "!^(sd[a-z]|dasd[a-z]|nvme[0-9])". + +Extra tests have been added to the blacklist unit tests to verify the +inverse matching code and the new default blacklist. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/blacklist.c | 41 +++++++++----- + libmultipath/blacklist.h | 3 + + multipath/multipath.conf.5 | 17 ++++-- + tests/blacklist.c | 110 +++++++++++++++++++++++++++++++++++++ + tests/test-lib.c | 2 +- + 5 files changed, 155 insertions(+), 18 deletions(-) + +diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c +index c21a0e27..db58ccca 100644 +--- a/libmultipath/blacklist.c ++++ b/libmultipath/blacklist.c +@@ -15,9 +15,24 @@ + #include "structs_vec.h" + #include "print.h" + ++char *check_invert(char *str, bool *invert) ++{ ++ if (str[0] == '!') { ++ *invert = true; ++ return str + 1; ++ } ++ if (str[0] == '\\' && str[1] == '!') { ++ *invert = false; ++ return str + 1; ++ } ++ *invert = false; ++ return str; ++} ++ + int store_ble(vector blist, char * str, int origin) + { + struct blentry * ble; ++ char *regex_str; + + if (!str) + return 0; +@@ -30,7 +45,8 @@ int store_ble(vector blist, char * str, int origin) + if (!ble) + goto out; + +- if (regcomp(&ble->regex, str, REG_EXTENDED|REG_NOSUB)) ++ regex_str = check_invert(str, &ble->invert); ++ if (regcomp(&ble->regex, regex_str, REG_EXTENDED|REG_NOSUB)) + goto out1; + + if (!vector_alloc_slot(blist)) +@@ -66,6 +82,7 @@ int alloc_ble_device(vector blist) + int set_ble_device(vector blist, char * vendor, char * product, int origin) + { + struct blentry_device * ble; ++ char *regex_str; + + if (!blist) + return 1; +@@ -76,7 +93,8 @@ int set_ble_device(vector blist, char * vendor, char * product, int origin) + return 1; + + if (vendor) { +- if (regcomp(&ble->vendor_reg, vendor, ++ regex_str = check_invert(vendor, &ble->vendor_invert); ++ if (regcomp(&ble->vendor_reg, regex_str, + REG_EXTENDED|REG_NOSUB)) { + FREE(vendor); + if (product) +@@ -86,7 +104,8 @@ int set_ble_device(vector blist, char * vendor, char * product, int origin) + ble->vendor = vendor; + } + if (product) { +- if (regcomp(&ble->product_reg, product, ++ regex_str = check_invert(product, &ble->product_invert); ++ if (regcomp(&ble->product_reg, regex_str, + REG_EXTENDED|REG_NOSUB)) { + FREE(product); + if (vendor) { +@@ -108,7 +127,7 @@ match_reglist (vector blist, const char * str) + struct blentry * ble; + + vector_foreach_slot (blist, ble, i) { +- if (!regexec(&ble->regex, str, 0, NULL, 0)) ++ if (!!regexec(&ble->regex, str, 0, NULL, 0) == ble->invert) + return 1; + } + return 0; +@@ -125,9 +144,11 @@ match_reglist_device (const struct _vector *blist, const char * vendor, + if (!ble->vendor && !ble->product) + continue; + if ((!ble->vendor || +- !regexec(&ble->vendor_reg, vendor, 0, NULL, 0)) && ++ !!regexec(&ble->vendor_reg, vendor, 0, NULL, 0) == ++ ble->vendor_invert) && + (!ble->product || +- !regexec(&ble->product_reg, product, 0, NULL, 0))) ++ !!regexec(&ble->product_reg, product, 0, NULL, 0) == ++ ble->product_invert)) + return 1; + } + return 0; +@@ -160,13 +181,7 @@ setup_default_blist (struct config * conf) + char * str; + int i; + +- str = STRDUP("^(ram|zram|raw|loop|fd|md|dm-|sr|scd|st|dcssblk)[0-9]"); +- if (!str) +- return 1; +- if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT)) +- return 1; +- +- str = STRDUP("^(td|hd|vd)[a-z]"); ++ str = STRDUP("!^(sd[a-z]|dasd[a-z]|nvme[0-9])"); + if (!str) + return 1; + if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT)) +diff --git a/libmultipath/blacklist.h b/libmultipath/blacklist.h +index 2d721f60..4305857d 100644 +--- a/libmultipath/blacklist.h ++++ b/libmultipath/blacklist.h +@@ -20,6 +20,7 @@ + struct blentry { + char * str; + regex_t regex; ++ bool invert; + int origin; + }; + +@@ -28,6 +29,8 @@ struct blentry_device { + char * product; + regex_t vendor_reg; + regex_t product_reg; ++ bool vendor_invert; ++ bool product_invert; + int origin; + }; + +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 +index 28cea88c..5adaced6 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5 +@@ -1249,6 +1249,16 @@ being handled by multipath-tools. + .LP + . + . ++In the \fIblacklist\fR and \fIblacklist_exceptions\fR sections, starting a ++quoted value with an exclamation mark \fB"!"\fR will invert the matching ++of the rest of the regular expression. For instance, \fB"!^sd[a-z]"\fR will ++match all values that do not start with \fB"sd[a-z]"\fR. The exclamation mark ++can be escaped \fB"\\!"\fR to match a literal \fB!\fR at the start of a ++regular expression. \fBNote:\fR The exclamation mark must be inside quotes, ++otherwise it will be treated as starting a comment. ++.LP ++. ++. + The \fIblacklist_exceptions\fR section is used to revert the actions of the + \fIblacklist\fR section. This allows one to selectively include ("whitelist") devices which + would normally be excluded via the \fIblacklist\fR section. A common usage is +@@ -1265,10 +1275,9 @@ unless explicitly stated. + Regular expression matching the device nodes to be excluded/included. + .RS + .PP +-The default \fIblacklist\fR consists of the regular expressions +-"^(ram|zram|raw|loop|fd|md|dm-|sr|scd|st|dcssblk)[0-9]" and +-"^(td|hd|vd)[a-z]". This causes virtual devices, non-disk devices, and some other +-device types to be excluded from multipath handling by default. ++The default \fIblacklist\fR consists of the regular expression ++\fB"!^(sd[a-z]|dasd[a-z]|nvme[0-9])"\fR. This causes all device types other ++than scsi, dasd, and nvme to be excluded from multipath handling by default. + .RE + .TP + .B wwid +diff --git a/tests/blacklist.c b/tests/blacklist.c +index 6e7c1864..d5c40898 100644 +--- a/tests/blacklist.c ++++ b/tests/blacklist.c +@@ -60,20 +60,46 @@ __wrap_udev_list_entry_get_name(struct udev_list_entry *list_entry) + return *(const char **)list_entry; + } + ++vector elist_property_default; ++vector blist_devnode_default; + vector blist_devnode_sdb; ++vector blist_devnode_sdb_inv; + vector blist_all; + vector blist_device_foo_bar; ++vector blist_device_foo_inv_bar; ++vector blist_device_foo_bar_inv; + vector blist_device_all; + vector blist_wwid_xyzzy; ++vector blist_wwid_xyzzy_inv; + vector blist_protocol_fcp; ++vector blist_protocol_fcp_inv; + vector blist_property_wwn; ++vector blist_property_wwn_inv; + + static int setup(void **state) + { ++ struct config conf; ++ ++ memset(&conf, 0, sizeof(conf)); ++ conf.blist_devnode = vector_alloc(); ++ if (!conf.blist_devnode) ++ return -1; ++ conf.elist_property = vector_alloc(); ++ if (!conf.elist_property) ++ return -1; ++ if (setup_default_blist(&conf) != 0) ++ return -1; ++ elist_property_default = conf.elist_property; ++ blist_devnode_default = conf.blist_devnode; ++ + blist_devnode_sdb = vector_alloc(); + if (!blist_devnode_sdb || + store_ble(blist_devnode_sdb, strdup("sdb"), ORIGIN_CONFIG)) + return -1; ++ blist_devnode_sdb_inv = vector_alloc(); ++ if (!blist_devnode_sdb_inv || ++ store_ble(blist_devnode_sdb_inv, strdup("!sdb"), ORIGIN_CONFIG)) ++ return -1; + + blist_all = vector_alloc(); + if (!blist_all || store_ble(blist_all, strdup(".*"), ORIGIN_CONFIG)) +@@ -84,6 +110,18 @@ static int setup(void **state) + set_ble_device(blist_device_foo_bar, strdup("foo"), strdup("bar"), + ORIGIN_CONFIG)) + return -1; ++ blist_device_foo_inv_bar = vector_alloc(); ++ if (!blist_device_foo_inv_bar || ++ alloc_ble_device(blist_device_foo_inv_bar) || ++ set_ble_device(blist_device_foo_inv_bar, strdup("!foo"), ++ strdup("bar"), ORIGIN_CONFIG)) ++ return -1; ++ blist_device_foo_bar_inv = vector_alloc(); ++ if (!blist_device_foo_bar_inv || ++ alloc_ble_device(blist_device_foo_bar_inv) || ++ set_ble_device(blist_device_foo_bar_inv, strdup("foo"), ++ strdup("!bar"), ORIGIN_CONFIG)) ++ return -1; + + blist_device_all = vector_alloc(); + if (!blist_device_all || alloc_ble_device(blist_device_all) || +@@ -95,29 +133,50 @@ static int setup(void **state) + if (!blist_wwid_xyzzy || + store_ble(blist_wwid_xyzzy, strdup("xyzzy"), ORIGIN_CONFIG)) + return -1; ++ blist_wwid_xyzzy_inv = vector_alloc(); ++ if (!blist_wwid_xyzzy_inv || ++ store_ble(blist_wwid_xyzzy_inv, strdup("!xyzzy"), ORIGIN_CONFIG)) ++ return -1; + + blist_protocol_fcp = vector_alloc(); + if (!blist_protocol_fcp || + store_ble(blist_protocol_fcp, strdup("scsi:fcp"), ORIGIN_CONFIG)) + return -1; ++ blist_protocol_fcp_inv = vector_alloc(); ++ if (!blist_protocol_fcp_inv || ++ store_ble(blist_protocol_fcp_inv, strdup("!scsi:fcp"), ++ ORIGIN_CONFIG)) ++ return -1; + + blist_property_wwn = vector_alloc(); + if (!blist_property_wwn || + store_ble(blist_property_wwn, strdup("ID_WWN"), ORIGIN_CONFIG)) + return -1; ++ blist_property_wwn_inv = vector_alloc(); ++ if (!blist_property_wwn_inv || ++ store_ble(blist_property_wwn_inv, strdup("!ID_WWN"), ORIGIN_CONFIG)) ++ return -1; + + return 0; + } + + static int teardown(void **state) + { ++ free_blacklist(elist_property_default); ++ free_blacklist(blist_devnode_default); + free_blacklist(blist_devnode_sdb); ++ free_blacklist(blist_devnode_sdb_inv); + free_blacklist(blist_all); + free_blacklist_device(blist_device_foo_bar); ++ free_blacklist_device(blist_device_foo_inv_bar); ++ free_blacklist_device(blist_device_foo_bar_inv); + free_blacklist_device(blist_device_all); + free_blacklist(blist_wwid_xyzzy); ++ free_blacklist(blist_wwid_xyzzy_inv); + free_blacklist(blist_protocol_fcp); ++ free_blacklist(blist_protocol_fcp_inv); + free_blacklist(blist_property_wwn); ++ free_blacklist(blist_property_wwn_inv); + return 0; + } + +@@ -141,6 +200,11 @@ static void test_devnode_blacklist(void **state) + expect_condlog(3, "sdb: device node name blacklisted\n"); + assert_int_equal(filter_devnode(blist_devnode_sdb, NULL, "sdb"), + MATCH_DEVNODE_BLIST); ++ assert_int_equal(filter_devnode(blist_devnode_sdb_inv, NULL, "sdb"), ++ MATCH_NOTHING); ++ expect_condlog(3, "sdc: device node name blacklisted\n"); ++ assert_int_equal(filter_devnode(blist_devnode_sdb_inv, NULL, "sdc"), ++ MATCH_DEVNODE_BLIST); + } + + static void test_devnode_whitelist(void **state) +@@ -159,12 +223,39 @@ static void test_devnode_missing(void **state) + MATCH_NOTHING); + } + ++static void test_devnode_default(void **state) ++{ ++ assert_int_equal(filter_devnode(blist_devnode_default, NULL, "sdaa"), ++ MATCH_NOTHING); ++ assert_int_equal(filter_devnode(blist_devnode_default, NULL, "nvme0n1"), ++ MATCH_NOTHING); ++ assert_int_equal(filter_devnode(blist_devnode_default, NULL, "dasda"), ++ MATCH_NOTHING); ++ expect_condlog(3, "hda: device node name blacklisted\n"); ++ assert_int_equal(filter_devnode(blist_devnode_default, NULL, "hda"), ++ MATCH_DEVNODE_BLIST); ++} ++ + static void test_device_blacklist(void **state) + { + expect_condlog(3, "sdb: (foo:bar) vendor/product blacklisted\n"); + assert_int_equal(filter_device(blist_device_foo_bar, NULL, "foo", + "bar", "sdb"), + MATCH_DEVICE_BLIST); ++ assert_int_equal(filter_device(blist_device_foo_inv_bar, NULL, "foo", ++ "bar", "sdb"), ++ MATCH_NOTHING); ++ assert_int_equal(filter_device(blist_device_foo_bar_inv, NULL, "foo", ++ "bar", "sdb"), ++ MATCH_NOTHING); ++ expect_condlog(3, "sdb: (baz:bar) vendor/product blacklisted\n"); ++ assert_int_equal(filter_device(blist_device_foo_inv_bar, NULL, "baz", ++ "bar", "sdb"), ++ MATCH_DEVICE_BLIST); ++ expect_condlog(3, "sdb: (foo:baz) vendor/product blacklisted\n"); ++ assert_int_equal(filter_device(blist_device_foo_bar_inv, NULL, "foo", ++ "baz", "sdb"), ++ MATCH_DEVICE_BLIST); + } + + static void test_device_whitelist(void **state) +@@ -191,6 +282,11 @@ static void test_wwid_blacklist(void **state) + expect_condlog(3, "sdb: wwid xyzzy blacklisted\n"); + assert_int_equal(filter_wwid(blist_wwid_xyzzy, NULL, "xyzzy", "sdb"), + MATCH_WWID_BLIST); ++ assert_int_equal(filter_wwid(blist_wwid_xyzzy_inv, NULL, "xyzzy", ++ "sdb"), MATCH_NOTHING); ++ expect_condlog(3, "sdb: wwid plugh blacklisted\n"); ++ assert_int_equal(filter_wwid(blist_wwid_xyzzy_inv, NULL, "plugh", ++ "sdb"), MATCH_WWID_BLIST); + } + + static void test_wwid_whitelist(void **state) +@@ -218,6 +314,12 @@ static void test_protocol_blacklist(void **state) + expect_condlog(3, "sdb: protocol scsi:fcp blacklisted\n"); + assert_int_equal(filter_protocol(blist_protocol_fcp, NULL, &pp), + MATCH_PROTOCOL_BLIST); ++ assert_int_equal(filter_protocol(blist_protocol_fcp_inv, NULL, &pp), ++ MATCH_NOTHING); ++ pp.sg_id.proto_id = SCSI_PROTOCOL_ATA; ++ expect_condlog(3, "sdb: protocol scsi:ata blacklisted\n"); ++ assert_int_equal(filter_protocol(blist_protocol_fcp_inv, NULL, &pp), ++ MATCH_PROTOCOL_BLIST); + } + + static void test_protocol_whitelist(void **state) +@@ -245,10 +347,17 @@ static void test_protocol_missing(void **state) + static void test_property_blacklist(void **state) + { + static struct udev_device udev = { "sdb", { "ID_FOO", "ID_WWN", "ID_BAR", NULL } }; ++ static struct udev_device udev_inv = { "sdb", { "ID_WWN", NULL } }; + conf.blist_property = blist_property_wwn; + expect_condlog(3, "sdb: udev property ID_WWN blacklisted\n"); + assert_int_equal(filter_property(&conf, &udev, 3, "ID_SERIAL"), + MATCH_PROPERTY_BLIST); ++ conf.blist_property = blist_property_wwn_inv; ++ expect_condlog(3, "sdb: udev property ID_FOO blacklisted\n"); ++ assert_int_equal(filter_property(&conf, &udev, 3, "ID_SERIAL"), ++ MATCH_PROPERTY_BLIST); ++ assert_int_equal(filter_property(&conf, &udev_inv, 3, "ID_SERIAL"), ++ MATCH_NOTHING); + } + + /* the property check works different in that you check all the property +@@ -484,6 +593,7 @@ int test_blacklist(void) + cmocka_unit_test(test_devnode_blacklist), + cmocka_unit_test(test_devnode_whitelist), + cmocka_unit_test(test_devnode_missing), ++ cmocka_unit_test(test_devnode_default), + cmocka_unit_test(test_device_blacklist), + cmocka_unit_test(test_device_whitelist), + cmocka_unit_test(test_device_missing), +diff --git a/tests/test-lib.c b/tests/test-lib.c +index 00bae58e..b7c09cc2 100644 +--- a/tests/test-lib.c ++++ b/tests/test-lib.c +@@ -15,7 +15,7 @@ + #include "test-lib.h" + + const int default_mask = (DI_SYSFS|DI_BLACKLIST|DI_WWID|DI_CHECKER|DI_PRIO); +-const char default_devnode[] = "sdTEST"; ++const char default_devnode[] = "sdxTEST"; + const char default_wwid[] = "TEST-WWID"; + /* default_wwid should be a substring of default_wwid_1! */ + const char default_wwid_1[] = "TEST-WWID-1"; +-- +2.17.2 + diff --git a/0036-multipath-Fix-compiler-warnings-when-built-without-s.patch b/0036-multipath-Fix-compiler-warnings-when-built-without-s.patch new file mode 100644 index 0000000..f631fdb --- /dev/null +++ b/0036-multipath-Fix-compiler-warnings-when-built-without-s.patch @@ -0,0 +1,111 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Marius Bakke +Date: Wed, 17 Jun 2020 01:11:26 +0200 +Subject: [PATCH] multipath: Fix compiler warnings when built without systemd. + +Add ifdef guards for code that is unused when systemd is not available. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/config.c | 6 ++++-- + multipathd/main.c | 10 +++++++++- + 2 files changed, 13 insertions(+), 3 deletions(-) + +diff --git a/libmultipath/config.c b/libmultipath/config.c +index b4d87689..658bec8b 100644 +--- a/libmultipath/config.c ++++ b/libmultipath/config.c +@@ -696,9 +696,9 @@ process_config_dir(struct config *conf, char *dir) + pthread_cleanup_pop(1); + } + ++#ifdef USE_SYSTEMD + static void set_max_checkint_from_watchdog(struct config *conf) + { +-#ifdef USE_SYSTEMD + char *envp = getenv("WATCHDOG_USEC"); + unsigned long checkint; + +@@ -714,8 +714,8 @@ static void set_max_checkint_from_watchdog(struct config *conf) + condlog(3, "enabling watchdog, interval %ld", checkint); + conf->use_watchdog = true; + } +-#endif + } ++#endif + + struct config * + load_config (char * file) +@@ -789,7 +789,9 @@ load_config (char * file) + /* + * fill the voids left in the config file + */ ++#ifdef USE_SYSTEMD + set_max_checkint_from_watchdog(conf); ++#endif + if (conf->max_checkint == 0) { + if (conf->checkint == CHECKINT_UNDEF) + conf->checkint = DEFAULT_CHECKINT; +diff --git a/multipathd/main.c b/multipathd/main.c +index 6b7db2c0..205ddb32 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -176,6 +176,7 @@ daemon_status(void) + /* + * I love you too, systemd ... + */ ++#ifdef USE_SYSTEMD + static const char * + sd_notify_status(enum daemon_status state) + { +@@ -195,7 +196,6 @@ sd_notify_status(enum daemon_status state) + return NULL; + } + +-#ifdef USE_SYSTEMD + static void do_sd_notify(enum daemon_status old_state, + enum daemon_status new_state) + { +@@ -247,7 +247,9 @@ enum daemon_status wait_for_state_change_if(enum daemon_status oldstate, + static void __post_config_state(enum daemon_status state) + { + if (state != running_state && running_state != DAEMON_SHUTDOWN) { ++#ifdef USE_SYSTEMD + enum daemon_status old_state = running_state; ++#endif + + running_state = state; + pthread_cond_broadcast(&config_cond); +@@ -272,7 +274,9 @@ int set_config_state(enum daemon_status state) + pthread_cleanup_push(config_cleanup, NULL); + pthread_mutex_lock(&config_lock); + if (running_state != state) { ++#ifdef USE_SYSTEMD + enum daemon_status old_state = running_state; ++#endif + + if (running_state == DAEMON_SHUTDOWN) + rc = EINVAL; +@@ -2280,7 +2284,9 @@ checkerloop (void *ap) + struct timespec last_time; + struct config *conf; + int foreign_tick = 0; ++#ifdef USE_SYSTEMD + bool use_watchdog; ++#endif + + pthread_cleanup_push(rcu_unregister, NULL); + rcu_register_thread(); +@@ -2294,7 +2300,9 @@ checkerloop (void *ap) + + /* use_watchdog is set from process environment and never changes */ + conf = get_multipath_config(); ++#ifdef USE_SYSTEMD + use_watchdog = conf->use_watchdog; ++#endif + put_multipath_config(conf); + + while (1) { +-- +2.17.2 + diff --git a/0037-libmultipath-fix-sysfs-dev_loss_tmo-parsing.patch b/0037-libmultipath-fix-sysfs-dev_loss_tmo-parsing.patch new file mode 100644 index 0000000..0888750 --- /dev/null +++ b/0037-libmultipath-fix-sysfs-dev_loss_tmo-parsing.patch @@ -0,0 +1,43 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 2 Jul 2020 19:38:24 -0500 +Subject: [PATCH] libmultipath: fix sysfs dev_loss_tmo parsing + +dev_loss_tmo is a u32 value. However the kernel sysfs code prints it as +a signed integer. This means that if dev_loss_tmo is above INT_MAX, the +sysfs value will be a negative number. Parsing this was causing +sysfs_set_rport_tmo() to fail. + +Signed-off-by: Benjamin Marzinski +Signed-off-by: Martin Wilck +--- + libmultipath/discovery.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index ffec5162..83a41a4a 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -583,7 +583,7 @@ sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp) + struct udev_device *rport_dev = NULL; + char value[16], *eptr; + char rport_id[32]; +- unsigned long long tmo = 0; ++ unsigned int tmo; + int ret; + + sprintf(rport_id, "rport-%d:%d-%d", +@@ -607,8 +607,8 @@ sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp) + "error %d", rport_id, -ret); + goto out; + } +- tmo = strtoull(value, &eptr, 0); +- if (value == eptr || tmo == ULLONG_MAX) { ++ tmo = strtoul(value, &eptr, 0); ++ if (value == eptr) { + condlog(0, "%s: Cannot parse dev_loss_tmo " + "attribute '%s'", rport_id, value); + goto out; +-- +2.17.2 + diff --git a/0038-kpartx-read-devices-with-direct-IO.patch b/0038-kpartx-read-devices-with-direct-IO.patch new file mode 100644 index 0000000..eaa91c3 --- /dev/null +++ b/0038-kpartx-read-devices-with-direct-IO.patch @@ -0,0 +1,267 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 2 Jul 2020 19:38:25 -0500 +Subject: [PATCH] kpartx: read devices with direct IO + +If kpartx is used on top of shared storage, and a device has its +partition table changed on one machine, and then kpartx is run on +another, it may not see the new data, because the cache still contains +the old data, and there is nothing to tell the machine running kpartx to +invalidate it. To solve this, kpartx should read the devices using +direct io. + +One issue with how this code has been updated is that the original code +for getblock() always read 1024 bytes. The new code reads a logical +sector size chunk of the device, and returns a pointer to the 512 byte +sector that the caller asked for, within that (possibly larger) chunk. +This means that if the logical sector size is 512, then the code is now +only reading 512 bytes. Looking through the code for the various +partition types, I can't see a case where more than 512 bytes is needed +and getblock() is used. If anyone has a reason why this code should be +reading 1024 bytes at minmum, I can certainly change this. But when I +looked, I couldn't find a case where reading 512 bytes would cause a +problem. + +Signed-off-by: Benjamin Marzinski +--- + kpartx/dasd.c | 7 ++++--- + kpartx/gpt.c | 22 +++++++++---------- + kpartx/kpartx.c | 56 +++++++++++++++++++++++++++++++++++++++---------- + kpartx/kpartx.h | 2 ++ + 4 files changed, 61 insertions(+), 26 deletions(-) + +diff --git a/kpartx/dasd.c b/kpartx/dasd.c +index 14b9d3aa..f0398645 100644 +--- a/kpartx/dasd.c ++++ b/kpartx/dasd.c +@@ -22,6 +22,7 @@ + * along with this program. If not, see . + */ + ++#define _GNU_SOURCE + #include + #include + #include +@@ -117,13 +118,13 @@ read_dasd_pt(int fd, __attribute__((unused)) struct slice all, + + sprintf(pathname, "/dev/.kpartx-node-%u-%u", + (unsigned int)major(dev), (unsigned int)minor(dev)); +- if ((fd_dasd = open(pathname, O_RDONLY)) == -1) { ++ if ((fd_dasd = open(pathname, O_RDONLY | O_DIRECT)) == -1) { + /* Devicenode does not exist. Try to create one */ + if (mknod(pathname, 0600 | S_IFBLK, dev) == -1) { + /* Couldn't create a device node */ + return -1; + } +- fd_dasd = open(pathname, O_RDONLY); ++ fd_dasd = open(pathname, O_RDONLY | O_DIRECT); + /* + * The file will vanish when the last process (we) + * has ceased to access it. +@@ -175,7 +176,7 @@ read_dasd_pt(int fd, __attribute__((unused)) struct slice all, + * Get volume label, extract name and type. + */ + +- if (!(data = (unsigned char *)malloc(blocksize))) ++ if (aligned_malloc((void **)&data, blocksize, NULL)) + goto out; + + +diff --git a/kpartx/gpt.c b/kpartx/gpt.c +index 785b34ea..f7fefb70 100644 +--- a/kpartx/gpt.c ++++ b/kpartx/gpt.c +@@ -243,8 +243,7 @@ alloc_read_gpt_entries(int fd, gpt_header * gpt) + + if (!count) return NULL; + +- pte = (gpt_entry *)malloc(count); +- if (!pte) ++ if (aligned_malloc((void **)&pte, get_sector_size(fd), &count)) + return NULL; + memset(pte, 0, count); + +@@ -269,12 +268,11 @@ static gpt_header * + alloc_read_gpt_header(int fd, uint64_t lba) + { + gpt_header *gpt; +- gpt = (gpt_header *) +- malloc(sizeof (gpt_header)); +- if (!gpt) ++ size_t size = sizeof (gpt_header); ++ if (aligned_malloc((void **)&gpt, get_sector_size(fd), &size)) + return NULL; +- memset(gpt, 0, sizeof (*gpt)); +- if (!read_lba(fd, lba, gpt, sizeof (gpt_header))) { ++ memset(gpt, 0, size); ++ if (!read_lba(fd, lba, gpt, size)) { + free(gpt); + return NULL; + } +@@ -498,6 +496,7 @@ find_valid_gpt(int fd, gpt_header ** gpt, gpt_entry ** ptes) + gpt_header *pgpt = NULL, *agpt = NULL; + gpt_entry *pptes = NULL, *aptes = NULL; + legacy_mbr *legacymbr = NULL; ++ size_t size = sizeof(legacy_mbr); + uint64_t lastlba; + if (!gpt || !ptes) + return 0; +@@ -526,11 +525,10 @@ find_valid_gpt(int fd, gpt_header ** gpt, gpt_entry ** ptes) + } + + /* This will be added to the EFI Spec. per Intel after v1.02. */ +- legacymbr = malloc(sizeof (*legacymbr)); +- if (legacymbr) { +- memset(legacymbr, 0, sizeof (*legacymbr)); +- read_lba(fd, 0, (uint8_t *) legacymbr, +- sizeof (*legacymbr)); ++ if (aligned_malloc((void **)&legacymbr, get_sector_size(fd), ++ &size) == 0) { ++ memset(legacymbr, 0, size); ++ read_lba(fd, 0, (uint8_t *) legacymbr, size); + good_pmbr = is_pmbr_valid(legacymbr); + free(legacymbr); + legacymbr=NULL; +diff --git a/kpartx/kpartx.c b/kpartx/kpartx.c +index d3620c5c..c24ad6d9 100644 +--- a/kpartx/kpartx.c ++++ b/kpartx/kpartx.c +@@ -19,6 +19,7 @@ + * cva, 2002-10-26 + */ + ++#define _GNU_SOURCE + #include + #include + #include +@@ -41,7 +42,6 @@ + + #define SIZE(a) (sizeof(a)/sizeof((a)[0])) + +-#define READ_SIZE 1024 + #define MAXTYPES 64 + #define MAXSLICES 256 + #define DM_TARGET "linear" +@@ -388,7 +388,7 @@ main(int argc, char **argv){ + set_delimiter(mapname, delim); + } + +- fd = open(device, O_RDONLY); ++ fd = open(device, O_RDONLY | O_DIRECT); + + if (fd == -1) { + perror(device); +@@ -690,9 +690,9 @@ xmalloc (size_t size) { + */ + + static int +-sseek(int fd, unsigned int secnr) { ++sseek(int fd, unsigned int secnr, int secsz) { + off64_t in, out; +- in = ((off64_t) secnr << 9); ++ in = ((off64_t) secnr * secsz); + out = 1; + + if ((out = lseek64(fd, in, SEEK_SET)) != in) +@@ -703,6 +703,31 @@ sseek(int fd, unsigned int secnr) { + return 0; + } + ++int ++aligned_malloc(void **mem_p, size_t align, size_t *size_p) ++{ ++ static size_t pgsize = 0; ++ size_t size; ++ int err; ++ ++ if (!mem_p || !align || (size_p && !*size_p)) ++ return EINVAL; ++ ++ if (!pgsize) ++ pgsize = getpagesize(); ++ ++ if (size_p) ++ size = ((*size_p + align - 1) / align) * align; ++ else ++ size = pgsize; ++ ++ err = posix_memalign(mem_p, pgsize, size); ++ if (!err && size_p) ++ *size_p = size; ++ return err; ++} ++ ++/* always in sector size blocks */ + static + struct block { + unsigned int secnr; +@@ -710,30 +735,39 @@ struct block { + struct block *next; + } *blockhead; + ++/* blknr is always in 512 byte blocks */ + char * +-getblock (int fd, unsigned int secnr) { ++getblock (int fd, unsigned int blknr) { ++ unsigned int secsz = get_sector_size(fd); ++ unsigned int blks_per_sec = secsz / 512; ++ unsigned int secnr = blknr / blks_per_sec; ++ unsigned int blk_off = (blknr % blks_per_sec) * 512; + struct block *bp; + + for (bp = blockhead; bp; bp = bp->next) + + if (bp->secnr == secnr) +- return bp->block; ++ return bp->block + blk_off; + +- if (sseek(fd, secnr)) ++ if (sseek(fd, secnr, secsz)) + return NULL; + + bp = xmalloc(sizeof(struct block)); + bp->secnr = secnr; + bp->next = blockhead; + blockhead = bp; +- bp->block = (char *) xmalloc(READ_SIZE); ++ if (aligned_malloc((void **)&bp->block, secsz, NULL)) { ++ fprintf(stderr, "aligned_malloc failed\n"); ++ exit(1); ++ } + +- if (read(fd, bp->block, READ_SIZE) != READ_SIZE) { ++ if (read(fd, bp->block, secsz) != secsz) { + fprintf(stderr, "read error, sector %d\n", secnr); +- bp->block = NULL; ++ blockhead = bp->next; ++ return NULL; + } + +- return bp->block; ++ return bp->block + blk_off; + } + + int +diff --git a/kpartx/kpartx.h b/kpartx/kpartx.h +index 67edeb82..727632c1 100644 +--- a/kpartx/kpartx.h ++++ b/kpartx/kpartx.h +@@ -1,6 +1,7 @@ + #ifndef _KPARTX_H + #define _KPARTX_H + ++#include + #include + #include + +@@ -61,6 +62,7 @@ extern ptreader read_mac_pt; + extern ptreader read_sun_pt; + extern ptreader read_ps3_pt; + ++int aligned_malloc(void **mem_p, size_t align, size_t *size_p); + char *getblock(int fd, unsigned int secnr); + + static inline unsigned int +-- +2.17.2 + diff --git a/0039-kpartx-handle-alternate-bsd-disklabel-location.patch b/0039-kpartx-handle-alternate-bsd-disklabel-location.patch new file mode 100644 index 0000000..4b6e7e5 --- /dev/null +++ b/0039-kpartx-handle-alternate-bsd-disklabel-location.patch @@ -0,0 +1,53 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 2 Jul 2020 19:38:26 -0500 +Subject: [PATCH] kpartx: handle alternate bsd disklabel location + +bsd disk labels can either be at the start of the second sector, or 64 +bytes into the first sector, but kpartx only handled the first case. +However the second case is what parted creates, and what the linux +kernel partition code expects. kpartx should handle both cases. + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + kpartx/bsd.c | 16 ++++++++++++++-- + 1 file changed, 14 insertions(+), 2 deletions(-) + +diff --git a/kpartx/bsd.c b/kpartx/bsd.c +index 0e661fbc..950b0f92 100644 +--- a/kpartx/bsd.c ++++ b/kpartx/bsd.c +@@ -1,6 +1,7 @@ + #include "kpartx.h" + #include + ++#define BSD_LABEL_OFFSET 64 + #define BSD_DISKMAGIC (0x82564557UL) /* The disk magic number */ + #define XBSD_MAXPARTITIONS 16 + #define BSD_FS_UNUSED 0 +@@ -60,8 +61,19 @@ read_bsd_pt(int fd, struct slice all, struct slice *sp, unsigned int ns) { + return -1; + + l = (struct bsd_disklabel *) bp; +- if (l->d_magic != BSD_DISKMAGIC) +- return -1; ++ if (l->d_magic != BSD_DISKMAGIC) { ++ /* ++ * BSD disklabels can also start 64 bytes offset from the ++ * start of the first sector ++ */ ++ bp = getblock(fd, offset); ++ if (bp == NULL) ++ return -1; ++ ++ l = (struct bsd_disklabel *)(bp + 64); ++ if (l->d_magic != BSD_DISKMAGIC) ++ return -1; ++ } + + max_partitions = 16; + if (l->d_npartitions < max_partitions) +-- +2.17.2 + diff --git a/0040-libmultipath-fix-checker-detection-for-nvme-devices.patch b/0040-libmultipath-fix-checker-detection-for-nvme-devices.patch new file mode 100644 index 0000000..1054e30 --- /dev/null +++ b/0040-libmultipath-fix-checker-detection-for-nvme-devices.patch @@ -0,0 +1,62 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 2 Jul 2020 19:38:27 -0500 +Subject: [PATCH] libmultipath: fix checker detection for nvme devices + +In order to fix hwhandler autodetection, commit 8794a776 made +detect_alua() differentiate between failures to detect whether alua was +supported, and successfully detecting that it was not supported. +However, this causes nvme devices to get the TUR checker assigned to +them. This is because there is nothing in detect_alua() to make it only +work on scsi devices, and select_checker wasn't updated to handle +detect_alua() failing without setting pp->tpgs to TPGS_NONE. + +detect_alua() should automatically set pp->tpgs to TPGS_NONE and exit on +non-scsi devices. Also, select_checker() should not assume that a +devices is ALUA, simply because if failed to detect if alua was +supported. + +Fixes: 8794a776 "libmultipath: fix ALUA autodetection when paths are + down" +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/discovery.c | 6 ++++++ + libmultipath/propsel.c | 4 +++- + 2 files changed, 9 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index 83a41a4a..aa5942c3 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -887,6 +887,12 @@ detect_alua(struct path * pp) + int tpgs; + unsigned int timeout; + ++ ++ if (pp->bus != SYSFS_BUS_SCSI) { ++ pp->tpgs = TPGS_NONE; ++ return; ++ } ++ + if (sysfs_get_timeout(pp, &timeout) <= 0) + timeout = DEF_TIMEOUT; + +diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c +index 897e48ca..d362beb4 100644 +--- a/libmultipath/propsel.c ++++ b/libmultipath/propsel.c +@@ -521,7 +521,9 @@ int select_checker(struct config *conf, struct path *pp) + if (check_rdac(pp)) { + ckr_name = RDAC; + goto out; +- } else if (path_get_tpgs(pp) != TPGS_NONE) { ++ } ++ path_get_tpgs(pp); ++ if (pp->tpgs != TPGS_NONE && pp->tpgs != TPGS_UNDEF) { + ckr_name = TUR; + goto out; + } +-- +2.17.2 + diff --git a/0041-libmultipath-make-dm_get_map-status-return-codes-sym.patch b/0041-libmultipath-make-dm_get_map-status-return-codes-sym.patch new file mode 100644 index 0000000..91c9a8b --- /dev/null +++ b/0041-libmultipath-make-dm_get_map-status-return-codes-sym.patch @@ -0,0 +1,322 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 2 Jul 2020 19:07:00 -0500 +Subject: [PATCH] libmultipath: make dm_get_map/status return codes symbolic + +dm_get_map() and dm_get_status() now use symbolic return codes. They +also differentiate between failing to get information from device-mapper +and not finding the requested device. These symboilc return codes are +also used by update_multipath_* functions. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/devmapper.c | 51 +++++++++++++++++++++++++------------- + libmultipath/devmapper.h | 6 +++++ + libmultipath/structs_vec.c | 45 +++++++++++++++++++-------------- + multipathd/main.c | 12 ++++----- + 4 files changed, 72 insertions(+), 42 deletions(-) + +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index 27d52398..24cc616a 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -534,36 +534,43 @@ int dm_map_present(const char * str) + + int dm_get_map(const char *name, unsigned long long *size, char *outparams) + { +- int r = 1; ++ int r = DMP_ERR; + struct dm_task *dmt; + uint64_t start, length; + char *target_type = NULL; + char *params = NULL; + + if (!(dmt = libmp_dm_task_create(DM_DEVICE_TABLE))) +- return 1; ++ return r; + + if (!dm_task_set_name(dmt, name)) + goto out; + + dm_task_no_open_count(dmt); + +- if (!dm_task_run(dmt)) ++ errno = 0; ++ if (!dm_task_run(dmt)) { ++ if (dm_task_get_errno(dmt) == ENXIO) ++ r = DMP_NOT_FOUND; + goto out; ++ } + ++ r = DMP_NOT_FOUND; + /* Fetch 1st target */ +- dm_get_next_target(dmt, NULL, &start, &length, +- &target_type, ¶ms); ++ if (dm_get_next_target(dmt, NULL, &start, &length, ++ &target_type, ¶ms) != NULL) ++ /* more than one target */ ++ goto out; + + if (size) + *size = length; + + if (!outparams) { +- r = 0; ++ r = DMP_OK; + goto out; + } + if (snprintf(outparams, PARAMS_SIZE, "%s", params) <= PARAMS_SIZE) +- r = 0; ++ r = DMP_OK; + out: + dm_task_destroy(dmt); + return r; +@@ -637,35 +644,45 @@ is_mpath_part(const char *part_name, const char *map_name) + + int dm_get_status(const char *name, char *outstatus) + { +- int r = 1; ++ int r = DMP_ERR; + struct dm_task *dmt; + uint64_t start, length; + char *target_type = NULL; + char *status = NULL; + + if (!(dmt = libmp_dm_task_create(DM_DEVICE_STATUS))) +- return 1; ++ return r; + + if (!dm_task_set_name(dmt, name)) + goto out; + + dm_task_no_open_count(dmt); + +- if (!dm_task_run(dmt)) ++ errno = 0; ++ if (!dm_task_run(dmt)) { ++ if (dm_task_get_errno(dmt) == ENXIO) ++ r = DMP_NOT_FOUND; + goto out; ++ } + ++ r = DMP_NOT_FOUND; + /* Fetch 1st target */ +- dm_get_next_target(dmt, NULL, &start, &length, +- &target_type, &status); ++ if (dm_get_next_target(dmt, NULL, &start, &length, ++ &target_type, &status) != NULL) ++ goto out; ++ ++ if (!target_type || strcmp(target_type, TGT_MPATH) != 0) ++ goto out; ++ + if (!status) { + condlog(2, "get null status."); + goto out; + } + + if (snprintf(outstatus, PARAMS_SIZE, "%s", status) <= PARAMS_SIZE) +- r = 0; ++ r = DMP_OK; + out: +- if (r) ++ if (r != DMP_OK) + condlog(0, "%s: error getting map status string", name); + + dm_task_destroy(dmt); +@@ -920,7 +937,7 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, + return 1; + + if (need_suspend && +- !dm_get_map(mapname, &mapsize, params) && ++ dm_get_map(mapname, &mapsize, params) == DMP_OK && + strstr(params, "queue_if_no_path")) { + if (!dm_queue_if_no_path(mapname, 0)) + queue_if_no_path = 1; +@@ -1129,7 +1146,7 @@ struct multipath *dm_get_multipath(const char *name) + if (!mpp->alias) + goto out; + +- if (dm_get_map(name, &mpp->size, NULL)) ++ if (dm_get_map(name, &mpp->size, NULL) != DMP_OK) + goto out; + + dm_get_uuid(name, mpp->wwid, WWID_SIZE); +@@ -1313,7 +1330,7 @@ do_foreach_partmaps (const char * mapname, + /* + * and we can fetch the map table from the kernel + */ +- !dm_get_map(names->name, &size, ¶ms[0]) && ++ dm_get_map(names->name, &size, ¶ms[0]) == DMP_OK && + + /* + * and the table maps over the multipath map +diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h +index 5ed7edc5..b2108638 100644 +--- a/libmultipath/devmapper.h ++++ b/libmultipath/devmapper.h +@@ -27,6 +27,12 @@ + #define UUID_PREFIX "mpath-" + #define UUID_PREFIX_LEN (sizeof(UUID_PREFIX) - 1) + ++enum { ++ DMP_ERR, ++ DMP_OK, ++ DMP_NOT_FOUND, ++}; ++ + void dm_init(int verbosity); + int dm_prereq(unsigned int *v); + void skip_libmp_dm_init(void); +diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c +index 077f2e42..8137ea21 100644 +--- a/libmultipath/structs_vec.c ++++ b/libmultipath/structs_vec.c +@@ -196,43 +196,47 @@ extract_hwe_from_path(struct multipath * mpp) + int + update_multipath_table (struct multipath *mpp, vector pathvec, int is_daemon) + { ++ int r = DMP_ERR; + char params[PARAMS_SIZE] = {0}; + + if (!mpp) +- return 1; ++ return r; + +- if (dm_get_map(mpp->alias, &mpp->size, params)) { +- condlog(3, "%s: cannot get map", mpp->alias); +- return 1; ++ r = dm_get_map(mpp->alias, &mpp->size, params); ++ if (r != DMP_OK) { ++ condlog(3, "%s: %s", mpp->alias, (r == DMP_ERR)? "error getting table" : "map not present"); ++ return r; + } + + if (disassemble_map(pathvec, params, mpp, is_daemon)) { + condlog(3, "%s: cannot disassemble map", mpp->alias); +- return 1; ++ return DMP_ERR; + } + +- return 0; ++ return DMP_OK; + } + + int + update_multipath_status (struct multipath *mpp) + { ++ int r = DMP_ERR; + char status[PARAMS_SIZE] = {0}; + + if (!mpp) +- return 1; ++ return r; + +- if (dm_get_status(mpp->alias, status)) { +- condlog(3, "%s: cannot get status", mpp->alias); +- return 1; ++ r = dm_get_status(mpp->alias, status); ++ if (r != DMP_OK) { ++ condlog(3, "%s: %s", mpp->alias, (r == DMP_ERR)? "error getting status" : "map not present"); ++ return r; + } + + if (disassemble_status(status, mpp)) { + condlog(3, "%s: cannot disassemble status", mpp->alias); +- return 1; ++ return DMP_ERR; + } + +- return 0; ++ return DMP_OK; + } + + void sync_paths(struct multipath *mpp, vector pathvec) +@@ -264,10 +268,10 @@ int + update_multipath_strings(struct multipath *mpp, vector pathvec, int is_daemon) + { + struct pathgroup *pgp; +- int i; ++ int i, r = DMP_ERR; + + if (!mpp) +- return 1; ++ return r; + + update_mpp_paths(mpp, pathvec); + condlog(4, "%s: %s", mpp->alias, __FUNCTION__); +@@ -276,18 +280,21 @@ update_multipath_strings(struct multipath *mpp, vector pathvec, int is_daemon) + free_pgvec(mpp->pg, KEEP_PATHS); + mpp->pg = NULL; + +- if (update_multipath_table(mpp, pathvec, is_daemon)) +- return 1; ++ r = update_multipath_table(mpp, pathvec, is_daemon); ++ if (r != DMP_OK) ++ return r; ++ + sync_paths(mpp, pathvec); + +- if (update_multipath_status(mpp)) +- return 1; ++ r = update_multipath_status(mpp); ++ if (r != DMP_OK) ++ return r; + + vector_foreach_slot(mpp->pg, pgp, i) + if (pgp->paths) + path_group_prio_update(pgp); + +- return 0; ++ return DMP_OK; + } + + static void enter_recovery_mode(struct multipath *mpp) +diff --git a/multipathd/main.c b/multipathd/main.c +index 205ddb32..ab141fed 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -418,7 +418,7 @@ int __setup_multipath(struct vectors *vecs, struct multipath *mpp, + goto out; + } + +- if (update_multipath_strings(mpp, vecs->pathvec, 1)) { ++ if (update_multipath_strings(mpp, vecs->pathvec, 1) != DMP_OK) { + condlog(0, "%s: failed to setup multipath", mpp->alias); + goto out; + } +@@ -557,9 +557,9 @@ add_map_without_path (struct vectors *vecs, const char *alias) + mpp->mpe = find_mpe(conf->mptable, mpp->wwid); + put_multipath_config(conf); + +- if (update_multipath_table(mpp, vecs->pathvec, 1)) ++ if (update_multipath_table(mpp, vecs->pathvec, 1) != DMP_OK) + goto out; +- if (update_multipath_status(mpp)) ++ if (update_multipath_status(mpp) != DMP_OK) + goto out; + + if (!vector_alloc_slot(vecs->mpvec)) +@@ -1350,8 +1350,8 @@ map_discovery (struct vectors * vecs) + return 1; + + vector_foreach_slot (vecs->mpvec, mpp, i) +- if (update_multipath_table(mpp, vecs->pathvec, 1) || +- update_multipath_status(mpp)) { ++ if (update_multipath_table(mpp, vecs->pathvec, 1) != DMP_OK || ++ update_multipath_status(mpp) != DMP_OK) { + remove_map(mpp, vecs, 1); + i--; + } +@@ -2091,7 +2091,7 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) + /* + * Synchronize with kernel state + */ +- if (update_multipath_strings(pp->mpp, vecs->pathvec, 1)) { ++ if (update_multipath_strings(pp->mpp, vecs->pathvec, 1) != DMP_OK) { + condlog(1, "%s: Could not synchronize with kernel state", + pp->dev); + pp->dmstate = PSTATE_UNDEF; +-- +2.17.2 + diff --git a/0042-multipathd-fix-check_path-errors-with-removed-map.patch b/0042-multipathd-fix-check_path-errors-with-removed-map.patch new file mode 100644 index 0000000..155e93a --- /dev/null +++ b/0042-multipathd-fix-check_path-errors-with-removed-map.patch @@ -0,0 +1,116 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 2 Jul 2020 19:07:01 -0500 +Subject: [PATCH] multipathd: fix check_path errors with removed map + +If a multipath device is removed during, or immediately before the call +to check_path(), multipathd can behave incorrectly. A missing multpath +device will cause update_multipath_strings() to fail, setting +pp->dmstate to PSTATE_UNDEF. If the path is up, this state will cause +reinstate_path() to be called, which will also fail. This will trigger +a reload, restoring the recently removed device. + +If update_multipath_strings() fails because there is no multipath +device, check_path should just quit, since the remove dmevent and uevent +are likely already queued up. Also, I don't see any reason to reload the +multipath device if reinstate fails. This code was added by +fac68d7a99ef17d496079538a5c6836acd7911ab, which clamined that reinstate +could fail if the path was disabled. Looking through the current kernel +code, I can't see any reason why a reinstate would fail, where a reload +would help. If the path was missing from the multipath device, +update_multipath_strings() would already catch that, and quit +check_path() early, which make more sense to me than reloading does. + +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 44 +++++++++++++++++++------------------------- + 1 file changed, 19 insertions(+), 25 deletions(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index ab141fed..daf19a4e 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -1615,22 +1615,18 @@ fail_path (struct path * pp, int del_active) + /* + * caller must have locked the path list before calling that function + */ +-static int ++static void + reinstate_path (struct path * pp) + { +- int ret = 0; +- + if (!pp->mpp) +- return 0; ++ return; + +- if (dm_reinstate_path(pp->mpp->alias, pp->dev_t)) { ++ if (dm_reinstate_path(pp->mpp->alias, pp->dev_t)) + condlog(0, "%s: reinstate failed", pp->dev_t); +- ret = 1; +- } else { ++ else { + condlog(2, "%s: reinstated", pp->dev_t); + update_queue_mode_add_path(pp->mpp); + } +- return ret; + } + + static void +@@ -2091,9 +2087,16 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) + /* + * Synchronize with kernel state + */ +- if (update_multipath_strings(pp->mpp, vecs->pathvec, 1) != DMP_OK) { +- condlog(1, "%s: Could not synchronize with kernel state", +- pp->dev); ++ ret = update_multipath_strings(pp->mpp, vecs->pathvec, 1); ++ if (ret != DMP_OK) { ++ if (ret == DMP_NOT_FOUND) { ++ /* multipath device missing. Likely removed */ ++ condlog(1, "%s: multipath device '%s' not found", ++ pp->dev, pp->mpp->alias); ++ return 0; ++ } else ++ condlog(1, "%s: Couldn't synchronize with kernel state", ++ pp->dev); + pp->dmstate = PSTATE_UNDEF; + } + /* if update_multipath_strings orphaned the path, quit early */ +@@ -2183,12 +2186,8 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) + /* + * reinstate this path + */ +- if (!disable_reinstate && reinstate_path(pp)) { +- condlog(3, "%s: reload map", pp->dev); +- ev_add_path(pp, vecs, 1); +- pp->tick = 1; +- return 0; +- } ++ if (!disable_reinstate) ++ reinstate_path(pp); + new_path_up = 1; + + if (oldchkrstate != PATH_UP && oldchkrstate != PATH_GHOST) +@@ -2204,15 +2203,10 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) + else if (newstate == PATH_UP || newstate == PATH_GHOST) { + if ((pp->dmstate == PSTATE_FAILED || + pp->dmstate == PSTATE_UNDEF) && +- !disable_reinstate) { ++ !disable_reinstate) + /* Clear IO errors */ +- if (reinstate_path(pp)) { +- condlog(3, "%s: reload map", pp->dev); +- ev_add_path(pp, vecs, 1); +- pp->tick = 1; +- return 0; +- } +- } else { ++ reinstate_path(pp); ++ else { + LOG_MSG(4, verbosity, pp); + if (pp->checkint != max_checkint) { + /* +-- +2.17.2 + diff --git a/0043-libmultipath-make-dm_flush_maps-only-return-0-on-suc.patch b/0043-libmultipath-make-dm_flush_maps-only-return-0-on-suc.patch new file mode 100644 index 0000000..4dce980 --- /dev/null +++ b/0043-libmultipath-make-dm_flush_maps-only-return-0-on-suc.patch @@ -0,0 +1,46 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 2 Jul 2020 19:07:02 -0500 +Subject: [PATCH] libmultipath: make dm_flush_maps only return 0 on success + +dm_flush_maps() returned both 0 and 1 on error, depending on which part +of the function it was in, but the caller was always treating 0 as a +success. Make dm_flush_maps() always return 1 on error and 0 on success. + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/devmapper.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index 24cc616a..4c86b6d4 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -1007,13 +1007,13 @@ dm_flush_map_nopaths(const char * mapname, int deferred_remove) + + int dm_flush_maps (int retries) + { +- int r = 0; ++ int r = 1; + struct dm_task *dmt; + struct dm_names *names; + unsigned next = 0; + + if (!(dmt = libmp_dm_task_create (DM_DEVICE_LIST))) +- return 0; ++ return r; + + dm_task_no_open_count(dmt); + +@@ -1026,6 +1026,7 @@ int dm_flush_maps (int retries) + if (!names->dev) + goto out; + ++ r = 0; + do { + r |= dm_suspend_and_flush_map(names->name, retries); + next = names->next; +-- +2.17.2 + diff --git a/0044-multipathd-add-del-maps-multipathd-command.patch b/0044-multipathd-add-del-maps-multipathd-command.patch new file mode 100644 index 0000000..9f32eb2 --- /dev/null +++ b/0044-multipathd-add-del-maps-multipathd-command.patch @@ -0,0 +1,161 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 2 Jul 2020 19:07:03 -0500 +Subject: [PATCH] multipathd: add "del maps" multipathd command + +This will flush all multipath devices. + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/devmapper.c | 7 +++++-- + libmultipath/devmapper.h | 2 +- + multipath/main.c | 2 +- + multipathd/cli.c | 1 + + multipathd/cli_handlers.c | 19 +++++++++++++++++++ + multipathd/cli_handlers.h | 1 + + multipathd/main.c | 3 ++- + multipathd/main.h | 1 + + 8 files changed, 31 insertions(+), 5 deletions(-) + +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index 4c86b6d4..f597ff8b 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -1005,7 +1005,7 @@ dm_flush_map_nopaths(const char * mapname, int deferred_remove) + + #endif + +-int dm_flush_maps (int retries) ++int dm_flush_maps (int need_suspend, int retries) + { + int r = 1; + struct dm_task *dmt; +@@ -1028,7 +1028,10 @@ int dm_flush_maps (int retries) + + r = 0; + do { +- r |= dm_suspend_and_flush_map(names->name, retries); ++ if (need_suspend) ++ r |= dm_suspend_and_flush_map(names->name, retries); ++ else ++ r |= dm_flush_map(names->name); + next = names->next; + names = (void *) names + next; + } while (next); +diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h +index b2108638..6dd178c8 100644 +--- a/libmultipath/devmapper.h ++++ b/libmultipath/devmapper.h +@@ -57,7 +57,7 @@ int dm_flush_map_nopaths(const char * mapname, int deferred_remove); + #define dm_suspend_and_flush_map(mapname, retries) \ + _dm_flush_map(mapname, 1, 0, 1, retries) + int dm_cancel_deferred_remove(struct multipath *mpp); +-int dm_flush_maps (int retries); ++int dm_flush_maps (int need_suspend, int retries); + int dm_fail_path(const char * mapname, char * path); + int dm_reinstate_path(const char * mapname, char * path); + int dm_queue_if_no_path(const char *mapname, int enable); +diff --git a/multipath/main.c b/multipath/main.c +index c4740fab..d89f0a91 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -1096,7 +1096,7 @@ main (int argc, char *argv[]) + goto out; + } + else if (conf->remove == FLUSH_ALL) { +- r = dm_flush_maps(retries) ? RTVL_FAIL : RTVL_OK; ++ r = dm_flush_maps(1, retries) ? RTVL_FAIL : RTVL_OK; + goto out; + } + while ((r = configure(conf, cmd, dev_type, dev)) == RTVL_RETRY) +diff --git a/multipathd/cli.c b/multipathd/cli.c +index 800c0fbe..bdc9fb10 100644 +--- a/multipathd/cli.c ++++ b/multipathd/cli.c +@@ -568,6 +568,7 @@ cli_init (void) { + add_handler(DEL+PATH, NULL); + add_handler(ADD+MAP, NULL); + add_handler(DEL+MAP, NULL); ++ add_handler(DEL+MAPS, NULL); + add_handler(SWITCH+MAP+GROUP, NULL); + add_handler(RECONFIGURE, NULL); + add_handler(SUSPEND+MAP, NULL); +diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c +index 31c3d9fd..782bb003 100644 +--- a/multipathd/cli_handlers.c ++++ b/multipathd/cli_handlers.c +@@ -852,6 +852,25 @@ cli_del_map (void * v, char ** reply, int * len, void * data) + return rc; + } + ++int ++cli_del_maps (void *v, char **reply, int *len, void *data) ++{ ++ struct vectors * vecs = (struct vectors *)data; ++ struct multipath *mpp; ++ int i, ret = 0; ++ ++ condlog(2, "remove maps (operator)"); ++ vector_foreach_slot(vecs->mpvec, mpp, i) { ++ if (flush_map(mpp, vecs, 0)) ++ ret++; ++ else ++ i--; ++ } ++ /* flush any multipath maps that aren't currently known by multipathd */ ++ ret |= dm_flush_maps(0, 0); ++ return ret; ++} ++ + int + cli_reload(void *v, char **reply, int *len, void *data) + { +diff --git a/multipathd/cli_handlers.h b/multipathd/cli_handlers.h +index 0f451064..6f57b429 100644 +--- a/multipathd/cli_handlers.h ++++ b/multipathd/cli_handlers.h +@@ -26,6 +26,7 @@ int cli_add_path (void * v, char ** reply, int * len, void * data); + int cli_del_path (void * v, char ** reply, int * len, void * data); + int cli_add_map (void * v, char ** reply, int * len, void * data); + int cli_del_map (void * v, char ** reply, int * len, void * data); ++int cli_del_maps (void * v, char ** reply, int * len, void * data); + int cli_switch_group(void * v, char ** reply, int * len, void * data); + int cli_reconfigure(void * v, char ** reply, int * len, void * data); + int cli_resize(void * v, char ** reply, int * len, void * data); +diff --git a/multipathd/main.c b/multipathd/main.c +index daf19a4e..f014d2a1 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -635,7 +635,7 @@ sync_maps_state(vector mpvec) + sync_map_state(mpp); + } + +-static int ++int + flush_map(struct multipath * mpp, struct vectors * vecs, int nopaths) + { + int r; +@@ -1555,6 +1555,7 @@ uxlsnrloop (void * ap) + set_handler_callback(DEL+PATH, cli_del_path); + set_handler_callback(ADD+MAP, cli_add_map); + set_handler_callback(DEL+MAP, cli_del_map); ++ set_handler_callback(DEL+MAPS, cli_del_maps); + set_handler_callback(SWITCH+MAP+GROUP, cli_switch_group); + set_unlocked_handler_callback(RECONFIGURE, cli_reconfigure); + set_handler_callback(SUSPEND+MAP, cli_suspend); +diff --git a/multipathd/main.h b/multipathd/main.h +index 7bb8463f..5dff17e5 100644 +--- a/multipathd/main.h ++++ b/multipathd/main.h +@@ -28,6 +28,7 @@ int ev_add_path (struct path *, struct vectors *, int); + int ev_remove_path (struct path *, struct vectors *, int); + int ev_add_map (char *, const char *, struct vectors *); + int ev_remove_map (char *, char *, int, struct vectors *); ++int flush_map(struct multipath *, struct vectors *, int); + int set_config_state(enum daemon_status); + void * mpath_alloc_prin_response(int prin_sa); + int prin_do_scsi_ioctl(char *, int rq_servact, struct prin_resp * resp, +-- +2.17.2 + diff --git a/0045-multipath-make-flushing-maps-work-like-other-command.patch b/0045-multipath-make-flushing-maps-work-like-other-command.patch new file mode 100644 index 0000000..b7450ee --- /dev/null +++ b/0045-multipath-make-flushing-maps-work-like-other-command.patch @@ -0,0 +1,104 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 2 Jul 2020 19:07:04 -0500 +Subject: [PATCH] multipath: make flushing maps work like other commands + +The config structure doesn't need a special variable just for removes. +Multipath can just use the cmd variable, like it does for the other +commands. + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/config.h | 3 ++- + libmultipath/configure.h | 3 --- + multipath/main.c | 20 ++++++++++---------- + 3 files changed, 12 insertions(+), 14 deletions(-) + +diff --git a/libmultipath/config.h b/libmultipath/config.h +index ceecff2d..55569360 100644 +--- a/libmultipath/config.h ++++ b/libmultipath/config.h +@@ -38,6 +38,8 @@ enum mpath_cmds { + CMD_ADD_WWID, + CMD_USABLE_PATHS, + CMD_DUMP_CONFIG, ++ CMD_FLUSH_ONE, ++ CMD_FLUSH_ALL, + }; + + enum force_reload_types { +@@ -142,7 +144,6 @@ struct config { + unsigned int max_checkint; + bool use_watchdog; + int pgfailback; +- int remove; + int rr_weight; + int no_path_retry; + int user_friendly_names; +diff --git a/libmultipath/configure.h b/libmultipath/configure.h +index d7509000..0e33bf40 100644 +--- a/libmultipath/configure.h ++++ b/libmultipath/configure.h +@@ -45,9 +45,6 @@ enum { + CP_RETRY, + }; + +-#define FLUSH_ONE 1 +-#define FLUSH_ALL 2 +- + struct vectors; + + int setup_map (struct multipath * mpp, char * params, int params_size, +diff --git a/multipath/main.c b/multipath/main.c +index d89f0a91..101fd656 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -909,10 +909,10 @@ main (int argc, char *argv[]) + cmd = CMD_DRY_RUN; + break; + case 'f': +- conf->remove = FLUSH_ONE; ++ cmd = CMD_FLUSH_ONE; + break; + case 'F': +- conf->remove = FLUSH_ALL; ++ cmd = CMD_FLUSH_ALL; + break; + case 'l': + if (optarg && !strncmp(optarg, "l", 1)) +@@ -1053,6 +1053,10 @@ main (int argc, char *argv[]) + condlog(0, "the -w option requires a device"); + goto out; + } ++ if (cmd == CMD_FLUSH_ONE && dev_type != DEV_DEVMAP) { ++ condlog(0, "the -f option requires a map name to remove"); ++ goto out; ++ } + + switch(delegate_to_multipathd(cmd, dev, dev_type, conf)) { + case DELEGATE_OK: +@@ -1086,16 +1090,12 @@ main (int argc, char *argv[]) + } + if (retries < 0) + retries = conf->remove_retries; +- if (conf->remove == FLUSH_ONE) { +- if (dev_type == DEV_DEVMAP) { +- r = dm_suspend_and_flush_map(dev, retries) ? +- RTVL_FAIL : RTVL_OK; +- } else +- condlog(0, "must provide a map name to remove"); +- ++ if (cmd == CMD_FLUSH_ONE) { ++ r = dm_suspend_and_flush_map(dev, retries) ? ++ RTVL_FAIL : RTVL_OK; + goto out; + } +- else if (conf->remove == FLUSH_ALL) { ++ else if (cmd == CMD_FLUSH_ALL) { + r = dm_flush_maps(1, retries) ? RTVL_FAIL : RTVL_OK; + goto out; + } +-- +2.17.2 + diff --git a/0046-multipath-delegate-flushing-maps-to-multipathd.patch b/0046-multipath-delegate-flushing-maps-to-multipathd.patch new file mode 100644 index 0000000..1a4a771 --- /dev/null +++ b/0046-multipath-delegate-flushing-maps-to-multipathd.patch @@ -0,0 +1,64 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 2 Jul 2020 19:07:05 -0500 +Subject: [PATCH] multipath: delegate flushing maps to multipathd + +Since there can be problems with removing maps outside of multipathd, +multipath should attempt to delegate this command to multipathd. +However, multipathd doesn't attempt to suspend the device, in order +to avoid potential hangs. If delegating to multipathd fails, multipath +should try the remove itself. + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + multipath/main.c | 14 ++++++++++++++ + multipath/multipath.8 | 4 ++-- + 2 files changed, 16 insertions(+), 2 deletions(-) + +diff --git a/multipath/main.c b/multipath/main.c +index 101fd656..6a24e483 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -820,6 +820,20 @@ int delegate_to_multipathd(enum mpath_cmds cmd, + if (cmd == CMD_CREATE && conf->force_reload == FORCE_RELOAD_YES) { + p += snprintf(p, n, "reconfigure"); + } ++ else if (cmd == CMD_FLUSH_ONE && dev && dev_type == DEV_DEVMAP) { ++ p += snprintf(p, n, "del map %s", dev); ++ /* multipathd doesn't try as hard, to avoid potentially ++ * hanging. If it fails, retry with the regular multipath ++ * command */ ++ r = NOT_DELEGATED; ++ } ++ else if (cmd == CMD_FLUSH_ALL) { ++ p += snprintf(p, n, "del maps"); ++ /* multipathd doesn't try as hard, to avoid potentially ++ * hanging. If it fails, retry with the regular multipath ++ * command */ ++ r = NOT_DELEGATED; ++ } + /* Add other translations here */ + + if (strlen(command) == 0) +diff --git a/multipath/multipath.8 b/multipath/multipath.8 +index 6fb8645a..5b29a5d9 100644 +--- a/multipath/multipath.8 ++++ b/multipath/multipath.8 +@@ -125,11 +125,11 @@ the system. + Other operation modes are chosen by using one of the following command line switches: + .TP + .B \-f +-Flush (remove) a multipath device map specified as parameter, if unused. ++Flush (remove) a multipath device map specified as parameter, if unused. This operation is delegated to the multipathd daemon if it's running. + . + .TP + .B \-F +-Flush (remove) all unused multipath device maps. ++Flush (remove) all unused multipath device maps. This operation is delegated to the multipathd daemon if it's running. + . + .TP + .B \-l +-- +2.17.2 + diff --git a/0047-multipath-add-option-to-skip-multipathd-delegation.patch b/0047-multipath-add-option-to-skip-multipathd-delegation.patch new file mode 100644 index 0000000..51284aa --- /dev/null +++ b/0047-multipath-add-option-to-skip-multipathd-delegation.patch @@ -0,0 +1,63 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 2 Jul 2020 19:07:06 -0500 +Subject: [PATCH] multipath: add option to skip multipathd delegation + +Add the -D option to allow users to skip delegating commands to +multipathd. + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/config.h | 1 + + multipath/main.c | 8 +++++++- + 2 files changed, 8 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/config.h b/libmultipath/config.h +index 55569360..92c61a0d 100644 +--- a/libmultipath/config.h ++++ b/libmultipath/config.h +@@ -190,6 +190,7 @@ struct config { + int ghost_delay; + int find_multipaths_timeout; + int marginal_pathgroups; ++ int skip_delegate; + unsigned int version[3]; + unsigned int sequence_nr; + +diff --git a/multipath/main.c b/multipath/main.c +index 6a24e483..4c43314e 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -817,6 +817,9 @@ int delegate_to_multipathd(enum mpath_cmds cmd, + *p = '\0'; + n = sizeof(command); + ++ if (conf->skip_delegate) ++ return NOT_DELEGATED; ++ + if (cmd == CMD_CREATE && conf->force_reload == FORCE_RELOAD_YES) { + p += snprintf(p, n, "reconfigure"); + } +@@ -890,7 +893,7 @@ main (int argc, char *argv[]) + multipath_conf = conf; + conf->retrigger_tries = 0; + conf->force_sync = 1; +- while ((arg = getopt(argc, argv, ":adcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { ++ while ((arg = getopt(argc, argv, ":adDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { + switch(arg) { + case 1: printf("optarg : %s\n",optarg); + break; +@@ -922,6 +925,9 @@ main (int argc, char *argv[]) + if (cmd == CMD_CREATE) + cmd = CMD_DRY_RUN; + break; ++ case 'D': ++ conf->skip_delegate = 1; ++ break; + case 'f': + cmd = CMD_FLUSH_ONE; + break; +-- +2.17.2 + diff --git a/0048-Makefile.inc-trim-extra-information-from-systemd-ver.patch b/0048-Makefile.inc-trim-extra-information-from-systemd-ver.patch new file mode 100644 index 0000000..5c3f614 --- /dev/null +++ b/0048-Makefile.inc-trim-extra-information-from-systemd-ver.patch @@ -0,0 +1,30 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 6 Jul 2020 13:21:12 -0500 +Subject: [PATCH] Makefile.inc: trim extra information from systemd version + +Some systemd versions print extra information in the +"pkg-config --modversion" output, which confuses make. Trim this +off. + +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile.inc b/Makefile.inc +index e7256e3a..8ea3352d 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -37,7 +37,7 @@ endif + + ifndef SYSTEMD + ifeq ($(shell pkg-config --modversion libsystemd >/dev/null 2>&1 && echo 1), 1) +- SYSTEMD = $(shell pkg-config --modversion libsystemd) ++ SYSTEMD = $(shell pkg-config --modversion libsystemd | awk '{print $$1}') + else + ifeq ($(shell systemctl --version >/dev/null 2>&1 && echo 1), 1) + SYSTEMD = $(shell systemctl --version 2> /dev/null | \ +-- +2.17.2 + diff --git a/0049-kpartx-fix-Wsign-compare-error.patch b/0049-kpartx-fix-Wsign-compare-error.patch new file mode 100644 index 0000000..ffaa477 --- /dev/null +++ b/0049-kpartx-fix-Wsign-compare-error.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 6 Jul 2020 17:28:46 -0500 +Subject: [PATCH] kpartx: fix -Wsign-compare error + +Signed-off-by: Benjamin Marzinski +--- + kpartx/kpartx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kpartx/kpartx.c b/kpartx/kpartx.c +index c24ad6d9..653ce0c8 100644 +--- a/kpartx/kpartx.c ++++ b/kpartx/kpartx.c +@@ -738,7 +738,7 @@ struct block { + /* blknr is always in 512 byte blocks */ + char * + getblock (int fd, unsigned int blknr) { +- unsigned int secsz = get_sector_size(fd); ++ int secsz = get_sector_size(fd); + unsigned int blks_per_sec = secsz / 512; + unsigned int secnr = blknr / blks_per_sec; + unsigned int blk_off = (blknr % blks_per_sec) * 512; +-- +2.17.2 + diff --git a/0013-RH-fixup-udev-rules-for-redhat.patch b/0050-RH-fixup-udev-rules-for-redhat.patch similarity index 95% rename from 0013-RH-fixup-udev-rules-for-redhat.patch rename to 0050-RH-fixup-udev-rules-for-redhat.patch index 1a8e108..b1f5beb 100644 --- a/0013-RH-fixup-udev-rules-for-redhat.patch +++ b/0050-RH-fixup-udev-rules-for-redhat.patch @@ -15,7 +15,7 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 9060ac9b..034752d9 100644 +index 8ea3352d..873fb62f 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -53,7 +53,7 @@ endif @@ -28,10 +28,10 @@ index 9060ac9b..034752d9 100644 udevrulesdir = $(libudevdir)/rules.d multipathdir = $(TOPDIR)/libmultipath diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules -index 8f990494..8a3a1718 100644 +index d7527d7d..0e0d70d5 100644 --- a/kpartx/kpartx.rules +++ b/kpartx/kpartx.rules -@@ -32,6 +32,6 @@ LABEL="mpath_kpartx_end" +@@ -36,6 +36,6 @@ LABEL="mpath_kpartx_end" GOTO="kpartx_end" LABEL="run_kpartx" diff --git a/0014-RH-Remove-the-property-blacklist-exception-builtin.patch b/0051-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 89% rename from 0014-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0051-RH-Remove-the-property-blacklist-exception-builtin.patch index 10cc1b3..f760f87 100644 --- a/0014-RH-Remove-the-property-blacklist-exception-builtin.patch +++ b/0051-RH-Remove-the-property-blacklist-exception-builtin.patch @@ -19,10 +19,10 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c -index 00e8dbdb..d9691b17 100644 +index db58ccca..0c58aa32 100644 --- a/libmultipath/blacklist.c +++ b/libmultipath/blacklist.c -@@ -204,12 +204,6 @@ setup_default_blist (struct config * conf) +@@ -187,12 +187,6 @@ setup_default_blist (struct config * conf) if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT)) return 1; @@ -35,7 +35,7 @@ index 00e8dbdb..d9691b17 100644 vector_foreach_slot (conf->hwtable, hwe, i) { if (hwe->bl_product) { if (find_blacklist_device(conf->blist_device, -@@ -411,7 +405,8 @@ filter_property(struct config *conf, struct udev_device *udev, int lvl, +@@ -394,7 +388,8 @@ filter_property(struct config *conf, struct udev_device *udev, int lvl, *uid_attribute != '\0'; bool uid_attr_seen = false; @@ -46,10 +46,10 @@ index 00e8dbdb..d9691b17 100644 udev_device_get_properties_list_entry(udev)) { diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 05a5e8ff..3455b1cc 100644 +index 5adaced6..42a192f6 100644 --- a/multipath/multipath.conf.5 +++ b/multipath/multipath.conf.5 -@@ -1286,9 +1286,14 @@ keywords. Both are regular expressions. For a full description of these keywords +@@ -1296,9 +1296,14 @@ keywords. Both are regular expressions. For a full description of these keywords Regular expression for an udev property. All devices that have matching udev properties will be excluded/included. The handling of the \fIproperty\fR keyword is special, @@ -65,7 +65,7 @@ index 05a5e8ff..3455b1cc 100644 . .RS .PP -@@ -1299,10 +1304,6 @@ Blacklisting by missing properties is only applied to devices which do have the +@@ -1309,10 +1314,6 @@ Blacklisting by missing properties is only applied to devices which do have the property specified by \fIuid_attribute\fR (e.g. \fIID_SERIAL\fR) set. Previously, it was applied to every device, possibly causing devices to be blacklisted because of temporary I/O error conditions. @@ -77,10 +77,10 @@ index 05a5e8ff..3455b1cc 100644 .TP .B protocol diff --git a/tests/blacklist.c b/tests/blacklist.c -index 6e7c1864..cc8a9a4a 100644 +index d5c40898..d20e97af 100644 --- a/tests/blacklist.c +++ b/tests/blacklist.c -@@ -271,7 +271,7 @@ static void test_property_missing(void **state) +@@ -380,7 +380,7 @@ static void test_property_missing(void **state) conf.blist_property = blist_property_wwn; expect_condlog(3, "sdb: blacklisted, udev property missing\n"); assert_int_equal(filter_property(&conf, &udev, 3, "ID_SERIAL"), @@ -89,7 +89,7 @@ index 6e7c1864..cc8a9a4a 100644 assert_int_equal(filter_property(&conf, &udev, 3, "ID_BLAH"), MATCH_NOTHING); assert_int_equal(filter_property(&conf, &udev, 3, ""), -@@ -363,9 +363,7 @@ static void test_filter_path_missing1(void **state) +@@ -472,9 +472,7 @@ static void test_filter_path_missing1(void **state) conf.blist_device = blist_device_foo_bar; conf.blist_protocol = blist_protocol_fcp; conf.blist_wwid = blist_wwid_xyzzy; diff --git a/0015-RH-don-t-start-without-a-config-file.patch b/0052-RH-don-t-start-without-a-config-file.patch similarity index 98% rename from 0015-RH-don-t-start-without-a-config-file.patch rename to 0052-RH-don-t-start-without-a-config-file.patch index 86cdf68..4712300 100644 --- a/0015-RH-don-t-start-without-a-config-file.patch +++ b/0052-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 b4d87689..b36778b0 100644 +index 658bec8b..1c02e230 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c @@ -26,6 +26,7 @@ @@ -53,7 +53,7 @@ index b4d87689..b36778b0 100644 conf->processed_main_config = 1; diff --git a/libmultipath/config.h b/libmultipath/config.h -index ceecff2d..3368d8c9 100644 +index 92c61a0d..160867cd 100644 --- a/libmultipath/config.h +++ b/libmultipath/config.h @@ -9,6 +9,7 @@ diff --git a/0016-RH-use-rpm-optflags-if-present.patch b/0053-RH-use-rpm-optflags-if-present.patch similarity index 55% rename from 0016-RH-use-rpm-optflags-if-present.patch rename to 0053-RH-use-rpm-optflags-if-present.patch index be1af2e..d6c97c1 100644 --- a/0016-RH-use-rpm-optflags-if-present.patch +++ b/0053-RH-use-rpm-optflags-if-present.patch @@ -9,26 +9,28 @@ still being generic. Signed-off-by: Benjamin Marzinski --- - Makefile.inc | 29 +++++++++++++++++++++-------- - 1 file changed, 21 insertions(+), 8 deletions(-) + Makefile.inc | 24 ++++++++++++++++++------ + 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 034752d9..c2abd301 100644 +index 873fb62f..479523bc 100644 --- a/Makefile.inc +++ b/Makefile.inc -@@ -89,16 +89,29 @@ TEST_CC_OPTION = $(shell \ +@@ -89,15 +89,27 @@ TEST_CC_OPTION = $(shell \ echo "$(2)"; \ fi) -STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector) ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers,) WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered -Wno-error=clobbered,) + +-OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 +-WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 -Werror=implicit-int \ +ifndef RPM_OPT_FLAGS + STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector) -+ OPTFLAGS = -O2 -g -pipe -Wall -Werror=format-security \ -+ -Wp,-D_FORTIFY_SOURCE=2 -fexceptions \ -+ $(STACKPROT) -grecord-gcc-switches \ -+ -fasynchronous-unwind-tables ++ OPTFLAGS := -O2 -g -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions \ ++ $(STACKPROT) -grecord-gcc-switches \ ++ -fasynchronous-unwind-tables --param=ssp-buffer-size=4 + ifeq ($(shell test -f /usr/lib/rpm/redhat/redhat-hardened-cc1 && echo 1),1) + OPTFLAGS += -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 + endif @@ -36,24 +38,18 @@ index 034752d9..c2abd301 100644 + OPTFLAGS += -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 + endif +else -+ OPTFLAGS = $(RPM_OPT_FLAGS) ++ OPTFLAGS := $(RPM_OPT_FLAGS) --param=ssp-buffer-size=4 +endif -+OPTFLAGS += -Werror -Wextra -Wstrict-prototypes -Wformat=2 \ -+ -Werror=implicit-int -Werror=implicit-function-declaration \ -+ $(WNOCLOBBERED) \ -+ -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) \ -+ --param=ssp-buffer-size=4 - --OPTFLAGS = -O2 -g -pipe -Werror -Wall -Wextra -Wformat=2 -Werror=implicit-int \ -- -Werror=implicit-function-declaration -Werror=format-security \ -- $(WNOCLOBBERED) \ -- -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) \ -- $(STACKPROT) --param=ssp-buffer-size=4 ++WARNFLAGS := -Werror -Wextra -Wformat=2 -Werror=implicit-int \ + -Werror=implicit-function-declaration -Werror=format-security \ +- $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) -CPPFLAGS := -Wp,-D_FORTIFY_SOURCE=2 - CFLAGS := $(OPTFLAGS) -DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" \ - -MMD -MP $(CFLAGS) - BIN_CFLAGS = -fPIE -DPIE -@@ -135,4 +148,4 @@ check_file = $(shell \ ++ $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) \ ++ -Wstrict-prototypes + CFLAGS := $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ + -DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" \ + -MMD -MP +@@ -135,4 +147,4 @@ check_file = $(shell \ %.o: %.c @echo building $@ because of $? diff --git a/0017-RH-add-mpathconf.patch b/0054-RH-add-mpathconf.patch similarity index 94% rename from 0017-RH-add-mpathconf.patch rename to 0054-RH-add-mpathconf.patch index 009a033..6480711 100644 --- a/0017-RH-add-mpathconf.patch +++ b/0054-RH-add-mpathconf.patch @@ -14,14 +14,14 @@ Signed-off-by: Benjamin Marzinski --- libmultipath/config.c | 2 + multipath/Makefile | 5 + - multipath/mpathconf | 555 ++++++++++++++++++++++++++++++++++++++++++ + multipath/mpathconf | 565 ++++++++++++++++++++++++++++++++++++++++++ multipath/mpathconf.8 | 135 ++++++++++ - 4 files changed, 697 insertions(+) + 4 files changed, 707 insertions(+) create mode 100644 multipath/mpathconf create mode 100644 multipath/mpathconf.8 diff --git a/libmultipath/config.c b/libmultipath/config.c -index b36778b0..26f8e050 100644 +index 1c02e230..a253a936 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c @@ -781,6 +781,8 @@ load_config (char * file) @@ -69,10 +69,10 @@ index b9bbb3cf..e720c7f6 100644 $(RM) core *.o $(EXEC) *.gz diff --git a/multipath/mpathconf b/multipath/mpathconf new file mode 100644 -index 00000000..f34003c9 +index 00000000..f0d09cbb --- /dev/null +++ b/multipath/mpathconf -@@ -0,0 +1,555 @@ +@@ -0,0 +1,565 @@ +#!/bin/bash +# +# Copyright (C) 2010 Red Hat, Inc. All rights reserved. @@ -107,11 +107,6 @@ index 00000000..f34003c9 +defaults { + user_friendly_names yes + find_multipaths yes -+ enable_foreign \"^$\" -+} -+ -+blacklist_exceptions { -+ property \"(SCSI_IDENT_|ID_WWN)\" +}" + +CONFIGFILE="/etc/multipath.conf" @@ -130,7 +125,7 @@ index 00000000..f34003c9 + echo "Only allow certain wwids (instead of enable): --allow " + echo "Set user_friendly_names (Default y): --user_friendly_names " + echo "Set find_multipaths (Default y): --find_multipaths " -+ echo "Set default property blacklist (Default y): --property_blacklist " ++ echo "Set default property blacklist (Default n): --property_blacklist " + echo "Set enable_foreign to show foreign devices (Default n): --enable_foreign " + echo "Load the dm-multipath modules on enable (Default y): --with_module " + echo "start/stop/reload multipathd (Default n): --with_multipathd " @@ -288,12 +283,13 @@ index 00000000..f34003c9 + +function validate_args +{ -+ if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$PROPERTY" -o -n "$MODULE" ]; then ++ if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$PROPERTY" -o -n "$MODULE" -o -n "$FOREIGN" ]; then + echo "ignoring extra parameters on disable" + FRIENDLY="" + FIND="" + PROPERTY="" + MODULE="" ++ FOREIGN="" + fi + if [ -n "$FRIENDLY" ] && [ "$FRIENDLY" != "y" -a "$FRIENDLY" != "n" ]; then + echo "--user_friendly_names must be either 'y' or 'n'" @@ -311,7 +307,7 @@ index 00000000..f34003c9 + echo "--enable_foreign must be either 'y' or 'n'" + exit 1 + fi -+ if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" -a -z "$PROPERTY" ]; then ++ if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" -a -z "$PROPERTY" -a -z "$FOREIGN" ]; then + SHOW_STATUS=1 + fi + if [ -n "$MODULE" ] && [ "$MODULE" != "y" -a "$MODULE" != "n" ]; then @@ -416,8 +412,12 @@ index 00000000..f34003c9 + HAVE_FOREIGN=0 + elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]]*\"\^\$\"" ; then + HAVE_FOREIGN=1 -+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign" ; then ++ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]]*\"NONE\"" ; then ++ HAVE_FOREIGN=1 ++ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]] \"\.\?\*\"" ; then + HAVE_FOREIGN=2 ++ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign" ; then ++ HAVE_FOREIGN=3 + fi +fi + @@ -451,9 +451,11 @@ index 00000000..f34003c9 + echo "default property blacklist is enabled" + fi + if [ -z "$HAVE_FOREIGN" -o "$HAVE_FOREIGN" = 0 ]; then -+ echo "enable_foreign is not set (all foreign multipath devices will be shown)" ++ echo "enable_foreign is not set (no foreign multipath devices will be shown)" + elif [ "$HAVE_FOREIGN" = 1 ]; then + echo "enable_foreign is set (no foreign multipath devices will be shown)" ++ elif [ "$HAVE_FOREIGN" = 2 ]; then ++ echo "enable_foreign is set (all foreign multipath devices will be shown)" + else + echo "enable_foreign is set (foreign multipath devices may not be shown)" + fi @@ -570,7 +572,15 @@ index 00000000..f34003c9 + CHANGED_CONFIG=1 + fi +elif [ "$PROPERTY" = "y" ]; then -+ if [ -z "$HAVE_PROPERTY" ]; then ++ if [ -z "$HAVE_PROPERTY" -a -z "$HAVE_EXCEPTIONS" ]; then ++ cat >> $TMPFILE << _EOF_ ++ ++blacklist_exceptions { ++ property "(SCSI_IDENT_|ID_WWN)" ++} ++_EOF_ ++ CHANGED_CONFIG=1 ++ elif [ -z "$HAVE_PROPERTY" ]; then + sed -i '/^blacklist_exceptions[[:space:]]*{/ a\ + property "(SCSI_IDENT_|ID_WWN)" +' $TMPFILE @@ -582,18 +592,18 @@ index 00000000..f34003c9 +fi + +if [ "$FOREIGN" = "y" ]; then -+ if [ "$HAVE_FOREIGN" = 1 -o "$HAVE_FOREIGN" = 2 ]; then -+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*enable_foreign/# enable_foreign/' $TMPFILE ++ if [ -z "$HAVE_FOREIGN" ]; then ++ sed -i '/^defaults[[:space:]]*{/ a\ ++ enable_foreign ".*" ++' $TMPFILE ++ CHANGED_CONFIG=1 ++ elif [ "$HAVE_FOREIGN" = 0 -o "$HAVE_FOREIGN" = 1 -o "$HAVE_FOREIGN" = 3 ]; then ++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*#\?[[:space:]]*enable_foreign.*$/ enable_foreign ".*"/' $TMPFILE + CHANGED_CONFIG=1 + fi +elif [ "$FOREIGN" = "n" ]; then -+ if [ -z "$HAVE_FOREIGN" ]; then -+ sed -i '/^defaults[[:space:]]*{/ a\ -+ enable_foreign "^$" -+' $TMPFILE -+ CHANGED_CONFIG=1 -+ elif [ "$HAVE_FOREIGN" = 0 -o "$HAVE_FOREIGN" = 2 ]; then -+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*#\?[[:space:]]*enable_foreign.*$/ enable_foreign "^$"/' $TMPFILE ++ if [ "$HAVE_FOREIGN" = 2 -o "$HAVE_FOREIGN" = 3 ]; then ++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*enable_foreign/# enable_foreign/' $TMPFILE + CHANGED_CONFIG=1 + fi +fi diff --git a/0018-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0055-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 88% rename from 0018-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0055-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch index fb0d281..a10f147 100644 --- a/0018-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +++ b/0055-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch @@ -22,13 +22,13 @@ Signed-off-by: Benjamin Marzinski 5 files changed, 60 insertions(+), 3 deletions(-) diff --git a/libmultipath/wwids.c b/libmultipath/wwids.c -index 28a2150d..fab6fc8f 100644 +index 61d9c39e..c7a16636 100644 --- a/libmultipath/wwids.c +++ b/libmultipath/wwids.c -@@ -454,3 +454,47 @@ int op ## _wwid(const char *wwid) \ - declare_failed_wwid_op(is_failed, false) - declare_failed_wwid_op(mark_failed, true) - declare_failed_wwid_op(unmark_failed, true) +@@ -451,3 +451,47 @@ int unmark_failed_wwid(const char *wwid) + print_failed_wwid_result("unmark_failed", wwid, r); + return r; + } + +int remember_cmdline_wwid(void) +{ @@ -86,10 +86,10 @@ index 0c6ee54d..e32a0b0e 100644 enum { WWID_IS_NOT_FAILED = 0, diff --git a/multipath/main.c b/multipath/main.c -index cf9d2a28..78822ee1 100644 +index 4c43314e..c73f6963 100644 --- a/multipath/main.c +++ b/multipath/main.c -@@ -138,7 +138,7 @@ usage (char * progname) +@@ -135,7 +135,7 @@ usage (char * progname) fprintf (stderr, " %s [-v level] [-R retries] -F\n", progname); fprintf (stderr, " %s [-v level] [-l|-ll] [device]\n", progname); fprintf (stderr, " %s [-v level] [-a|-w] device\n", progname); @@ -98,7 +98,7 @@ index cf9d2a28..78822ee1 100644 fprintf (stderr, " %s [-v level] [-i] [-c|-C] device\n", progname); fprintf (stderr, " %s [-v level] [-i] [-u|-U]\n", progname); fprintf (stderr, " %s [-h|-t|-T]\n", progname); -@@ -151,6 +151,8 @@ usage (char * progname) +@@ -149,6 +149,8 @@ usage (char * progname) " -f flush a multipath device map\n" " -F flush all multipath device maps\n" " -a add a device wwid to the wwids file\n" @@ -107,16 +107,16 @@ index cf9d2a28..78822ee1 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[]) +@@ -893,7 +895,7 @@ main (int argc, char *argv[]) multipath_conf = conf; conf->retrigger_tries = 0; conf->force_sync = 1; -- while ((arg = getopt(argc, argv, ":adcChl::FfM:v:p:b:BrR:itTquUwW")) != EOF ) { -+ while ((arg = getopt(argc, argv, ":aAdcChl::FfM:v:p:b:BrR:itTquUwW")) != EOF ) { +- while ((arg = getopt(argc, argv, ":adDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { ++ while ((arg = getopt(argc, argv, ":aAdDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { switch(arg) { case 1: printf("optarg : %s\n",optarg); break; -@@ -977,6 +979,10 @@ main (int argc, char *argv[]) +@@ -970,6 +972,10 @@ main (int argc, char *argv[]) case 'T': cmd = CMD_DUMP_CONFIG; break; @@ -128,7 +128,7 @@ index cf9d2a28..78822ee1 100644 usage(argv[0]); exit(RTVL_OK); diff --git a/multipath/multipath.8 b/multipath/multipath.8 -index 9cdd05a3..8befc45a 100644 +index 5b29a5d9..0478f4e7 100644 --- a/multipath/multipath.8 +++ b/multipath/multipath.8 @@ -63,7 +63,7 @@ multipath \- Device mapper target autoconfig. diff --git a/0019-RH-warn-on-invalid-regex-instead-of-failing.patch b/0056-RH-warn-on-invalid-regex-instead-of-failing.patch similarity index 98% rename from 0019-RH-warn-on-invalid-regex-instead-of-failing.patch rename to 0056-RH-warn-on-invalid-regex-instead-of-failing.patch index 18dd530..4bdd97e 100644 --- a/0019-RH-warn-on-invalid-regex-instead-of-failing.patch +++ b/0056-RH-warn-on-invalid-regex-instead-of-failing.patch @@ -81,10 +81,10 @@ index 0e9ea387..184d4b22 100644 declare_hw_handler(hwhandler, set_str) diff --git a/libmultipath/parser.c b/libmultipath/parser.c -index d478b177..a184511b 100644 +index 11a6168c..a7285a35 100644 --- a/libmultipath/parser.c +++ b/libmultipath/parser.c -@@ -382,6 +382,19 @@ oom: +@@ -384,6 +384,19 @@ oom: return NULL; } diff --git a/0020-RH-reset-default-find_mutipaths-value-to-off.patch b/0057-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 96% rename from 0020-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0057-RH-reset-default-find_mutipaths-value-to-off.patch index 2e53cd9..2dfb52e 100644 --- a/0020-RH-reset-default-find_mutipaths-value-to-off.patch +++ b/0057-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 e5ee6afe..52fe05b9 100644 +index 01a501bd..984d8dd8 100644 --- a/libmultipath/defaults.h +++ b/libmultipath/defaults.h @@ -22,7 +22,7 @@ diff --git a/0021-RH-Fix-nvme-compilation-warning.patch b/0058-RH-Fix-nvme-compilation-warning.patch similarity index 100% rename from 0021-RH-Fix-nvme-compilation-warning.patch rename to 0058-RH-Fix-nvme-compilation-warning.patch diff --git a/0022-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0059-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 100% rename from 0022-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0059-RH-attempt-to-get-ANA-info-via-sysfs-first.patch diff --git a/0023-RH-work-around-gcc-10-format-truncation-issue.patch b/0060-RH-work-around-gcc-10-format-truncation-issue.patch similarity index 58% rename from 0023-RH-work-around-gcc-10-format-truncation-issue.patch rename to 0060-RH-work-around-gcc-10-format-truncation-issue.patch index f03c1a6..c501ce9 100644 --- a/0023-RH-work-around-gcc-10-format-truncation-issue.patch +++ b/0060-RH-work-around-gcc-10-format-truncation-issue.patch @@ -14,18 +14,18 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc -index c2abd301..bb642931 100644 +index 479523bc..e2f5d0dc 100644 --- a/Makefile.inc +++ b/Makefile.inc -@@ -108,7 +108,7 @@ else - endif - OPTFLAGS += -Werror -Wextra -Wstrict-prototypes -Wformat=2 \ - -Werror=implicit-int -Werror=implicit-function-declaration \ -- $(WNOCLOBBERED) \ -+ $(WNOCLOBBERED) -Wno-error=format-truncation \ - -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) \ - --param=ssp-buffer-size=4 - +@@ -109,7 +109,7 @@ endif + WARNFLAGS := -Werror -Wextra -Wformat=2 -Werror=implicit-int \ + -Werror=implicit-function-declaration -Werror=format-security \ + $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) \ +- -Wstrict-prototypes ++ -Wstrict-prototypes -Wno-error=format-truncation + CFLAGS := $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ + -DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" \ + -MMD -MP -- 2.17.2 diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index f6b5f85..dd5590a 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.8.4 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -10,29 +10,66 @@ URL: http://christophe.varoqui.free.fr/ # curl "https://git.opensvc.com/?p=multipath-tools/.git;a=snapshot;h=refs/tags/0.8.4;sf=tgz" -o multipath-tools-0.8.4.tgz Source0: multipath-tools-0.8.4.tgz Source1: multipath.conf -Patch0001:0001-libmultipath-assign-variable-to-make-gcc-happy.patch -Patch0002: 0002-libmutipath-don-t-close-fd-on-dm_lib_release.patch -Patch0003: 0003-libmultipath-allow-force-reload-with-no-active-paths.patch -Patch0004: 0004-libmpathpersist-depend-on-libmultipath.patch -Patch0005: 0005-multipath-tools-Makefile-more-dependency-fixes-for-p.patch -Patch0006: 0006-multipath-tools-Makefile.inc-set-Wno-error-clobbered.patch -Patch0007: 0007-libmultipath-discovery.c-use-z-qualifier-for-size_t.patch -Patch0008: 0008-libmultipath-eliminate-more-signed-unsigned-comparis.patch -Patch0009: 0009-libmultipath-set_uint-fix-parsing-for-32bit.patch -Patch0010: 0010-multipath-tools-Makefile-add-install-dependency.patch -Patch0011: 0011-libdmmp-Add-support-for-upcoming-json-c-0.14.0.patch -Patch0012: 0012-libmultipath-fix-condlog-NULL-argument-in-uevent_get.patch -Patch0013: 0013-RH-fixup-udev-rules-for-redhat.patch -Patch0014: 0014-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0015: 0015-RH-don-t-start-without-a-config-file.patch -Patch0016: 0016-RH-use-rpm-optflags-if-present.patch -Patch0017: 0017-RH-add-mpathconf.patch -Patch0018: 0018-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0019: 0019-RH-warn-on-invalid-regex-instead-of-failing.patch -Patch0020: 0020-RH-reset-default-find_mutipaths-value-to-off.patch -Patch0021: 0021-RH-Fix-nvme-compilation-warning.patch -Patch0022: 0022-RH-attempt-to-get-ANA-info-via-sysfs-first.patch -Patch0023: 0023-RH-work-around-gcc-10-format-truncation-issue.patch +Patch0001: 0001-libmpathpersist-limit-PRIN-allocation-length-to-8192.patch +Patch0002: 0002-libmpathpersist-format_transportids-avoid-PROUT-over.patch +Patch0003: 0003-libmpathpersist-mpath_format_readfullstatus-use-real.patch +Patch0004: 0004-libmultipath-assign-variable-to-make-gcc-happy.patch +Patch0005: 0005-libmutipath-don-t-close-fd-on-dm_lib_release.patch +Patch0006: 0006-libmultipath-allow-force-reload-with-no-active-paths.patch +Patch0007: 0007-kpartx.rules-honor-DM_UDEV_DISABLE_OTHER_RULES_FLAG.patch +Patch0008: 0008-kpartx.rules-check-for-skip_kpartx-on-synthetic-ueve.patch +Patch0009: 0009-libmpathpersist-depend-on-libmultipath.patch +Patch0010: 0010-multipath-tools-Makefile-more-dependency-fixes-for-p.patch +Patch0011: 0011-multipath-tools-Makefile.inc-separate-out-OPTFLAGS.patch +Patch0012: 0012-multipath-tools-Makefile.inc-allow-user-settings-for.patch +Patch0013: 0013-multipath-tools-Makefile.inc-set-Wno-error-clobbered.patch +Patch0014: 0014-libmultipath-discovery.c-use-z-qualifier-for-size_t.patch +Patch0015: 0015-libmultipath-eliminate-more-signed-unsigned-comparis.patch +Patch0016: 0016-libmultipath-set_uint-fix-parsing-for-32bit.patch +Patch0017: 0017-multipath-tools-tests-Makefile-add-lmpathcmd-to-LIBD.patch +Patch0018: 0018-multipath-tools-tests-Makefile-Fix-OBJDEPS-for-hwtab.patch +Patch0019: 0019-multipath-tools-tests-test-lib.c-drop-__wrap_is_clai.patch +Patch0020: 0020-multipath-tools-tests-directio-fix-Wmaybe-uninitaliz.patch +Patch0021: 0021-libmultipath-move-libsg-into-libmultipath.patch +Patch0022: 0022-multipath-tools-Makefile-add-install-dependency.patch +Patch0023: 0023-libmultipath-make-libmp_dm_init-optional.patch +Patch0024: 0024-libmultipath-make-sysfs_is_multipathed-able-to-retur.patch +Patch0025: 0025-multipath-centralize-validation-code.patch +Patch0026: 0026-Unit-tests-for-is_path_valid.patch +Patch0027: 0027-libmultipath-simplify-failed-wwid-code.patch +Patch0028: 0028-libmultipath-use-atomic-linkat-in-mark_failed_wwid.patch +Patch0029: 0029-fix-boolean-value-with-json-c-0.14.patch +Patch0030: 0030-libmultipath-fix-condlog-NULL-argument-in-uevent_get.patch +Patch0031: 0031-libmultipath-set-enable_foreign-to-NONE-by-default.patch +Patch0032: 0032-multipath-add-e-option-to-enable-foreign-libraries.patch +Patch0033: 0033-libmultipath-remove-_blacklist_exceptions-functions.patch +Patch0034: 0034-libmultipath-fix-parser-issue-with-comments-in-strin.patch +Patch0035: 0035-libmultipath-invert-regexes-that-start-with-exclamat.patch +Patch0036: 0036-multipath-Fix-compiler-warnings-when-built-without-s.patch +Patch0037: 0037-libmultipath-fix-sysfs-dev_loss_tmo-parsing.patch +Patch0038: 0038-kpartx-read-devices-with-direct-IO.patch +Patch0039: 0039-kpartx-handle-alternate-bsd-disklabel-location.patch +Patch0040: 0040-libmultipath-fix-checker-detection-for-nvme-devices.patch +Patch0041: 0041-libmultipath-make-dm_get_map-status-return-codes-sym.patch +Patch0042: 0042-multipathd-fix-check_path-errors-with-removed-map.patch +Patch0043: 0043-libmultipath-make-dm_flush_maps-only-return-0-on-suc.patch +Patch0044: 0044-multipathd-add-del-maps-multipathd-command.patch +Patch0045: 0045-multipath-make-flushing-maps-work-like-other-command.patch +Patch0046: 0046-multipath-delegate-flushing-maps-to-multipathd.patch +Patch0047: 0047-multipath-add-option-to-skip-multipathd-delegation.patch +Patch0048: 0048-Makefile.inc-trim-extra-information-from-systemd-ver.patch +Patch0049: 0049-kpartx-fix-Wsign-compare-error.patch +Patch0050: 0050-RH-fixup-udev-rules-for-redhat.patch +Patch0051: 0051-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0052: 0052-RH-don-t-start-without-a-config-file.patch +Patch0053: 0053-RH-use-rpm-optflags-if-present.patch +Patch0054: 0054-RH-add-mpathconf.patch +Patch0055: 0055-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0056: 0056-RH-warn-on-invalid-regex-instead-of-failing.patch +Patch0057: 0057-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0058: 0058-RH-Fix-nvme-compilation-warning.patch +Patch0059: 0059-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0060: 0060-RH-work-around-gcc-10-format-truncation-issue.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -227,8 +264,24 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Wed Jul 8 2020 Benjamin Marzinski - 0.8.4-2 +- Rebased on top of Martin Wilck's queue of ACKed upstream commits + * https://github.com/openSUSE/multipath-tools/tree/upstream-queue + * All previous patches have been reordered, with the exception of + 0011-libdmmp-Add-support-for-upcoming-json-c-0.14.0.patch + which has been replaced with + 0029-fix-boolean-value-with-json-c-0.14.patch +- Modify 0054-RH-add-mpathconf.patch + * remove default enable_foreign and property blacklist_exceptions + settings, and deal with the builtin default change from + 0031-libmultipath-set-enable_foreign-to-NONE-by-default.patch. + Fixes bz #1853668 +- Add 0048-Makefile.inc-trim-extra-information-from-systemd-ver.patch +- Add 0049-kpartx-fix-Wsign-compare-error.patch + * The above two patches have been submitted upstream + * Fri May 29 2020 Benjamin Marzinski - 0.8.4-1 -- Update Source to upstream version 0.8.2 +- Update Source to upstream version 0.8.4 * Previoud patches 0001-0020 & 0031 are included in this commit - Rename files * Previous patches 0021-0032 are now patches 0012-0022 @@ -509,7 +562,7 @@ fi - Rename files * Previous patches 0007-0014 are now patches 0008-0015 -* Tue Apr 02 2018 Björn Esser - 0.7.6-1.git1cb704b +* Mon Apr 02 2018 Benjamin Marzinski 0.7.6-1.git1cb704b - Update Source to the latest upstream commit * Previous patches 0001-0014 are included in this commit * Previous patches 0015-0022 are now patches 0007-0014 From f478b960f2521d55f275c84ed5852fbb3d4e87b8 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Mon, 13 Jul 2020 19:03:45 +0000 Subject: [PATCH 05/67] Use make macros https://fedoraproject.org/wiki/Changes/UseMakeBuildInstallMacro --- device-mapper-multipath.spec | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index dd5590a..b492b91 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.8.4 -Release: 2%{?dist} +Release: 3%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -160,11 +160,10 @@ cp %{SOURCE1} . %define _libdir /usr/%{_lib} %define _libmpathdir %{_libdir}/multipath %define _pkgconfdir %{_libdir}/pkgconfig -make %{?_smp_mflags} LIB=%{_lib} +%make_build LIB=%{_lib} %install -make install \ - DESTDIR=%{buildroot} \ +%make_install \ bindir=%{_sbindir} \ syslibdir=%{_libdir} \ usrlibdir=%{_libdir} \ @@ -264,6 +263,10 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Mon Jul 13 2020 Tom Stellard - 0.8.4-3 +- Use make macros +- https://fedoraproject.org/wiki/Changes/UseMakeBuildInstallMacro + * Wed Jul 8 2020 Benjamin Marzinski - 0.8.4-2 - Rebased on top of Martin Wilck's queue of ACKed upstream commits * https://github.com/openSUSE/multipath-tools/tree/upstream-queue From 9abdc502cfe5a5b374b0a9bacc7a79fef2ab0f06 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Tue, 21 Jul 2020 17:39:38 -0500 Subject: [PATCH 06/67] device-mapper-multipath-0.8.4-4 Rebased on top of additional commits staged for upstream * Previous patches 0048-0060 are now patches 0053-0054 & 0059-0069 Add 0048-libmultipath-add-device-to-hwtable.c.patch Add 0049-master-libmultipath-fix-use-after-free-when-iscsi-lo.patch Add 0050-libmultipath-warn-if-freeing-path-that-holds-mpp-hwe.patch Add 0051-libmultipath-warn-about-NULL-value-of-mpp-hwe.patch Add 0052-libmultipath-fix-mpp-hwe-handling-in-sync_paths.patch Add 0055-libmultipath-remove-code-duplication-in-path-countin.patch Add 0056-libmultipath-count-pending-paths-as-active-on-loads.patch Add 0057-libmultipath-deal-with-flushing-no-maps.patch Add 0058-multipath-deal-with-delegation-failures-correctly.patch Add 0070-multipath-add-libmpathvalid-library.patch * adds the libmpathvalid.so library to determine if devices are valid multipath paths. Add 0071-libmultipath-add-uid-failback-for-dasd-devices.patch Add 0072-libmultipath-add-ignore_udev_uid-option.patch --- ...libmultipath-add-device-to-hwtable.c.patch | 44 +++ ...ath-fix-use-after-free-when-iscsi-lo.patch | 84 ++++ ...n-if-freeing-path-that-holds-mpp-hwe.patch | 33 ++ ...ath-warn-about-NULL-value-of-mpp-hwe.patch | 33 ++ ...h-fix-mpp-hwe-handling-in-sync_paths.patch | 45 +++ ...m-extra-information-from-systemd-ver.patch | 0 ... 0054-kpartx-fix-Wsign-compare-error.patch | 0 ...ove-code-duplication-in-path-countin.patch | 129 ++++++ ...unt-pending-paths-as-active-on-loads.patch | 73 ++++ ...multipath-deal-with-flushing-no-maps.patch | 33 ++ ...l-with-delegation-failures-correctly.patch | 39 ++ ... 0059-RH-fixup-udev-rules-for-redhat.patch | 0 ...property-blacklist-exception-builtin.patch | 0 ...RH-don-t-start-without-a-config-file.patch | 0 ... 0062-RH-use-rpm-optflags-if-present.patch | 0 ...hconf.patch => 0063-RH-add-mpathconf.patch | 0 ...om-kernel-cmdline-mpath.wwids-with-A.patch | 6 +- ...-on-invalid-regex-instead-of-failing.patch | 0 ...-default-find_mutipaths-value-to-off.patch | 0 ...0067-RH-Fix-nvme-compilation-warning.patch | 0 ...empt-to-get-ANA-info-via-sysfs-first.patch | 0 ...round-gcc-10-format-truncation-issue.patch | 0 ...-multipath-add-libmpathvalid-library.patch | 369 ++++++++++++++++++ ...th-add-uid-failback-for-dasd-devices.patch | 89 +++++ ...multipath-add-ignore_udev_uid-option.patch | 192 +++++++++ device-mapper-multipath.spec | 61 ++- 26 files changed, 1213 insertions(+), 17 deletions(-) create mode 100644 0048-libmultipath-add-device-to-hwtable.c.patch create mode 100644 0049-master-libmultipath-fix-use-after-free-when-iscsi-lo.patch create mode 100644 0050-libmultipath-warn-if-freeing-path-that-holds-mpp-hwe.patch create mode 100644 0051-libmultipath-warn-about-NULL-value-of-mpp-hwe.patch create mode 100644 0052-libmultipath-fix-mpp-hwe-handling-in-sync_paths.patch rename 0048-Makefile.inc-trim-extra-information-from-systemd-ver.patch => 0053-Makefile.inc-trim-extra-information-from-systemd-ver.patch (100%) rename 0049-kpartx-fix-Wsign-compare-error.patch => 0054-kpartx-fix-Wsign-compare-error.patch (100%) create mode 100644 0055-libmultipath-remove-code-duplication-in-path-countin.patch create mode 100644 0056-libmultipath-count-pending-paths-as-active-on-loads.patch create mode 100644 0057-libmultipath-deal-with-flushing-no-maps.patch create mode 100644 0058-multipath-deal-with-delegation-failures-correctly.patch rename 0050-RH-fixup-udev-rules-for-redhat.patch => 0059-RH-fixup-udev-rules-for-redhat.patch (100%) rename 0051-RH-Remove-the-property-blacklist-exception-builtin.patch => 0060-RH-Remove-the-property-blacklist-exception-builtin.patch (100%) rename 0052-RH-don-t-start-without-a-config-file.patch => 0061-RH-don-t-start-without-a-config-file.patch (100%) rename 0053-RH-use-rpm-optflags-if-present.patch => 0062-RH-use-rpm-optflags-if-present.patch (100%) rename 0054-RH-add-mpathconf.patch => 0063-RH-add-mpathconf.patch (100%) rename 0055-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch => 0064-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch (97%) rename 0056-RH-warn-on-invalid-regex-instead-of-failing.patch => 0065-RH-warn-on-invalid-regex-instead-of-failing.patch (100%) rename 0057-RH-reset-default-find_mutipaths-value-to-off.patch => 0066-RH-reset-default-find_mutipaths-value-to-off.patch (100%) rename 0058-RH-Fix-nvme-compilation-warning.patch => 0067-RH-Fix-nvme-compilation-warning.patch (100%) rename 0059-RH-attempt-to-get-ANA-info-via-sysfs-first.patch => 0068-RH-attempt-to-get-ANA-info-via-sysfs-first.patch (100%) rename 0060-RH-work-around-gcc-10-format-truncation-issue.patch => 0069-RH-work-around-gcc-10-format-truncation-issue.patch (100%) create mode 100644 0070-multipath-add-libmpathvalid-library.patch create mode 100644 0071-libmultipath-add-uid-failback-for-dasd-devices.patch create mode 100644 0072-libmultipath-add-ignore_udev_uid-option.patch diff --git a/0048-libmultipath-add-device-to-hwtable.c.patch b/0048-libmultipath-add-device-to-hwtable.c.patch new file mode 100644 index 0000000..9d5e780 --- /dev/null +++ b/0048-libmultipath-add-device-to-hwtable.c.patch @@ -0,0 +1,44 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Steve Schremmer +Date: Mon, 6 Jul 2020 20:22:35 +0000 +Subject: [PATCH] libmultipath: add device to hwtable.c + +Add FUJITSU ETERNUS_AHB defaults. + +Signed-off-by: Steve Schremmer +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/hwtable.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index d1fcfdb3..d680bdfc 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -428,6 +428,22 @@ static struct hwentry default_hw[] = { + .pgpolicy = MULTIBUS, + .no_path_retry = 10, + }, ++ { ++ /* ++ * ETERNUS AB/HB ++ * Maintainer: NetApp RDAC team ++ */ ++ .vendor = "FUJITSU", ++ .product = "ETERNUS_AHB", ++ .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, ++ }, + /* + * Hitachi Vantara + * +-- +2.17.2 + diff --git a/0049-master-libmultipath-fix-use-after-free-when-iscsi-lo.patch b/0049-master-libmultipath-fix-use-after-free-when-iscsi-lo.patch new file mode 100644 index 0000000..bfb9f8f --- /dev/null +++ b/0049-master-libmultipath-fix-use-after-free-when-iscsi-lo.patch @@ -0,0 +1,84 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: lixiaokeng +Date: Mon, 13 Jul 2020 13:07:40 +0200 +Subject: [PATCH] master - libmultipath: fix use after free when iscsi logs in + +When two iscsi ips log in and out alternately and the following scripts run +at the same time, + +#!/bin/bash +interval=5 +while true +do + iscsiadm -m node -p 9.41.147.171 &> /dev/null + iscsiadm -m node -p 9.41.148.172 &> /dev/null + iscsiadm -m session &> /dev/null + rescan-scsi-bus.sh &> /dev/null + multipath -v2 &> /dev/null + multipath -ll &> /dev/null + sleep $interval +done + +multipathd will have a segfault after about 30 mins. + +The reason is that mpp->hwe is accessed after hwe is already freed. In +extract_hwe_from_path func, mpp->hwe is set to pp->hwe, so they points to the +same hwe. For some reasons, pp->mpp will be set to NULL in orphan_path func. +Then, pp and hwe will be freed with (pp->mpp == NULL) in free_path func +called by ev_remove_path func. However, mpp->hwe is not set to NULL while hwe +is already freed. So, when iscsi device logs in and new path is added to mpp, +mpp->hwe will be accessed in select_pgfailback func. Finally, use-after-free +problem occurs. + +The procedure details given as follows, +1.wait_dmevents thread +wait_dmevents + ->dmevent_loop + ->update_multipath + ->__setup_multipath + ->update_multipath_strings + -> sync_paths + ->orphan_path +2.uevqloop thread (iscsi log out, remove path) +uevqloop +->uevent_dispatch + ->service_uevq + ->uev_remove_path + ->ev_remove_path //pp->mpp is NULL + ->free_path(pp) + //pp->hew are freed but mpp->hwe is not set to NULL +3.ev_remove_path (iscsi log in, add path) +uevqloop +->uevent_dispatch + ->service_uevq + ->ev_add_path + ->select_pgfailback //mpp->hwe is accessed + +Here, we will set mpp->hwe to NULL before setting pp->map to NULL in orphan_path +func. + +Signed-off-by: Tianxiong Lu +Signed-off-by: lixiaokeng +Signed-off-by: Zhiqiang Liu +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/structs_vec.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c +index 8137ea21..430eaad7 100644 +--- a/libmultipath/structs_vec.c ++++ b/libmultipath/structs_vec.c +@@ -93,6 +93,8 @@ int adopt_paths(vector pathvec, struct multipath *mpp) + void orphan_path(struct path *pp, const char *reason) + { + condlog(3, "%s: orphan path, %s", pp->dev, reason); ++ if (pp->mpp && pp->mpp->hwe == pp->hwe) ++ pp->mpp->hwe = NULL; + pp->mpp = NULL; + pp->dmstate = PSTATE_UNDEF; + pp->uid_attribute = NULL; +-- +2.17.2 + diff --git a/0050-libmultipath-warn-if-freeing-path-that-holds-mpp-hwe.patch b/0050-libmultipath-warn-if-freeing-path-that-holds-mpp-hwe.patch new file mode 100644 index 0000000..3c286fa --- /dev/null +++ b/0050-libmultipath-warn-if-freeing-path-that-holds-mpp-hwe.patch @@ -0,0 +1,33 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 13 Jul 2020 13:07:41 +0200 +Subject: [PATCH] libmultipath: warn if freeing path that holds mpp->hwe + +This just adds an error message to the previous patch. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/structs_vec.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c +index 430eaad7..cde4dbe6 100644 +--- a/libmultipath/structs_vec.c ++++ b/libmultipath/structs_vec.c +@@ -93,8 +93,11 @@ int adopt_paths(vector pathvec, struct multipath *mpp) + void orphan_path(struct path *pp, const char *reason) + { + condlog(3, "%s: orphan path, %s", pp->dev, reason); +- if (pp->mpp && pp->mpp->hwe == pp->hwe) ++ if (pp->mpp && pp->hwe && pp->mpp->hwe == pp->hwe) { ++ condlog(0, "BUG: orphaning path %s that holds hwe of %s", ++ pp->dev, pp->mpp->alias); + pp->mpp->hwe = NULL; ++ } + pp->mpp = NULL; + pp->dmstate = PSTATE_UNDEF; + pp->uid_attribute = NULL; +-- +2.17.2 + diff --git a/0051-libmultipath-warn-about-NULL-value-of-mpp-hwe.patch b/0051-libmultipath-warn-about-NULL-value-of-mpp-hwe.patch new file mode 100644 index 0000000..a50b9b2 --- /dev/null +++ b/0051-libmultipath-warn-about-NULL-value-of-mpp-hwe.patch @@ -0,0 +1,33 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 13 Jul 2020 13:07:42 +0200 +Subject: [PATCH] libmultipath: warn about NULL value of mpp->hwe + +mpp->hwe is only accessed in propsel.c. It may become unset if +all paths of the mpp have been deleted. Access to mpp->hwe in this +case should be avoided. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/propsel.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c +index d362beb4..68228272 100644 +--- a/libmultipath/propsel.c ++++ b/libmultipath/propsel.c +@@ -65,7 +65,9 @@ do { \ + __do_set_from_vec(struct hwentry, var, (src)->hwe, dest) + + #define do_set_from_hwe(var, src, dest, msg) \ +- if (__do_set_from_hwe(var, src, dest)) { \ ++ if (!src->hwe) { \ ++ condlog(0, "BUG: do_set_from_hwe called with hwe == NULL"); \ ++ } else if (__do_set_from_hwe(var, src, dest)) { \ + origin = msg; \ + goto out; \ + } +-- +2.17.2 + diff --git a/0052-libmultipath-fix-mpp-hwe-handling-in-sync_paths.patch b/0052-libmultipath-fix-mpp-hwe-handling-in-sync_paths.patch new file mode 100644 index 0000000..b9caf46 --- /dev/null +++ b/0052-libmultipath-fix-mpp-hwe-handling-in-sync_paths.patch @@ -0,0 +1,45 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 13 Jul 2020 13:07:43 +0200 +Subject: [PATCH] libmultipath: fix mpp->hwe handling in sync_paths() + +This is anologous to + +1f96269 ("multipathd: fix mpp->hwe handling on path removal") +f6839eb ("multipathd: fix mpp->hwe handling when paths are freed") + +When paths are removed from a map, we need to make sure that +mpp->hwe doesn't become stale. + +Reported-by: Lixiaokeng +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/structs_vec.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c +index cde4dbe6..ede14297 100644 +--- a/libmultipath/structs_vec.c ++++ b/libmultipath/structs_vec.c +@@ -260,6 +260,8 @@ void sync_paths(struct multipath *mpp, vector pathvec) + } + if (!found) { + condlog(3, "%s dropped path %s", mpp->alias, pp->dev); ++ if (mpp->hwe == pp->hwe) ++ mpp->hwe = NULL; + vector_del_slot(mpp->paths, i--); + orphan_path(pp, "path removed externally"); + } +@@ -267,6 +269,8 @@ void sync_paths(struct multipath *mpp, vector pathvec) + update_mpp_paths(mpp, pathvec); + vector_foreach_slot (mpp->paths, pp, i) + pp->mpp = mpp; ++ if (mpp->hwe == NULL) ++ extract_hwe_from_path(mpp); + } + + int +-- +2.17.2 + diff --git a/0048-Makefile.inc-trim-extra-information-from-systemd-ver.patch b/0053-Makefile.inc-trim-extra-information-from-systemd-ver.patch similarity index 100% rename from 0048-Makefile.inc-trim-extra-information-from-systemd-ver.patch rename to 0053-Makefile.inc-trim-extra-information-from-systemd-ver.patch diff --git a/0049-kpartx-fix-Wsign-compare-error.patch b/0054-kpartx-fix-Wsign-compare-error.patch similarity index 100% rename from 0049-kpartx-fix-Wsign-compare-error.patch rename to 0054-kpartx-fix-Wsign-compare-error.patch diff --git a/0055-libmultipath-remove-code-duplication-in-path-countin.patch b/0055-libmultipath-remove-code-duplication-in-path-countin.patch new file mode 100644 index 0000000..699049a --- /dev/null +++ b/0055-libmultipath-remove-code-duplication-in-path-countin.patch @@ -0,0 +1,129 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 21 Jul 2020 01:12:05 -0500 +Subject: [PATCH] libmultipath: remove code duplication in path counting + +pathcountgr() is never used except by pathcount(), and neither is the +special case for PATH_WILD. Simplify this and make one function that is +used by both pathcount() and count_active_paths(). This will be used +again in a future patch. + +Also use count_active_paths() in mpath_persist. + +Signed-off-by: Benjamin Marzinski +--- + libmpathpersist/mpath_persist.c | 4 +-- + libmultipath/structs.c | 47 +++++++++++++-------------------- + libmultipath/structs.h | 1 - + 3 files changed, 21 insertions(+), 31 deletions(-) + +diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c +index 3da7a6cf..a132f4e9 100644 +--- a/libmpathpersist/mpath_persist.c ++++ b/libmpathpersist/mpath_persist.c +@@ -436,7 +436,7 @@ int mpath_prout_reg(struct multipath *mpp,int rq_servact, int rq_scope, + + 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); ++ active_pathcount = count_active_paths(mpp); + + if (active_pathcount == 0) { + condlog (0, "%s: no path available", mpp->wwid); +@@ -648,7 +648,7 @@ int mpath_prout_rel(struct multipath *mpp,int rq_servact, int rq_scope, + if (!mpp) + return MPATH_PR_DMMP_ERROR; + +- active_pathcount = pathcount (mpp, PATH_UP) + pathcount (mpp, PATH_GHOST); ++ active_pathcount = count_active_paths(mpp); + + struct threadinfo thread[active_pathcount]; + memset(thread, 0, sizeof(thread)); +diff --git a/libmultipath/structs.c b/libmultipath/structs.c +index 2dd378c4..3eac3d61 100644 +--- a/libmultipath/structs.c ++++ b/libmultipath/structs.c +@@ -455,49 +455,40 @@ find_path_by_devt (const struct _vector *pathvec, const char * dev_t) + return NULL; + } + +-int pathcountgr(const struct pathgroup *pgp, int state) ++static int do_pathcount(const struct multipath *mpp, const int *states, ++ unsigned int nr_states) + { ++ struct pathgroup *pgp; + struct path *pp; + int count = 0; +- int i; ++ unsigned int i, j, k; + +- vector_foreach_slot (pgp->paths, pp, i) +- if ((pp->state == state) || (state == PATH_WILD)) +- count++; ++ if (!mpp->pg || !nr_states) ++ return count; + ++ vector_foreach_slot (mpp->pg, pgp, i) { ++ vector_foreach_slot (pgp->paths, pp, j) { ++ for (k = 0; k < nr_states; k++) { ++ if (pp->state == states[k]) { ++ count++; ++ break; ++ } ++ } ++ } ++ } + return count; + } + + int pathcount(const struct multipath *mpp, int state) + { +- struct pathgroup *pgp; +- int count = 0; +- int i; +- +- if (mpp->pg) { +- vector_foreach_slot (mpp->pg, pgp, i) +- count += pathcountgr(pgp, state); +- } +- return count; ++ return do_pathcount(mpp, &state, 1); + } + + int count_active_paths(const struct multipath *mpp) + { +- struct pathgroup *pgp; +- struct path *pp; +- int count = 0; +- int i, j; +- +- if (!mpp->pg) +- return 0; ++ int states[] = {PATH_UP, PATH_GHOST}; + +- vector_foreach_slot (mpp->pg, pgp, i) { +- vector_foreach_slot (pgp->paths, pp, j) { +- if (pp->state == PATH_UP || pp->state == PATH_GHOST) +- count++; +- } +- } +- return count; ++ return do_pathcount(mpp, states, 2); + } + + int pathcmp(const struct pathgroup *pgp, const struct pathgroup *cpgp) +diff --git a/libmultipath/structs.h b/libmultipath/structs.h +index d69bc2e9..0c03e711 100644 +--- a/libmultipath/structs.h ++++ b/libmultipath/structs.h +@@ -446,7 +446,6 @@ struct path * find_path_by_devt (const struct _vector *pathvec, const char *devt + struct path * find_path_by_dev (const struct _vector *pathvec, const char *dev); + struct path * first_path (const struct multipath *mpp); + +-int pathcountgr (const struct pathgroup *, int); + int pathcount (const struct multipath *, int); + int count_active_paths(const struct multipath *); + int pathcmp (const struct pathgroup *, const struct pathgroup *); +-- +2.17.2 + diff --git a/0056-libmultipath-count-pending-paths-as-active-on-loads.patch b/0056-libmultipath-count-pending-paths-as-active-on-loads.patch new file mode 100644 index 0000000..5320297 --- /dev/null +++ b/0056-libmultipath-count-pending-paths-as-active-on-loads.patch @@ -0,0 +1,73 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 21 Jul 2020 01:19:30 -0500 +Subject: [PATCH] libmultipath: count pending paths as active on loads + +When multipath loads a table, it signals to udev if there are no active +paths. Multipath wasn't counting pending paths as active. This meant +that if all the paths were pending, udev would treat the device as not +ready, and not run kpartx on it. Even if the pending paths later +because active and were reinstated, the kernel would not send a new +uevent, because from its point of view, they were always up. + +The alternative would be to continue to treat them as failed in the udev +rules, but then also tell the kernel that they were down, so that it +would trigger a uevent when they were reinstated. However, this could +lead to newly created multipath devices failing IO, simply because the +path checkers hadn't returned yet. Having udev assume that the the +device is up, like the kernel does, seems like the safer option. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/devmapper.c | 3 ++- + libmultipath/structs.c | 7 +++++++ + libmultipath/structs.h | 1 + + 3 files changed, 10 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index f597ff8b..126cd728 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -417,7 +417,8 @@ static uint16_t build_udev_flags(const struct multipath *mpp, int reload) + /* DM_UDEV_DISABLE_LIBRARY_FALLBACK is added in dm_addmap */ + return (mpp->skip_kpartx == SKIP_KPARTX_ON ? + MPATH_UDEV_NO_KPARTX_FLAG : 0) | +- ((count_active_paths(mpp) == 0 || mpp->ghost_delay_tick > 0) ? ++ ((count_active_pending_paths(mpp) == 0 || ++ mpp->ghost_delay_tick > 0) ? + MPATH_UDEV_NO_PATHS_FLAG : 0) | + (reload && !mpp->force_udev_reload ? + MPATH_UDEV_RELOAD_FLAG : 0); +diff --git a/libmultipath/structs.c b/libmultipath/structs.c +index 3eac3d61..0d1f969d 100644 +--- a/libmultipath/structs.c ++++ b/libmultipath/structs.c +@@ -491,6 +491,13 @@ int count_active_paths(const struct multipath *mpp) + return do_pathcount(mpp, states, 2); + } + ++int count_active_pending_paths(const struct multipath *mpp) ++{ ++ int states[] = {PATH_UP, PATH_GHOST, PATH_PENDING}; ++ ++ return do_pathcount(mpp, states, 3); ++} ++ + int pathcmp(const struct pathgroup *pgp, const struct pathgroup *cpgp) + { + int i, j; +diff --git a/libmultipath/structs.h b/libmultipath/structs.h +index 0c03e711..917e4083 100644 +--- a/libmultipath/structs.h ++++ b/libmultipath/structs.h +@@ -448,6 +448,7 @@ struct path * first_path (const struct multipath *mpp); + + int pathcount (const struct multipath *, int); + int count_active_paths(const struct multipath *); ++int count_active_pending_paths(const struct multipath *); + int pathcmp (const struct pathgroup *, const struct pathgroup *); + int add_feature (char **, const char *); + int remove_feature (char **, const char *); +-- +2.17.2 + diff --git a/0057-libmultipath-deal-with-flushing-no-maps.patch b/0057-libmultipath-deal-with-flushing-no-maps.patch new file mode 100644 index 0000000..0aee761 --- /dev/null +++ b/0057-libmultipath-deal-with-flushing-no-maps.patch @@ -0,0 +1,33 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 21 Jul 2020 01:28:22 -0500 +Subject: [PATCH] libmultipath: deal with flushing no maps + +dm_flush_maps() was failing if there were no device-mapper devices at +all, instead of returning success, since there is nothing to do. + +Fixes: "libmultipath: make dm_flush_maps only return 0 on success" +Signed-off-by: Benjamin Marzinski +--- + libmultipath/devmapper.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index 126cd728..b8199cb5 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -1024,10 +1024,10 @@ int dm_flush_maps (int need_suspend, int retries) + if (!(names = dm_task_get_names (dmt))) + goto out; + ++ r = 0; + if (!names->dev) + goto out; + +- r = 0; + do { + if (need_suspend) + r |= dm_suspend_and_flush_map(names->name, retries); +-- +2.17.2 + diff --git a/0058-multipath-deal-with-delegation-failures-correctly.patch b/0058-multipath-deal-with-delegation-failures-correctly.patch new file mode 100644 index 0000000..e8d0050 --- /dev/null +++ b/0058-multipath-deal-with-delegation-failures-correctly.patch @@ -0,0 +1,39 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 21 Jul 2020 01:37:18 -0500 +Subject: [PATCH] multipath: deal with delegation failures correctly + +delegate_to_multipathd() was returning success, even if the multipathd +command failed. Also, if the command was set to fail with NOT_DELEGATED, +it shouldn't print any errors, since multipath will try to issue to +command itself. + +Fixes: "multipath: delegate flushing maps to multipathd" +Signed-off-by: Benjamin Marzinski +--- + multipath/main.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/multipath/main.c b/multipath/main.c +index 4c43314e..3da692dc 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -861,9 +861,12 @@ int delegate_to_multipathd(enum mpath_cmds cmd, + goto out; + } + +- if (reply != NULL && *reply != '\0' && strcmp(reply, "ok\n")) +- printf("%s", reply); +- r = DELEGATE_OK; ++ if (reply != NULL && *reply != '\0') { ++ if (strcmp(reply, "fail\n")) ++ r = DELEGATE_OK; ++ if (r != NOT_DELEGATED && strcmp(reply, "ok\n")) ++ printf("%s", reply); ++ } + + out: + FREE(reply); +-- +2.17.2 + diff --git a/0050-RH-fixup-udev-rules-for-redhat.patch b/0059-RH-fixup-udev-rules-for-redhat.patch similarity index 100% rename from 0050-RH-fixup-udev-rules-for-redhat.patch rename to 0059-RH-fixup-udev-rules-for-redhat.patch diff --git a/0051-RH-Remove-the-property-blacklist-exception-builtin.patch b/0060-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 100% rename from 0051-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0060-RH-Remove-the-property-blacklist-exception-builtin.patch diff --git a/0052-RH-don-t-start-without-a-config-file.patch b/0061-RH-don-t-start-without-a-config-file.patch similarity index 100% rename from 0052-RH-don-t-start-without-a-config-file.patch rename to 0061-RH-don-t-start-without-a-config-file.patch diff --git a/0053-RH-use-rpm-optflags-if-present.patch b/0062-RH-use-rpm-optflags-if-present.patch similarity index 100% rename from 0053-RH-use-rpm-optflags-if-present.patch rename to 0062-RH-use-rpm-optflags-if-present.patch diff --git a/0054-RH-add-mpathconf.patch b/0063-RH-add-mpathconf.patch similarity index 100% rename from 0054-RH-add-mpathconf.patch rename to 0063-RH-add-mpathconf.patch diff --git a/0055-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0064-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 97% rename from 0055-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0064-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch index a10f147..0b95ee6 100644 --- a/0055-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +++ b/0064-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch @@ -86,7 +86,7 @@ index 0c6ee54d..e32a0b0e 100644 enum { WWID_IS_NOT_FAILED = 0, diff --git a/multipath/main.c b/multipath/main.c -index 4c43314e..c73f6963 100644 +index 3da692dc..ce48a932 100644 --- a/multipath/main.c +++ b/multipath/main.c @@ -135,7 +135,7 @@ usage (char * progname) @@ -107,7 +107,7 @@ index 4c43314e..c73f6963 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" -@@ -893,7 +895,7 @@ main (int argc, char *argv[]) +@@ -896,7 +898,7 @@ main (int argc, char *argv[]) multipath_conf = conf; conf->retrigger_tries = 0; conf->force_sync = 1; @@ -116,7 +116,7 @@ index 4c43314e..c73f6963 100644 switch(arg) { case 1: printf("optarg : %s\n",optarg); break; -@@ -970,6 +972,10 @@ main (int argc, char *argv[]) +@@ -973,6 +975,10 @@ main (int argc, char *argv[]) case 'T': cmd = CMD_DUMP_CONFIG; break; diff --git a/0056-RH-warn-on-invalid-regex-instead-of-failing.patch b/0065-RH-warn-on-invalid-regex-instead-of-failing.patch similarity index 100% rename from 0056-RH-warn-on-invalid-regex-instead-of-failing.patch rename to 0065-RH-warn-on-invalid-regex-instead-of-failing.patch diff --git a/0057-RH-reset-default-find_mutipaths-value-to-off.patch b/0066-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 100% rename from 0057-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0066-RH-reset-default-find_mutipaths-value-to-off.patch diff --git a/0058-RH-Fix-nvme-compilation-warning.patch b/0067-RH-Fix-nvme-compilation-warning.patch similarity index 100% rename from 0058-RH-Fix-nvme-compilation-warning.patch rename to 0067-RH-Fix-nvme-compilation-warning.patch diff --git a/0059-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0068-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 100% rename from 0059-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0068-RH-attempt-to-get-ANA-info-via-sysfs-first.patch diff --git a/0060-RH-work-around-gcc-10-format-truncation-issue.patch b/0069-RH-work-around-gcc-10-format-truncation-issue.patch similarity index 100% rename from 0060-RH-work-around-gcc-10-format-truncation-issue.patch rename to 0069-RH-work-around-gcc-10-format-truncation-issue.patch diff --git a/0070-multipath-add-libmpathvalid-library.patch b/0070-multipath-add-libmpathvalid-library.patch new file mode 100644 index 0000000..b3863cd --- /dev/null +++ b/0070-multipath-add-libmpathvalid-library.patch @@ -0,0 +1,369 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 13 May 2020 17:04:24 -0500 +Subject: [PATCH] multipath: add libmpathvalid library + +This library allows other programs to check if a path should be claimed +by multipath. It exports an init and exit function, that need to be +called before any other functions can be called, a pointer to a struct +config, that stores the configuration which is dealt with in the +init and exit functions, and two more functions. + +mpath_get_mode() get the configured find_multipaths mode. +mpath_is_path() returns whether the device is claimed by multipath, and +optionally returns the wwid. This code works slightly different than +the multipath -c/u code for SMART mode. Instead of checking all the +existing paths to see if another has the same wwid, it expects the +caller to pass in an array of the already known path wwids, and checks +if the current path matches any of those. + +The library also doesn't set up the device-mapper log fuctions. It +leaves this up to the caller. + +Signed-off-by: Benjamin Marzinski +--- + Makefile | 3 +- + Makefile.inc | 1 + + libmpathvalid/Makefile | 38 +++++++ + libmpathvalid/libmpathvalid.version | 10 ++ + libmpathvalid/mpath_valid.c | 168 ++++++++++++++++++++++++++++ + libmpathvalid/mpath_valid.h | 57 ++++++++++ + 6 files changed, 276 insertions(+), 1 deletion(-) + create mode 100644 libmpathvalid/Makefile + create mode 100644 libmpathvalid/libmpathvalid.version + create mode 100644 libmpathvalid/mpath_valid.c + create mode 100644 libmpathvalid/mpath_valid.h + +diff --git a/Makefile b/Makefile +index 8bcaba66..f157a549 100644 +--- a/Makefile ++++ b/Makefile +@@ -9,6 +9,7 @@ BUILDDIRS := \ + libmultipath/checkers \ + libmultipath/foreign \ + libmpathpersist \ ++ libmpathvalid \ + multipath \ + multipathd \ + mpathpersist \ +@@ -29,7 +30,7 @@ $(BUILDDIRS): + $(MAKE) -C $@ + + libmultipath libdmmp: libmpathcmd +-libmpathpersist multipath multipathd: libmultipath ++libmpathpersist libmpathvalid multipath multipathd: libmultipath + mpathpersist multipathd: libmpathpersist + + libmultipath/checkers.install \ +diff --git a/Makefile.inc b/Makefile.inc +index e2f5d0dc..936e5833 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -66,6 +66,7 @@ libdir = $(prefix)/$(LIB)/multipath + unitdir = $(prefix)/$(SYSTEMDPATH)/systemd/system + mpathpersistdir = $(TOPDIR)/libmpathpersist + mpathcmddir = $(TOPDIR)/libmpathcmd ++mpathvaliddir = $(TOPDIR)/libmpathvalid + thirdpartydir = $(TOPDIR)/third-party + libdmmpdir = $(TOPDIR)/libdmmp + nvmedir = $(TOPDIR)/libmultipath/nvme +diff --git a/libmpathvalid/Makefile b/libmpathvalid/Makefile +new file mode 100644 +index 00000000..70b97eca +--- /dev/null ++++ b/libmpathvalid/Makefile +@@ -0,0 +1,38 @@ ++include ../Makefile.inc ++ ++SONAME = 0 ++DEVLIB = libmpathvalid.so ++LIBS = $(DEVLIB).$(SONAME) ++ ++CFLAGS += $(LIB_CFLAGS) -I$(multipathdir) -I$(mpathcmddir) ++ ++LIBDEPS += -lpthread -ldevmapper -ldl -L$(multipathdir) \ ++ -lmultipath -L$(mpathcmddir) -lmpathcmd -ludev ++ ++OBJS = mpath_valid.o ++ ++all: $(LIBS) ++ ++$(LIBS): $(OBJS) ++ $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ -o $@ $(OBJS) $(LIBDEPS) -Wl,--version-script=libmpathvalid.version ++ $(LN) $(LIBS) $(DEVLIB) ++ ++install: $(LIBS) ++ $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(syslibdir) ++ $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) ++ $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) ++ $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(includedir) ++ $(INSTALL_PROGRAM) -m 644 mpath_valid.h $(DESTDIR)$(includedir) ++ ++uninstall: ++ $(RM) $(DESTDIR)$(syslibdir)/$(LIBS) ++ $(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) ++ $(RM) $(DESTDIR)$(includedir)/mpath_valid.h ++ ++clean: dep_clean ++ $(RM) core *.a *.o *.so *.so.* *.gz ++ ++include $(wildcard $(OBJS:.o=.d)) ++ ++dep_clean: ++ $(RM) $(OBJS:.o=.d) +diff --git a/libmpathvalid/libmpathvalid.version b/libmpathvalid/libmpathvalid.version +new file mode 100644 +index 00000000..4d8a8ba4 +--- /dev/null ++++ b/libmpathvalid/libmpathvalid.version +@@ -0,0 +1,10 @@ ++MPATH_1.0 { ++ global: ++ mpathvalid_conf; ++ mpathvalid_init; ++ mpathvalid_exit; ++ mpathvalid_is_path; ++ mpathvalid_get_mode; ++ local: ++ *; ++}; +diff --git a/libmpathvalid/mpath_valid.c b/libmpathvalid/mpath_valid.c +new file mode 100644 +index 00000000..6153e8b7 +--- /dev/null ++++ b/libmpathvalid/mpath_valid.c +@@ -0,0 +1,168 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "devmapper.h" ++#include "structs.h" ++#include "util.h" ++#include "config.h" ++#include "discovery.h" ++#include "wwids.h" ++#include "sysfs.h" ++#include "mpath_cmd.h" ++#include "valid.h" ++#include "mpath_valid.h" ++ ++static struct config default_config = { .verbosity = -1 }; ++struct config *mpathvalid_conf = &default_config; ++ ++static unsigned int get_conf_mode(struct config *conf) ++{ ++ if (conf->find_multipaths == FIND_MULTIPATHS_SMART) ++ return MPATH_SMART; ++ if (conf->find_multipaths == FIND_MULTIPATHS_GREEDY) ++ return MPATH_GREEDY; ++ return MPATH_STRICT; ++} ++ ++static void set_conf_mode(struct config *conf, unsigned int mode) ++{ ++ if (mode == MPATH_SMART) ++ conf->find_multipaths = FIND_MULTIPATHS_SMART; ++ else if (mode == MPATH_GREEDY) ++ conf->find_multipaths = FIND_MULTIPATHS_GREEDY; ++ else ++ conf->find_multipaths = FIND_MULTIPATHS_STRICT; ++} ++ ++unsigned int mpathvalid_get_mode(void) ++{ ++ int mode; ++ struct config *conf; ++ ++ conf = get_multipath_config(); ++ if (!conf) ++ return -1; ++ mode = get_conf_mode(conf); ++ put_multipath_config(conf); ++ return mode; ++} ++ ++static int convert_result(int result) { ++ switch (result) { ++ case PATH_IS_ERROR: ++ return MPATH_IS_ERROR; ++ case PATH_IS_NOT_VALID: ++ return MPATH_IS_NOT_VALID; ++ case PATH_IS_VALID: ++ return MPATH_IS_VALID; ++ case PATH_IS_VALID_NO_CHECK: ++ return MPATH_IS_VALID_NO_CHECK; ++ case PATH_IS_MAYBE_VALID: ++ return MPATH_IS_MAYBE_VALID; ++ } ++ return MPATH_IS_ERROR; ++} ++ ++int ++mpathvalid_init(int verbosity) ++{ ++ unsigned int version[3]; ++ struct config *conf; ++ ++ default_config.verbosity = verbosity; ++ skip_libmp_dm_init(); ++ conf = load_config(DEFAULT_CONFIGFILE); ++ if (!conf) ++ return -1; ++ conf->verbosity = verbosity; ++ if (dm_prereq(version)) ++ goto fail; ++ memcpy(conf->version, version, sizeof(version)); ++ ++ mpathvalid_conf = conf; ++ return 0; ++fail: ++ free_config(conf); ++ return -1; ++} ++ ++int ++mpathvalid_exit(void) ++{ ++ struct config *conf = mpathvalid_conf; ++ ++ default_config.verbosity = -1; ++ if (mpathvalid_conf == &default_config) ++ return 0; ++ mpathvalid_conf = &default_config; ++ free_config(conf); ++ return 0; ++} ++ ++/* ++ * name: name of path to check ++ * mode: mode to use for determination. MPATH_DEFAULT uses configured mode ++ * info: on success, contains the path wwid ++ * paths: array of the returned mpath_info from other claimed paths ++ * nr_paths: the size of the paths array ++ */ ++int ++mpathvalid_is_path(const char *name, unsigned int mode, char **wwid, ++ const char **path_wwids, unsigned int nr_paths) ++{ ++ struct config *conf; ++ int r = MPATH_IS_ERROR; ++ unsigned int i; ++ struct path *pp; ++ ++ if (!name || mode >= MPATH_MAX_MODE) ++ return r; ++ ++ if (nr_paths > 0 && !path_wwids) ++ return r; ++ ++ pp = alloc_path(); ++ if (!pp) ++ return r; ++ ++ if (wwid) { ++ *wwid = (char *)malloc(WWID_SIZE); ++ if (!*wwid) ++ goto out; ++ } ++ ++ conf = get_multipath_config(); ++ if (!conf || conf == &default_config) ++ goto out_wwid; ++ if (mode != MPATH_DEFAULT) ++ set_conf_mode(conf, mode); ++ r = convert_result(is_path_valid(name, conf, pp, true)); ++ put_multipath_config(conf); ++ ++ if (r == MPATH_IS_MAYBE_VALID) { ++ for (i = 0; i < nr_paths; i++) { ++ if (strncmp(path_wwids[i], pp->wwid, WWID_SIZE) == 0) { ++ r = MPATH_IS_VALID; ++ break; ++ } ++ } ++ } ++ ++out_wwid: ++ if (wwid) { ++ if (r == MPATH_IS_VALID || r == MPATH_IS_VALID_NO_CHECK || ++ r == MPATH_IS_MAYBE_VALID) ++ strlcpy(*wwid, pp->wwid, WWID_SIZE); ++ else { ++ free(*wwid); ++ *wwid = NULL; ++ } ++ } ++out: ++ free_path(pp); ++ return r; ++} +diff --git a/libmpathvalid/mpath_valid.h b/libmpathvalid/mpath_valid.h +new file mode 100644 +index 00000000..7fd8aa47 +--- /dev/null ++++ b/libmpathvalid/mpath_valid.h +@@ -0,0 +1,57 @@ ++/* ++ * Copyright (C) 2015 Red Hat, Inc. ++ * ++ * This file is part of the device-mapper multipath userspace tools. ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public License ++ * along with this program. If not, see . ++ */ ++ ++#ifndef LIB_MPATH_VALID_H ++#define LIB_MPATH_VALID_H ++ ++#ifdef __cpluscplus ++extern "C" { ++#endif ++ ++enum mpath_valid_mode { ++ MPATH_DEFAULT, ++ MPATH_STRICT, ++ MPATH_SMART, ++ MPATH_GREEDY, ++ MPATH_MAX_MODE, /* used only for bounds checking */ ++}; ++ ++/* MPATH_IS_VALID_NO_CHECK is used to skip checks to see if the device ++ * has already been unclaimed by multipath in the past */ ++enum mpath_valid_result { ++ MPATH_IS_ERROR = -1, ++ MPATH_IS_NOT_VALID, ++ MPATH_IS_VALID, ++ MPATH_IS_VALID_NO_CHECK, ++ MPATH_IS_MAYBE_VALID, ++}; ++ ++struct config; ++extern struct config *mpathvalid_conf; ++int mpathvalid_init(int verbosity); ++int mpathvalid_exit(void); ++unsigned int mpathvalid_get_mode(void); ++int mpathvalid_is_path(const char *name, unsigned int mode, char **wwid, ++ const char **path_wwids, unsigned int nr_paths); ++ ++ ++#ifdef __cplusplus ++} ++#endif ++#endif /* LIB_PATH_VALID_H */ +-- +2.17.2 + diff --git a/0071-libmultipath-add-uid-failback-for-dasd-devices.patch b/0071-libmultipath-add-uid-failback-for-dasd-devices.patch new file mode 100644 index 0000000..2515095 --- /dev/null +++ b/0071-libmultipath-add-uid-failback-for-dasd-devices.patch @@ -0,0 +1,89 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 19 May 2020 15:55:15 -0500 +Subject: [PATCH] libmultipath: add uid failback for dasd devices + +Add failback code to get the uid for dasd devices from sysfs. Copied +from dasdinfo + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/defaults.h | 1 + + libmultipath/discovery.c | 37 ++++++++++++++++++++++++++++++++++++- + 2 files changed, 37 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h +index 984d8dd8..6a678a83 100644 +--- a/libmultipath/defaults.h ++++ b/libmultipath/defaults.h +@@ -8,6 +8,7 @@ + */ + #define DEFAULT_UID_ATTRIBUTE "ID_SERIAL" + #define DEFAULT_NVME_UID_ATTRIBUTE "ID_WWN" ++#define DEFAULT_DASD_UID_ATTRIBUTE "ID_UID" + #define DEFAULT_UDEVDIR "/dev" + #define DEFAULT_MULTIPATHDIR "/" LIB_STRING "/multipath" + #define DEFAULT_SELECTOR "service-time 0" +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index aa5942c3..002d3d18 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -1920,12 +1920,44 @@ get_vpd_uid(struct path * pp) + return get_vpd_sysfs(parent, 0x83, pp->wwid, WWID_SIZE); + } + ++/* based on code from s390-tools/dasdinfo/dasdinfo.c */ ++static ssize_t dasd_get_uid(struct path *pp) ++{ ++ struct udev_device *parent; ++ char value[80]; ++ char *p; ++ int i; ++ ++ parent = udev_device_get_parent_with_subsystem_devtype(pp->udev, "ccw", ++ NULL); ++ if (!parent) ++ return -1; ++ ++ if (sysfs_attr_get_value(parent, "uid", value, 80) < 0) ++ return -1; ++ ++ p = value - 1; ++ /* look for the 4th '.' and cut there */ ++ for (i = 0; i < 4; i++) { ++ p = index(p + 1, '.'); ++ if (!p) ++ break; ++ } ++ if (p) ++ *p = '\0'; ++ ++ return strlcpy(pp->wwid, value, WWID_SIZE); ++} ++ + static ssize_t uid_fallback(struct path *pp, int path_state, + const char **origin) + { + ssize_t len = -1; + +- if (pp->bus == SYSFS_BUS_SCSI) { ++ if (pp->bus == SYSFS_BUS_CCW) { ++ len = dasd_get_uid(pp); ++ *origin = "sysfs"; ++ } else if (pp->bus == SYSFS_BUS_SCSI) { + len = get_vpd_uid(pp); + *origin = "sysfs"; + if (len < 0 && path_state == PATH_UP) { +@@ -1970,6 +2002,9 @@ static bool has_uid_fallback(struct path *pp) + !strcmp(pp->uid_attribute, ""))) || + (pp->bus == SYSFS_BUS_NVME && + (!strcmp(pp->uid_attribute, DEFAULT_NVME_UID_ATTRIBUTE) || ++ !strcmp(pp->uid_attribute, ""))) || ++ (pp->bus == SYSFS_BUS_CCW && ++ (!strcmp(pp->uid_attribute, DEFAULT_DASD_UID_ATTRIBUTE) || + !strcmp(pp->uid_attribute, "")))); + } + +-- +2.17.2 + diff --git a/0072-libmultipath-add-ignore_udev_uid-option.patch b/0072-libmultipath-add-ignore_udev_uid-option.patch new file mode 100644 index 0000000..d9cf8a7 --- /dev/null +++ b/0072-libmultipath-add-ignore_udev_uid-option.patch @@ -0,0 +1,192 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 20 May 2020 16:46:55 -0500 +Subject: [PATCH] libmultipath: add ignore_udev_uid option + +Setting this option to yes will force multipath to get the uid by using +the fallback sysfs methods, instead of getting it from udev. This will +cause devices that can't get their uid from the standard locations to +not get a uid. It will also disable uevent merging. + +It will not stop uevents from being resent for device that failed to +get a WWID, although I'm on the fence about the benefit of this. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/config.h | 1 + + libmultipath/dict.c | 4 ++++ + libmultipath/discovery.c | 17 +++++++++++------ + libmultipath/discovery.h | 8 +++++++- + libmultipath/uevent.c | 2 +- + multipath/multipath.conf.5 | 13 +++++++++++++ + multipathd/main.c | 7 ++++++- + 7 files changed, 43 insertions(+), 9 deletions(-) + +diff --git a/libmultipath/config.h b/libmultipath/config.h +index 160867cd..c7a73fba 100644 +--- a/libmultipath/config.h ++++ b/libmultipath/config.h +@@ -192,6 +192,7 @@ struct config { + int find_multipaths_timeout; + int marginal_pathgroups; + int skip_delegate; ++ int ignore_udev_uid; + unsigned int version[3]; + unsigned int sequence_nr; + +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index 184d4b22..9a0729bf 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -1406,6 +1406,9 @@ declare_hw_snprint(all_tg_pt, print_yes_no_undef) + declare_def_handler(marginal_pathgroups, set_yes_no) + declare_def_snprint(marginal_pathgroups, print_yes_no) + ++declare_def_handler(ignore_udev_uid, set_yes_no) ++declare_def_snprint(ignore_udev_uid, print_yes_no) ++ + static int + def_uxsock_timeout_handler(struct config *conf, vector strvec) + { +@@ -1816,6 +1819,7 @@ init_keywords(vector keywords) + install_keyword("enable_foreign", &def_enable_foreign_handler, + &snprint_def_enable_foreign); + install_keyword("marginal_pathgroups", &def_marginal_pathgroups_handler, &snprint_def_marginal_pathgroups); ++ install_keyword("ignore_udev_uid", &def_ignore_udev_uid_handler, &snprint_def_ignore_udev_uid); + __deprecated install_keyword("default_selector", &def_selector_handler, NULL); + __deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL); + __deprecated install_keyword("default_uid_attribute", &def_uid_attribute_handler, NULL); +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index 002d3d18..f0e92227 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -2010,7 +2010,7 @@ static bool has_uid_fallback(struct path *pp) + + int + get_uid (struct path * pp, int path_state, struct udev_device *udev, +- int allow_fallback) ++ int fallback) + { + char *c; + const char *origin = "unknown"; +@@ -2043,7 +2043,9 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev, + } else + len = strlen(pp->wwid); + origin = "callout"; +- } else { ++ } else if (fallback == UID_FALLBACK_FORCE) ++ len = uid_fallback(pp, path_state, &origin); ++ else { + bool udev_available = udev && pp->uid_attribute + && *pp->uid_attribute; + +@@ -2056,8 +2058,9 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev, + else + origin = "udev"; + } +- if ((!udev_available || (len <= 0 && allow_fallback)) +- && has_uid_fallback(pp)) { ++ if ((!udev_available || ++ (len <= 0 && fallback == UID_FALLBACK_ALLOW)) && ++ has_uid_fallback(pp)) { + used_fallback = 1; + len = uid_fallback(pp, path_state, &origin); + } +@@ -2197,8 +2200,10 @@ int pathinfo(struct path *pp, struct config *conf, int mask) + } + + if ((mask & DI_WWID) && !strlen(pp->wwid)) { +- get_uid(pp, path_state, pp->udev, +- (pp->retriggers >= conf->retrigger_tries)); ++ int fallback = conf->ignore_udev_uid? UID_FALLBACK_FORCE : ++ (pp->retriggers >= conf->retrigger_tries)? ++ UID_FALLBACK_ALLOW : UID_FALLBACK_NONE; ++ get_uid(pp, path_state, pp->udev, fallback); + if (!strlen(pp->wwid)) { + if (pp->bus == SYSFS_BUS_UNDEF) + return PATHINFO_SKIPPED; +diff --git a/libmultipath/discovery.h b/libmultipath/discovery.h +index 6444887d..ca8542d6 100644 +--- a/libmultipath/discovery.h ++++ b/libmultipath/discovery.h +@@ -54,8 +54,14 @@ ssize_t sysfs_get_inquiry(struct udev_device *udev, + unsigned char *buff, size_t len); + int sysfs_get_asymmetric_access_state(struct path *pp, + char *buff, int buflen); ++ ++enum { ++ UID_FALLBACK_NONE, ++ UID_FALLBACK_ALLOW, ++ UID_FALLBACK_FORCE, ++}; + int get_uid(struct path * pp, int path_state, struct udev_device *udev, +- int allow_fallback); ++ int fallback); + + /* + * discovery bitmask +diff --git a/libmultipath/uevent.c b/libmultipath/uevent.c +index e0d13b11..d67129d1 100644 +--- a/libmultipath/uevent.c ++++ b/libmultipath/uevent.c +@@ -179,7 +179,7 @@ uevent_need_merge(void) + bool need_merge = false; + + conf = get_multipath_config(); +- if (VECTOR_SIZE(&conf->uid_attrs) > 0) ++ if (!conf->ignore_udev_uid && VECTOR_SIZE(&conf->uid_attrs) > 0) + need_merge = true; + put_multipath_config(conf); + +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 +index 42a192f6..175ca095 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5 +@@ -286,6 +286,19 @@ The default is: \fB\fR + . + . + .TP ++.B ignore_udev_uid ++Setting this option to yes will force multipath to ignore the the uid_attrs ++and uid_attribute settings, and generate the WWID by the \fIsysfs\fR ++method. This will cause devices that cannot get their WWID from the standard ++locations for their device type to not get a WWID; see \fBWWID generation\fR ++below. ++.RS ++.TP ++The default is: \fBno\fR ++.RE ++. ++. ++.TP + .B prio + The name of the path priority routine. The specified routine + should return a numeric value specifying the relative priority +diff --git a/multipathd/main.c b/multipathd/main.c +index f014d2a1..48b62937 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -1226,6 +1226,7 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) + if (pp) { + struct multipath *mpp = pp->mpp; + char wwid[WWID_SIZE]; ++ int fallback; + + if (pp->initialized == INIT_REQUESTED_UDEV) { + needs_reinit = 1; +@@ -1237,7 +1238,11 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) + goto out; + + strcpy(wwid, pp->wwid); +- rc = get_uid(pp, pp->state, uev->udev, 0); ++ conf = get_multipath_config(); ++ fallback = conf->ignore_udev_uid? UID_FALLBACK_FORCE: ++ UID_FALLBACK_NONE; ++ put_multipath_config(conf); ++ rc = get_uid(pp, pp->state, uev->udev, fallback); + + if (rc != 0) + strcpy(pp->wwid, wwid); +-- +2.17.2 + diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index b492b91..953787c 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.8.4 -Release: 3%{?dist} +Release: 4%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -57,19 +57,31 @@ Patch0044: 0044-multipathd-add-del-maps-multipathd-command.patch Patch0045: 0045-multipath-make-flushing-maps-work-like-other-command.patch Patch0046: 0046-multipath-delegate-flushing-maps-to-multipathd.patch Patch0047: 0047-multipath-add-option-to-skip-multipathd-delegation.patch -Patch0048: 0048-Makefile.inc-trim-extra-information-from-systemd-ver.patch -Patch0049: 0049-kpartx-fix-Wsign-compare-error.patch -Patch0050: 0050-RH-fixup-udev-rules-for-redhat.patch -Patch0051: 0051-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0052: 0052-RH-don-t-start-without-a-config-file.patch -Patch0053: 0053-RH-use-rpm-optflags-if-present.patch -Patch0054: 0054-RH-add-mpathconf.patch -Patch0055: 0055-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0056: 0056-RH-warn-on-invalid-regex-instead-of-failing.patch -Patch0057: 0057-RH-reset-default-find_mutipaths-value-to-off.patch -Patch0058: 0058-RH-Fix-nvme-compilation-warning.patch -Patch0059: 0059-RH-attempt-to-get-ANA-info-via-sysfs-first.patch -Patch0060: 0060-RH-work-around-gcc-10-format-truncation-issue.patch +Patch0048: 0048-libmultipath-add-device-to-hwtable.c.patch +Patch0049: 0049-master-libmultipath-fix-use-after-free-when-iscsi-lo.patch +Patch0050: 0050-libmultipath-warn-if-freeing-path-that-holds-mpp-hwe.patch +Patch0051: 0051-libmultipath-warn-about-NULL-value-of-mpp-hwe.patch +Patch0052: 0052-libmultipath-fix-mpp-hwe-handling-in-sync_paths.patch +Patch0053: 0053-Makefile.inc-trim-extra-information-from-systemd-ver.patch +Patch0054: 0054-kpartx-fix-Wsign-compare-error.patch +Patch0055: 0055-libmultipath-remove-code-duplication-in-path-countin.patch +Patch0056: 0056-libmultipath-count-pending-paths-as-active-on-loads.patch +Patch0057: 0057-libmultipath-deal-with-flushing-no-maps.patch +Patch0058: 0058-multipath-deal-with-delegation-failures-correctly.patch +Patch0059: 0059-RH-fixup-udev-rules-for-redhat.patch +Patch0060: 0060-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0061: 0061-RH-don-t-start-without-a-config-file.patch +Patch0062: 0062-RH-use-rpm-optflags-if-present.patch +Patch0063: 0063-RH-add-mpathconf.patch +Patch0064: 0064-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0065: 0065-RH-warn-on-invalid-regex-instead-of-failing.patch +Patch0066: 0066-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0067: 0067-RH-Fix-nvme-compilation-warning.patch +Patch0068: 0068-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0069: 0069-RH-work-around-gcc-10-format-truncation-issue.patch +Patch0070: 0070-multipath-add-libmpathvalid-library.patch +Patch0071: 0071-libmultipath-add-uid-failback-for-dasd-devices.patch +Patch0072: 0072-libmultipath-add-ignore_udev_uid-option.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -222,6 +234,7 @@ fi %{_libdir}/libmultipath.so.* %{_libdir}/libmpathpersist.so.* %{_libdir}/libmpathcmd.so.* +%{_libdir}/libmpathvalid.so.* %dir %{_libmpathdir} %{_libmpathdir}/* @@ -231,8 +244,10 @@ fi %doc README %{_libdir}/libmpathpersist.so %{_libdir}/libmpathcmd.so +%{_libdir}/libmpathvalid.so %{_includedir}/mpath_cmd.h %{_includedir}/mpath_persist.h +%{_includedir}/mpath_valid.h %{_mandir}/man3/mpath_persistent_reserve_in.3.gz %{_mandir}/man3/mpath_persistent_reserve_out.3.gz @@ -263,6 +278,24 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Tue Jul 21 2020 Benjamin Marzinski - 0.8.4-4 +- Rebased on top of additional commits staged for upstream + * Previous patches 0048-0060 are now patches 0053-0054 & 0059-0069 +- Add 0048-libmultipath-add-device-to-hwtable.c.patch +- Add 0049-master-libmultipath-fix-use-after-free-when-iscsi-lo.patch +- Add 0050-libmultipath-warn-if-freeing-path-that-holds-mpp-hwe.patch +- Add 0051-libmultipath-warn-about-NULL-value-of-mpp-hwe.patch +- Add 0052-libmultipath-fix-mpp-hwe-handling-in-sync_paths.patch +- Add 0055-libmultipath-remove-code-duplication-in-path-countin.patch +- Add 0056-libmultipath-count-pending-paths-as-active-on-loads.patch +- Add 0057-libmultipath-deal-with-flushing-no-maps.patch +- Add 0058-multipath-deal-with-delegation-failures-correctly.patch +- Add 0070-multipath-add-libmpathvalid-library.patch + * adds the libmpathvalid.so library to determine if devices are + valid multipath paths. +- Add 0071-libmultipath-add-uid-failback-for-dasd-devices.patch +- Add 0072-libmultipath-add-ignore_udev_uid-option.patch + * Mon Jul 13 2020 Tom Stellard - 0.8.4-3 - Use make macros - https://fedoraproject.org/wiki/Changes/UseMakeBuildInstallMacro From 3140cfbb24f450dc0d4ff4d915bc3d8db207eeaa Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Tue, 21 Jul 2020 19:45:41 -0500 Subject: [PATCH 07/67] device-mapper-multipath-0.8.4-5 Update CI tests to match RHEL * This commit also pulls in changes from Lin Li and Bruno Goncalves --- device-mapper-multipath.spec | 7 +- tests/.fmf/version | 1 + tests/bindings/Makefile | 49 --------- tests/bindings/main.sh | 4 +- tests/include/ec.sh | 8 +- tests/kpartx_4k_aligned/Makefile | 49 --------- tests/medium_error_scsi_debug/Makefile | 47 --------- tests/medium_error_scsi_debug/PURPOSE | 4 +- tests/medium_error_scsi_debug/main.sh | 45 ++++---- tests/multipath_conf_syntax/main.sh | 22 ++-- tests/multipathd_oom/Makefile | 49 --------- tests/provision.fmf | 5 + tests/restate_module/main.sh | 136 ++++++++++++------------- tests/squelch_scsi_id/Makefile | 49 --------- tests/squelch_scsi_id/main.sh | 2 +- tests/tests.yml | 36 +++++-- tests/user_friendly_names/Makefile | 49 --------- tests/user_friendly_names/main.sh | 17 ++-- 18 files changed, 166 insertions(+), 413 deletions(-) create mode 100644 tests/.fmf/version delete mode 100644 tests/bindings/Makefile delete mode 100644 tests/kpartx_4k_aligned/Makefile delete mode 100644 tests/medium_error_scsi_debug/Makefile delete mode 100644 tests/multipathd_oom/Makefile create mode 100644 tests/provision.fmf delete mode 100644 tests/squelch_scsi_id/Makefile delete mode 100644 tests/user_friendly_names/Makefile diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 953787c..5324f5d 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.8.4 -Release: 4%{?dist} +Release: 5%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -278,6 +278,11 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Tue Jul 21 2020 Benjamin Marzinski - 0.8.4-5 +- Update CI tests to match RHEL + * This commit also pulls in changes from Lin Li + and Bruno Goncalves + * Tue Jul 21 2020 Benjamin Marzinski - 0.8.4-4 - Rebased on top of additional commits staged for upstream * Previous patches 0048-0060 are now patches 0053-0054 & 0059-0069 diff --git a/tests/.fmf/version b/tests/.fmf/version new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/tests/.fmf/version @@ -0,0 +1 @@ +1 diff --git a/tests/bindings/Makefile b/tests/bindings/Makefile deleted file mode 100644 index 6fc0484..0000000 --- a/tests/bindings/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/bash - -# Copyright (c) 2016 Red Hat, Inc. -# # -# # 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 3 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 . -# -# # Author: Lin Li - -.PHONY: all install download clean - -BUILT_FILES= - -FILES=$(METADATA) Makefile PURPOSE main.sh - -run: $(FILES) build - ./main.sh - -build: $(BUILT_FILES) - chmod a+x ./main.sh - -clean: - rm -f *~ *.rpm $(BUILT_FILES) - -include /usr/share/rhts/lib/rhts-make.include - -$(METADATA): Makefile - @touch $(METADATA) - @echo "Owner: LiLin " > $(METADATA) - @echo "Name: $(TEST)" >> $(METADATA) - @echo "Path: $(TEST_DIR)" >> $(METADATA) - @echo "License: GPLv3" >> $(METADATA) - @echo "TestVersion: $(TESTVERSION)" >> $(METADATA) - @echo "Description: bindings" >> $(METADATA) - @echo "TestTime: 15m" >> $(METADATA) - @echo "RunFor: device-mapper-multipath" >> $(METADATA) - @echo "Requires: device-mapper-multipath" >> $(METADATA) - - rhts-lint $(METADATA) diff --git a/tests/bindings/main.sh b/tests/bindings/main.sh index 518333d..2d6f284 100755 --- a/tests/bindings/main.sh +++ b/tests/bindings/main.sh @@ -31,8 +31,8 @@ sleep 5 trun "multipath -F" sleep 5 terr "modprobe -r scsi_debug" -terr "modprobe scsi_debug dev_size_mb=1024 num_tgts=1 vpd_use_hostno=0 \ -add_host=2 delay=20 max_luns=2 no_lun_0=1" +terr "modprobe scsi_debug num_tgts=1 vpd_use_hostno=0 add_host=2 delay=20 \ +max_luns=2 no_lun_0=1" sleep 60 disk_path=$(get_scsi_debug_devices) diff --git a/tests/include/ec.sh b/tests/include/ec.sh index e9726eb..22dfc40 100755 --- a/tests/include/ec.sh +++ b/tests/include/ec.sh @@ -174,13 +174,7 @@ AA fi #setup scsi_debug echo "INFO: Loading scsi_debug module for simulation of mpath" - local dev_size=100 - if [ "CHK$(uname -m)" == "CHKi386" ] \ - || [ "CHK$(uname -m)" == "CHKi686" ]; then -#i386 platform cannot allocate 100 MiB in kernel space - dev_size=10 - fi - modprobe scsi_debug dev_size_mb=${dev_size} \ + modprobe scsi_debug \ num_tgts=1 vpd_use_hostno=0 \ add_host=4 delay=20 \ max_luns=2 no_lun_0=1 2>&1 1>/dev/null diff --git a/tests/kpartx_4k_aligned/Makefile b/tests/kpartx_4k_aligned/Makefile deleted file mode 100644 index fabfdc6..0000000 --- a/tests/kpartx_4k_aligned/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/bash - -# Copyright (c) 2016 Red Hat, Inc. -# # -# # 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 3 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 . -# -# # Author: Lin Li - -.PHONY: all install download clean - -BUILT_FILES= - -FILES=$(METADATA) Makefile PURPOSE main.sh - -run: $(FILES) build - ./main.sh - -build: $(BUILT_FILES) - chmod a+x ./main.sh - -clean: - rm -f *~ *.rpm $(BUILT_FILES) - -include /usr/share/rhts/lib/rhts-make.include - -$(METADATA): Makefile - @touch $(METADATA) - @echo "Owner: LiLin " > $(METADATA) - @echo "Name: $(TEST)" >> $(METADATA) - @echo "Path: $(TEST_DIR)" >> $(METADATA) - @echo "License: GPLv3" >> $(METADATA) - @echo "TestVersion: $(TESTVERSION)" >> $(METADATA) - @echo "Description: kpartx_4k_aligned" >> $(METADATA) - @echo "TestTime: 15m" >> $(METADATA) - @echo "RunFor: device-mapper-multipath" >> $(METADATA) - @echo "Requires: device-mapper-multipath" >> $(METADATA) - - rhts-lint $(METADATA) diff --git a/tests/medium_error_scsi_debug/Makefile b/tests/medium_error_scsi_debug/Makefile deleted file mode 100644 index 113012f..0000000 --- a/tests/medium_error_scsi_debug/Makefile +++ /dev/null @@ -1,47 +0,0 @@ -# Copyright (c) 2006 Red Hat, Inc. This copyrighted -# material is made available to anyone wishing to use, modify, copy, or -# redistribute it subject to the terms and conditions of the GNU General -# Public License v.2. -# -# 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, write to the Free Software Foundation, Inc., 51 -# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# Author: LiLin - - -.PHONY: all install download clean - -BUILT_FILES= - -FILES=$(METADATA) Makefile PURPOSE main.sh - -run: $(FILES) build - ./main.sh - -build: $(BUILT_FILES) - chmod a+x ./main.sh - -clean: - rm -f *~ *.rpm $(BUILT_FILES) - -include /usr/share/rhts/lib/rhts-make.include - -$(METADATA): Makefile - @touch $(METADATA) - @echo "Owner: LiLin " > $(METADATA) - @echo "Name: $(TEST)" >> $(METADATA) - @echo "Path: $(TEST_DIR)" >> $(METADATA) - @echo "License: GPLv3" >> $(METADATA) - @echo "TestVersion: $(TESTVERSION)" >> $(METADATA) - @echo "Description: CEE feedback" >> $(METADATA) - @echo "TestTime: 15m" >> $(METADATA) - @echo "RunFor: device-mapper-multipath" >> $(METADATA) - @echo "Requires: device-mapper-multipath" >> $(METADATA) - - rhts-lint $(METADATA) diff --git a/tests/medium_error_scsi_debug/PURPOSE b/tests/medium_error_scsi_debug/PURPOSE index 74e4fdc..88fa796 100644 --- a/tests/medium_error_scsi_debug/PURPOSE +++ b/tests/medium_error_scsi_debug/PURPOSE @@ -1,8 +1,8 @@ multipath: Test that some fatal errors which should not be retried, for example a medium error, correctly generate an I/O error and do not get infinitely retried. steps: -1.# modprobe scsi_debug dev_size_mb=1024 num_tgts=1 vpd_use_hostno=0 add_host=2 delay=20 max_luns=2 no_lun_0=1 opts=2 every_nth=1 +1.# modprobe scsi_debug num_tgts=1 vpd_use_hostno=0 add_host=2 delay=20 max_luns=2 no_lun_0=1 opts=2 2.# multipath -ll | grep -C 5 scsi_debug -3.# dd if=/dev/zero of=/dev/sdf bs=1024 count=262144 +3.# dd if=/dev/zero of=/dev/mapper/$mpathdev bs=1024 seek=2330 count=10 4. check if an I/O error generated diff --git a/tests/medium_error_scsi_debug/main.sh b/tests/medium_error_scsi_debug/main.sh index 23cb5e4..db2f008 100755 --- a/tests/medium_error_scsi_debug/main.sh +++ b/tests/medium_error_scsi_debug/main.sh @@ -19,37 +19,44 @@ function cleanup() { + sleep 5 + udevadm settle multipath -F - service multipathd stop - sleep 15 + sleep 5 modprobe -r scsi_debug - rt=$? - while [ $rt -ne 0 ] - do - sleep 15 - modprobe -r scsi_debug - rt=$? - done + + return 0 } yum -y install device-mapper device-mapper-multipath mpathconf --enable -modprobe scsi_debug dev_size_mb=1024 num_tgts=1 vpd_use_hostno=0 add_host=2 delay=20 max_luns=2 no_lun_0=1 opts=2 every_nth=1 +service multipathd stop +modprobe scsi_debug num_tgts=1 vpd_use_hostno=0 add_host=2 delay=20 max_luns=2 no_lun_0=1 opts=2 sleep 5 -service multipathd restart -sleep 10 -disk1=`multipath -ll | grep -A 5 scsi_debug | grep -oE "sd." | head -1` -if [ -z "$disk1" ]; then +multipath > /dev/null +sleep 5 +mpathdev=`multipath -l | grep scsi_debug | awk '{print $1}' | head -1` +if [ -z "$mpathdev" ]; then + echo "------- FAIL, no multipath device created -----" cleanup exit 1 fi +before_active=`multipath -l $mpathdev | grep "active undef" | wc -l` -IO_error=`dd if=/dev/zero of=/dev/$disk1 bs=1024 count=262144 2>&1 | grep -o "Input/output error" ` +IO_error=`dd if=/dev/zero of=/dev/mapper/$mpathdev bs=1024 seek=2330 count=10 2>&1 | grep -o "Input/output error" ` if [ -n "$IO_error" ];then - echo "------- PASS, a medium error, correctly generate an I/O error and do not get infinitely retried -----" - cleanup + after_active=`multipath -l $mpathdev | grep "active undef" | wc -l` + if [ "$before_active" -eq "$after_active" ]; then + echo "------- PASS, a medium error, correctly generated an I/O error and did not fail paths -----" + cleanup + exit 0 + else + echo "------- FAIL, paths failed -----" + cleanup + exit 1 + fi else - echo "------- FAIL, not generate an I/O error -----" + echo "------- FAIL, did not generate an I/O error -----" cleanup - exit -1 + exit 1 fi diff --git a/tests/multipath_conf_syntax/main.sh b/tests/multipath_conf_syntax/main.sh index 9572b32..f29109d 100755 --- a/tests/multipath_conf_syntax/main.sh +++ b/tests/multipath_conf_syntax/main.sh @@ -50,39 +50,46 @@ multipaths { } _EOF_ rlRun "multipath 2>&1 | grep 'missing closing quotes on line'" 0 "test missing closing quote on alias" - rlRun "multipath -r |grep mypath" 0 "mpath rename to mypath" + rlRun "multipath -r" + rlRun "multipath -ll |grep mypath" 0 "check if mpath rename to mypath successfully" # test no value for alias rlRun "sed -i 's/alias.*$/alias/g' /etc/multipath.conf" rlRun "multipath 2>&1 | grep \"missing value for option 'alias' on line\"" 0 "test no value for alias" - rlRun "multipath -r |grep mpath*" 0 "mpath rename to mpath* from mypath" + rlRun "multipath -r" + rlRun "multipath -ll |grep mpath*" 0 "check if mpath rename to mpath* from mypath successfully" # test missing starting quote on alias rlRun "sed -i 's/alias.*$/alias mypath\"/g' /etc/multipath.conf" rlRun "multipath 2>&1 |grep 'ignoring extra data starting with'" 0 "test missing starting quote on alias" - rlRun "multipath -r |grep mypath" 0 "mpath rename to mypath" + rlRun "multipath -r" + rlRun "multipath -ll |grep mypath" 0 "check if mpath rename to mypath successfully" # test wrong quote on alias rlRun "sed -i 's/alias.*$/alias /g' /etc/multipath.conf" rlRun "multipath 2>&1 | grep config" 1 "no warning" - rlRun "multipath -r |grep ''" 0 "mpath rename to " + rlRun "multipath -r" + rlRun "multipath -ll |grep ''" 0 "check if mpath rename to successfully" # test value has a space rlRun "sed -i 's/alias.*$/alias mypath test/g' /etc/multipath.conf" rlRun "multipath 2>&1 |grep 'ignoring extra data starting with'" 0 "test value has a space" - rlRun "multipath -r |grep mypath" 0 "mpath rename to mypath" + rlRun "multipath -r" + rlRun "multipath -ll |grep mypath" 0 "check if mpath rename to mypath successfully" # test wrong alias keyword rlRun "sed -i 's/alias.*$/alia mypath/g' /etc/multipath.conf" rlRun "multipath 2>&1 |grep 'invalid keyword: alia'" 0 "invalid keyword: alia" - rlRun "multipath -r |grep mpath*" 0 "mpath rename to mpath* from mypath" + rlRun "multipath -r" + rlRun "multipath -ll |grep mpath*" 0 "check if mpath rename to mpath* from mypath successfully" rlRun "sed -i 's/alia.*$/alias mypath/g' /etc/multipath.conf" # test no space between the section name and the open bracket that followed it # fix issue about if a section doesn't have a space between the section name and the open bracket, that section isn't read in. rlRun "sed -i 's/multipaths.*/multipaths{/g' /etc/multipath.conf" rlRun "multipath 2>&1 | grep config" 1 "no warning" - rlRun "multipath -r |grep mypath" 0 "mpath rename to mypath" + rlRun "multipath -r" + rlRun "multipath -ll |grep mypath" 0 "check if mpath rename to mypath successfully" # test wrong section keywords rlRun "sed -i 's/multipaths.*/ultipaths {/g' /etc/multipath.conf" @@ -95,6 +102,7 @@ _EOF_ rlPhaseEnd rlPhaseStartCleanup + rlRun "udevadm settle" rlRun "multipath -F" 0 "Flush all unused multipath device maps" rlServiceStop multipathd rlRun "modprobe -r scsi_debug" 0 "Remove scsi_debug" diff --git a/tests/multipathd_oom/Makefile b/tests/multipathd_oom/Makefile deleted file mode 100644 index 13ce211..0000000 --- a/tests/multipathd_oom/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/bash - -# Copyright (c) 2016 Red Hat, Inc. -# # -# # 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 3 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 . -# -# # Author: Lin Li - -.PHONY: all install download clean - -BUILT_FILES= - -FILES=$(METADATA) Makefile PURPOSE main.sh - -run: $(FILES) build - ./main.sh - -build: $(BUILT_FILES) - chmod a+x ./main.sh - -clean: - rm -f *~ *.rpm $(BUILT_FILES) - -include /usr/share/rhts/lib/rhts-make.include - -$(METADATA): Makefile - @touch $(METADATA) - @echo "Owner: LiLin " > $(METADATA) - @echo "Name: $(TEST)" >> $(METADATA) - @echo "Path: $(TEST_DIR)" >> $(METADATA) - @echo "License: GPLv3" >> $(METADATA) - @echo "TestVersion: $(TESTVERSION)" >> $(METADATA) - @echo "Description: multipathd invoked oom-killer" >> $(METADATA) - @echo "TestTime: 15m" >> $(METADATA) - @echo "RunFor: device-mapper-multipath" >> $(METADATA) - @echo "Requires: device-mapper-multipath" >> $(METADATA) - - rhts-lint $(METADATA) diff --git a/tests/provision.fmf b/tests/provision.fmf new file mode 100644 index 0000000..62a6eba --- /dev/null +++ b/tests/provision.fmf @@ -0,0 +1,5 @@ +--- + +standard-inventory-qcow2: + qemu: + m: 2G diff --git a/tests/restate_module/main.sh b/tests/restate_module/main.sh index 1da179b..6d5b0c5 100755 --- a/tests/restate_module/main.sh +++ b/tests/restate_module/main.sh @@ -18,81 +18,79 @@ # Author: Lin Li source ../include/ec.sh || exit 200 +tlog "running $0" -tlog "start running" -Result=FAILED -MulDevice=`rpm -qa|grep device-mapper-multipath | wc -l` -if [ $MulDevice != 2 ]; then - tlog "multi-device is not install" - exit 1 -fi -tlog "multi-device is installed" -trun "mpathconf --enable --find_multipaths n --with_module y --with_multipathd y" -trun "echo '' > /var/log/messages" +cleanup () +{ + trun "multipathd disablequeueing maps" + trun "service multipathd stop" + sleep 5 + trun "udevadm settle" + trun "multipath -F" + sleep 5 + trun "modprobe -r scsi_debug" +} + +assert () +{ + local cmd="$*" + _trun_ "$cmd" 0 + if test $? -eq 0; then + tpass_ "$cmd" ; + else + tfail_ "$cmd" ; + cleanup ; + tend ; + fi +} + +rpm -q device-mapper-multipath || yum install -y device-mapper-multipath +tlog "device-mapper-multipath is installed" +# cleanup existing devices +trun "rm /etc/multipath.conf" +trun "mpathconf --enable --with_module y" +sed -i '/^defaults[[:space:]]*{/ a\ + max_polling_interval 10 +' /etc/multipath.conf +trun "service multipathd stop" trun "multipath -F" +sleep 5 trun "modprobe -r scsi_debug" -trun "dmsetup remove_all" -OriginalDev=`multipathd show paths | grep "running" | awk '{print $2}'` -OLD_IFS="$IFS" -IFS=" " -OriginalDevList=($OriginalDev) -IFS="$OLD_IFS" +#trun "service multipathd restart" +trun "service multipathd start" +trun "modprobe scsi_debug vpd_use_hostno=0 add_host=2" +sleep 5 +mpathdev=`multipath -l | grep scsi_debug | awk '{print $1}' | head -1` +tlog "using multipathd device ${mpathdev}" +trun "multipath -ll ${mpathdev}" +pathcount=`multipathd show paths raw format "%m %t" | grep ${mpathdev} | grep "active" | wc -l` +tlog "Checking if active path count equals 2" +assert "[[ $pathcount -eq 2 ]]" -#trun "service multipathd restart" -OriPathCount=`multipathd show paths | grep -i "running" |grep -v grep|wc -l` -tlog "Original MultPathDevice = ${OriPathCount}" -trun "modprobe scsi_debug vpd_use_hostno=0 add_host=2 dev_size_mb=1024" -trun "multipath -ll" -sleep 1s -OriPathCount=`multipathd show paths | grep -i "running" |grep -v grep|wc -l` -tlog "After add tow virturl device, MultPathDevice = ${OriPathCount}" - -if [ $OriPathCount -eq 0 ];then - tlog "Virtual MultiPath is Fail" - exit 1 -fi - -tlog "offline one MultiPathDevice" -DeviceName=`multipath -ll | grep -i "sd[a|b|c|d|e|f|g|h]" | awk -F" " '{print $3}' | tail -1` -trun "echo 'offline' > /sys/block/${DeviceName}/device/state" -sleep 1s -trun "multipath -ll" -sleep 1s -trun "multipath -r" -sleep 1s +tlog "offline one path device" +pathname=`multipathd show paths raw format "%d %m" | grep ${mpathdev} | head -1 | awk '{print $1}'` +tlog "path to offline: ${pathname}" +trun "echo 'offline' > /sys/block/${pathname}/device/state" +tlog "waiting for multipathd to fail path" +sleep 15 trun "multipathd show paths" -sleep 5s -MulPathCount=`multipathd show paths | grep -i "running" |grep -v grep|wc -l` -let "RightPathCout=$OriPathCount-1" -if [ $MulPathCount != $RightPathCout ]; then - Result=FAIL - tlog "second check fail MulPathCount=$MulPathCount RightPathCout=$RightPathCout" - tlog "running result $Result" - exit 1 -fi -tlog "second check is OK MulPathCount=$MulPathCount" +pathcount=`multipathd show paths raw format "%m %t" | grep ${mpathdev} | grep "active" | wc -l` +tlog "Checking if active path count equals 1" +assert "[[ $pathcount -eq 1 ]]" -tlog "running one Multipath" -trun "echo 'running' > /sys/block/${DeviceName}/device/state" -sleep 1s -trun "multipath -ll" -sleep 4s +tlog "restore ${pathname}" +trun "echo 'running' > /sys/block/${pathname}/device/state" +sleep 10 #verified -Condition1=`grep "reinstate failed" /var/log/messages | wc -l` -Condition2=`grep "segfault" /var/log/messages | wc -l` -trun "service multipathd status > tmp_file" -Condition3=`grep " DM message failed" tmp_file | wc -l` - -trun "multipath -F" -trun "modprobe -r scsi_debug" -trun "dmsetup remove_all" - -trun "rm -f tmp_file" -tlog "Condition1=${Condition1} Condition2=${Condition2} Condition3=${Condition3}" -RESULT=PASS -[[ $Condition1 -eq 1 ]]&&[[ $Condition2 -eq 1 ]]&&[[ $Condition3 -eq 1 ]]&&RESULT=FAIL -echo "Test Result = $RESULT" -[[ $RESULT = "FAIL" ]]&&exit 1 -exit 0 +multipathd_state=`service multipathd status | grep "Active: active (running)" | wc -l` +tlog "Checking if multipathd service is running" +assert "[[ $multipathd_state -eq 1 ]]" +pathcount=`multipathd show paths raw format "%m %t" | grep ${mpathdev} | grep "active" | wc -l` +tlog "Checking if active path count equals 2" +assert "[[ $pathcount -eq 2 ]]" +path_state=`multipathd show paths raw format "%d %t %T %o" | grep ${pathname} | grep "active ready running" | wc -l` +tlog "Checking state of ${pathname}" +assert "[[ $path_state -eq 1 ]]" +tend diff --git a/tests/squelch_scsi_id/Makefile b/tests/squelch_scsi_id/Makefile deleted file mode 100644 index 6a7a713..0000000 --- a/tests/squelch_scsi_id/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/bash - -# Copyright (c) 2016 Red Hat, Inc. -# # -# # 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 3 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 . -# -# # Author: Lin Li - -.PHONY: all install download clean - -BUILT_FILES= - -FILES=$(METADATA) Makefile PURPOSE main.sh - -run: $(FILES) build - ./main.sh - -build: $(BUILT_FILES) - chmod a+x ./main.sh - -clean: - rm -f *~ *.rpm $(BUILT_FILES) - -include /usr/share/rhts/lib/rhts-make.include - -$(METADATA): Makefile - @touch $(METADATA) - @echo "Owner: LiLin " > $(METADATA) - @echo "Name: $(TEST)" >> $(METADATA) - @echo "Path: $(TEST_DIR)" >> $(METADATA) - @echo "License: GPLv3" >> $(METADATA) - @echo "TestVersion: $(TESTVERSION)" >> $(METADATA) - @echo "Description: Squelch scsi_id on multipath -ll" >> $(METADATA) - @echo "TestTime: 15m" >> $(METADATA) - @echo "RunFor: device-mapper-multipath" >> $(METADATA) - @echo "Requires: device-mapper-multipath" >> $(METADATA) - - rhts-lint $(METADATA) diff --git a/tests/squelch_scsi_id/main.sh b/tests/squelch_scsi_id/main.sh index 3394303..e75619a 100755 --- a/tests/squelch_scsi_id/main.sh +++ b/tests/squelch_scsi_id/main.sh @@ -21,7 +21,7 @@ source ../include/ec.sh || exit 200 function main (){ local exit_status=1 - + Multipath_installation || Fail "fail to install device-mapper-multipath" Print_kernel_info Print_multipath_pkginfo diff --git a/tests/tests.yml b/tests/tests.yml index 8806fee..4c396d2 100644 --- a/tests/tests.yml +++ b/tests/tests.yml @@ -5,16 +5,38 @@ # Tests suitable for classic environment - hosts: localhost roles: + - role: standard-test-basic + tags: + - classic + tests: + - medium_error_scsi_debug: + run: ./main.sh + timeout: 15m + - squelch_scsi_id: + run: ./main.sh + timeout: 15m + - multipathd_oom: + run: ./main.sh + timeout: 15m + - user_friendly_names: + run: ./main.sh + timeout: 15m + - kpartx_4k_aligned: + run: ./main.sh + timeout: 15m + - bindings: + run: ./main.sh + timeout: 15m + required_packages: + - device-mapper-multipath + - perl + - role: standard-test-beakerlib tags: - classic tests: - - medium_error_scsi_debug - - squelch_scsi_id - - multipathd_oom - - user_friendly_names - - multipath_conf_syntax - - kpartx_4k_aligned - - bindings + - multipath_conf_syntax: + timeout: 15m required_packages: - device-mapper-multipath + - perl diff --git a/tests/user_friendly_names/Makefile b/tests/user_friendly_names/Makefile deleted file mode 100644 index 80fca20..0000000 --- a/tests/user_friendly_names/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/bash - -# Copyright (c) 2016 Red Hat, Inc. -# # -# # 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 3 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 . -# -# # Author: Lin Li - -.PHONY: all install download clean - -BUILT_FILES= - -FILES=$(METADATA) Makefile PURPOSE main.sh multipath.conf.no multipath.conf.yes - -run: $(FILES) build - ./main.sh - -build: $(BUILT_FILES) - chmod a+x ./main.sh - -clean: - rm -f *~ *.rpm $(BUILT_FILES) - -include /usr/share/rhts/lib/rhts-make.include - -$(METADATA): Makefile - @touch $(METADATA) - @echo "Owner: LiLin " > $(METADATA) - @echo "Name: $(TEST)" >> $(METADATA) - @echo "Path: $(TEST_DIR)" >> $(METADATA) - @echo "License: GPLv3" >> $(METADATA) - @echo "TestVersion: $(TESTVERSION)" >> $(METADATA) - @echo "Description: user_friendly_names" >> $(METADATA) - @echo "TestTime: 15m" >> $(METADATA) - @echo "RunFor: device-mapper-multipath" >> $(METADATA) - @echo "Requires: device-mapper-multipath" >> $(METADATA) - - rhts-lint $(METADATA) diff --git a/tests/user_friendly_names/main.sh b/tests/user_friendly_names/main.sh index b8d3a36..56082fd 100755 --- a/tests/user_friendly_names/main.sh +++ b/tests/user_friendly_names/main.sh @@ -13,7 +13,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, see . +# along with this program. If not, see . # Author: Lin Li @@ -28,8 +28,8 @@ trun "mpathconf --enable --with_multipathd y --user_friendly_names y" trun "cp /etc/multipath.conf /etc/multipath.conf.$$" trun "multipath -F" -trun "modprobe scsi_debug dev_size_mb=256 num_tgts=1 vpd_use_hostno=0 \ -add_host=2 delay=20 max_luns=2 no_lun_0=1" +trun "modprobe scsi_debug num_tgts=1 vpd_use_hostno=0 add_host=2 delay=20 \ +max_luns=2 no_lun_0=1" trun "multipath" # wwid shown slowly on s390x by the script framework, but normally when run by multipath command directly # so extend sleep time @@ -43,14 +43,19 @@ mpath=$(get_mpath_disk_by_scsi_device $disk) # user_friendly_names = yes and mpath=test #cur_dir=/mnt/tests/kernel/storage/multipath/user_friendly_names/ #cur_dir=/home/test/scratch/device-mapper-multipath/user_friendly_names -trun "cat multipath.conf.yes | sed 's/your_wwid/$wwid/g' > /etc/multipath.conf" +trun "cat multipath.conf.yes | sed "s/your_wwid/$wwid/g" > /etc/multipath.conf" +trun "cat -n /etc/multipath.conf" trun "multipath -r" -tok "multipath -ll | grep -w '^test'" +echo ">>> Verify 'test ($wwid)' is present ..." +trun "multipath -ll" +tok "multipath -ll | egrep \"^test\"" # user_friendly_names = no trun "cat multipath.conf.no > /etc/multipath.conf" trun "multipath -r" -tok "multipath -ll | grep -w '^$wwid'" +echo ">>> Verify 'test' is gone but '$wwid' present ..." +trun "multipath -ll" +tok "multipath -ll | egrep \"^$wwid\"" sleep 10 tok "multipath -F $wwid" sleep 10 From c8438866fb084c0a10931520bce2166c73a924d0 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Mon, 27 Jul 2020 15:17:45 +0000 Subject: [PATCH 08/67] - Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- device-mapper-multipath.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 5324f5d..19ff1d5 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.8.4 -Release: 5%{?dist} +Release: 6%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -278,6 +278,9 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Mon Jul 27 2020 Fedora Release Engineering - 0.8.4-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + * Tue Jul 21 2020 Benjamin Marzinski - 0.8.4-5 - Update CI tests to match RHEL * This commit also pulls in changes from Lin Li From 2cf40b2f98808e3533e915c0a204b885d9da5e43 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Sun, 27 Sep 2020 00:56:23 -0500 Subject: [PATCH 09/67] device-mapper-multipath-0.8.4-7 - Add 0073-libmultipath-util-constify-function-arguments.patch - Add 0074-libmultipath-constify-file-argument-in-config-parser.patch - Add 0075-libmultipath-provide-defaults-for-get-put-_multipath.patch - Add 0076-libmpathpersist-allow-using-libmultipath-get-put-_mu.patch - Add 0077-multipath-use-get_put-_multipath_config-from-libmult.patch - Add 0078-mpathpersist-use-get-put-_multipath_config-from-libm.patch - Add 0079-libmultipath-add-udev-and-logsink-symbols.patch - Add 0080-multipath-remove-logsink-and-udev.patch - Add 0081-libmpathpersist-call-libmultipath_-init-exit.patch - Add 0082-mpathpersist-remove-logsink-and-udev.patch - Add 0083-multipathd-remove-logsink-and-udev.patch * Pull in upsteam library changes - Add 0084-libmpathvalid-use-default-_multipath_config-udev-and.patch - Add 0085-Revert-libmultipath-add-ignore_udev_uid-option.patch - Add 0086-libmultipath-change-log-level-for-null-uid_attribute.patch - Add 0087-libmultipath-orphan_paths-avoid-BUG-message.patch * update libmpathvalid to use upstream library changes. changes submitted upstream --- ...ath-util-constify-function-arguments.patch | 111 +++++++++++ ...stify-file-argument-in-config-parser.patch | 99 ++++++++++ ...vide-defaults-for-get-put-_multipath.patch | 182 +++++++++++++++++ ...allow-using-libmultipath-get-put-_mu.patch | 142 +++++++++++++ ...t_put-_multipath_config-from-libmult.patch | 68 +++++++ ...-get-put-_multipath_config-from-libm.patch | 56 ++++++ ...ltipath-add-udev-and-logsink-symbols.patch | 156 +++++++++++++++ 0080-multipath-remove-logsink-and-udev.patch | 49 +++++ ...persist-call-libmultipath_-init-exit.patch | 98 +++++++++ ...mpathpersist-remove-logsink-and-udev.patch | 52 +++++ 0083-multipathd-remove-logsink-and-udev.patch | 57 ++++++ ...e-default-_multipath_config-udev-and.patch | 180 +++++++++++++++++ ...multipath-add-ignore_udev_uid-option.patch | 186 ++++++++++++++++++ ...nge-log-level-for-null-uid_attribute.patch | 31 +++ ...ipath-orphan_paths-avoid-BUG-message.patch | 33 ++++ device-mapper-multipath.spec | 37 +++- 16 files changed, 1536 insertions(+), 1 deletion(-) create mode 100644 0073-libmultipath-util-constify-function-arguments.patch create mode 100644 0074-libmultipath-constify-file-argument-in-config-parser.patch create mode 100644 0075-libmultipath-provide-defaults-for-get-put-_multipath.patch create mode 100644 0076-libmpathpersist-allow-using-libmultipath-get-put-_mu.patch create mode 100644 0077-multipath-use-get_put-_multipath_config-from-libmult.patch create mode 100644 0078-mpathpersist-use-get-put-_multipath_config-from-libm.patch create mode 100644 0079-libmultipath-add-udev-and-logsink-symbols.patch create mode 100644 0080-multipath-remove-logsink-and-udev.patch create mode 100644 0081-libmpathpersist-call-libmultipath_-init-exit.patch create mode 100644 0082-mpathpersist-remove-logsink-and-udev.patch create mode 100644 0083-multipathd-remove-logsink-and-udev.patch create mode 100644 0084-libmpathvalid-use-default-_multipath_config-udev-and.patch create mode 100644 0085-Revert-libmultipath-add-ignore_udev_uid-option.patch create mode 100644 0086-libmultipath-change-log-level-for-null-uid_attribute.patch create mode 100644 0087-libmultipath-orphan_paths-avoid-BUG-message.patch diff --git a/0073-libmultipath-util-constify-function-arguments.patch b/0073-libmultipath-util-constify-function-arguments.patch new file mode 100644 index 0000000..d1a0763 --- /dev/null +++ b/0073-libmultipath-util-constify-function-arguments.patch @@ -0,0 +1,111 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 8 Jul 2020 09:23:20 +0200 +Subject: [PATCH] libmultipath: util: constify function arguments + +Use "const" for function arguments where possible. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/dmparser.c | 2 +- + libmultipath/util.c | 12 ++++++------ + libmultipath/util.h | 10 +++++----- + 3 files changed, 12 insertions(+), 12 deletions(-) + +diff --git a/libmultipath/dmparser.c b/libmultipath/dmparser.c +index b856a07f..27581cde 100644 +--- a/libmultipath/dmparser.c ++++ b/libmultipath/dmparser.c +@@ -18,7 +18,7 @@ + #define WORD_SIZE 64 + + static int +-merge_words(char **dst, char *word) ++merge_words(char **dst, const char *word) + { + char * p = *dst; + int len, dstlen; +diff --git a/libmultipath/util.c b/libmultipath/util.c +index 51c38c87..67e7a42f 100644 +--- a/libmultipath/util.c ++++ b/libmultipath/util.c +@@ -52,7 +52,7 @@ basenamecpy (const char *src, char *dst, size_t size) + } + + int +-filepresent (char * run) { ++filepresent (const char *run) { + struct stat buf; + + if(!stat(run, &buf)) +@@ -60,7 +60,7 @@ filepresent (char * run) { + return 0; + } + +-char *get_next_string(char **temp, char *split_char) ++char *get_next_string(char **temp, const char *split_char) + { + char *token = NULL; + token = strsep(temp, split_char); +@@ -70,9 +70,9 @@ char *get_next_string(char **temp, char *split_char) + } + + int +-get_word (char * sentence, char ** word) ++get_word (const char *sentence, char **word) + { +- char * p; ++ const char *p; + int len; + int skip = 0; + +@@ -381,7 +381,7 @@ int get_linux_version_code(void) + return _linux_version_code; + } + +-int parse_prkey(char *ptr, uint64_t *prkey) ++int parse_prkey(const char *ptr, uint64_t *prkey) + { + if (!ptr) + return 1; +@@ -398,7 +398,7 @@ int parse_prkey(char *ptr, uint64_t *prkey) + return 0; + } + +-int parse_prkey_flags(char *ptr, uint64_t *prkey, uint8_t *flags) ++int parse_prkey_flags(const char *ptr, uint64_t *prkey, uint8_t *flags) + { + char *flagstr; + +diff --git a/libmultipath/util.h b/libmultipath/util.h +index 56bd78c7..c19c5ac3 100644 +--- a/libmultipath/util.h ++++ b/libmultipath/util.h +@@ -9,9 +9,9 @@ + + size_t strchop(char *); + int basenamecpy (const char *src, char *dst, size_t size); +-int filepresent (char * run); +-char *get_next_string(char **temp, char *split_char); +-int get_word (char * sentence, char ** word); ++int filepresent (const char *run); ++char *get_next_string(char **temp, const char *split_char); ++int get_word (const char * sentence, char ** word); + size_t strlcpy(char *dst, const char *src, size_t size); + size_t strlcat(char *dst, const char *src, size_t size); + int devt2devname (char *, int, char *); +@@ -20,8 +20,8 @@ char *convert_dev(char *dev, int is_path_device); + 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 parse_prkey(const char *ptr, uint64_t *prkey); ++int parse_prkey_flags(const char *ptr, uint64_t *prkey, uint8_t *flags); + int safe_write(int fd, const void *buf, size_t count); + void set_max_fds(rlim_t max_fds); + +-- +2.17.2 + diff --git a/0074-libmultipath-constify-file-argument-in-config-parser.patch b/0074-libmultipath-constify-file-argument-in-config-parser.patch new file mode 100644 index 0000000..ffef052 --- /dev/null +++ b/0074-libmultipath-constify-file-argument-in-config-parser.patch @@ -0,0 +1,99 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 24 Sep 2020 15:37:07 +0200 +Subject: [PATCH] libmultipath: constify file argument in config parser + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/config.c | 3 +-- + libmultipath/config.h | 2 +- + libmultipath/parser.c | 9 +++++---- + libmultipath/parser.h | 2 +- + 4 files changed, 8 insertions(+), 8 deletions(-) + +diff --git a/libmultipath/config.c b/libmultipath/config.c +index a253a936..1818f8b9 100644 +--- a/libmultipath/config.c ++++ b/libmultipath/config.c +@@ -718,8 +718,7 @@ static void set_max_checkint_from_watchdog(struct config *conf) + } + #endif + +-struct config * +-load_config (char * file) ++struct config *load_config(const char *file) + { + struct config *conf = alloc_config(); + +diff --git a/libmultipath/config.h b/libmultipath/config.h +index c7a73fba..78375f2f 100644 +--- a/libmultipath/config.h ++++ b/libmultipath/config.h +@@ -253,7 +253,7 @@ void free_mptable (vector mptable); + + int store_hwe (vector hwtable, struct hwentry *); + +-struct config *load_config (char * file); ++struct config *load_config (const char *file); + struct config * alloc_config (void); + void free_config (struct config * conf); + extern struct config *get_multipath_config(void); +diff --git a/libmultipath/parser.c b/libmultipath/parser.c +index a7285a35..d150e7b2 100644 +--- a/libmultipath/parser.c ++++ b/libmultipath/parser.c +@@ -400,7 +400,7 @@ set_regex_value(vector strvec) + /* non-recursive configuration stream handler */ + static int kw_level = 0; + +-int warn_on_duplicates(vector uniques, char *str, char *file) ++int warn_on_duplicates(vector uniques, char *str, const char *file) + { + char *tmp; + int i; +@@ -444,7 +444,7 @@ is_sublevel_keyword(char *str) + } + + int +-validate_config_strvec(vector strvec, char *file) ++validate_config_strvec(vector strvec, const char *file) + { + char *str; + int i; +@@ -507,7 +507,8 @@ validate_config_strvec(vector strvec, char *file) + } + + static int +-process_stream(struct config *conf, FILE *stream, vector keywords, char *file) ++process_stream(struct config *conf, FILE *stream, vector keywords, ++ const char *file) + { + int i; + int r = 0, t; +@@ -592,7 +593,7 @@ out: + + /* Data initialization */ + int +-process_file(struct config *conf, char *file) ++process_file(struct config *conf, const char *file) + { + int r; + FILE *stream; +diff --git a/libmultipath/parser.h b/libmultipath/parser.h +index b7917052..b385fb9e 100644 +--- a/libmultipath/parser.h ++++ b/libmultipath/parser.h +@@ -78,7 +78,7 @@ extern void free_keywords(vector keywords); + extern vector alloc_strvec(char *string); + extern void *set_value(vector strvec); + extern void *set_regex_value(vector strvec); +-extern int process_file(struct config *conf, char *conf_file); ++extern int process_file(struct config *conf, const char *conf_file); + extern struct keyword * find_keyword(vector keywords, vector v, char * name); + int snprint_keyword(char *buff, int len, char *fmt, struct keyword *kw, + const void *data); +-- +2.17.2 + diff --git a/0075-libmultipath-provide-defaults-for-get-put-_multipath.patch b/0075-libmultipath-provide-defaults-for-get-put-_multipath.patch new file mode 100644 index 0000000..9fe50d0 --- /dev/null +++ b/0075-libmultipath-provide-defaults-for-get-put-_multipath.patch @@ -0,0 +1,182 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 24 Sep 2020 15:37:08 +0200 +Subject: [PATCH] libmultipath: provide defaults for {get,put}_multipath_config + +Add an implementation of get_multipath_config() and put_multipath_config() +to libmultipath. The linker's symbol lookup rules will make sure that +applications can override these functions if they need to. Defining +these functions in libmultipath avoids the need to provide stubs +for these functions in every appliation linking to libmultipath. + +libmultipath's internal functions simply refer to a static "struct config". +It must be initialized with init_config() rather than load_config(), +which always allocates a new struct for backward compatibility, and must +be teared down using uninit_config(). + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/config.c | 72 +++++++++++++++++++++++++++++++++++++------ + libmultipath/config.h | 21 +++++++++++-- + 2 files changed, 80 insertions(+), 13 deletions(-) + +diff --git a/libmultipath/config.c b/libmultipath/config.c +index 1818f8b9..422e923d 100644 +--- a/libmultipath/config.c ++++ b/libmultipath/config.c +@@ -28,6 +28,23 @@ + #include "propsel.h" + #include "version.h" + ++static struct config __internal_config; ++struct config *libmp_get_multipath_config(void) ++{ ++ return &__internal_config; ++} ++ ++struct config *get_multipath_config(void) ++ __attribute__((weak, alias("libmp_get_multipath_config"))); ++ ++void libmp_put_multipath_config(void *conf __attribute__((unused))) ++{ ++ /* empty */ ++} ++ ++void put_multipath_config(void *conf) ++ __attribute__((weak, alias("libmp_put_multipath_config"))); ++ + static int + hwe_strmatch (const struct hwentry *hwe1, const struct hwentry *hwe2) + { +@@ -575,17 +592,15 @@ restart: + return; + } + +-struct config * +-alloc_config (void) ++static struct config *alloc_config (void) + { + return (struct config *)MALLOC(sizeof(struct config)); + } + +-void +-free_config (struct config * conf) ++static void _uninit_config(struct config *conf) + { + if (!conf) +- return; ++ conf = &__internal_config; + + if (conf->multipath_dir) + FREE(conf->multipath_dir); +@@ -649,7 +664,27 @@ free_config (struct config * conf) + free_hwtable(conf->hwtable); + free_hwe(conf->overrides); + free_keywords(conf->keywords); +- FREE(conf); ++ ++ memset(conf, 0, sizeof(*conf)); ++} ++ ++void uninit_config(void) ++{ ++ _uninit_config(&__internal_config); ++} ++ ++void free_config(struct config *conf) ++{ ++ if (!conf) ++ return; ++ else if (conf == &__internal_config) { ++ condlog(0, "ERROR: %s called for internal config. Use uninit_config() instead", ++ __func__); ++ return; ++ } ++ ++ _uninit_config(conf); ++ free(conf); + } + + /* if multipath fails to process the config directory, it should continue, +@@ -718,12 +753,29 @@ static void set_max_checkint_from_watchdog(struct config *conf) + } + #endif + ++static int _init_config (const char *file, struct config *conf); ++ ++int init_config(const char *file) ++{ ++ return _init_config(file, &__internal_config); ++} ++ + struct config *load_config(const char *file) + { + struct config *conf = alloc_config(); + ++ if (conf && !_init_config(file, conf)) ++ return conf; ++ ++ free(conf); ++ return NULL; ++} ++ ++int _init_config (const char *file, struct config *conf) ++{ ++ + if (!conf) +- return NULL; ++ conf = &__internal_config; + + /* + * internal defaults +@@ -911,10 +963,10 @@ struct config *load_config(const char *file) + !conf->wwids_file || !conf->prkeys_file) + goto out; + +- return conf; ++ return 0; + out: +- free_config(conf); +- return NULL; ++ _uninit_config(conf); ++ return 1; + } + + char *get_uid_attribute_by_attrs(struct config *conf, +diff --git a/libmultipath/config.h b/libmultipath/config.h +index 78375f2f..83d179ac 100644 +--- a/libmultipath/config.h ++++ b/libmultipath/config.h +@@ -254,10 +254,25 @@ void free_mptable (vector mptable); + int store_hwe (vector hwtable, struct hwentry *); + + struct config *load_config (const char *file); +-struct config * alloc_config (void); + void free_config (struct config * conf); +-extern struct config *get_multipath_config(void); +-extern void put_multipath_config(void *); ++int init_config(const char *file); ++void uninit_config(void); ++ ++/* ++ * libmultipath provides default implementations of ++ * get_multipath_config() and put_multipath_config(). ++ * Applications using these should use init_config(file, NULL) ++ * to load the configuration, rather than load_config(file). ++ * Likewise, uninit_config() should be used for teardown, but ++ * using free_config() for that is supported, too. ++ * Applications can define their own {get,put}_multipath_config() ++ * functions, which override the library-internal ones, but ++ * could still call libmp_{get,put}_multipath_config(). ++ */ ++struct config *libmp_get_multipath_config(void); ++struct config *get_multipath_config(void); ++void libmp_put_multipath_config(void *); ++void put_multipath_config(void *); + + int parse_uid_attrs(char *uid_attrs, struct config *conf); + char *get_uid_attribute_by_attrs(struct config *conf, +-- +2.17.2 + diff --git a/0076-libmpathpersist-allow-using-libmultipath-get-put-_mu.patch b/0076-libmpathpersist-allow-using-libmultipath-get-put-_mu.patch new file mode 100644 index 0000000..c36aa90 --- /dev/null +++ b/0076-libmpathpersist-allow-using-libmultipath-get-put-_mu.patch @@ -0,0 +1,142 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 24 Sep 2020 15:37:09 +0200 +Subject: [PATCH] libmpathpersist: allow using libmultipath + {get,put}_multipath_config + +Provide an alternative init function libmpathpersist_init() which +avoids allocating a new struct config, simply using libmultipath's +internal implementation. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmpathpersist/mpath_persist.c | 42 ++++++++++++++++++++++++++++----- + libmpathpersist/mpath_persist.h | 28 ++++++++++++++++++++++ + 2 files changed, 64 insertions(+), 6 deletions(-) + +diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c +index a132f4e9..9dfc98cd 100644 +--- a/libmpathpersist/mpath_persist.c ++++ b/libmpathpersist/mpath_persist.c +@@ -37,6 +37,27 @@ + + extern struct udev *udev; + ++static void adapt_config(struct config *conf) ++{ ++ conf->force_sync = 1; ++ set_max_fds(conf->max_fds); ++} ++ ++int libmpathpersist_init(void) ++{ ++ struct config *conf; ++ int rc = 0; ++ ++ if (init_config(DEFAULT_CONFIGFILE)) { ++ condlog(0, "Failed to initialize multipath config."); ++ return 1; ++ } ++ conf = libmp_get_multipath_config(); ++ adapt_config(conf); ++ libmp_put_multipath_config(conf); ++ return rc; ++} ++ + struct config * + mpath_lib_init (void) + { +@@ -47,21 +68,30 @@ mpath_lib_init (void) + condlog(0, "Failed to initialize multipath config."); + return NULL; + } +- conf->force_sync = 1; +- set_max_fds(conf->max_fds); +- ++ adapt_config(conf); + return conf; + } + +-int +-mpath_lib_exit (struct config *conf) ++static void libmpathpersist_cleanup(void) + { + dm_lib_release(); + dm_lib_exit(); + cleanup_prio(); + cleanup_checkers(); ++} ++ ++int ++mpath_lib_exit (struct config *conf) ++{ ++ libmpathpersist_cleanup(); + free_config(conf); +- conf = NULL; ++ return 0; ++} ++ ++int libmpathpersist_exit(void) ++{ ++ libmpathpersist_cleanup(); ++ uninit_config(); + return 0; + } + +diff --git a/libmpathpersist/mpath_persist.h b/libmpathpersist/mpath_persist.h +index 7cf4faf9..91606efc 100644 +--- a/libmpathpersist/mpath_persist.h ++++ b/libmpathpersist/mpath_persist.h +@@ -175,6 +175,22 @@ struct prout_param_descriptor { /* PROUT parameter descriptor */ + * DESCRIPTION : + * Initialize device mapper multipath configuration. This function must be invoked first + * before performing reservation management functions. ++ * Either this function or mpath_lib_init() may be used. ++ * Use this function to work with libmultipath's internal "struct config". ++ * Call libmpathpersist_exit() for cleanup. ++ * RESTRICTIONS: ++ * ++ * RETURNS: 0->Success, 1->Failed. ++ */ ++extern int libmpathpersist_init (void); ++ ++/* ++ * DESCRIPTION : ++ * Initialize device mapper multipath configuration. This function must be invoked first ++ * before performing reservation management functions. ++ * Either this function or libmpathpersist_init() may be used. ++ * Use this function to work with an application-specific "struct config". ++ * Call mpath_lib_exit() for cleanup. + * RESTRICTIONS: + * + * RETURNS: struct config ->Success, NULL->Failed. +@@ -186,12 +202,24 @@ extern struct config * mpath_lib_init (void); + * DESCRIPTION : + * Release device mapper multipath configuration. This function must be invoked after + * performing reservation management functions. ++ * Use this after initialization with mpath_lib_init(). + * RESTRICTIONS: + * + * RETURNS: 0->Success, 1->Failed. + */ + extern int mpath_lib_exit (struct config *conf); + ++/* ++ * DESCRIPTION : ++ * Release device mapper multipath configuration. This function must be invoked after ++ * performing reservation management functions. ++ * Use this after initialization with libmpathpersist_init(). ++ * RESTRICTIONS: ++ * ++ * RETURNS: 0->Success, 1->Failed. ++ */ ++extern int libmpathpersist_exit (void); ++ + + /* + * DESCRIPTION : +-- +2.17.2 + diff --git a/0077-multipath-use-get_put-_multipath_config-from-libmult.patch b/0077-multipath-use-get_put-_multipath_config-from-libmult.patch new file mode 100644 index 0000000..8f0f443 --- /dev/null +++ b/0077-multipath-use-get_put-_multipath_config-from-libmult.patch @@ -0,0 +1,68 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 24 Sep 2020 15:37:10 +0200 +Subject: [PATCH] multipath: use {get_put}_multipath_config from libmultipath + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + multipath/main.c | 20 ++++---------------- + 1 file changed, 4 insertions(+), 16 deletions(-) + +diff --git a/multipath/main.c b/multipath/main.c +index ce48a932..879d7ac9 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -67,7 +67,6 @@ + + int logsink; + struct udev *udev; +-struct config *multipath_conf; + + /* + * Return values of configure(), check_path_valid(), and main(). +@@ -78,16 +77,6 @@ enum { + RTVL_RETRY, /* returned by configure(), not by main() */ + }; + +-struct config *get_multipath_config(void) +-{ +- return multipath_conf; +-} +- +-void put_multipath_config(__attribute__((unused)) void *arg) +-{ +- /* Noop for now */ +-} +- + static int + dump_config (struct config *conf, vector hwes, vector mpvec) + { +@@ -892,10 +881,9 @@ main (int argc, char *argv[]) + + udev = udev_new(); + logsink = 0; +- conf = load_config(DEFAULT_CONFIGFILE); +- if (!conf) ++ if (init_config(DEFAULT_CONFIGFILE)) + exit(RTVL_FAIL); +- multipath_conf = conf; ++ conf = get_multipath_config(); + conf->retrigger_tries = 0; + conf->force_sync = 1; + while ((arg = getopt(argc, argv, ":aAdDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { +@@ -1148,8 +1136,8 @@ out_free_config: + * the logging function (dm_write_log()), which is called there, + * references the config. + */ +- free_config(conf); +- conf = NULL; ++ put_multipath_config(conf); ++ uninit_config(); + udev_unref(udev); + if (dev) + FREE(dev); +-- +2.17.2 + diff --git a/0078-mpathpersist-use-get-put-_multipath_config-from-libm.patch b/0078-mpathpersist-use-get-put-_multipath_config-from-libm.patch new file mode 100644 index 0000000..cc601bb --- /dev/null +++ b/0078-mpathpersist-use-get-put-_multipath_config-from-libm.patch @@ -0,0 +1,56 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 24 Sep 2020 15:37:11 +0200 +Subject: [PATCH] mpathpersist: use {get,put}_multipath_config() from + libmultipath + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + mpathpersist/main.c | 16 ++-------------- + 1 file changed, 2 insertions(+), 14 deletions(-) + +diff --git a/mpathpersist/main.c b/mpathpersist/main.c +index 28bfe410..0f0db4b8 100644 +--- a/mpathpersist/main.c ++++ b/mpathpersist/main.c +@@ -43,17 +43,6 @@ void mpath_print_transport_id(struct prin_fulldescr *fdesc); + int construct_transportid(const char * inp, struct transportid transid[], int num_transportids); + + int logsink; +-struct config *multipath_conf; +- +-struct config *get_multipath_config(void) +-{ +- return multipath_conf; +-} +- +-void put_multipath_config(__attribute__((unused)) void * arg) +-{ +- /* Noop for now */ +-} + + void rcu_register_thread_memb(void) {} + +@@ -620,15 +609,14 @@ int main(int argc, char *argv[]) + } + + udev = udev_new(); +- multipath_conf = mpath_lib_init(); +- if(!multipath_conf) { ++ if (libmpathpersist_init()) { + udev_unref(udev); + exit(1); + } + + ret = handle_args(argc, argv, 0); + +- mpath_lib_exit(multipath_conf); ++ libmpathpersist_exit(); + udev_unref(udev); + + return (ret >= 0) ? ret : MPATH_PR_OTHER; +-- +2.17.2 + diff --git a/0079-libmultipath-add-udev-and-logsink-symbols.patch b/0079-libmultipath-add-udev-and-logsink-symbols.patch new file mode 100644 index 0000000..1b17a12 --- /dev/null +++ b/0079-libmultipath-add-udev-and-logsink-symbols.patch @@ -0,0 +1,156 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 24 Sep 2020 15:37:12 +0200 +Subject: [PATCH] libmultipath: add udev and logsink symbols + +With these symbols added, applications using libmultipath don't +need to define global variables "udev" and "logsink" any more. +This comes at the cost of having to call an init function. +Currently, libmultipath_init() does nothing but initialize +"udev". + +The linker's symbol lookup order still allows applications to use +their own "logsink" and "udev" variables, which will take precendence +over libmultipath's internal ones. In this case, calling +libmultipath_init() can be skipped, but like before, +udev should be initialized (using udev_new()) before making any +libmultipath calls. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/config.c | 46 +++++++++++++++++++++++++++++++++++++++++++ + libmultipath/config.h | 46 ++++++++++++++++++++++++++++++++++++++++++- + libmultipath/debug.c | 2 ++ + 3 files changed, 93 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/config.c b/libmultipath/config.c +index 422e923d..b3809433 100644 +--- a/libmultipath/config.c ++++ b/libmultipath/config.c +@@ -28,6 +28,52 @@ + #include "propsel.h" + #include "version.h" + ++/* ++ * We don't support re-initialization after ++ * libmultipath_exit(). ++ */ ++static bool libmultipath_exit_called; ++static pthread_once_t _init_once = PTHREAD_ONCE_INIT; ++static pthread_once_t _exit_once = PTHREAD_ONCE_INIT; ++struct udev *udev; ++ ++static void _udev_init(void) ++{ ++ if (udev) ++ udev_ref(udev); ++ else ++ udev = udev_new(); ++ if (!udev) ++ condlog(0, "%s: failed to initialize udev", __func__); ++} ++ ++static void _libmultipath_init(void) ++{ ++ _udev_init(); ++} ++ ++static bool _is_libmultipath_initialized(void) ++{ ++ return !libmultipath_exit_called && !!udev; ++} ++ ++int libmultipath_init(void) ++{ ++ pthread_once(&_init_once, _libmultipath_init); ++ return !_is_libmultipath_initialized(); ++} ++ ++static void _libmultipath_exit(void) ++{ ++ libmultipath_exit_called = true; ++ udev_unref(udev); ++} ++ ++void libmultipath_exit(void) ++{ ++ pthread_once(&_exit_once, _libmultipath_exit); ++} ++ + static struct config __internal_config; + struct config *libmp_get_multipath_config(void) + { +diff --git a/libmultipath/config.h b/libmultipath/config.h +index 83d179ac..089b2ac2 100644 +--- a/libmultipath/config.h ++++ b/libmultipath/config.h +@@ -235,7 +235,51 @@ struct config { + char *enable_foreign; + }; + +-extern struct udev * udev; ++/** ++ * extern variable: udev ++ * ++ * A &struct udev instance used by libmultipath. libmultipath expects ++ * a valid, initialized &struct udev in this variable. ++ * An application can define this variable itself, in which case ++ * the applications's instance will take precedence. ++ * The application can initialize and destroy this variable by ++ * calling libmultipath_init() and libmultipath_exit(), respectively, ++ * whether or not it defines the variable itself. ++ * An application can initialize udev with udev_new() before calling ++ * libmultipath_init(), e.g. if it has to make libudev calls before ++ * libmultipath calls. If an application wants to keep using the ++ * udev variable after calling libmultipath_exit(), it should have taken ++ * an additional reference on it beforehand. This is the case e.g. ++ * after initiazing udev with udev_new(). ++ */ ++extern struct udev *udev; ++ ++/** ++ * libmultipath_init() - library initialization ++ * ++ * This function initializes libmultipath data structures. ++ * It is light-weight; some other initializations, like device-mapper ++ * initialization, are done lazily when the respective functionality ++ * is required. ++ * ++ * Clean up by libmultipath_exit() when the program terminates. ++ * It is an error to call libmultipath_init() after libmultipath_exit(). ++ * Return: 0 on success, 1 on failure. ++ */ ++int libmultipath_init(void); ++ ++/** ++ * libmultipath_exit() - library un-initialization ++ * ++ * This function un-initializes libmultipath data structures. ++ * It is recommended to call this function at program exit. ++ * ++ * Calls to libmultipath_init() after libmultipath_exit() will fail ++ * (in other words, libmultipath can't be re-initialized). ++ * Any other libmultipath calls after libmultipath_exit() may cause ++ * undefined behavior. ++ */ ++void libmultipath_exit(void); + + int find_hwe (const struct _vector *hwtable, + const char * vendor, const char * product, const char *revision, +diff --git a/libmultipath/debug.c b/libmultipath/debug.c +index 4128cb90..b3a1de9e 100644 +--- a/libmultipath/debug.c ++++ b/libmultipath/debug.c +@@ -15,6 +15,8 @@ + #include "defaults.h" + #include "debug.h" + ++int logsink; ++ + void dlog (int sink, int prio, const char * fmt, ...) + { + va_list ap; +-- +2.17.2 + diff --git a/0080-multipath-remove-logsink-and-udev.patch b/0080-multipath-remove-logsink-and-udev.patch new file mode 100644 index 0000000..9c4b728 --- /dev/null +++ b/0080-multipath-remove-logsink-and-udev.patch @@ -0,0 +1,49 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 24 Sep 2020 15:37:13 +0200 +Subject: [PATCH] multipath: remove logsink and udev + +We can use libmultipath's symbols now. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + multipath/main.c | 7 ++----- + 1 file changed, 2 insertions(+), 5 deletions(-) + +diff --git a/multipath/main.c b/multipath/main.c +index 879d7ac9..322b30e0 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -65,9 +65,6 @@ + #include "file.h" + #include "valid.h" + +-int logsink; +-struct udev *udev; +- + /* + * Return values of configure(), check_path_valid(), and main(). + */ +@@ -879,7 +876,7 @@ main (int argc, char *argv[]) + int retries = -1; + bool enable_foreign = false; + +- udev = udev_new(); ++ libmultipath_init(); + logsink = 0; + if (init_config(DEFAULT_CONFIGFILE)) + exit(RTVL_FAIL); +@@ -1138,7 +1135,7 @@ out_free_config: + */ + put_multipath_config(conf); + uninit_config(); +- udev_unref(udev); ++ libmultipath_exit(); + if (dev) + FREE(dev); + #ifdef _DEBUG_ +-- +2.17.2 + diff --git a/0081-libmpathpersist-call-libmultipath_-init-exit.patch b/0081-libmpathpersist-call-libmultipath_-init-exit.patch new file mode 100644 index 0000000..2163f02 --- /dev/null +++ b/0081-libmpathpersist-call-libmultipath_-init-exit.patch @@ -0,0 +1,98 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 24 Sep 2020 15:37:14 +0200 +Subject: [PATCH] libmpathpersist: call libmultipath_{init,exit}() + +Have libmpathpersist_{init,exit} do the udev initialization, too. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmpathpersist/mpath_persist.c | 13 +++++++++---- + libmpathpersist/mpath_persist.h | 9 ++++++--- + 2 files changed, 15 insertions(+), 7 deletions(-) + +diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c +index 9dfc98cd..d1538195 100644 +--- a/libmpathpersist/mpath_persist.c ++++ b/libmpathpersist/mpath_persist.c +@@ -48,6 +48,10 @@ int libmpathpersist_init(void) + struct config *conf; + int rc = 0; + ++ if (libmultipath_init()) { ++ condlog(0, "Failed to initialize libmultipath."); ++ return 1; ++ } + if (init_config(DEFAULT_CONFIGFILE)) { + condlog(0, "Failed to initialize multipath config."); + return 1; +@@ -74,24 +78,25 @@ mpath_lib_init (void) + + static void libmpathpersist_cleanup(void) + { +- dm_lib_release(); +- dm_lib_exit(); + cleanup_prio(); + cleanup_checkers(); ++ libmultipath_exit(); ++ dm_lib_release(); ++ dm_lib_exit(); + } + + int + mpath_lib_exit (struct config *conf) + { +- libmpathpersist_cleanup(); + free_config(conf); ++ libmpathpersist_cleanup(); + return 0; + } + + int libmpathpersist_exit(void) + { +- libmpathpersist_cleanup(); + uninit_config(); ++ libmpathpersist_cleanup(); + return 0; + } + +diff --git a/libmpathpersist/mpath_persist.h b/libmpathpersist/mpath_persist.h +index 91606efc..5435eae4 100644 +--- a/libmpathpersist/mpath_persist.h ++++ b/libmpathpersist/mpath_persist.h +@@ -176,7 +176,8 @@ struct prout_param_descriptor { /* PROUT parameter descriptor */ + * Initialize device mapper multipath configuration. This function must be invoked first + * before performing reservation management functions. + * Either this function or mpath_lib_init() may be used. +- * Use this function to work with libmultipath's internal "struct config". ++ * Use this function to work with libmultipath's internal "struct config" ++ * and "struct udev". The latter will be initialized automatically. + * Call libmpathpersist_exit() for cleanup. + * RESTRICTIONS: + * +@@ -189,7 +190,8 @@ extern int libmpathpersist_init (void); + * Initialize device mapper multipath configuration. This function must be invoked first + * before performing reservation management functions. + * Either this function or libmpathpersist_init() may be used. +- * Use this function to work with an application-specific "struct config". ++ * Use this function to work with an application-specific "struct config" ++ * and "struct udev". The latter must be initialized by the application. + * Call mpath_lib_exit() for cleanup. + * RESTRICTIONS: + * +@@ -211,9 +213,10 @@ extern int mpath_lib_exit (struct config *conf); + + /* + * DESCRIPTION : +- * Release device mapper multipath configuration. This function must be invoked after ++ * Release device mapper multipath configuration a. This function must be invoked after + * performing reservation management functions. + * Use this after initialization with libmpathpersist_init(). ++ * Calling libmpathpersist_init() after libmpathpersist_exit() will fail. + * RESTRICTIONS: + * + * RETURNS: 0->Success, 1->Failed. +-- +2.17.2 + diff --git a/0082-mpathpersist-remove-logsink-and-udev.patch b/0082-mpathpersist-remove-logsink-and-udev.patch new file mode 100644 index 0000000..8dde360 --- /dev/null +++ b/0082-mpathpersist-remove-logsink-and-udev.patch @@ -0,0 +1,52 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 24 Sep 2020 15:37:15 +0200 +Subject: [PATCH] mpathpersist: remove logsink and udev + +We can use libmultipath's internal symbols now. The libmultipath +initialization is taken care of by libmpathpersist_init(). + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + mpathpersist/main.c | 6 ------ + 1 file changed, 6 deletions(-) + +diff --git a/mpathpersist/main.c b/mpathpersist/main.c +index 0f0db4b8..a25b08f0 100644 +--- a/mpathpersist/main.c ++++ b/mpathpersist/main.c +@@ -42,13 +42,10 @@ void * mpath_alloc_prin_response(int prin_sa); + void mpath_print_transport_id(struct prin_fulldescr *fdesc); + int construct_transportid(const char * inp, struct transportid transid[], int num_transportids); + +-int logsink; +- + void rcu_register_thread_memb(void) {} + + void rcu_unregister_thread_memb(void) {} + +-struct udev *udev; + + static int verbose, loglevel, noisy; + +@@ -608,16 +605,13 @@ int main(int argc, char *argv[]) + exit (1); + } + +- udev = udev_new(); + if (libmpathpersist_init()) { +- udev_unref(udev); + exit(1); + } + + ret = handle_args(argc, argv, 0); + + libmpathpersist_exit(); +- udev_unref(udev); + + return (ret >= 0) ? ret : MPATH_PR_OTHER; + } +-- +2.17.2 + diff --git a/0083-multipathd-remove-logsink-and-udev.patch b/0083-multipathd-remove-logsink-and-udev.patch new file mode 100644 index 0000000..a2b656b --- /dev/null +++ b/0083-multipathd-remove-logsink-and-udev.patch @@ -0,0 +1,57 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 24 Sep 2020 15:37:16 +0200 +Subject: [PATCH] multipathd: remove logsink and udev + +We can use the symbols from libmultipath now. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 9 +++------ + 1 file changed, 3 insertions(+), 6 deletions(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 48b62937..6a4b8b83 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -113,7 +113,6 @@ struct mpath_event_param + struct multipath *mpp; + }; + +-int logsink; + int uxsock_timeout; + int verbosity; + int bindings_read_only; +@@ -144,8 +143,6 @@ static inline enum daemon_status get_running_state(void) + */ + struct vectors * gvecs; + +-struct udev * udev; +- + struct config *multipath_conf; + + /* Local variables */ +@@ -3009,8 +3006,6 @@ child (__attribute__((unused)) void *param) + conf = rcu_dereference(multipath_conf); + rcu_assign_pointer(multipath_conf, NULL); + call_rcu(&conf->rcu, rcu_free_config); +- udev_unref(udev); +- udev = NULL; + pthread_attr_destroy(&waiter_attr); + pthread_attr_destroy(&io_err_stat_attr); + #ifdef _DEBUG_ +@@ -3114,7 +3109,9 @@ main (int argc, char *argv[]) + + pthread_cond_init_mono(&config_cond); + +- udev = udev_new(); ++ libmultipath_init(); ++ if (atexit(libmultipath_exit)) ++ condlog(3, "failed to register exit handler for libmultipath"); + libmp_udev_set_sync_support(0); + + while ((arg = getopt(argc, argv, ":dsv:k::Bniw")) != EOF ) { +-- +2.17.2 + diff --git a/0084-libmpathvalid-use-default-_multipath_config-udev-and.patch b/0084-libmpathvalid-use-default-_multipath_config-udev-and.patch new file mode 100644 index 0000000..114d0f4 --- /dev/null +++ b/0084-libmpathvalid-use-default-_multipath_config-udev-and.patch @@ -0,0 +1,180 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Sat, 26 Sep 2020 23:25:46 -0500 +Subject: [PATCH] libmpathvalid: use default *_multipath_config, udev, and + logsink + +Signed-off-by: Benjamin Marzinski +--- + libmpathvalid/libmpathvalid.version | 2 +- + libmpathvalid/mpath_valid.c | 73 ++++++++++++++++++++--------- + libmpathvalid/mpath_valid.h | 12 +++-- + 3 files changed, 61 insertions(+), 26 deletions(-) + +diff --git a/libmpathvalid/libmpathvalid.version b/libmpathvalid/libmpathvalid.version +index 4d8a8ba4..3bd0d3c5 100644 +--- a/libmpathvalid/libmpathvalid.version ++++ b/libmpathvalid/libmpathvalid.version +@@ -1,7 +1,7 @@ + MPATH_1.0 { + global: +- mpathvalid_conf; + mpathvalid_init; ++ mpathvalid_reload_config; + mpathvalid_exit; + mpathvalid_is_path; + mpathvalid_get_mode; +diff --git a/libmpathvalid/mpath_valid.c b/libmpathvalid/mpath_valid.c +index 6153e8b7..d839dbac 100644 +--- a/libmpathvalid/mpath_valid.c ++++ b/libmpathvalid/mpath_valid.c +@@ -15,9 +15,7 @@ + #include "mpath_cmd.h" + #include "valid.h" + #include "mpath_valid.h" +- +-static struct config default_config = { .verbosity = -1 }; +-struct config *mpathvalid_conf = &default_config; ++#include "debug.h" + + static unsigned int get_conf_mode(struct config *conf) + { +@@ -68,38 +66,70 @@ static int convert_result(int result) { + } + + int +-mpathvalid_init(int verbosity) ++mpathvalid_init(int verbosity, int log_style) + { + unsigned int version[3]; + struct config *conf; + +- default_config.verbosity = verbosity; +- skip_libmp_dm_init(); +- conf = load_config(DEFAULT_CONFIGFILE); +- if (!conf) ++ logsink = log_style; ++ if (libmultipath_init()) + return -1; ++ conf = get_multipath_config(); + conf->verbosity = verbosity; +- if (dm_prereq(version)) ++ put_multipath_config(conf); ++ ++ skip_libmp_dm_init(); ++ if (init_config(DEFAULT_CONFIGFILE)) + goto fail; +- memcpy(conf->version, version, sizeof(version)); ++ if (dm_prereq(version)) ++ goto fail_config; + +- mpathvalid_conf = conf; ++ conf = get_multipath_config(); ++ conf->verbosity = verbosity; ++ memcpy(conf->version, version, sizeof(version)); ++ put_multipath_config(conf); + return 0; ++ ++fail_config: ++ uninit_config(); + fail: +- free_config(conf); ++ libmultipath_exit(); + return -1; + } + + int +-mpathvalid_exit(void) ++mpathvalid_reload_config(void) + { +- struct config *conf = mpathvalid_conf; ++ int verbosity; ++ unsigned int version[3]; ++ struct config *conf; ++ ++ conf = get_multipath_config(); ++ memcpy(version, conf->version, sizeof(version)); ++ verbosity = conf->verbosity; ++ put_multipath_config(conf); + +- default_config.verbosity = -1; +- if (mpathvalid_conf == &default_config) +- return 0; +- mpathvalid_conf = &default_config; +- free_config(conf); ++ uninit_config(); ++ ++ conf = get_multipath_config(); ++ conf->verbosity = verbosity; ++ put_multipath_config(conf); ++ ++ if (init_config(DEFAULT_CONFIGFILE)) ++ return -1; ++ ++ conf = get_multipath_config(); ++ conf->verbosity = verbosity; ++ memcpy(conf->version, version, sizeof(version)); ++ put_multipath_config(conf); ++ return 0; ++} ++ ++int ++mpathvalid_exit(void) ++{ ++ uninit_config(); ++ libmultipath_exit(); + return 0; + } + +@@ -121,9 +151,10 @@ mpathvalid_is_path(const char *name, unsigned int mode, char **wwid, + + if (!name || mode >= MPATH_MAX_MODE) + return r; +- + if (nr_paths > 0 && !path_wwids) + return r; ++ if (!udev) ++ return r; + + pp = alloc_path(); + if (!pp) +@@ -136,7 +167,7 @@ mpathvalid_is_path(const char *name, unsigned int mode, char **wwid, + } + + conf = get_multipath_config(); +- if (!conf || conf == &default_config) ++ if (!conf) + goto out_wwid; + if (mode != MPATH_DEFAULT) + set_conf_mode(conf, mode); +diff --git a/libmpathvalid/mpath_valid.h b/libmpathvalid/mpath_valid.h +index 7fd8aa47..c83b8da5 100644 +--- a/libmpathvalid/mpath_valid.h ++++ b/libmpathvalid/mpath_valid.h +@@ -42,15 +42,19 @@ enum mpath_valid_result { + MPATH_IS_MAYBE_VALID, + }; + +-struct config; +-extern struct config *mpathvalid_conf; +-int mpathvalid_init(int verbosity); ++enum mpath_valid_log_style { ++ MPATH_LOG_STDIO = -1, ++ MPATH_LOG_STDIO_TIMESTAMP, ++ MPATH_LOG_SYSLOG, ++}; ++ ++int mpathvalid_init(int verbosity, int log_style); ++int mpathvalid_reload_config(void); + int mpathvalid_exit(void); + unsigned int mpathvalid_get_mode(void); + int mpathvalid_is_path(const char *name, unsigned int mode, char **wwid, + const char **path_wwids, unsigned int nr_paths); + +- + #ifdef __cplusplus + } + #endif +-- +2.17.2 + diff --git a/0085-Revert-libmultipath-add-ignore_udev_uid-option.patch b/0085-Revert-libmultipath-add-ignore_udev_uid-option.patch new file mode 100644 index 0000000..57ff199 --- /dev/null +++ b/0085-Revert-libmultipath-add-ignore_udev_uid-option.patch @@ -0,0 +1,186 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Sat, 26 Sep 2020 23:26:32 -0500 +Subject: [PATCH] Revert "libmultipath: add ignore_udev_uid option" + +This reverts commit f1350bc5c4aa445804f3f4fc8968fb46d581336e. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/config.h | 1 - + libmultipath/dict.c | 4 ---- + libmultipath/discovery.c | 17 ++++++----------- + libmultipath/discovery.h | 8 +------- + libmultipath/uevent.c | 2 +- + multipath/multipath.conf.5 | 13 ------------- + multipathd/main.c | 7 +------ + 7 files changed, 9 insertions(+), 43 deletions(-) + +diff --git a/libmultipath/config.h b/libmultipath/config.h +index 089b2ac2..576f15d1 100644 +--- a/libmultipath/config.h ++++ b/libmultipath/config.h +@@ -192,7 +192,6 @@ struct config { + int find_multipaths_timeout; + int marginal_pathgroups; + int skip_delegate; +- int ignore_udev_uid; + unsigned int version[3]; + unsigned int sequence_nr; + +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index 9a0729bf..184d4b22 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -1406,9 +1406,6 @@ declare_hw_snprint(all_tg_pt, print_yes_no_undef) + declare_def_handler(marginal_pathgroups, set_yes_no) + declare_def_snprint(marginal_pathgroups, print_yes_no) + +-declare_def_handler(ignore_udev_uid, set_yes_no) +-declare_def_snprint(ignore_udev_uid, print_yes_no) +- + static int + def_uxsock_timeout_handler(struct config *conf, vector strvec) + { +@@ -1819,7 +1816,6 @@ init_keywords(vector keywords) + install_keyword("enable_foreign", &def_enable_foreign_handler, + &snprint_def_enable_foreign); + install_keyword("marginal_pathgroups", &def_marginal_pathgroups_handler, &snprint_def_marginal_pathgroups); +- install_keyword("ignore_udev_uid", &def_ignore_udev_uid_handler, &snprint_def_ignore_udev_uid); + __deprecated install_keyword("default_selector", &def_selector_handler, NULL); + __deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL); + __deprecated install_keyword("default_uid_attribute", &def_uid_attribute_handler, NULL); +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index f0e92227..002d3d18 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -2010,7 +2010,7 @@ static bool has_uid_fallback(struct path *pp) + + int + get_uid (struct path * pp, int path_state, struct udev_device *udev, +- int fallback) ++ int allow_fallback) + { + char *c; + const char *origin = "unknown"; +@@ -2043,9 +2043,7 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev, + } else + len = strlen(pp->wwid); + origin = "callout"; +- } else if (fallback == UID_FALLBACK_FORCE) +- len = uid_fallback(pp, path_state, &origin); +- else { ++ } else { + bool udev_available = udev && pp->uid_attribute + && *pp->uid_attribute; + +@@ -2058,9 +2056,8 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev, + else + origin = "udev"; + } +- if ((!udev_available || +- (len <= 0 && fallback == UID_FALLBACK_ALLOW)) && +- has_uid_fallback(pp)) { ++ if ((!udev_available || (len <= 0 && allow_fallback)) ++ && has_uid_fallback(pp)) { + used_fallback = 1; + len = uid_fallback(pp, path_state, &origin); + } +@@ -2200,10 +2197,8 @@ int pathinfo(struct path *pp, struct config *conf, int mask) + } + + if ((mask & DI_WWID) && !strlen(pp->wwid)) { +- int fallback = conf->ignore_udev_uid? UID_FALLBACK_FORCE : +- (pp->retriggers >= conf->retrigger_tries)? +- UID_FALLBACK_ALLOW : UID_FALLBACK_NONE; +- get_uid(pp, path_state, pp->udev, fallback); ++ get_uid(pp, path_state, pp->udev, ++ (pp->retriggers >= conf->retrigger_tries)); + if (!strlen(pp->wwid)) { + if (pp->bus == SYSFS_BUS_UNDEF) + return PATHINFO_SKIPPED; +diff --git a/libmultipath/discovery.h b/libmultipath/discovery.h +index ca8542d6..6444887d 100644 +--- a/libmultipath/discovery.h ++++ b/libmultipath/discovery.h +@@ -54,14 +54,8 @@ ssize_t sysfs_get_inquiry(struct udev_device *udev, + unsigned char *buff, size_t len); + int sysfs_get_asymmetric_access_state(struct path *pp, + char *buff, int buflen); +- +-enum { +- UID_FALLBACK_NONE, +- UID_FALLBACK_ALLOW, +- UID_FALLBACK_FORCE, +-}; + int get_uid(struct path * pp, int path_state, struct udev_device *udev, +- int fallback); ++ int allow_fallback); + + /* + * discovery bitmask +diff --git a/libmultipath/uevent.c b/libmultipath/uevent.c +index d67129d1..e0d13b11 100644 +--- a/libmultipath/uevent.c ++++ b/libmultipath/uevent.c +@@ -179,7 +179,7 @@ uevent_need_merge(void) + bool need_merge = false; + + conf = get_multipath_config(); +- if (!conf->ignore_udev_uid && VECTOR_SIZE(&conf->uid_attrs) > 0) ++ if (VECTOR_SIZE(&conf->uid_attrs) > 0) + need_merge = true; + put_multipath_config(conf); + +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 +index 175ca095..42a192f6 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5 +@@ -286,19 +286,6 @@ The default is: \fB\fR + . + . + .TP +-.B ignore_udev_uid +-Setting this option to yes will force multipath to ignore the the uid_attrs +-and uid_attribute settings, and generate the WWID by the \fIsysfs\fR +-method. This will cause devices that cannot get their WWID from the standard +-locations for their device type to not get a WWID; see \fBWWID generation\fR +-below. +-.RS +-.TP +-The default is: \fBno\fR +-.RE +-. +-. +-.TP + .B prio + The name of the path priority routine. The specified routine + should return a numeric value specifying the relative priority +diff --git a/multipathd/main.c b/multipathd/main.c +index 6a4b8b83..94926b57 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -1223,7 +1223,6 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) + if (pp) { + struct multipath *mpp = pp->mpp; + char wwid[WWID_SIZE]; +- int fallback; + + if (pp->initialized == INIT_REQUESTED_UDEV) { + needs_reinit = 1; +@@ -1235,11 +1234,7 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) + goto out; + + strcpy(wwid, pp->wwid); +- conf = get_multipath_config(); +- fallback = conf->ignore_udev_uid? UID_FALLBACK_FORCE: +- UID_FALLBACK_NONE; +- put_multipath_config(conf); +- rc = get_uid(pp, pp->state, uev->udev, fallback); ++ rc = get_uid(pp, pp->state, uev->udev, 0); + + if (rc != 0) + strcpy(pp->wwid, wwid); +-- +2.17.2 + diff --git a/0086-libmultipath-change-log-level-for-null-uid_attribute.patch b/0086-libmultipath-change-log-level-for-null-uid_attribute.patch new file mode 100644 index 0000000..8567bc3 --- /dev/null +++ b/0086-libmultipath-change-log-level-for-null-uid_attribute.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 22 Sep 2020 16:03:31 -0500 +Subject: [PATCH] libmultipath: change log level for null uid_attribute + +If uid_attribute is explicitly set to an empty string, multipath should +log the uid at the default log level, since using the fallback code is +the expected behavior. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/discovery.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index 002d3d18..77468524 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -2058,7 +2058,8 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev, + } + if ((!udev_available || (len <= 0 && allow_fallback)) + && has_uid_fallback(pp)) { +- used_fallback = 1; ++ if (udev_available || !(udev && pp->uid_attribute)) ++ used_fallback = 1; + len = uid_fallback(pp, path_state, &origin); + } + } +-- +2.17.2 + diff --git a/0087-libmultipath-orphan_paths-avoid-BUG-message.patch b/0087-libmultipath-orphan_paths-avoid-BUG-message.patch new file mode 100644 index 0000000..3dcc3a4 --- /dev/null +++ b/0087-libmultipath-orphan_paths-avoid-BUG-message.patch @@ -0,0 +1,33 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 11 Aug 2020 21:08:27 +0200 +Subject: [PATCH] libmultipath: orphan_paths(): avoid BUG message + +Since c44d769, we print a BUG message when we orphan a path that +holds the mpp->hwe pointer. But if this called via orphan_paths(), +this is expected and we shouldn't warn. + +Fixes: c44d769 ("libmultipath: warn if freeing path that holds mpp->hwe") + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/structs_vec.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c +index ede14297..d70bb6ad 100644 +--- a/libmultipath/structs_vec.c ++++ b/libmultipath/structs_vec.c +@@ -114,6 +114,8 @@ void orphan_paths(vector pathvec, struct multipath *mpp, const char *reason) + int i; + struct path * pp; + ++ /* Avoid BUG message from orphan_path() */ ++ mpp->hwe = NULL; + vector_foreach_slot (pathvec, pp, i) { + if (pp->mpp == mpp) { + orphan_path(pp, reason); +-- +2.17.2 + diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 19ff1d5..7b4fb7a 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.8.4 -Release: 6%{?dist} +Release: 7%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -82,6 +82,21 @@ Patch0069: 0069-RH-work-around-gcc-10-format-truncation-issue.patch Patch0070: 0070-multipath-add-libmpathvalid-library.patch Patch0071: 0071-libmultipath-add-uid-failback-for-dasd-devices.patch Patch0072: 0072-libmultipath-add-ignore_udev_uid-option.patch +Patch0073: 0073-libmultipath-util-constify-function-arguments.patch +Patch0074: 0074-libmultipath-constify-file-argument-in-config-parser.patch +Patch0075: 0075-libmultipath-provide-defaults-for-get-put-_multipath.patch +Patch0076: 0076-libmpathpersist-allow-using-libmultipath-get-put-_mu.patch +Patch0077: 0077-multipath-use-get_put-_multipath_config-from-libmult.patch +Patch0078: 0078-mpathpersist-use-get-put-_multipath_config-from-libm.patch +Patch0079: 0079-libmultipath-add-udev-and-logsink-symbols.patch +Patch0080: 0080-multipath-remove-logsink-and-udev.patch +Patch0081: 0081-libmpathpersist-call-libmultipath_-init-exit.patch +Patch0082: 0082-mpathpersist-remove-logsink-and-udev.patch +Patch0083: 0083-multipathd-remove-logsink-and-udev.patch +Patch0084: 0084-libmpathvalid-use-default-_multipath_config-udev-and.patch +Patch0085: 0085-Revert-libmultipath-add-ignore_udev_uid-option.patch +Patch0086: 0086-libmultipath-change-log-level-for-null-uid_attribute.patch +Patch0087: 0087-libmultipath-orphan_paths-avoid-BUG-message.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -278,6 +293,26 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Sun Sep 27 2020 Benjamin Marzinski - 0.8.4-7 +- Add 0073-libmultipath-util-constify-function-arguments.patch +- Add 0074-libmultipath-constify-file-argument-in-config-parser.patch +- Add 0075-libmultipath-provide-defaults-for-get-put-_multipath.patch +- Add 0076-libmpathpersist-allow-using-libmultipath-get-put-_mu.patch +- Add 0077-multipath-use-get_put-_multipath_config-from-libmult.patch +- Add 0078-mpathpersist-use-get-put-_multipath_config-from-libm.patch +- Add 0079-libmultipath-add-udev-and-logsink-symbols.patch +- Add 0080-multipath-remove-logsink-and-udev.patch +- Add 0081-libmpathpersist-call-libmultipath_-init-exit.patch +- Add 0082-mpathpersist-remove-logsink-and-udev.patch +- Add 0083-multipathd-remove-logsink-and-udev.patch + * Pull in upsteam library changes +- Add 0084-libmpathvalid-use-default-_multipath_config-udev-and.patch +- Add 0085-Revert-libmultipath-add-ignore_udev_uid-option.patch +- Add 0086-libmultipath-change-log-level-for-null-uid_attribute.patch +- Add 0087-libmultipath-orphan_paths-avoid-BUG-message.patch + * update libmpathvalid to use upstream library changes. changes + submitted upstream + * Mon Jul 27 2020 Fedora Release Engineering - 0.8.4-6 - Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild From d5b202726fc18b45fa8f03e5c72b6ec918e14814 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Thu, 17 Dec 2020 04:27:34 +0000 Subject: [PATCH 10/67] Add BuildRequires: make https://fedoraproject.org/wiki/Changes/Remove_make_from_BuildRoot --- device-mapper-multipath.spec | 1 + 1 file changed, 1 insertion(+) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 7b4fb7a..053e0d3 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -124,6 +124,7 @@ BuildRequires: readline-devel, ncurses-devel BuildRequires: systemd-units, systemd-devel BuildRequires: json-c-devel, perl-interpreter, pkgconfig, gcc BuildRequires: userspace-rcu-devel +BuildRequires: make %description %{name} provides tools to manage multipath devices by From 1dad67a5af60eb8d17756c72c863327a56a903c0 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Tue, 19 Jan 2021 18:06:09 -0600 Subject: [PATCH 11/67] device-mapper-multipath-0.8.5-1 Update Source to upstream version 0.8.5 plus post tag commits * Patches 0001-0102 are from https://github.com/openSUSE/multipath-tools/tree/queue and are already queued for upstream. Rename files * Previous patches 0059-0068 are now patches 0103-0111 --- .gitignore | 1 + ...path.conf-manpage-uxsock_timeout-def.patch | 30 + ...limit-PRIN-allocation-length-to-8192.patch | 35 - ...format_transportids-avoid-PROUT-over.patch | 93 --- ...find_mpe-don-t-match-with-empty-WWID.patch | 27 + ...mpath_format_readfullstatus-use-real.patch | 54 -- ...ibmultipath-copy-mpp-hwe-from-pp-hwe.patch | 260 ++++++ ...th-assign-variable-to-make-gcc-happy.patch | 42 - ...map_present_by_uuid-fix-dm_task_crea.patch | 31 + 0005-libdmmp-tests-fix-compilation.patch | 43 + ...ath-don-t-close-fd-on-dm_lib_release.patch | 66 -- ...ow-force-reload-with-no-active-paths.patch | 64 -- ...io-constify-some-function-parameters.patch | 53 ++ ...nor-DM_UDEV_DISABLE_OTHER_RULES_FLAG.patch | 30 - ...ckers-prio-allow-non-lazy-.so-loadin.patch | 90 ++ ...ck-for-skip_kpartx-on-synthetic-ueve.patch | 43 - ...Makefiles-separate-rules-for-.so-and.patch | 96 +++ ...bmpathpersist-depend-on-libmultipath.patch | 31 - ...h-create-separate-.so-for-unit-tests.patch | 87 ++ ...bmultipath-add-linker-version-script.patch | 303 +++++++ ...Makefile-more-dependency-fixes-for-p.patch | 33 - ...athpersist-add-linker-version-script.patch | 81 ++ ...s-Makefile.inc-separate-out-OPTFLAGS.patch | 44 - ...ibmpathcmd-add-linker-version-script.patch | 74 ++ ...Makefile.inc-allow-user-settings-for.patch | 33 - ...sist-initialize-mpp-hwe-in-get_mpvec.patch | 38 + ...Makefile.inc-set-Wno-error-clobbered.patch | 32 - ...scovery.c-use-z-qualifier-for-size_t.patch | 90 -- ...athd-allow-shutdown-during-configure.patch | 140 ++++ ...minate-more-signed-unsigned-comparis.patch | 198 ----- ...-sending-READY-1-to-systemd-on-early.patch | 67 ++ ...ipath-set_uint-fix-parsing-for-32bit.patch | 48 -- ...nd-STOPPING-1-to-systemd-on-shutdown.patch | 31 + ...tests-Makefile-add-lmpathcmd-to-LIBD.patch | 28 - ...RELOADING-1-to-systemd-on-DAEMON_CON.patch | 42 + ...tests-Makefile-Fix-OBJDEPS-for-hwtab.patch | 34 - ...volatile-qualifier-for-running_state.patch | 31 + ...tests-test-lib.c-drop-__wrap_is_clai.patch | 33 - ...alize-and-fix-wait_for_state_change_.patch | 72 ++ ...tests-directio-fix-Wmaybe-uninitaliz.patch | 29 - ..._config_state-avoid-code-duplication.patch | 55 ++ ...ltipath-move-libsg-into-libmultipath.patch | 83 -- ...cancel-threads-early-during-shutdown.patch | 61 ++ ...ools-Makefile-add-install-dependency.patch | 32 - ...s-don-t-call-dm_lib_release-any-more.patch | 165 ++++ ...mapper-refactor-libdm-version-determ.patch | 506 ++++++++++++ ...ultipath-make-libmp_dm_init-optional.patch | 89 -- ...e-sysfs_is_multipathed-able-to-retur.patch | 108 --- ...tect-racy-libdevmapper-calls-with-a-.patch | 437 ++++++++++ ...stify-file-argument-in-config-parser.patch | 29 +- ...multipath-centralize-validation-code.patch | 777 ------------------ 0026-Unit-tests-for-is_path_valid.patch | 530 ------------ ...vide-defaults-for-get-put-_multipath.patch | 50 +- ...allow-using-libmultipath-get-put-_mu.patch | 32 +- ...bmultipath-simplify-failed-wwid-code.patch | 205 ----- ...se-atomic-linkat-in-mark_failed_wwid.patch | 96 --- ...t_put-_multipath_config-from-libmult.patch | 15 +- 0029-fix-boolean-value-with-json-c-0.14.patch | 41 - ...-get-put-_multipath_config-from-libm.patch | 7 +- ...ltipath-add-udev-and-logsink-symbols.patch | 46 +- ...-condlog-NULL-argument-in-uevent_get.patch | 46 -- ...et-enable_foreign-to-NONE-by-default.patch | 49 -- ...31-multipath-remove-logsink-and-udev.patch | 13 +- ...persist-call-libmultipath_-init-exit.patch | 14 +- ...e-option-to-enable-foreign-libraries.patch | 89 -- ...move-_blacklist_exceptions-functions.patch | 139 ---- ...mpathpersist-remove-logsink-and-udev.patch | 8 +- ...-parser-issue-with-comments-in-strin.patch | 95 --- ...4-multipathd-remove-logsink-and-udev.patch | 14 +- ...ert-regexes-that-start-with-exclamat.patch | 435 ---------- ...-add-Vexata-by-StorCentric-VX-arrays.patch | 40 + ...mpiler-warnings-when-built-without-s.patch | 111 --- ...Violin-and-Nexsan-were-bought-by-Sto.patch | 45 + ...h-fix-memory-leaks-in-coalesce_paths.patch | 117 +++ ...ipath-fix-sysfs-dev_loss_tmo-parsing.patch | 43 - 0038-kpartx-read-devices-with-direct-IO.patch | 267 ------ ...replace-hidden-tab-by-space-in-hwtab.patch | 31 + ...dle-alternate-bsd-disklabel-location.patch | 53 -- ...ipathd-uxlsnr-avoid-deadlock-on-exit.patch | 105 +++ ...x-checker-detection-for-nvme-devices.patch | 62 -- 0040-multipathd-Fix-liburcu-memory-leak.patch | 98 +++ ...e-dm_get_map-status-return-codes-sym.patch | 322 -------- ...handling-of-io_err_stat_attr-into-li.patch | 146 ++++ ...x-check_path-errors-with-removed-map.patch | 116 --- ...vecs-desctruction-into-cleanup-funct.patch | 125 +++ ...e-dm_flush_maps-only-return-0-on-suc.patch | 46 -- ...-multipathd-make-some-globals-static.patch | 45 + ...athd-add-del-maps-multipathd-command.patch | 161 ---- ...threads-destruction-into-separate-fu.patch | 164 ++++ ...lushing-maps-work-like-other-command.patch | 104 --- ...conf-destruction-into-separate-funct.patch | 56 ++ ...delegate-flushing-maps-to-multipathd.patch | 64 -- ...pid-destruction-into-separate-functi.patch | 42 + ...option-to-skip-multipathd-delegation.patch | 63 -- 0047-multipathd-close-pidfile-on-exit.patch | 45 + ...libmultipath-add-device-to-hwtable.c.patch | 44 - ...elper-for-systemd-notification-at-ex.patch | 60 ++ ...ath-fix-use-after-free-when-iscsi-lo.patch | 84 -- ...ld-call-cleanups-in-failure-case-too.patch | 52 ++ ...n-if-freeing-path-that-holds-mpp-hwe.patch | 33 - ...ch_all_dmevents-check-if-waiter-is-i.patch | 28 + ...ath-warn-about-NULL-value-of-mpp-hwe.patch | 33 - ...-error-message-if-config-can-t-be-lo.patch | 30 + 0052-libmultipath-add-libmp_dm_exit.patch | 92 +++ ...h-fix-mpp-hwe-handling-in-sync_paths.patch | 45 - ...m-extra-information-from-systemd-ver.patch | 30 - ...tipathd-fixup-libdm-deinitialization.patch | 40 + 0054-kpartx-fix-Wsign-compare-error.patch | 26 - ..._thread_stop-check-if-logarea-is-ini.patch | 29 + ...ove-code-duplication-in-path-countin.patch | 129 --- ...pathd-add-cleanup_child-exit-handler.patch | 95 +++ ...unt-pending-paths-as-active-on-loads.patch | 73 -- ...-fix-log_thread-startup-and-teardown.patch | 148 ++++ ...multipath-deal-with-flushing-no-maps.patch | 33 - ...cleanup_-prio-checkers-foreign-to-li.patch | 93 +++ ...l-with-delegation-failures-correctly.patch | 39 - ...path-use-atexit-for-cleanup-handlers.patch | 110 +++ ...sist-use-atexit-for-cleanup-handlers.patch | 32 + ...ltipath-fix-leak-in-check_path_valid.patch | 95 +++ ...mpath-tools.supp-file-with-valgrind-.patch | 62 ++ ...e-libmp_verbosity-to-track-verbosity.patch | 441 ++++++++++ ...ntroduce-symbolic-values-for-logsink.patch | 185 +++++ 0064-libmultipath-simplify-dlog.patch | 152 ++++ ...-on-invalid-regex-instead-of-failing.patch | 121 --- ...d-common-code-for-k-and-command-args.patch | 87 ++ 0066-multipathd-sanitize-uxsock_listen.patch | 157 ++++ ...-race-between-log_safe-and-log_threa.patch | 107 +++ ...-multipath-add-libmpathvalid-library.patch | 284 +++++-- ...round-gcc-10-format-truncation-issue.patch | 31 - ...tests-and-unit-tests-for-libmpathval.patch | 532 ++++++++++++ ...th-add-uid-failback-for-dasd-devices.patch | 11 +- ...nge-log-level-for-null-uid_attribute.patch | 26 +- ...multipath-add-ignore_udev_uid-option.patch | 192 ----- ...ve-fast_io_fail-defines-to-structs.h.patch | 160 ++++ ...-eh_deadline-multipath.conf-paramete.patch | 338 ++++++++ ...ath-util-constify-function-arguments.patch | 111 --- ...e-redundant-vector_free-int-configur.patch | 37 + ...factor-out-code-to-get-vpd-page-data.patch | 66 ++ ...ultipath-limit-reading-0xc9-vpd-page.patch | 91 ++ ...ath-move-logq_lock-handling-to-log.c.patch | 141 ++++ ...ipath-protect-logarea-with-logq_lock.patch | 110 +++ ...vent-DSO-unloading-with-astray-check.patch | 284 +++++++ ...-force-map-reload-if-udev-incomplete.patch | 151 ++++ ...-tools-avoid-access-to-etc-localtime.patch | 112 +++ ...make-sure-plugin-DSOs-use-symbol-ver.patch | 149 ++++ ...multipath.version-add-missing-symbol.patch | 30 + ...e-default-_multipath_config-udev-and.patch | 180 ---- ...tests-unversioned-.so-for-valgrind-t.patch | 30 + ...multipath-add-ignore_udev_uid-option.patch | 186 ----- ...unit-tests-fix-memory-leaks-in-mpath.patch | 53 ++ ...x-Register-and-Ignore-with-0x00-SARK.patch | 34 + ...ipath-orphan_paths-avoid-BUG-message.patch | 33 - ...ate-prkeys-file-on-changing-registra.patch | 39 + ...n-about-missing-braces-at-end-of-mul.patch | 42 + ...ore-multipaths-sections-without-wwid.patch | 37 + ...tipath-fix-format-warning-with-clang.patch | 28 + ...th-check-for-null-wwid-before-strcmp.patch | 34 + ...-Improve-checker_timeout-description.patch | 65 ++ ...ath-checkint-not-changed-when-path-s.patch | 36 + ...ect_action-skip-is_mpp_known_to_udev.patch | 51 ++ ...lesce_paths-stop-triggering-spurious.patch | 65 ++ ...d-uev_trigger-handle-incomplete-ADD-.patch | 61 ++ ...ath-make-find_err_path_by_dev-static.patch | 27 + ...id-io_err_stat-crash-during-shutdown.patch | 257 ++++++ ...athd-avoid-io_err_stat-ABBA-deadlock.patch | 146 ++++ ...et_monotonic_time-in-io_err_stat-cod.patch | 111 +++ ...ne-free_io_err_stat_path-and-destroy.patch | 101 +++ ...d-cleanup-logging-for-marginal-paths.patch | 123 +++ ... 0103-RH-fixup-udev-rules-for-redhat.patch | 2 +- ...property-blacklist-exception-builtin.patch | 35 +- ...RH-don-t-start-without-a-config-file.patch | 25 +- ...H-Fix-nvme-function-missing-argument.patch | 5 +- ... 0107-RH-use-rpm-optflags-if-present.patch | 8 +- ...hconf.patch => 0108-RH-add-mpathconf.patch | 62 +- ...om-kernel-cmdline-mpath.wwids-with-A.patch | 87 +- ...-default-find_mutipaths-value-to-off.patch | 4 +- ...empt-to-get-ANA-info-via-sysfs-first.patch | 0 device-mapper-multipath.spec | 215 +++-- sources | 2 +- 179 files changed, 10110 insertions(+), 7109 deletions(-) create mode 100644 0001-Change-the-multipath.conf-manpage-uxsock_timeout-def.patch delete mode 100644 0001-libmpathpersist-limit-PRIN-allocation-length-to-8192.patch delete mode 100644 0002-libmpathpersist-format_transportids-avoid-PROUT-over.patch create mode 100644 0002-libmultipath-find_mpe-don-t-match-with-empty-WWID.patch delete mode 100644 0003-libmpathpersist-mpath_format_readfullstatus-use-real.patch create mode 100644 0003-libmultipath-copy-mpp-hwe-from-pp-hwe.patch delete mode 100644 0004-libmultipath-assign-variable-to-make-gcc-happy.patch create mode 100644 0004-libmultipath-dm_map_present_by_uuid-fix-dm_task_crea.patch create mode 100644 0005-libdmmp-tests-fix-compilation.patch delete mode 100644 0005-libmutipath-don-t-close-fd-on-dm_lib_release.patch delete mode 100644 0006-libmultipath-allow-force-reload-with-no-active-paths.patch create mode 100644 0006-libmultipath-prio-constify-some-function-parameters.patch delete mode 100644 0007-kpartx.rules-honor-DM_UDEV_DISABLE_OTHER_RULES_FLAG.patch create mode 100644 0007-libmultipath-checkers-prio-allow-non-lazy-.so-loadin.patch delete mode 100644 0008-kpartx.rules-check-for-skip_kpartx-on-synthetic-ueve.patch create mode 100644 0008-multipath-tools-Makefiles-separate-rules-for-.so-and.patch delete mode 100644 0009-libmpathpersist-depend-on-libmultipath.patch create mode 100644 0009-libmultipath-create-separate-.so-for-unit-tests.patch create mode 100644 0010-libmultipath-add-linker-version-script.patch delete mode 100644 0010-multipath-tools-Makefile-more-dependency-fixes-for-p.patch create mode 100644 0011-libmpathpersist-add-linker-version-script.patch delete mode 100644 0011-multipath-tools-Makefile.inc-separate-out-OPTFLAGS.patch create mode 100644 0012-libmpathcmd-add-linker-version-script.patch delete mode 100644 0012-multipath-tools-Makefile.inc-allow-user-settings-for.patch create mode 100644 0013-libmpathpersist-initialize-mpp-hwe-in-get_mpvec.patch delete mode 100644 0013-multipath-tools-Makefile.inc-set-Wno-error-clobbered.patch delete mode 100644 0014-libmultipath-discovery.c-use-z-qualifier-for-size_t.patch create mode 100644 0014-multipathd-allow-shutdown-during-configure.patch delete mode 100644 0015-libmultipath-eliminate-more-signed-unsigned-comparis.patch create mode 100644 0015-multipathd-avoid-sending-READY-1-to-systemd-on-early.patch delete mode 100644 0016-libmultipath-set_uint-fix-parsing-for-32bit.patch create mode 100644 0016-multipathd-send-STOPPING-1-to-systemd-on-shutdown.patch delete mode 100644 0017-multipath-tools-tests-Makefile-add-lmpathcmd-to-LIBD.patch create mode 100644 0017-multipathd-send-RELOADING-1-to-systemd-on-DAEMON_CON.patch delete mode 100644 0018-multipath-tools-tests-Makefile-Fix-OBJDEPS-for-hwtab.patch create mode 100644 0018-multipathd-use-volatile-qualifier-for-running_state.patch delete mode 100644 0019-multipath-tools-tests-test-lib.c-drop-__wrap_is_clai.patch create mode 100644 0019-multipathd-generalize-and-fix-wait_for_state_change_.patch delete mode 100644 0020-multipath-tools-tests-directio-fix-Wmaybe-uninitaliz.patch create mode 100644 0020-multipathd-set_config_state-avoid-code-duplication.patch delete mode 100644 0021-libmultipath-move-libsg-into-libmultipath.patch create mode 100644 0021-multipathd-cancel-threads-early-during-shutdown.patch delete mode 100644 0022-multipath-tools-Makefile-add-install-dependency.patch create mode 100644 0022-multipath-tools-don-t-call-dm_lib_release-any-more.patch create mode 100644 0023-libmultipath-devmapper-refactor-libdm-version-determ.patch delete mode 100644 0023-libmultipath-make-libmp_dm_init-optional.patch delete mode 100644 0024-libmultipath-make-sysfs_is_multipathed-able-to-retur.patch create mode 100644 0024-libmultipath-protect-racy-libdevmapper-calls-with-a-.patch rename 0074-libmultipath-constify-file-argument-in-config-parser.patch => 0025-libmultipath-constify-file-argument-in-config-parser.patch (79%) delete mode 100644 0025-multipath-centralize-validation-code.patch delete mode 100644 0026-Unit-tests-for-is_path_valid.patch rename 0075-libmultipath-provide-defaults-for-get-put-_multipath.patch => 0026-libmultipath-provide-defaults-for-get-put-_multipath.patch (78%) rename 0076-libmpathpersist-allow-using-libmultipath-get-put-_mu.patch => 0027-libmpathpersist-allow-using-libmultipath-get-put-_mu.patch (81%) delete mode 100644 0027-libmultipath-simplify-failed-wwid-code.patch delete mode 100644 0028-libmultipath-use-atomic-linkat-in-mark_failed_wwid.patch rename 0077-multipath-use-get_put-_multipath_config-from-libmult.patch => 0028-multipath-use-get_put-_multipath_config-from-libmult.patch (81%) delete mode 100644 0029-fix-boolean-value-with-json-c-0.14.patch rename 0078-mpathpersist-use-get-put-_multipath_config-from-libm.patch => 0029-mpathpersist-use-get-put-_multipath_config-from-libm.patch (88%) rename 0079-libmultipath-add-udev-and-logsink-symbols.patch => 0030-libmultipath-add-udev-and-logsink-symbols.patch (81%) delete mode 100644 0030-libmultipath-fix-condlog-NULL-argument-in-uevent_get.patch delete mode 100644 0031-libmultipath-set-enable_foreign-to-NONE-by-default.patch rename 0080-multipath-remove-logsink-and-udev.patch => 0031-multipath-remove-logsink-and-udev.patch (79%) rename 0081-libmpathpersist-call-libmultipath_-init-exit.patch => 0032-libmpathpersist-call-libmultipath_-init-exit.patch (91%) delete mode 100644 0032-multipath-add-e-option-to-enable-foreign-libraries.patch delete mode 100644 0033-libmultipath-remove-_blacklist_exceptions-functions.patch rename 0082-mpathpersist-remove-logsink-and-udev.patch => 0033-mpathpersist-remove-logsink-and-udev.patch (86%) delete mode 100644 0034-libmultipath-fix-parser-issue-with-comments-in-strin.patch rename 0083-multipathd-remove-logsink-and-udev.patch => 0034-multipathd-remove-logsink-and-udev.patch (77%) delete mode 100644 0035-libmultipath-invert-regexes-that-start-with-exclamat.patch create mode 100644 0035-multipath-tools-add-Vexata-by-StorCentric-VX-arrays.patch delete mode 100644 0036-multipath-Fix-compiler-warnings-when-built-without-s.patch create mode 100644 0036-multipath-tools-Violin-and-Nexsan-were-bought-by-Sto.patch create mode 100644 0037-libmultipath-fix-memory-leaks-in-coalesce_paths.patch delete mode 100644 0037-libmultipath-fix-sysfs-dev_loss_tmo-parsing.patch delete mode 100644 0038-kpartx-read-devices-with-direct-IO.patch create mode 100644 0038-multipath-tools-replace-hidden-tab-by-space-in-hwtab.patch delete mode 100644 0039-kpartx-handle-alternate-bsd-disklabel-location.patch create mode 100644 0039-multipathd-uxlsnr-avoid-deadlock-on-exit.patch delete mode 100644 0040-libmultipath-fix-checker-detection-for-nvme-devices.patch create mode 100644 0040-multipathd-Fix-liburcu-memory-leak.patch delete mode 100644 0041-libmultipath-make-dm_get_map-status-return-codes-sym.patch create mode 100644 0041-multipathd-move-handling-of-io_err_stat_attr-into-li.patch delete mode 100644 0042-multipathd-fix-check_path-errors-with-removed-map.patch create mode 100644 0042-multipathd-move-vecs-desctruction-into-cleanup-funct.patch delete mode 100644 0043-libmultipath-make-dm_flush_maps-only-return-0-on-suc.patch create mode 100644 0043-multipathd-make-some-globals-static.patch delete mode 100644 0044-multipathd-add-del-maps-multipathd-command.patch create mode 100644 0044-multipathd-move-threads-destruction-into-separate-fu.patch delete mode 100644 0045-multipath-make-flushing-maps-work-like-other-command.patch create mode 100644 0045-multipathd-move-conf-destruction-into-separate-funct.patch delete mode 100644 0046-multipath-delegate-flushing-maps-to-multipathd.patch create mode 100644 0046-multipathd-move-pid-destruction-into-separate-functi.patch delete mode 100644 0047-multipath-add-option-to-skip-multipathd-delegation.patch create mode 100644 0047-multipathd-close-pidfile-on-exit.patch delete mode 100644 0048-libmultipath-add-device-to-hwtable.c.patch create mode 100644 0048-multipathd-add-helper-for-systemd-notification-at-ex.patch delete mode 100644 0049-master-libmultipath-fix-use-after-free-when-iscsi-lo.patch create mode 100644 0049-multipathd-child-call-cleanups-in-failure-case-too.patch delete mode 100644 0050-libmultipath-warn-if-freeing-path-that-holds-mpp-hwe.patch create mode 100644 0050-multipathd-unwatch_all_dmevents-check-if-waiter-is-i.patch delete mode 100644 0051-libmultipath-warn-about-NULL-value-of-mpp-hwe.patch create mode 100644 0051-multipathd-print-error-message-if-config-can-t-be-lo.patch create mode 100644 0052-libmultipath-add-libmp_dm_exit.patch delete mode 100644 0052-libmultipath-fix-mpp-hwe-handling-in-sync_paths.patch delete mode 100644 0053-Makefile.inc-trim-extra-information-from-systemd-ver.patch create mode 100644 0053-multipathd-fixup-libdm-deinitialization.patch delete mode 100644 0054-kpartx-fix-Wsign-compare-error.patch create mode 100644 0054-libmultipath-log_thread_stop-check-if-logarea-is-ini.patch delete mode 100644 0055-libmultipath-remove-code-duplication-in-path-countin.patch create mode 100644 0055-multipathd-add-cleanup_child-exit-handler.patch delete mode 100644 0056-libmultipath-count-pending-paths-as-active-on-loads.patch create mode 100644 0056-libmultipath-fix-log_thread-startup-and-teardown.patch delete mode 100644 0057-libmultipath-deal-with-flushing-no-maps.patch create mode 100644 0057-multipathd-move-cleanup_-prio-checkers-foreign-to-li.patch delete mode 100644 0058-multipath-deal-with-delegation-failures-correctly.patch create mode 100644 0058-multipath-use-atexit-for-cleanup-handlers.patch create mode 100644 0059-mpathpersist-use-atexit-for-cleanup-handlers.patch create mode 100644 0060-multipath-fix-leak-in-check_path_valid.patch create mode 100644 0061-multipath-tools-mpath-tools.supp-file-with-valgrind-.patch create mode 100644 0062-libmultipath-use-libmp_verbosity-to-track-verbosity.patch create mode 100644 0063-libmultipath-introduce-symbolic-values-for-logsink.patch create mode 100644 0064-libmultipath-simplify-dlog.patch delete mode 100644 0065-RH-warn-on-invalid-regex-instead-of-failing.patch create mode 100644 0065-multipathd-common-code-for-k-and-command-args.patch create mode 100644 0066-multipathd-sanitize-uxsock_listen.patch create mode 100644 0067-libmultipath-fix-race-between-log_safe-and-log_threa.patch rename 0070-multipath-add-libmpathvalid-library.patch => 0068-multipath-add-libmpathvalid-library.patch (52%) delete mode 100644 0069-RH-work-around-gcc-10-format-truncation-issue.patch create mode 100644 0069-multipath-tools-tests-and-unit-tests-for-libmpathval.patch rename 0071-libmultipath-add-uid-failback-for-dasd-devices.patch => 0070-libmultipath-add-uid-failback-for-dasd-devices.patch (90%) rename 0086-libmultipath-change-log-level-for-null-uid_attribute.patch => 0071-libmultipath-change-log-level-for-null-uid_attribute.patch (50%) delete mode 100644 0072-libmultipath-add-ignore_udev_uid-option.patch create mode 100644 0072-libmultipath-move-fast_io_fail-defines-to-structs.h.patch create mode 100644 0073-libmultipath-add-eh_deadline-multipath.conf-paramete.patch delete mode 100644 0073-libmultipath-util-constify-function-arguments.patch create mode 100644 0074-multipathd-remove-redundant-vector_free-int-configur.patch create mode 100644 0075-libmultipath-factor-out-code-to-get-vpd-page-data.patch create mode 100644 0076-libmultipath-limit-reading-0xc9-vpd-page.patch create mode 100644 0077-libmultipath-move-logq_lock-handling-to-log.c.patch create mode 100644 0078-libmultipath-protect-logarea-with-logq_lock.patch create mode 100644 0079-libmultipath-prevent-DSO-unloading-with-astray-check.patch create mode 100644 0080-libmultipath-force-map-reload-if-udev-incomplete.patch create mode 100644 0081-multipath-tools-avoid-access-to-etc-localtime.patch create mode 100644 0082-multipath-tools-make-sure-plugin-DSOs-use-symbol-ver.patch create mode 100644 0083-libmultipath.version-add-missing-symbol.patch delete mode 100644 0084-libmpathvalid-use-default-_multipath_config-udev-and.patch create mode 100644 0084-multipath-tools-tests-unversioned-.so-for-valgrind-t.patch delete mode 100644 0085-Revert-libmultipath-add-ignore_udev_uid-option.patch create mode 100644 0085-multipath-tools-unit-tests-fix-memory-leaks-in-mpath.patch create mode 100644 0086-mpathpersist-Fix-Register-and-Ignore-with-0x00-SARK.patch delete mode 100644 0087-libmultipath-orphan_paths-avoid-BUG-message.patch create mode 100644 0087-mpathpersist-update-prkeys-file-on-changing-registra.patch create mode 100644 0088-libmultipath-warn-about-missing-braces-at-end-of-mul.patch create mode 100644 0089-libmultipath-ignore-multipaths-sections-without-wwid.patch create mode 100644 0090-libmultipath-fix-format-warning-with-clang.patch create mode 100644 0091-libmultipath-check-for-null-wwid-before-strcmp.patch create mode 100644 0092-multipath.conf.5-Improve-checker_timeout-description.patch create mode 100644 0093-multipathd-fix-path-checkint-not-changed-when-path-s.patch create mode 100644 0094-libmultipath-select_action-skip-is_mpp_known_to_udev.patch create mode 100644 0095-libmultipath-coalesce_paths-stop-triggering-spurious.patch create mode 100644 0096-Revert-multipathd-uev_trigger-handle-incomplete-ADD-.patch create mode 100644 0097-libmultipath-make-find_err_path_by_dev-static.patch create mode 100644 0098-multipathd-avoid-io_err_stat-crash-during-shutdown.patch create mode 100644 0099-multipathd-avoid-io_err_stat-ABBA-deadlock.patch create mode 100644 0100-multipathd-use-get_monotonic_time-in-io_err_stat-cod.patch create mode 100644 0101-multipathd-combine-free_io_err_stat_path-and-destroy.patch create mode 100644 0102-multipathd-cleanup-logging-for-marginal-paths.patch rename 0059-RH-fixup-udev-rules-for-redhat.patch => 0103-RH-fixup-udev-rules-for-redhat.patch (98%) rename 0060-RH-Remove-the-property-blacklist-exception-builtin.patch => 0104-RH-Remove-the-property-blacklist-exception-builtin.patch (78%) rename 0061-RH-don-t-start-without-a-config-file.patch => 0105-RH-don-t-start-without-a-config-file.patch (85%) rename 0067-RH-Fix-nvme-compilation-warning.patch => 0106-RH-Fix-nvme-function-missing-argument.patch (82%) rename 0062-RH-use-rpm-optflags-if-present.patch => 0107-RH-use-rpm-optflags-if-present.patch (92%) rename 0063-RH-add-mpathconf.patch => 0108-RH-add-mpathconf.patch (94%) rename 0064-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch => 0109-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch (78%) rename 0066-RH-reset-default-find_mutipaths-value-to-off.patch => 0110-RH-reset-default-find_mutipaths-value-to-off.patch (95%) rename 0068-RH-attempt-to-get-ANA-info-via-sysfs-first.patch => 0111-RH-attempt-to-get-ANA-info-via-sysfs-first.patch (100%) diff --git a/.gitignore b/.gitignore index 703cbe1..befbabe 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ multipath-tools-091027.tar.gz /multipath-tools-0.8.0.tgz /multipath-tools-0.8.2.tgz /multipath-tools-0.8.4.tgz +/multipath-tools-0.8.5.tgz diff --git a/0001-Change-the-multipath.conf-manpage-uxsock_timeout-def.patch b/0001-Change-the-multipath.conf-manpage-uxsock_timeout-def.patch new file mode 100644 index 0000000..02b2e18 --- /dev/null +++ b/0001-Change-the-multipath.conf-manpage-uxsock_timeout-def.patch @@ -0,0 +1,30 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Christophe Varoqui +Date: Mon, 14 Dec 2020 11:05:24 +0100 +Subject: [PATCH] Change the multipath.conf manpage uxsock_timeout default + value + +Fixes: 7db0c44 ("multipathd: Set CLI timeout correctly") + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + multipath/multipath.conf.5 | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 +index d2101ed6..7242d39b 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5 +@@ -1153,7 +1153,7 @@ In these cases it is recommended to increase the CLI timeout to avoid + those issues. + .RS + .TP +-The default is: \fB1000\fR ++The default is: \fB4000\fR + .RE + . + . +-- +2.17.2 + diff --git a/0001-libmpathpersist-limit-PRIN-allocation-length-to-8192.patch b/0001-libmpathpersist-limit-PRIN-allocation-length-to-8192.patch deleted file mode 100644 index d40166a..0000000 --- a/0001-libmpathpersist-limit-PRIN-allocation-length-to-8192.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 6 Mar 2020 21:50:30 +0100 -Subject: [PATCH] libmpathpersist: limit PRIN allocation length to 8192 bytes - -Some targets (notably the qemu-pr-helper) don't support PERSISTENT -RESERVE IN commands with more than 8192 bytes allocation length. -While I have found no explicit requirement in the SCSI specs that -the allocation lengh may not exceed 8k, an 8k limit is also enforced -by sg_persist(8), and actually by mpathpersist itself for the ---allocation-length option, but not for the auto-determined length. - -Fix that. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmpathpersist/mpath_pr_ioctl.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/libmpathpersist/mpath_pr_ioctl.c b/libmpathpersist/mpath_pr_ioctl.c -index 74b26b0c..1a28cba7 100644 ---- a/libmpathpersist/mpath_pr_ioctl.c -+++ b/libmpathpersist/mpath_pr_ioctl.c -@@ -543,5 +543,7 @@ int get_prin_length(int rq_servact) - mx_resp_len = 0; - break; - } -+ if (mx_resp_len > MPATH_MAX_PARAM_LEN) -+ mx_resp_len = MPATH_MAX_PARAM_LEN; - return mx_resp_len; - } --- -2.17.2 - diff --git a/0002-libmpathpersist-format_transportids-avoid-PROUT-over.patch b/0002-libmpathpersist-format_transportids-avoid-PROUT-over.patch deleted file mode 100644 index 6164b26..0000000 --- a/0002-libmpathpersist-format_transportids-avoid-PROUT-over.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 6 Mar 2020 23:33:04 +0100 -Subject: [PATCH] libmpathpersist: format_transportids(): avoid PROUT overflow - -This limits the PERSISTENT RESERVE OUT data size to max. 8192 bytes. - -Signed-off-by: Benjamin Marzinski ---- - libmpathpersist/mpath_pr_ioctl.c | 31 +++++++++++++++++++++++++++++-- - 1 file changed, 29 insertions(+), 2 deletions(-) - -diff --git a/libmpathpersist/mpath_pr_ioctl.c b/libmpathpersist/mpath_pr_ioctl.c -index 1a28cba7..c78e8000 100644 ---- a/libmpathpersist/mpath_pr_ioctl.c -+++ b/libmpathpersist/mpath_pr_ioctl.c -@@ -1,5 +1,6 @@ - #include - #include -+#include - - #include - #include -@@ -138,38 +139,64 @@ retry : - return status; - } - -+/* -+ * Helper macro to avoid overflow of prout_param_descriptor in -+ * format_transportids(). Data must not be written past -+ * MPATH_MAX_PARAM_LEN bytes from struct prout_param_descriptor. -+ */ -+#define check_overflow(ofs, n, start, label) \ -+ do { \ -+ if ((ofs) + (n) + \ -+ offsetof(struct prout_param_descriptor, private_buffer) \ -+ > MPATH_MAX_PARAM_LEN) \ -+ { \ -+ (ofs) = (start); \ -+ goto label; \ -+ } \ -+ } while(0) -+ - uint32_t format_transportids(struct prout_param_descriptor *paramp) - { - unsigned int i = 0, len; - uint32_t buff_offset = 4; -- memset(paramp->private_buffer, 0, MPATH_MAX_PARAM_LEN); -+ memset(paramp->private_buffer, 0, sizeof(paramp->private_buffer)); - for (i=0; i < paramp->num_transportid; i++ ) - { -+ uint32_t start_offset = buff_offset; -+ -+ check_overflow(buff_offset, 1, start_offset, end_loop); - paramp->private_buffer[buff_offset] = (uint8_t)((paramp->trnptid_list[i]->format_code & 0xff)| - (paramp->trnptid_list[i]->protocol_id & 0xff)); - buff_offset += 1; - switch(paramp->trnptid_list[i]->protocol_id) - { - case MPATH_PROTOCOL_ID_FC: -+ check_overflow(buff_offset, 7 + 8 + 8, -+ start_offset, end_loop); - buff_offset += 7; - memcpy(¶mp->private_buffer[buff_offset], ¶mp->trnptid_list[i]->n_port_name, 8); - buff_offset +=8 ; - buff_offset +=8 ; - break; - case MPATH_PROTOCOL_ID_SAS: -+ check_overflow(buff_offset, 3 + 12, -+ start_offset, end_loop); - buff_offset += 3; - memcpy(¶mp->private_buffer[buff_offset], ¶mp->trnptid_list[i]->sas_address, 8); - buff_offset += 12; - break; - case MPATH_PROTOCOL_ID_ISCSI: -- buff_offset += 1; - len = (paramp->trnptid_list[i]->iscsi_name[1] & 0xff)+2; -+ check_overflow(buff_offset, 1 + len, -+ start_offset, end_loop); -+ buff_offset += 1; - memcpy(¶mp->private_buffer[buff_offset], ¶mp->trnptid_list[i]->iscsi_name,len); - buff_offset += len ; - break; - } - - } -+end_loop: - buff_offset -= 4; - paramp->private_buffer[0] = (unsigned char)((buff_offset >> 24) & 0xff); - paramp->private_buffer[1] = (unsigned char)((buff_offset >> 16) & 0xff); --- -2.17.2 - diff --git a/0002-libmultipath-find_mpe-don-t-match-with-empty-WWID.patch b/0002-libmultipath-find_mpe-don-t-match-with-empty-WWID.patch new file mode 100644 index 0000000..2d38590 --- /dev/null +++ b/0002-libmultipath-find_mpe-don-t-match-with-empty-WWID.patch @@ -0,0 +1,27 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 16 Sep 2020 21:59:11 +0200 +Subject: [PATCH] libmultipath: find_mpe(): don't match with empty WWID + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/config.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmultipath/config.c b/libmultipath/config.c +index b9bdbdbc..df0f8f45 100644 +--- a/libmultipath/config.c ++++ b/libmultipath/config.c +@@ -147,7 +147,7 @@ struct mpentry *find_mpe(vector mptable, char *wwid) + int i; + struct mpentry * mpe; + +- if (!wwid) ++ if (!wwid || !*wwid) + return NULL; + + vector_foreach_slot (mptable, mpe, i) +-- +2.17.2 + diff --git a/0003-libmpathpersist-mpath_format_readfullstatus-use-real.patch b/0003-libmpathpersist-mpath_format_readfullstatus-use-real.patch deleted file mode 100644 index 6d0cf1e..0000000 --- a/0003-libmpathpersist-mpath_format_readfullstatus-use-real.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 6 Mar 2020 23:46:47 +0100 -Subject: [PATCH] libmpathpersist: mpath_format_readfullstatus(): use real - buffer size - -This changes no semantics, but it will allow changing the size of -prin_readfd.private_buffer in a follow-up patch. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmpathpersist/mpath_pr_ioctl.c | 12 ++++++++---- - 1 file changed, 8 insertions(+), 4 deletions(-) - -diff --git a/libmpathpersist/mpath_pr_ioctl.c b/libmpathpersist/mpath_pr_ioctl.c -index c78e8000..fadc9e10 100644 ---- a/libmpathpersist/mpath_pr_ioctl.c -+++ b/libmpathpersist/mpath_pr_ioctl.c -@@ -238,6 +238,8 @@ static void mpath_format_readfullstatus(struct prin_resp *pr_buff) - uint32_t additional_length, k, tid_len_len = 0; - char tempbuff[MPATH_MAX_PARAM_LEN]; - struct prin_fulldescr fdesc; -+ static const int pbuf_size = -+ sizeof(pr_buff->prin_descriptor.prin_readfd.private_buffer); - - convert_be32_to_cpu(&pr_buff->prin_descriptor.prin_readfd.prgeneration); - convert_be32_to_cpu(&pr_buff->prin_descriptor.prin_readfd.number_of_descriptor); -@@ -249,16 +251,18 @@ static void mpath_format_readfullstatus(struct prin_resp *pr_buff) - } - - additional_length = pr_buff->prin_descriptor.prin_readfd.number_of_descriptor; -- if (additional_length > MPATH_MAX_PARAM_LEN) { -+ if (additional_length > pbuf_size) { - condlog(3, "PRIN length %u exceeds max length %d", additional_length, -- MPATH_MAX_PARAM_LEN); -+ pbuf_size); - return; - } - - memset(&fdesc, 0, sizeof(struct prin_fulldescr)); - -- memcpy( tempbuff, pr_buff->prin_descriptor.prin_readfd.private_buffer,MPATH_MAX_PARAM_LEN ); -- memset(&pr_buff->prin_descriptor.prin_readfd.private_buffer, 0, MPATH_MAX_PARAM_LEN); -+ memcpy( tempbuff, pr_buff->prin_descriptor.prin_readfd.private_buffer, -+ pbuf_size); -+ memset(&pr_buff->prin_descriptor.prin_readfd.private_buffer, 0, -+ pbuf_size); - - p =(unsigned char *)tempbuff; - ppbuff = (char *)pr_buff->prin_descriptor.prin_readfd.private_buffer; --- -2.17.2 - diff --git a/0003-libmultipath-copy-mpp-hwe-from-pp-hwe.patch b/0003-libmultipath-copy-mpp-hwe-from-pp-hwe.patch new file mode 100644 index 0000000..63ff6a5 --- /dev/null +++ b/0003-libmultipath-copy-mpp-hwe-from-pp-hwe.patch @@ -0,0 +1,260 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 16 Sep 2020 22:22:36 +0200 +Subject: [PATCH] libmultipath: copy mpp->hwe from pp->hwe + +Since f0462f0 ("libmultipath: use vector for for pp->hwe and mp->hwe"), +we've been trying to fix issues caused by paths getting freed and mpp->hwe +dangling. This approach couldn't work because we need mpp->hwe to persist, +even if all paths are removed from the map. Before f0462f0, a simple +assignment worked, because the lifetime of the hwe wasn't bound to the +path. But now, we need to copy the vector. It turns out that we need to set +mpp->hwe only in two places, add_map_with_path() and setup_map(), and +that the code is simplified overall. + +Even now, it can happen that a map is added with add_map_without_paths(), +and has no paths. In that case, calling do_set_from_hwe() with a NULL +pointer is not a bug, so remove the message. + +Fixes: f0462f0 ("libmultipath: use vector for for pp->hwe and mp->hwe") +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/configure.c | 7 +++++ + libmultipath/propsel.c | 4 +-- + libmultipath/structs.c | 15 +++++++++++ + libmultipath/structs.h | 1 + + libmultipath/structs_vec.c | 54 ++++++++++++++++---------------------- + multipathd/main.c | 10 ------- + 6 files changed, 46 insertions(+), 45 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index 6fb477fc..d7afc915 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -311,6 +311,13 @@ int setup_map(struct multipath *mpp, char *params, int params_size, + if (mpp->disable_queueing && VECTOR_SIZE(mpp->paths) != 0) + mpp->disable_queueing = 0; + ++ /* ++ * If this map was created with add_map_without_path(), ++ * mpp->hwe might not be set yet. ++ */ ++ if (!mpp->hwe) ++ extract_hwe_from_path(mpp); ++ + /* + * properties selectors + * +diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c +index 7e6e0d68..40201344 100644 +--- a/libmultipath/propsel.c ++++ b/libmultipath/propsel.c +@@ -65,9 +65,7 @@ do { \ + __do_set_from_vec(struct hwentry, var, (src)->hwe, dest) + + #define do_set_from_hwe(var, src, dest, msg) \ +- if (!src->hwe) { \ +- condlog(0, "BUG: do_set_from_hwe called with hwe == NULL"); \ +- } else if (__do_set_from_hwe(var, src, dest)) { \ ++ if (src->hwe && __do_set_from_hwe(var, src, dest)) { \ + origin = msg; \ + goto out; \ + } +diff --git a/libmultipath/structs.c b/libmultipath/structs.c +index 464596fc..2efad6f0 100644 +--- a/libmultipath/structs.c ++++ b/libmultipath/structs.c +@@ -234,6 +234,17 @@ alloc_multipath (void) + return mpp; + } + ++void *set_mpp_hwe(struct multipath *mpp, const struct path *pp) ++{ ++ if (!mpp || !pp || !pp->hwe) ++ return NULL; ++ if (mpp->hwe) ++ return mpp->hwe; ++ mpp->hwe = vector_convert(NULL, pp->hwe, ++ struct hwentry, identity); ++ return mpp->hwe; ++} ++ + void free_multipath_attributes(struct multipath *mpp) + { + if (!mpp) +@@ -290,6 +301,10 @@ free_multipath (struct multipath * mpp, enum free_path_mode free_paths) + + free_pathvec(mpp->paths, free_paths); + free_pgvec(mpp->pg, free_paths); ++ if (mpp->hwe) { ++ vector_free(mpp->hwe); ++ mpp->hwe = NULL; ++ } + FREE_PTR(mpp->mpcontext); + FREE(mpp); + } +diff --git a/libmultipath/structs.h b/libmultipath/structs.h +index 7de93d6c..4ce30551 100644 +--- a/libmultipath/structs.h ++++ b/libmultipath/structs.h +@@ -422,6 +422,7 @@ struct host_group { + struct path * alloc_path (void); + struct pathgroup * alloc_pathgroup (void); + struct multipath * alloc_multipath (void); ++void *set_mpp_hwe(struct multipath *mpp, const struct path *pp); + void uninitialize_path(struct path *pp); + void free_path (struct path *); + void free_pathvec (vector vec, enum free_path_mode free_paths); +diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c +index 8895fa77..f7f45f11 100644 +--- a/libmultipath/structs_vec.c ++++ b/libmultipath/structs_vec.c +@@ -294,11 +294,6 @@ err: + void orphan_path(struct path *pp, const char *reason) + { + condlog(3, "%s: orphan path, %s", pp->dev, reason); +- if (pp->mpp && pp->hwe && pp->mpp->hwe == pp->hwe) { +- condlog(0, "BUG: orphaning path %s that holds hwe of %s", +- pp->dev, pp->mpp->alias); +- pp->mpp->hwe = NULL; +- } + pp->mpp = NULL; + uninitialize_path(pp); + } +@@ -308,8 +303,6 @@ void orphan_paths(vector pathvec, struct multipath *mpp, const char *reason) + int i; + struct path * pp; + +- /* Avoid BUG message from orphan_path() */ +- mpp->hwe = NULL; + vector_foreach_slot (pathvec, pp, i) { + if (pp->mpp == mpp) { + if (pp->initialized == INIT_REMOVED) { +@@ -397,24 +390,26 @@ extract_hwe_from_path(struct multipath * mpp) + if (mpp->hwe || !mpp->paths) + return; + +- condlog(3, "%s: searching paths for valid hwe", mpp->alias); ++ condlog(4, "%s: searching paths for valid hwe", mpp->alias); + /* doing this in two passes seems like paranoia to me */ + vector_foreach_slot(mpp->paths, pp, i) { +- if (pp->state != PATH_UP) +- continue; +- if (pp->hwe) { +- mpp->hwe = pp->hwe; +- return; +- } ++ if (pp->state == PATH_UP && ++ pp->initialized != INIT_REMOVED && pp->hwe) ++ goto done; + } + vector_foreach_slot(mpp->paths, pp, i) { +- if (pp->state == PATH_UP) +- continue; +- if (pp->hwe) { +- mpp->hwe = pp->hwe; +- return; +- } ++ if (pp->state != PATH_UP && ++ pp->initialized != INIT_REMOVED && pp->hwe) ++ goto done; + } ++done: ++ if (i < VECTOR_SIZE(mpp->paths)) ++ (void)set_mpp_hwe(mpp, pp); ++ ++ if (mpp->hwe) ++ condlog(3, "%s: got hwe from path %s", mpp->alias, pp->dev); ++ else ++ condlog(2, "%s: no hwe found", mpp->alias); + } + + int +@@ -514,8 +509,6 @@ void sync_paths(struct multipath *mpp, vector pathvec) + } + if (!found) { + condlog(3, "%s dropped path %s", mpp->alias, pp->dev); +- if (mpp->hwe == pp->hwe) +- mpp->hwe = NULL; + vector_del_slot(mpp->paths, i--); + orphan_path(pp, "path removed externally"); + } +@@ -524,8 +517,6 @@ void sync_paths(struct multipath *mpp, vector pathvec) + update_mpp_paths(mpp, pathvec); + vector_foreach_slot (mpp->paths, pp, i) + pp->mpp = mpp; +- if (mpp->hwe == NULL) +- extract_hwe_from_path(mpp); + } + + int +@@ -701,9 +692,15 @@ struct multipath *add_map_with_path(struct vectors *vecs, struct path *pp, + + conf = get_multipath_config(); + mpp->mpe = find_mpe(conf->mptable, pp->wwid); +- mpp->hwe = pp->hwe; + put_multipath_config(conf); + ++ /* ++ * We need to call this before select_alias(), ++ * because that accesses hwe properties. ++ */ ++ if (pp->hwe && !set_mpp_hwe(mpp, pp)) ++ goto out; ++ + strcpy(mpp->wwid, pp->wwid); + find_existing_alias(mpp, vecs); + if (select_alias(conf, mpp)) +@@ -754,12 +751,6 @@ int verify_paths(struct multipath *mpp) + vector_del_slot(mpp->paths, i); + i--; + +- /* Make sure mpp->hwe doesn't point to freed memory. +- * We call extract_hwe_from_path() below to restore +- * mpp->hwe +- */ +- if (mpp->hwe == pp->hwe) +- mpp->hwe = NULL; + /* + * Don't delete path from pathvec yet. We'll do this + * after the path has been removed from the map, in +@@ -771,7 +762,6 @@ int verify_paths(struct multipath *mpp) + mpp->alias, pp->dev, pp->dev_t); + } + } +- extract_hwe_from_path(mpp); + return count; + } + +diff --git a/multipathd/main.c b/multipathd/main.c +index a4abbb27..eedc6c10 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -1153,13 +1153,6 @@ ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map) + if (i != -1) + vector_del_slot(mpp->paths, i); + +- /* +- * Make sure mpp->hwe doesn't point to freed memory +- * We call extract_hwe_from_path() below to restore mpp->hwe +- */ +- if (mpp->hwe == pp->hwe) +- mpp->hwe = NULL; +- + /* + * remove the map IF removing the last path + */ +@@ -1191,9 +1184,6 @@ ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map) + */ + } + +- if (mpp->hwe == NULL) +- extract_hwe_from_path(mpp); +- + if (setup_map(mpp, params, PARAMS_SIZE, vecs)) { + condlog(0, "%s: failed to setup map for" + " removal of path %s", mpp->alias, pp->dev); +-- +2.17.2 + diff --git a/0004-libmultipath-assign-variable-to-make-gcc-happy.patch b/0004-libmultipath-assign-variable-to-make-gcc-happy.patch deleted file mode 100644 index 8db8dd9..0000000 --- a/0004-libmultipath-assign-variable-to-make-gcc-happy.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 25 Mar 2020 23:22:46 -0500 -Subject: [PATCH] libmultipath: assign variable to make gcc happy -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -There is nothing wrong with is_queueing not being set at the start -of __set_no_path_retry(), it will always get set before it is accessed, -but gcc 8.2.1 is failing with - -structs_vec.c: In function ‘__set_no_path_retry’: -structs_vec.c:339:7: error: ‘is_queueing’ may be used uninitialized in -this function [-Werror=maybe-uninitialized] - bool is_queueing; - ^~~~~~~~~~~ - -so, assign a value to make it happy. - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/structs_vec.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c -index 3dbbaa0f..077f2e42 100644 ---- a/libmultipath/structs_vec.c -+++ b/libmultipath/structs_vec.c -@@ -336,7 +336,7 @@ static void leave_recovery_mode(struct multipath *mpp) - - void __set_no_path_retry(struct multipath *mpp, bool check_features) - { -- bool is_queueing; -+ bool is_queueing = false; /* assign a value to make gcc happy */ - - check_features = check_features && mpp->features != NULL; - if (check_features) --- -2.17.2 - diff --git a/0004-libmultipath-dm_map_present_by_uuid-fix-dm_task_crea.patch b/0004-libmultipath-dm_map_present_by_uuid-fix-dm_task_crea.patch new file mode 100644 index 0000000..c3a0a18 --- /dev/null +++ b/0004-libmultipath-dm_map_present_by_uuid-fix-dm_task_crea.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 22 Sep 2020 14:24:41 +0200 +Subject: [PATCH] libmultipath: dm_map_present_by_uuid(): fix dm_task_create() + call + +libmultipath shouldn't call dm_task_create() directly any more. + +Fixes: 90535a3 ("multipath: centralize validation code") +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/devmapper.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index 7f093617..0bc1d16e 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -836,7 +836,7 @@ dm_map_present_by_uuid(const char *uuid) + if (safe_sprintf(prefixed_uuid, UUID_PREFIX "%s", uuid)) + goto out; + +- if (!(dmt = dm_task_create(DM_DEVICE_INFO))) ++ if (!(dmt = libmp_dm_task_create(DM_DEVICE_INFO))) + goto out; + + dm_task_no_open_count(dmt); +-- +2.17.2 + diff --git a/0005-libdmmp-tests-fix-compilation.patch b/0005-libdmmp-tests-fix-compilation.patch new file mode 100644 index 0000000..d1d9955 --- /dev/null +++ b/0005-libdmmp-tests-fix-compilation.patch @@ -0,0 +1,43 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 22 Sep 2020 12:10:35 +0200 +Subject: [PATCH] libdmmp tests: fix compilation + +These tests don't compile with -Werror=unused-parameter. Fix it. +Reviewed-by: Benjamin Marzinski + +Signed-off-by: Benjamin Marzinski +--- + libdmmp/test/libdmmp_speed_test.c | 2 +- + libdmmp/test/libdmmp_test.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libdmmp/test/libdmmp_speed_test.c b/libdmmp/test/libdmmp_speed_test.c +index 372cd390..d91ba50a 100644 +--- a/libdmmp/test/libdmmp_speed_test.c ++++ b/libdmmp/test/libdmmp_speed_test.c +@@ -27,7 +27,7 @@ + + #include + +-int main(int argc, char *argv[]) ++int main(void) + { + struct dmmp_context *ctx = NULL; + struct dmmp_mpath **dmmp_mps = NULL; +diff --git a/libdmmp/test/libdmmp_test.c b/libdmmp/test/libdmmp_test.c +index d944e1e3..a940b576 100644 +--- a/libdmmp/test/libdmmp_test.c ++++ b/libdmmp/test/libdmmp_test.c +@@ -102,7 +102,7 @@ out: + return rc; + } + +-int main(int argc, char *argv[]) ++int main(void) + { + struct dmmp_context *ctx = NULL; + struct dmmp_mpath **dmmp_mps = NULL; +-- +2.17.2 + diff --git a/0005-libmutipath-don-t-close-fd-on-dm_lib_release.patch b/0005-libmutipath-don-t-close-fd-on-dm_lib_release.patch deleted file mode 100644 index dd4af7e..0000000 --- a/0005-libmutipath-don-t-close-fd-on-dm_lib_release.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 25 Mar 2020 23:22:47 -0500 -Subject: [PATCH] libmutipath: don't close fd on dm_lib_release - -If dm_hold_control_open() isn't set, when dm_lib_release() is called, it -will close the control fd. The control fd will get re-opened on the next -dm_task_run() call, but if there is a dm_task_run() call already -in progress in another thread, it can fail. Since many of the -device-mapper callouts happen with the vecs lock held, this wasn't too -noticeable, but there is code that calls dm_task_run() without the -vecs lock held, notably the dmevent waiter code. - -Since, as Martin pointed out, dm_hold_control_open() hasn't always -existed in libdevmapper, check if it's supported on compilation, -and update the version requirements if so. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/Makefile | 4 ++++ - libmultipath/devmapper.c | 7 ++++++- - 2 files changed, 10 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/Makefile b/libmultipath/Makefile -index e5651e49..ad690a49 100644 ---- a/libmultipath/Makefile -+++ b/libmultipath/Makefile -@@ -36,6 +36,10 @@ ifneq ($(call check_func,dm_task_deferred_remove,/usr/include/libdevmapper.h),0) - CFLAGS += -DLIBDM_API_DEFERRED - endif - -+ifneq ($(call check_func,dm_hold_control_dev,/usr/include/libdevmapper.h),0) -+ CFLAGS += -DLIBDM_API_HOLD_CONTROL -+endif -+ - OBJS = memory.o parser.o vector.o devmapper.o callout.o \ - hwtable.o blacklist.o util.o dmparser.o config.o \ - structs.o discovery.o propsel.o dict.o \ -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index bed8ddc6..13a1cf53 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -108,7 +108,9 @@ dm_lib_prereq (void) - { - char version[64]; - int v[3]; --#if defined(LIBDM_API_DEFERRED) -+#if defined(LIBDM_API_HOLD_CONTROL) -+ int minv[3] = {1, 2, 111}; -+#elif defined(LIBDM_API_DEFERRED) - int minv[3] = {1, 2, 89}; - #elif defined(DM_SUBSYSTEM_UDEV_FLAG0) - int minv[3] = {1, 2, 82}; -@@ -254,6 +256,9 @@ void libmp_dm_init(void) - memcpy(conf->version, version, sizeof(version)); - put_multipath_config(conf); - dm_init(verbosity); -+#ifdef LIBDM_API_HOLD_CONTROL -+ dm_hold_control_dev(1); -+#endif - dm_udev_set_sync_support(libmp_dm_udev_sync); - } - --- -2.17.2 - diff --git a/0006-libmultipath-allow-force-reload-with-no-active-paths.patch b/0006-libmultipath-allow-force-reload-with-no-active-paths.patch deleted file mode 100644 index 77d5474..0000000 --- a/0006-libmultipath-allow-force-reload-with-no-active-paths.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 25 Mar 2020 23:22:48 -0500 -Subject: [PATCH] libmultipath: allow force reload with no active paths - -If the partition information has changed on multipath devices (say, -because it was updated on another node that has access to the same -storage), users expect that running "multipathd reconfigure" will update -that. However, if the checkers for the multipath device are pending for -too long when the the device is reconfigured, multipathd will give up -waiting for them, and refuse to reload the device, since there are no -active paths. This means that no kpartx update will be triggered. - -Multipath is fully capable of reloading a multipath device that has no -active paths. This has been possible for years. If multipath is supposed -to reload the device, it should do so, even if there are no active paths. - -Generally, when multipath is force reloaded, kpartx will be updated. -However when a device is reloaded with no paths, the udev rules won't -run kpartx. But they also weren't running kpartx when the first valid -path appeared, even though the dm activation rules get run in this case. -This changes 11-dm-mpath.rules to run kpartx when a device goes from no -usable paths to having usable paths. - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 6 ------ - multipath/11-dm-mpath.rules | 2 +- - 2 files changed, 1 insertion(+), 7 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index c95848a0..96c79610 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -710,12 +710,6 @@ select_action (struct multipath * mpp, vector curmp, int force_reload) - return; - } - -- if (pathcount(mpp, PATH_UP) == 0) { -- mpp->action = ACT_IMPOSSIBLE; -- condlog(3, "%s: set ACT_IMPOSSIBLE (no usable path)", -- mpp->alias); -- return; -- } - if (force_reload) { - mpp->force_udev_reload = 1; - mpp->action = ACT_RELOAD; -diff --git a/multipath/11-dm-mpath.rules b/multipath/11-dm-mpath.rules -index 07320a14..cd522e8c 100644 ---- a/multipath/11-dm-mpath.rules -+++ b/multipath/11-dm-mpath.rules -@@ -75,7 +75,7 @@ ENV{MPATH_DEVICE_READY}=="0", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1" - ENV{MPATH_DEVICE_READY}!="0", ENV{.MPATH_DEVICE_READY_OLD}=="0",\ - ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="$env{DM_DISABLE_OTHER_RULES_FLAG_OLD}",\ - ENV{DM_DISABLE_OTHER_RULES_FLAG_OLD}="",\ -- ENV{DM_ACTIVATION}="1" -+ ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0" - - # The code to check multipath state ends here. We need to set - # properties and symlinks regardless whether the map is usable or --- -2.17.2 - diff --git a/0006-libmultipath-prio-constify-some-function-parameters.patch b/0006-libmultipath-prio-constify-some-function-parameters.patch new file mode 100644 index 0000000..80771ea --- /dev/null +++ b/0006-libmultipath-prio-constify-some-function-parameters.patch @@ -0,0 +1,53 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 18 Sep 2020 23:57:22 +0200 +Subject: [PATCH] libmultipath: prio: constify some function parameters + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/prio.c | 4 ++-- + libmultipath/prio.h | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/libmultipath/prio.c b/libmultipath/prio.c +index 194563c4..3a718ba5 100644 +--- a/libmultipath/prio.c ++++ b/libmultipath/prio.c +@@ -18,7 +18,7 @@ unsigned int get_prio_timeout(unsigned int timeout_ms, + return default_timeout; + } + +-int init_prio (char *multipath_dir) ++int init_prio (const char *multipath_dir) + { + if (!add_prio(multipath_dir, DEFAULT_PRIO)) + return 1; +@@ -87,7 +87,7 @@ int prio_set_args (struct prio * p, const char * args) + return snprintf(p->args, PRIO_ARGS_LEN, "%s", args); + } + +-struct prio * add_prio (char *multipath_dir, char * name) ++struct prio * add_prio (const char *multipath_dir, const char * name) + { + char libname[LIB_PRIO_NAMELEN]; + struct stat stbuf; +diff --git a/libmultipath/prio.h b/libmultipath/prio.h +index 599d1d88..26754f78 100644 +--- a/libmultipath/prio.h ++++ b/libmultipath/prio.h +@@ -55,9 +55,9 @@ struct prio { + + unsigned int get_prio_timeout(unsigned int checker_timeout, + unsigned int default_timeout); +-int init_prio (char *); ++int init_prio (const char *); + void cleanup_prio (void); +-struct prio * add_prio (char *, char *); ++struct prio * add_prio (const char *, const char *); + int prio_getprio (struct prio *, struct path *, unsigned int); + void prio_get (char *, struct prio *, char *, char *); + void prio_put (struct prio *); +-- +2.17.2 + diff --git a/0007-kpartx.rules-honor-DM_UDEV_DISABLE_OTHER_RULES_FLAG.patch b/0007-kpartx.rules-honor-DM_UDEV_DISABLE_OTHER_RULES_FLAG.patch deleted file mode 100644 index 6c33439..0000000 --- a/0007-kpartx.rules-honor-DM_UDEV_DISABLE_OTHER_RULES_FLAG.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 3 Apr 2020 13:03:01 +0200 -Subject: [PATCH] kpartx.rules: honor DM_UDEV_DISABLE_OTHER_RULES_FLAG - -10-dm.rules sets DM_UDEV_DISABLE_OTHER_RULES_FLAG for spurious -events that should be ignored by other layers. This means devices -with DISK_RO set, and devices that have never been set up properly -by device-mapper before. This flag should be respected by kpartx. - -Signed-off-by: Benjamin Marzinski ---- - kpartx/kpartx.rules | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules -index 8f990494..f1bf31ca 100644 ---- a/kpartx/kpartx.rules -+++ b/kpartx/kpartx.rules -@@ -7,6 +7,7 @@ - KERNEL!="dm-*", GOTO="kpartx_end" - ACTION!="add|change", GOTO="kpartx_end" - ENV{DM_UUID}!="?*", GOTO="kpartx_end" -+ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}=="1", GOTO="kpartx_end" - - # Create dm tables for partitions on multipath devices. - ENV{DM_UUID}!="mpath-?*", GOTO="mpath_kpartx_end" --- -2.17.2 - diff --git a/0007-libmultipath-checkers-prio-allow-non-lazy-.so-loadin.patch b/0007-libmultipath-checkers-prio-allow-non-lazy-.so-loadin.patch new file mode 100644 index 0000000..90a2f25 --- /dev/null +++ b/0007-libmultipath-checkers-prio-allow-non-lazy-.so-loadin.patch @@ -0,0 +1,90 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 18 Sep 2020 23:58:15 +0200 +Subject: [PATCH] libmultipath: checkers/prio: allow non-lazy .so loading + +If compiled with -DLOAD_ALL_SHARED_LIBS, all known prioritizers +and checkers will be loaded immediately on startup. This is useful +for determining symbol usage (start executables with LD_BIND_NOW=1). + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/checkers.c | 17 +++++++++++++++++ + libmultipath/prio.c | 22 ++++++++++++++++++++++ + 2 files changed, 39 insertions(+) + +diff --git a/libmultipath/checkers.c b/libmultipath/checkers.c +index f7ddd536..18b1f5eb 100644 +--- a/libmultipath/checkers.c ++++ b/libmultipath/checkers.c +@@ -7,6 +7,7 @@ + #include "debug.h" + #include "checkers.h" + #include "vector.h" ++#include "util.h" + + struct checker_class { + struct list_head node; +@@ -375,7 +376,23 @@ void checker_get(const char *multipath_dir, struct checker *dst, + + int init_checkers(const char *multipath_dir) + { ++#ifdef LOAD_ALL_SHARED_LIBS ++ static const char *const all_checkers[] = { ++ DIRECTIO, ++ TUR, ++ HP_SW, ++ RDAC, ++ EMC_CLARIION, ++ READSECTOR0, ++ CCISS_TUR, ++ }; ++ unsigned int i; ++ ++ for (i = 0; i < ARRAY_SIZE(all_checkers); i++) ++ add_checker_class(multipath_dir, all_checkers[i]); ++#else + if (!add_checker_class(multipath_dir, DEFAULT_CHECKER)) + return 1; ++#endif + return 0; + } +diff --git a/libmultipath/prio.c b/libmultipath/prio.c +index 3a718ba5..c92bde7f 100644 +--- a/libmultipath/prio.c ++++ b/libmultipath/prio.c +@@ -20,8 +20,30 @@ unsigned int get_prio_timeout(unsigned int timeout_ms, + + int init_prio (const char *multipath_dir) + { ++#ifdef LOAD_ALL_SHARED_LIBS ++ static const char *const all_prios[] = { ++ PRIO_ALUA, ++ PRIO_CONST, ++ PRIO_DATACORE, ++ PRIO_EMC, ++ PRIO_HDS, ++ PRIO_HP_SW, ++ PRIO_ONTAP, ++ PRIO_RANDOM, ++ PRIO_RDAC, ++ PRIO_WEIGHTED_PATH, ++ PRIO_SYSFS, ++ PRIO_PATH_LATENCY, ++ PRIO_ANA, ++ }; ++ unsigned int i; ++ ++ for (i = 0; i < ARRAY_SIZE(all_prios); i++) ++ add_prio(multipath_dir, all_prios[i]); ++#else + if (!add_prio(multipath_dir, DEFAULT_PRIO)) + return 1; ++#endif + return 0; + } + +-- +2.17.2 + diff --git a/0008-kpartx.rules-check-for-skip_kpartx-on-synthetic-ueve.patch b/0008-kpartx.rules-check-for-skip_kpartx-on-synthetic-ueve.patch deleted file mode 100644 index 2a18b15..0000000 --- a/0008-kpartx.rules-check-for-skip_kpartx-on-synthetic-ueve.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 2 Apr 2020 18:12:48 +0200 -Subject: [PATCH] kpartx.rules: check for skip_kpartx on synthetic uevents - -The current test to detect "spurious" uevents, and thus whether to -import DM_SUBSYSTEM_UDEV_FLAG1 (the flag for the "skip_kpartx" option) -from the udev db is wrong. In 10-dm.rules, DM_UDEV_PRIMARY_SOURCE_FLAG -is imported from the db if it isn't set, meaning that it's always 1 -for active maps. The only events for which DM_SUBSYSTEM_UDEV_FLAG1 -must not be loaded from the db are the real "primary" events, which -are "change" events with DM_ACTIVATION=="1". - -11-dm-mpath.rules resets DM_ACTIVATION to 0 if nothing should change in upper -layers. In this case importing DM_SUBSYSTEM_UDEV_FLAG1 is correct, too. kpartx -will not be called anyway, because 11-dm-mpath.rules also sets MPATH_UNCHANGED=1. - -Signed-off-by: Benjamin Marzinski ---- - kpartx/kpartx.rules | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules -index f1bf31ca..d7527d7d 100644 ---- a/kpartx/kpartx.rules -+++ b/kpartx/kpartx.rules -@@ -13,8 +13,11 @@ ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}=="1", GOTO="kpartx_end" - ENV{DM_UUID}!="mpath-?*", GOTO="mpath_kpartx_end" - - # DM_SUBSYSTEM_UDEV_FLAG1 is the "skip_kpartx" flag. --# For events not generated by libdevmapper, we need to fetch it from db. --ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}!="1", IMPORT{db}="DM_SUBSYSTEM_UDEV_FLAG1" -+# For events not generated by libdevmapper, we need to fetch it from db: -+# - "change" events with DM_ACTIVATION!="1" (e.g. partition table changes) -+# - "add" events for which rules are not disabled ("coldplug" case) -+ENV{DM_ACTIVATION}!="1", IMPORT{db}="DM_SUBSYSTEM_UDEV_FLAG1" -+ACTION=="add", IMPORT{db}="DM_SUBSYSTEM_UDEV_FLAG1" - ENV{DM_SUBSYSTEM_UDEV_FLAG1}=="1", GOTO="mpath_kpartx_end" - - # 11-dm-mpath.rules sets MPATH_UNCHANGED for events that can be ignored. --- -2.17.2 - diff --git a/0008-multipath-tools-Makefiles-separate-rules-for-.so-and.patch b/0008-multipath-tools-Makefiles-separate-rules-for-.so-and.patch new file mode 100644 index 0000000..edc3e66 --- /dev/null +++ b/0008-multipath-tools-Makefiles-separate-rules-for-.so-and.patch @@ -0,0 +1,96 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 22 Sep 2020 12:52:49 +0200 +Subject: [PATCH] multipath-tools Makefiles: separate rules for .so and man + pages + +Rely more on "make" functionality than on sequential command execution. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmpathcmd/Makefile | 8 +++++--- + libmpathpersist/Makefile | 10 +++++++--- + libmultipath/Makefile | 8 +++++--- + 3 files changed, 17 insertions(+), 9 deletions(-) + +diff --git a/libmpathcmd/Makefile b/libmpathcmd/Makefile +index 0f6b8166..08ccb811 100644 +--- a/libmpathcmd/Makefile ++++ b/libmpathcmd/Makefile +@@ -8,13 +8,15 @@ CFLAGS += $(LIB_CFLAGS) + + OBJS = mpath_cmd.o + +-all: $(LIBS) ++all: $(DEVLIB) + + $(LIBS): $(OBJS) + $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ -o $@ $(OBJS) $(LIBDEPS) +- $(LN) $@ $(DEVLIB) + +-install: $(LIBS) ++$(DEVLIB): $(LIBS) ++ $(LN) $(LIBS) $@ ++ ++install: all + $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) + $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) + $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) +diff --git a/libmpathpersist/Makefile b/libmpathpersist/Makefile +index 21fdad80..9e869fdc 100644 +--- a/libmpathpersist/Makefile ++++ b/libmpathpersist/Makefile +@@ -11,15 +11,19 @@ LIBDEPS += -lpthread -ldevmapper -ldl -L$(multipathdir) -lmultipath \ + + OBJS = mpath_persist.o mpath_updatepr.o mpath_pr_ioctl.o + +-all: $(LIBS) ++all: $(DEVLIB) man + + $(LIBS): $(OBJS) + $(CC) $(LDFLAGS) $(SHARED_FLAGS) $(LIBDEPS) -Wl,-soname=$@ -o $@ $(OBJS) +- $(LN) $(LIBS) $(DEVLIB) ++ ++$(DEVLIB): $(LIBS) ++ $(LN) $(LIBS) $@ ++ ++man: + $(GZIP) mpath_persistent_reserve_in.3 > mpath_persistent_reserve_in.3.gz + $(GZIP) mpath_persistent_reserve_out.3 > mpath_persistent_reserve_out.3.gz + +-install: $(LIBS) ++install: all + $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) + $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) + $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(syslibdir) +diff --git a/libmultipath/Makefile b/libmultipath/Makefile +index 62ba16e8..40028556 100644 +--- a/libmultipath/Makefile ++++ b/libmultipath/Makefile +@@ -54,7 +54,7 @@ OBJS = memory.o parser.o vector.o devmapper.o callout.o \ + io_err_stat.o dm-generic.o generic.o foreign.o nvme-lib.o \ + libsg.o valid.o + +-all: $(LIBS) ++all: $(DEVLIB) + + nvme-lib.o: nvme-lib.c nvme-ioctl.c nvme-ioctl.h + $(CC) $(CFLAGS) -Wno-unused-function -c -o $@ $< +@@ -74,9 +74,11 @@ nvme-ioctl.h: nvme/nvme-ioctl.h + + $(LIBS): $(OBJS) + $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ -o $@ $(OBJS) $(LIBDEPS) +- $(LN) $@ $(DEVLIB) + +-install: ++$(DEVLIB): $(LIBS) ++ $(LN) $(LIBS) $@ ++ ++install: all + $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) + $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) + $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(libdir) +-- +2.17.2 + diff --git a/0009-libmpathpersist-depend-on-libmultipath.patch b/0009-libmpathpersist-depend-on-libmultipath.patch deleted file mode 100644 index 47aad9b..0000000 --- a/0009-libmpathpersist-depend-on-libmultipath.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Christian Hesse -Date: Wed, 6 May 2020 09:35:47 +0200 -Subject: [PATCH] libmpathpersist: depend on libmultipath - -Without this the build fails with: - -/usr/bin/ld: cannot find -lmultipath - -Signed-off-by: Christian Hesse -Signed-off-by: Benjamin Marzinski ---- - Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Makefile b/Makefile -index 1dee3680..ba1d73ba 100644 ---- a/Makefile -+++ b/Makefile -@@ -28,7 +28,7 @@ all: $(BUILDDIRS) - $(BUILDDIRS): - $(MAKE) -C $@ - --multipath multipathd mpathpersist: libmultipath -+libmpathpersist multipath multipathd mpathpersist: libmultipath - mpathpersist: libmpathpersist - - $(BUILDDIRS.clean): --- -2.17.2 - diff --git a/0009-libmultipath-create-separate-.so-for-unit-tests.patch b/0009-libmultipath-create-separate-.so-for-unit-tests.patch new file mode 100644 index 0000000..38a01d7 --- /dev/null +++ b/0009-libmultipath-create-separate-.so-for-unit-tests.patch @@ -0,0 +1,87 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Sat, 19 Sep 2020 00:29:45 +0200 +Subject: [PATCH] libmultipath: create separate .so for unit tests + +The unit tests use a lot of internal symbols that we don't want +to add to the ABI if we don't have to. As long as we don't +have to make incompatible changes to functions, we can work around +that by simply using a non-versioned library for the unit tests. +Therefore we add a seperate rule here. Do this before actually +adding a version script, to avoid breakage during bisection. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/Makefile | 7 +++++++ + tests/Makefile | 10 ++++++---- + 2 files changed, 13 insertions(+), 4 deletions(-) + +diff --git a/libmultipath/Makefile b/libmultipath/Makefile +index 40028556..12bf6300 100644 +--- a/libmultipath/Makefile ++++ b/libmultipath/Makefile +@@ -78,6 +78,13 @@ $(LIBS): $(OBJS) + $(DEVLIB): $(LIBS) + $(LN) $(LIBS) $@ + ++../tests/$(LIBS): $(OBJS) $(VERSION_SCRIPT) ++ $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=`basename $@` \ ++ -o $@ $(OBJS) $(LIBDEPS) ++ $(LN) $@ ${@:.so.0=.so} ++ ++test-lib: ../tests/$(LIBS) ++ + install: all + $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) + $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) +diff --git a/tests/Makefile b/tests/Makefile +index d26b3ce7..9658c9fd 100644 +--- a/tests/Makefile ++++ b/tests/Makefile +@@ -10,7 +10,7 @@ W_MISSING_INITIALIZERS := $(call TEST_MISSING_INITIALIZERS) + + CFLAGS += $(BIN_CFLAGS) -I$(multipathdir) -I$(mpathcmddir) \ + -Wno-unused-parameter $(W_MISSING_INITIALIZERS) +-LIBDEPS += -L$(multipathdir) -L$(mpathcmddir) -lmultipath -lmpathcmd -lcmocka ++LIBDEPS += -L. -L$(mpathcmddir) -lmultipath -lmpathcmd -lcmocka + + TESTS := uevent parser util dmevents hwtable blacklist unaligned vpd pgpolicy \ + alias directio valid devt +@@ -68,7 +68,7 @@ lib/libchecktur.so: + + %.out: %-test lib/libchecktur.so + @echo == running $< == +- @LD_LIBRARY_PATH=$(multipathdir):$(mpathcmddir) ./$< >$@ ++ @LD_LIBRARY_PATH=.:$(mpathcmddir) ./$< >$@ + + %.vgr: %-test lib/libchecktur.so + @echo == running valgrind for $< == +@@ -78,7 +78,7 @@ lib/libchecktur.so: + OBJS = $(TESTS:%=%.o) $(HELPERS) + + test_clean: +- $(RM) $(TESTS:%=%.out) $(TESTS:%=%.vgr) ++ $(RM) $(TESTS:%=%.out) $(TESTS:%=%.vgr) *.so* + + valgrind_clean: + $(RM) $(TESTS:%=%.vgr) +@@ -98,12 +98,14 @@ dep_clean: + @sed -n 's/^.*__wrap_\([a-zA-Z0-9_]*\).*$$/-Wl,--wrap=\1/p' $< | \ + sort -u | tr '\n' ' ' >$@ + ++libmultipath.so.0: ++ $(MAKE) -C $(multipathdir) test-lib + + # COLON will get expanded during second expansion below + COLON:=: + .SECONDEXPANSION: + %-test: %.o %.o.wrap $$($$@_OBJDEPS) $$($$@_TESTDEPS) $$($$@_TESTDEPS$$(COLON).o=.o.wrap) \ +- $(multipathdir)/libmultipath.so Makefile ++ libmultipath.so.0 Makefile + $(CC) $(CFLAGS) -o $@ $(LDFLAGS) $< $($@_TESTDEPS) $($@_OBJDEPS) \ + $(LIBDEPS) $($@_LIBDEPS) \ + $(shell cat $<.wrap) $(foreach dep,$($@_TESTDEPS),$(shell cat $(dep).wrap)) +-- +2.17.2 + diff --git a/0010-libmultipath-add-linker-version-script.patch b/0010-libmultipath-add-linker-version-script.patch new file mode 100644 index 0000000..ed6ad7f --- /dev/null +++ b/0010-libmultipath-add-linker-version-script.patch @@ -0,0 +1,303 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Sat, 19 Sep 2020 00:00:18 +0200 +Subject: [PATCH] libmultipath: add linker version script + +This version script documents the current ABI of libmultipath, +as used by multipath, multipathd, (lib)mpathpersist, and the +dynamically loaded libraries (prioritizers, checkers, and foreign). +The initial version string is set to "LIBMULTIPATH_1.0.0". + +This reduces the amount of exported symbols of libmultipath.so.0 +by more than a half (199 vs. 434). + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/Makefile | 7 +- + libmultipath/libmultipath.version | 248 ++++++++++++++++++++++++++++++ + 2 files changed, 253 insertions(+), 2 deletions(-) + create mode 100644 libmultipath/libmultipath.version + +diff --git a/libmultipath/Makefile b/libmultipath/Makefile +index 12bf6300..e7254f39 100644 +--- a/libmultipath/Makefile ++++ b/libmultipath/Makefile +@@ -6,6 +6,7 @@ include ../Makefile.inc + SONAME = 0 + DEVLIB = libmultipath.so + LIBS = $(DEVLIB).$(SONAME) ++VERSION_SCRIPT := libmultipath.version + + CFLAGS += $(LIB_CFLAGS) -I$(mpathcmddir) -I$(mpathpersistdir) -I$(nvmedir) + +@@ -72,8 +73,10 @@ nvme-ioctl.c: nvme/nvme-ioctl.c + nvme-ioctl.h: nvme/nvme-ioctl.h + $(call make_static,$<,$@) + +-$(LIBS): $(OBJS) +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ -o $@ $(OBJS) $(LIBDEPS) ++ ++$(LIBS): $(OBJS) $(VERSION_SCRIPT) ++ $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ ++ -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) + + $(DEVLIB): $(LIBS) + $(LN) $(LIBS) $@ +diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version +new file mode 100644 +index 00000000..a6bf8218 +--- /dev/null ++++ b/libmultipath/libmultipath.version +@@ -0,0 +1,248 @@ ++/* ++ * Copyright (c) 2020 SUSE LLC ++ * SPDX-License-Identifier: GPL-2.0-or-later ++ * ++ * libmultipath ABI ++ * ++ * libmultipath doesn't have a stable ABI in the usual sense. In particular, ++ * the library does not attempt to ship different versions of the same symbol ++ * for backward compatibility. ++ * ++ * The ABI versioning only serves to avoid linking with a non-matching ABI, to ++ * cut down the set of exported symbols, and to describe it. ++ * The version string is LIBMULTIPATH_$MAJOR.$MINOR.$REL. ++ * ++ * Policy: ++ * ++ * * Bump $MAJOR for incompatible changes, like: ++ * - symbols removed ++ * - parameter list or return values changed for existing functions ++ * - externally visible data structures changed in incompatible ways ++ * (like offsets of previously existing struct members) ++ * In this case, the new version doesn't inherit the previous versions, ++ * because the new library doesn't provide the full previous ABI any more. ++ * All predecessors are merged into the new version. ++ * ++ * * Bump $MINOR for compatible changes, like adding symbols. ++ * The new version inherits the previous ones. ++ * ++ * * Bump $REL to describe deviations from upstream, e.g. in ++ * multipath-tools packages shipped by distributions. ++ * The new version inherits the previous ones. ++ */ ++ ++LIBMULTIPATH_1.0.0 { ++global: ++ /* symbols referenced by multipath and multipathd */ ++ add_foreign; ++ add_map_with_path; ++ adopt_paths; ++ alloc_multipath; ++ alloc_path; ++ alloc_path_with_pathinfo; ++ alloc_strvec; ++ change_foreign; ++ check_alias_settings; ++ checker_clear_message; ++ checker_disable; ++ checker_enable; ++ checker_is_sync; ++ checker_message; ++ checker_name; ++ checker_state_name; ++ check_foreign; ++ cleanup_checkers; ++ cleanup_foreign; ++ cleanup_lock; ++ cleanup_prio; ++ close_fd; ++ coalesce_paths; ++ convert_dev; ++ count_active_paths; ++ delete_all_foreign; ++ delete_foreign; ++ disassemble_map; ++ disassemble_status; ++ dlog; ++ dm_cancel_deferred_remove; ++ dm_drv_version; ++ dm_enablegroup; ++ dm_fail_path; ++ _dm_flush_map; ++ dm_flush_map_nopaths; ++ dm_flush_maps; ++ dm_geteventnr; ++ dm_get_info; ++ dm_get_major_minor; ++ dm_get_map; ++ dm_get_maps; ++ dm_get_multipath; ++ dm_get_status; ++ dm_get_uuid; ++ dm_is_mpath; ++ dm_mapname; ++ dm_map_present; ++ dm_queue_if_no_path; ++ dm_reassign; ++ dm_reinstate_path; ++ dm_simplecmd_noflush; ++ dm_switchgroup; ++ dm_tgt_version; ++ domap; ++ ensure_directories_exist; ++ extract_hwe_from_path; ++ filter_devnode; ++ filter_path; ++ filter_wwid; ++ find_mp_by_alias; ++ find_mp_by_minor; ++ find_mp_by_str; ++ find_mp_by_wwid; ++ find_mpe; ++ find_path_by_dev; ++ find_path_by_devt; ++ find_slot; ++ foreign_multipath_layout; ++ foreign_path_layout; ++ free_config; ++ free_multipath; ++ free_multipathvec; ++ free_path; ++ free_pathvec; ++ free_strvec; ++ get_monotonic_time; ++ get_multipath_layout; ++ get_path_layout; ++ get_pgpolicy_id; ++ get_refwwid; ++ get_state; ++ get_udev_device; ++ get_uid; ++ get_used_hwes; ++ group_by_prio; ++ init_checkers; ++ init_foreign; ++ init_prio; ++ io_err_stat_attr; ++ io_err_stat_handle_pathfail; ++ is_path_valid; ++ is_quote; ++ libmp_dm_task_create; ++ libmp_udev_set_sync_support; ++ load_config; ++ log_thread_reset; ++ log_thread_start; ++ log_thread_stop; ++ need_io_err_check; ++ normalize_timespec; ++ orphan_path; ++ orphan_paths; ++ parse_prkey_flags; ++ pathcount; ++ path_discovery; ++ path_get_tpgs; ++ pathinfo; ++ path_offline; ++ print_all_paths; ++ print_foreign_topology; ++ _print_multipath_topology; ++ pthread_cond_init_mono; ++ recv_packet; ++ recv_packet_from_client; ++ reinstate_paths; ++ remember_wwid; ++ remove_map; ++ remove_map_by_alias; ++ remove_maps; ++ remove_wwid; ++ replace_wwids; ++ reset_checker_classes; ++ select_all_tg_pt; ++ select_action; ++ select_find_multipaths_timeout; ++ select_no_path_retry; ++ select_path_group; ++ select_reservation_key; ++ send_packet; ++ set_max_fds; ++ __set_no_path_retry; ++ set_path_removed; ++ set_prkey; ++ setup_map; ++ setup_thread_attr; ++ should_multipath; ++ snprint_blacklist_report; ++ snprint_config; ++ snprint_devices; ++ snprint_foreign_multipaths; ++ snprint_foreign_paths; ++ snprint_foreign_topology; ++ _snprint_multipath; ++ snprint_multipath_header; ++ snprint_multipath_map_json; ++ _snprint_multipath_topology; ++ snprint_multipath_topology_json; ++ _snprint_path; ++ snprint_path_header; ++ snprint_status; ++ snprint_wildcards; ++ stop_io_err_stat_thread; ++ store_path; ++ store_pathinfo; ++ strchop; ++ strlcpy; ++ sync_map_state; ++ sysfs_attr_set_value; ++ sysfs_get_size; ++ sysfs_is_multipathed; ++ timespecsub; ++ trigger_paths_udev_change; ++ uevent_dispatch; ++ uevent_get_dm_str; ++ uevent_get_env_positive_int; ++ uevent_is_mpath; ++ uevent_listen; ++ update_mpp_paths; ++ update_multipath_status; ++ update_multipath_strings; ++ update_multipath_table; ++ update_pathvec_from_dm; ++ update_queue_mode_add_path; ++ update_queue_mode_del_path; ++ ux_socket_listen; ++ valid_alias; ++ vector_alloc; ++ vector_alloc_slot; ++ vector_del_slot; ++ vector_free; ++ vector_reset; ++ vector_set_slot; ++ verify_paths; ++ ++ /* checkers */ ++ sg_read; ++ ++ /* prioritizers */ ++ get_asymmetric_access_state; ++ get_prio_timeout; ++ get_target_port_group; ++ get_target_port_group_support; ++ libmp_nvme_ana_log; ++ libmp_nvme_get_nsid; ++ libmp_nvme_identify_ns; ++ log_nvme_errcode; ++ nvme_id_ctrl_ana; ++ snprint_host_wwnn; ++ snprint_host_wwpn; ++ snprint_path_serial; ++ snprint_tgt_wwnn; ++ snprint_tgt_wwpn; ++ sysfs_get_asymmetric_access_state; ++ ++ /* foreign */ ++ free_scandir_result; ++ sysfs_attr_get_value; ++ ++local: ++ *; ++}; +-- +2.17.2 + diff --git a/0010-multipath-tools-Makefile-more-dependency-fixes-for-p.patch b/0010-multipath-tools-Makefile-more-dependency-fixes-for-p.patch deleted file mode 100644 index c4f0b3e..0000000 --- a/0010-multipath-tools-Makefile-more-dependency-fixes-for-p.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 11 May 2020 14:24:37 +0200 -Subject: [PATCH] multipath-tools: Makefile: more dependency fixes for parallel - build - -Extend the late fixes from Christian. - -Cc: Christian Hesse -Signed-off-by: Benjamin Marzinski ---- - Makefile | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/Makefile b/Makefile -index ba1d73ba..fec3b73b 100644 ---- a/Makefile -+++ b/Makefile -@@ -28,8 +28,9 @@ all: $(BUILDDIRS) - $(BUILDDIRS): - $(MAKE) -C $@ - --libmpathpersist multipath multipathd mpathpersist: libmultipath --mpathpersist: libmpathpersist -+libmultipath libdmmp: libmpathcmd -+libmpathpersist multipath multipathd: libmultipath -+mpathpersist multipathd: libmpathpersist - - $(BUILDDIRS.clean): - $(MAKE) -C ${@:.clean=} clean --- -2.17.2 - diff --git a/0011-libmpathpersist-add-linker-version-script.patch b/0011-libmpathpersist-add-linker-version-script.patch new file mode 100644 index 0000000..916c4f3 --- /dev/null +++ b/0011-libmpathpersist-add-linker-version-script.patch @@ -0,0 +1,81 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Sat, 19 Sep 2020 00:02:16 +0200 +Subject: [PATCH] libmpathpersist: add linker version script + +This defines the ABI of libmpathpersist in the current state. +The initial version is set to "LIBMPATHPERSIST_1.0.0". + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmpathpersist/Makefile | 6 +++-- + libmpathpersist/libmpathpersist.version | 32 +++++++++++++++++++++++++ + 2 files changed, 36 insertions(+), 2 deletions(-) + create mode 100644 libmpathpersist/libmpathpersist.version + +diff --git a/libmpathpersist/Makefile b/libmpathpersist/Makefile +index 9e869fdc..456ce4cf 100644 +--- a/libmpathpersist/Makefile ++++ b/libmpathpersist/Makefile +@@ -3,6 +3,7 @@ include ../Makefile.inc + SONAME = 0 + DEVLIB = libmpathpersist.so + LIBS = $(DEVLIB).$(SONAME) ++VERSION_SCRIPT := libmpathpersist.version + + CFLAGS += $(LIB_CFLAGS) -I$(multipathdir) -I$(mpathpersistdir) -I$(mpathcmddir) + +@@ -13,8 +14,9 @@ OBJS = mpath_persist.o mpath_updatepr.o mpath_pr_ioctl.o + + all: $(DEVLIB) man + +-$(LIBS): $(OBJS) +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) $(LIBDEPS) -Wl,-soname=$@ -o $@ $(OBJS) ++$(LIBS): $(OBJS) $(VERSION_SCRIPT) ++ $(CC) $(LDFLAGS) $(SHARED_FLAGS) $(LIBDEPS) -Wl,-soname=$@ \ ++ -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) + + $(DEVLIB): $(LIBS) + $(LN) $(LIBS) $@ +diff --git a/libmpathpersist/libmpathpersist.version b/libmpathpersist/libmpathpersist.version +new file mode 100644 +index 00000000..dc648ce6 +--- /dev/null ++++ b/libmpathpersist/libmpathpersist.version +@@ -0,0 +1,32 @@ ++/* ++ * Copyright (c) 2020 SUSE LLC ++ * SPDX-License-Identifier: GPL-2.0-or-later ++ * ++ * libmpathpersist ABI ++ * ++ * The ABI of libmpathpersist is supposed to remain stable. Removing symbols ++ * or altering existing symbols' semantics is not allowed. When changing a ++ * a symbol, either use a new name, or explicit symver directives. ++ * ++ * See libmultipath.version for general policy about version numbers. ++ */ ++LIBMPATHPERSIST_1.0.0 { ++global: ++ ++ __mpath_persistent_reserve_in; ++ __mpath_persistent_reserve_out; ++ dumpHex; ++ mpath_alloc_prin_response; ++ mpath_lib_exit; ++ mpath_lib_init; ++ mpath_mx_alloc_len; ++ mpath_persistent_reserve_in; ++ mpath_persistent_reserve_init_vecs; ++ mpath_persistent_reserve_out; ++ mpath_persistent_reserve_free_vecs; ++ prin_do_scsi_ioctl; ++ prout_do_scsi_ioctl; ++ update_map_pr; ++ ++local: *; ++}; +-- +2.17.2 + diff --git a/0011-multipath-tools-Makefile.inc-separate-out-OPTFLAGS.patch b/0011-multipath-tools-Makefile.inc-separate-out-OPTFLAGS.patch deleted file mode 100644 index 2082970..0000000 --- a/0011-multipath-tools-Makefile.inc-separate-out-OPTFLAGS.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 11 May 2020 15:27:34 +0200 -Subject: [PATCH] multipath-tools: Makefile.inc: separate out OPTFLAGS - -OPTFLAGS is what distribution builds would typically override. That -should not include the warning flags we use. - -Moreover, in the definition of CFLAGS, put $(CFLAGS) first to make it -easier for the user to spot her input in the build logs. - -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index d4d1e0dd..7a59db85 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -93,14 +93,14 @@ STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector) - ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers,) - WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered,) - --OPTFLAGS = -O2 -g -pipe -Werror -Wall -Wextra -Wformat=2 -Werror=implicit-int \ -+OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 -+WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 -Werror=implicit-int \ - -Werror=implicit-function-declaration -Werror=format-security \ -- $(WNOCLOBBERED) \ -- -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) \ -- $(STACKPROT) --param=ssp-buffer-size=4 -+ $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) - CPPFLAGS := -Wp,-D_FORTIFY_SOURCE=2 --CFLAGS := $(OPTFLAGS) -DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" \ -- -MMD -MP $(CFLAGS) -+CFLAGS := $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ -+ -DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" \ -+ -MMD -MP - BIN_CFLAGS = -fPIE -DPIE - LIB_CFLAGS = -fPIC - SHARED_FLAGS = -shared --- -2.17.2 - diff --git a/0012-libmpathcmd-add-linker-version-script.patch b/0012-libmpathcmd-add-linker-version-script.patch new file mode 100644 index 0000000..454c3b7 --- /dev/null +++ b/0012-libmpathcmd-add-linker-version-script.patch @@ -0,0 +1,74 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 22 Sep 2020 12:54:20 +0200 +Subject: [PATCH] libmpathcmd: add linker version script + +For completeness, this isn't really necessary. +The version string is set to "LIBMPATHCMD_1.0.0". + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmpathcmd/Makefile | 6 ++++-- + libmpathcmd/libmpathcmd.version | 25 +++++++++++++++++++++++++ + 2 files changed, 29 insertions(+), 2 deletions(-) + create mode 100644 libmpathcmd/libmpathcmd.version + +diff --git a/libmpathcmd/Makefile b/libmpathcmd/Makefile +index 08ccb811..25910194 100644 +--- a/libmpathcmd/Makefile ++++ b/libmpathcmd/Makefile +@@ -3,6 +3,7 @@ include ../Makefile.inc + SONAME = 0 + DEVLIB = libmpathcmd.so + LIBS = $(DEVLIB).$(SONAME) ++VERSION_SCRIPT := libmpathcmd.version + + CFLAGS += $(LIB_CFLAGS) + +@@ -10,8 +11,9 @@ OBJS = mpath_cmd.o + + all: $(DEVLIB) + +-$(LIBS): $(OBJS) +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ -o $@ $(OBJS) $(LIBDEPS) ++$(LIBS): $(OBJS) $(VERSION_SCRIPT) ++ $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ ++ -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) + + $(DEVLIB): $(LIBS) + $(LN) $(LIBS) $@ +diff --git a/libmpathcmd/libmpathcmd.version b/libmpathcmd/libmpathcmd.version +new file mode 100644 +index 00000000..f1006280 +--- /dev/null ++++ b/libmpathcmd/libmpathcmd.version +@@ -0,0 +1,25 @@ ++/* ++ * Copyright (c) 2020 SUSE LLC ++ * SPDX-License-Identifier: GPL-2.0-or-later ++ * ++ * libmpathcmd ABI ++ * ++ * The ABI of libmpathcmd is supposed to remain stable. Removing symbols ++ * or altering existing symbols' semantics is not allowed. When changing a ++ * a symbol, either use a new name, or explicit symver directives. ++ * ++ * See libmultipath.version for general policy about version numbers. ++ */ ++LIBMPATHCMD_1.0.0 { ++global: ++ __mpath_connect; ++ mpath_connect; ++ mpath_disconnect; ++ mpath_process_cmd; ++ mpath_recv_reply; ++ mpath_recv_reply_len; ++ mpath_recv_reply_data; ++ mpath_send_cmd; ++local: ++ *; ++}; +-- +2.17.2 + diff --git a/0012-multipath-tools-Makefile.inc-allow-user-settings-for.patch b/0012-multipath-tools-Makefile.inc-allow-user-settings-for.patch deleted file mode 100644 index ba2ec42..0000000 --- a/0012-multipath-tools-Makefile.inc-allow-user-settings-for.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 11 May 2020 16:00:04 +0200 -Subject: [PATCH] multipath-tools: Makefile.inc: allow user settings for - LDFLAGS - -This allows e.g. setting LDFLAGS="-m32 -Wl,-b,elf32-i386" to compile -for a 32bit target on a 64bit system. - -Note that, like CFLAGS, the variable needs to be set in the environment, -not on the "make" command line. - -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 7a59db85..671dd1ca 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -104,7 +104,7 @@ CFLAGS := $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ - BIN_CFLAGS = -fPIE -DPIE - LIB_CFLAGS = -fPIC - SHARED_FLAGS = -shared --LDFLAGS = -Wl,-z,relro -Wl,-z,now -+LDFLAGS := $(LDFLAGS) -Wl,-z,relro -Wl,-z,now - BIN_LDFLAGS = -pie - - # Check whether a function with name $1 has been declared in header file $2. --- -2.17.2 - diff --git a/0013-libmpathpersist-initialize-mpp-hwe-in-get_mpvec.patch b/0013-libmpathpersist-initialize-mpp-hwe-in-get_mpvec.patch new file mode 100644 index 0000000..a04673d --- /dev/null +++ b/0013-libmpathpersist-initialize-mpp-hwe-in-get_mpvec.patch @@ -0,0 +1,38 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 25 Sep 2020 21:37:16 +0200 +Subject: [PATCH] libmpathpersist: initialize mpp->hwe in get_mpvec() + +In __mpath_persistent_reserve_out, we call select_all_tg_pt(), +which requires mpp->hwe to be set. Initialize it in get_mpvec(). + +Fixes: 5b54e77 ("mpathpersist: add all_tg_pt option") +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmpathpersist/mpath_persist.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c +index 1f9817ed..4b3f3e0d 100644 +--- a/libmpathpersist/mpath_persist.c ++++ b/libmpathpersist/mpath_persist.c +@@ -341,11 +341,13 @@ get_mpvec (vector curmp, vector pathvec, char * refwwid) + continue; + + if (update_multipath_table(mpp, pathvec, DI_CHECKER) != DMP_OK || +- update_multipath_status(mpp) != DMP_OK) { ++ update_multipath_status(mpp) != DMP_OK || ++ update_mpp_paths(mpp, pathvec)) { + condlog(1, "error parsing map %s", mpp->wwid); + remove_map(mpp, pathvec, curmp, PURGE_VEC); + i--; +- } ++ } else ++ extract_hwe_from_path(mpp); + } + return MPATH_PR_SUCCESS ; + } +-- +2.17.2 + diff --git a/0013-multipath-tools-Makefile.inc-set-Wno-error-clobbered.patch b/0013-multipath-tools-Makefile.inc-set-Wno-error-clobbered.patch deleted file mode 100644 index 3de6cb6..0000000 --- a/0013-multipath-tools-Makefile.inc-set-Wno-error-clobbered.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 11 May 2020 17:19:37 +0200 -Subject: [PATCH] multipath-tools: Makefile.inc: set -Wno-error=clobbered - -We need to ignore -Wclobbered because gcc has trouble dealing with glibc's -implementation of pthread_cleanup_push(). - -For some variants of gcc, -Wno-clobbered alone isn't enough if -Werror is also -set. Compilation with -Wno-error=clobbered works, though. - -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 671dd1ca..e7256e3a 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -91,7 +91,7 @@ TEST_CC_OPTION = $(shell \ - - STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector) - ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers,) --WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered,) -+WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered -Wno-error=clobbered,) - - OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 - WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 -Werror=implicit-int \ --- -2.17.2 - diff --git a/0014-libmultipath-discovery.c-use-z-qualifier-for-size_t.patch b/0014-libmultipath-discovery.c-use-z-qualifier-for-size_t.patch deleted file mode 100644 index 749bef2..0000000 --- a/0014-libmultipath-discovery.c-use-z-qualifier-for-size_t.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 11 May 2020 16:02:25 +0200 -Subject: [PATCH] libmultipath: discovery.c: use %z qualifier for size_t - -Otherwise compilation for 32bit targets spits out warnings. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/discovery.c | 16 ++++++++-------- - 1 file changed, 8 insertions(+), 8 deletions(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index ee3290cd..ffec5162 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -986,7 +986,7 @@ parse_vpd_pg80(const unsigned char *in, char *out, size_t out_len) - } - - if (len >= out_len) { -- condlog(2, "vpd pg80 overflow, %lu/%lu bytes required", -+ condlog(2, "vpd pg80 overflow, %zu/%zu bytes required", - len + 1, out_len); - len = out_len - 1; - } -@@ -1087,7 +1087,7 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, - - len = sprintf(out, "%d", vpd_type); - if (2 * vpd_len >= out_len - len) { -- condlog(1, "%s: WWID overflow, type %d, %lu/%lu bytes required", -+ condlog(1, "%s: WWID overflow, type %d, %zu/%zu bytes required", - __func__, vpd_type, - 2 * vpd_len + len + 1, out_len); - vpd_len = (out_len - len - 1) / 2; -@@ -1096,7 +1096,7 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, - len += sprintf(out + len, - "%02x", vpd[i]); - } else if (vpd_type == 0x8 && vpd_len < 4) { -- condlog(1, "%s: VPD length %lu too small for designator type 8", -+ condlog(1, "%s: VPD length %zu too small for designator type 8", - __func__, vpd_len); - return -EINVAL; - } else if (vpd_type == 0x8) { -@@ -1112,7 +1112,7 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, - while (len > 2 && vpd[len - 2] == '\0') - --len; - if (len > out_len - 1) { -- condlog(1, "%s: WWID overflow, type 8/%c, %lu/%lu bytes required", -+ condlog(1, "%s: WWID overflow, type 8/%c, %zu/%zu bytes required", - __func__, out[0], len + 1, out_len); - len = out_len - 1; - } -@@ -1136,7 +1136,7 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, - while ((p = memchr(vpd, ' ', vpd_len))) { - p_len = p - vpd; - if (len + p_len > out_len - 1) { -- condlog(1, "%s: WWID overflow, type 1, %lu/%lu bytes required", -+ condlog(1, "%s: WWID overflow, type 1, %zu/%zu bytes required", - __func__, len + p_len, out_len); - p_len = out_len - len - 1; - } -@@ -1162,7 +1162,7 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, - p_len = vpd_len; - if (p_len > 0 && len < out_len - 1) { - if (len + p_len > out_len - 1) { -- condlog(1, "%s: WWID overflow, type 1, %lu/%lu bytes required", -+ condlog(1, "%s: WWID overflow, type 1, %zu/%zu bytes required", - __func__, len + p_len + 1, out_len); - p_len = out_len - len - 1; - } -@@ -1186,14 +1186,14 @@ parse_vpd_c0_hp3par(const unsigned char *in, size_t in_len, - - memset(out, 0x0, out_len); - if (in_len <= 4 || (in[4] > 3 && in_len < 44)) { -- condlog(3, "HP/3PAR vendor specific VPD page length too short: %lu", in_len); -+ condlog(3, "HP/3PAR vendor specific VPD page length too short: %zu", in_len); - return -EINVAL; - } - if (in[4] <= 3) /* revision must be > 3 to have Vomlume Name */ - return -ENODATA; - len = get_unaligned_be32(&in[40]); - if (len > out_len || len + 44 > in_len) { -- condlog(3, "HP/3PAR vendor specific Volume name too long: %lu", -+ condlog(3, "HP/3PAR vendor specific Volume name too long: %zu", - len); - return -EINVAL; - } --- -2.17.2 - diff --git a/0014-multipathd-allow-shutdown-during-configure.patch b/0014-multipathd-allow-shutdown-during-configure.patch new file mode 100644 index 0000000..2cbfecf --- /dev/null +++ b/0014-multipathd-allow-shutdown-during-configure.patch @@ -0,0 +1,140 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 4 Jan 2019 16:59:49 +0100 +Subject: [PATCH] multipathd: allow shutdown during configure() + +reconfigure() can be a long-running operation; both initial path +discovery and initial map setup can take a long time. Allow +the main program to indicate that the process should be +interrupted if a shutdown signal was received. + +We take advantage of the dynamic linker's symbol lookup ordering +here. The default implementation of should_exit never returns +true, but callers (like multipathd) can override it. + +Cc: Chongyun Wu +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/configure.c | 6 ++++++ + libmultipath/discovery.c | 3 +++ + libmultipath/util.c | 5 +++++ + libmultipath/util.h | 1 + + multipathd/main.c | 17 +++++++++++++++++ + 5 files changed, 32 insertions(+) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index d7afc915..1c8aac08 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -1173,6 +1173,12 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, + + vector_foreach_slot (pathvec, pp1, k) { + int invalid; ++ ++ if (should_exit()) { ++ ret = CP_FAIL; ++ goto out; ++ } ++ + /* skip this path for some reason */ + + /* 1. if path has no unique id or wwid blacklisted */ +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index c2e1754c..e7084664 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -200,6 +200,9 @@ path_discovery (vector pathvec, int flag) + const char *devtype; + const char *devpath; + ++ if (should_exit()) ++ break; ++ + devpath = udev_list_entry_get_name(entry); + condlog(4, "Discover device %s", devpath); + udevice = udev_device_new_from_syspath(udev, devpath); +diff --git a/libmultipath/util.c b/libmultipath/util.c +index 1748eafe..1f977792 100644 +--- a/libmultipath/util.c ++++ b/libmultipath/util.c +@@ -445,3 +445,8 @@ void _log_bitfield_overflow(const char *f, unsigned int bit, unsigned int len) + { + condlog(0, "%s: bitfield overflow: %u >= %u", f, bit, len); + } ++ ++int should_exit(void) ++{ ++ return 0; ++} +diff --git a/libmultipath/util.h b/libmultipath/util.h +index 2b9703ac..ac19473e 100644 +--- a/libmultipath/util.h ++++ b/libmultipath/util.h +@@ -27,6 +27,7 @@ int parse_prkey(const char *ptr, uint64_t *prkey); + int parse_prkey_flags(const char *ptr, uint64_t *prkey, uint8_t *flags); + int safe_write(int fd, const void *buf, size_t count); + void set_max_fds(rlim_t max_fds); ++int should_exit(void); + + #define KERNEL_VERSION(maj, min, ptc) ((((maj) * 256) + (min)) * 256 + (ptc)) + #define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) +diff --git a/multipathd/main.c b/multipathd/main.c +index eedc6c10..fa53e963 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -141,6 +141,11 @@ static inline enum daemon_status get_running_state(void) + return st; + } + ++int should_exit(void) ++{ ++ return get_running_state() == DAEMON_SHUTDOWN; ++} ++ + /* + * global copy of vecs for use in sig handlers + */ +@@ -2570,6 +2575,9 @@ configure (struct vectors * vecs) + goto fail; + } + ++ if (should_exit()) ++ goto fail; ++ + conf = get_multipath_config(); + pthread_cleanup_push(put_multipath_config, conf); + vector_foreach_slot (vecs->pathvec, pp, i){ +@@ -2586,6 +2594,9 @@ configure (struct vectors * vecs) + goto fail; + } + ++ if (should_exit()) ++ goto fail; ++ + /* + * create new set of maps & push changed ones into dm + * In the first call, use FORCE_RELOAD_WEAK to avoid making +@@ -2600,6 +2611,9 @@ configure (struct vectors * vecs) + goto fail; + } + ++ if (should_exit()) ++ goto fail; ++ + /* + * may need to remove some maps which are no longer relevant + * e.g., due to blacklist changes in conf file +@@ -2611,6 +2625,9 @@ configure (struct vectors * vecs) + + dm_lib_release(); + ++ if (should_exit()) ++ goto fail; ++ + sync_maps_state(mpvec); + vector_foreach_slot(mpvec, mpp, i){ + if (remember_wwid(mpp->wwid) == 1) +-- +2.17.2 + diff --git a/0015-libmultipath-eliminate-more-signed-unsigned-comparis.patch b/0015-libmultipath-eliminate-more-signed-unsigned-comparis.patch deleted file mode 100644 index a97c202..0000000 --- a/0015-libmultipath-eliminate-more-signed-unsigned-comparis.patch +++ /dev/null @@ -1,198 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 11 May 2020 16:03:58 +0200 -Subject: [PATCH] libmultipath: eliminate more signed/unsigned comparisons - -Fix some more compiler warnings about signed/unsigned comparison. -I've observed these only on 32bit builds, therefore they went unnoticed -before. - -Signed-off-by: Benjamin Marzinski ---- - libmpathpersist/mpath_pr_ioctl.c | 2 +- - libmultipath/print.c | 12 ++++++------ - libmultipath/prioritizers/alua_spc3.h | 2 +- - multipathd/cli_handlers.c | 20 ++++++++++---------- - multipathd/main.c | 2 +- - 5 files changed, 19 insertions(+), 19 deletions(-) - -diff --git a/libmpathpersist/mpath_pr_ioctl.c b/libmpathpersist/mpath_pr_ioctl.c -index fadc9e10..126601c3 100644 ---- a/libmpathpersist/mpath_pr_ioctl.c -+++ b/libmpathpersist/mpath_pr_ioctl.c -@@ -238,7 +238,7 @@ static void mpath_format_readfullstatus(struct prin_resp *pr_buff) - uint32_t additional_length, k, tid_len_len = 0; - char tempbuff[MPATH_MAX_PARAM_LEN]; - struct prin_fulldescr fdesc; -- static const int pbuf_size = -+ static const unsigned int pbuf_size = - sizeof(pr_buff->prin_descriptor.prin_readfd.private_buffer); - - convert_be32_to_cpu(&pr_buff->prin_descriptor.prin_readfd.prgeneration); -diff --git a/libmultipath/print.c b/libmultipath/print.c -index b944ef32..298b3764 100644 ---- a/libmultipath/print.c -+++ b/libmultipath/print.c -@@ -1958,25 +1958,25 @@ char *snprint_config(const struct config *conf, int *len, - } - - c = reply + snprint_defaults(conf, reply, maxlen); -- if ((c - reply) == maxlen) -+ if (c == reply + maxlen) - continue; - - c += snprint_blacklist(conf, c, reply + maxlen - c); -- if ((c - reply) == maxlen) -+ if (c == reply + maxlen) - continue; - - c += snprint_blacklist_except(conf, c, reply + maxlen - c); -- if ((c - reply) == maxlen) -+ if (c == reply + maxlen) - continue; - - c += snprint_hwtable(conf, c, reply + maxlen - c, - hwtable ? hwtable : conf->hwtable); -- if ((c - reply) == maxlen) -+ if (c == reply + maxlen) - continue; - - c += snprint_overrides(conf, c, reply + maxlen - c, - conf->overrides); -- if ((c - reply) == maxlen) -+ if (c == reply + maxlen) - continue; - - if (VECTOR_SIZE(conf->mptable) > 0 || -@@ -1984,7 +1984,7 @@ char *snprint_config(const struct config *conf, int *len, - c += snprint_mptable(conf, c, reply + maxlen - c, - mpvec); - -- if ((c - reply) < maxlen) { -+ if (c < reply + maxlen) { - if (len) - *len = c - reply; - return reply; -diff --git a/libmultipath/prioritizers/alua_spc3.h b/libmultipath/prioritizers/alua_spc3.h -index 18b495ef..7ba2cf4c 100644 ---- a/libmultipath/prioritizers/alua_spc3.h -+++ b/libmultipath/prioritizers/alua_spc3.h -@@ -284,7 +284,7 @@ struct rtpg_data { - #define RTPG_FOR_EACH_PORT_GROUP(p, g) \ - for( \ - g = &(p->data[0]); \ -- (((char *) g) - ((char *) p)) < get_unaligned_be32(p->length); \ -+ ((char *) g) < ((char *) p) + get_unaligned_be32(p->length); \ - g = (struct rtpg_tpg_dscr *) ( \ - ((char *) g) + \ - sizeof(struct rtpg_tpg_dscr) + \ -diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c -index 7d878c88..31c3d9fd 100644 ---- a/multipathd/cli_handlers.c -+++ b/multipathd/cli_handlers.c -@@ -66,7 +66,7 @@ show_paths (char ** r, int * len, struct vectors * vecs, char * style, - c += snprint_foreign_paths(c, reply + maxlen - c, - style, pretty); - -- again = ((c - reply) == (maxlen - 1)); -+ again = (c == reply + maxlen - 1); - - REALLOC_REPLY(reply, again, maxlen); - } -@@ -102,7 +102,7 @@ show_path (char ** r, int * len, struct vectors * vecs, struct path *pp, - - c += snprint_path(c, reply + maxlen - c, style, pp, 0); - -- again = ((c - reply) == (maxlen - 1)); -+ again = (c == reply + maxlen - 1); - - REALLOC_REPLY(reply, again, maxlen); - } -@@ -131,7 +131,7 @@ show_map_topology (char ** r, int * len, struct multipath * mpp, - c = reply; - - c += snprint_multipath_topology(c, reply + maxlen - c, mpp, 2); -- again = ((c - reply) == (maxlen - 1)); -+ again = (c == reply + maxlen - 1); - - REALLOC_REPLY(reply, again, maxlen); - } -@@ -171,7 +171,7 @@ show_maps_topology (char ** r, int * len, struct vectors * vecs) - } - c += snprint_foreign_topology(c, reply + maxlen - c, 2); - -- again = ((c - reply) == (maxlen - 1)); -+ again = (c == reply + maxlen - 1); - - REALLOC_REPLY(reply, again, maxlen); - } -@@ -209,7 +209,7 @@ show_maps_json (char ** r, int * len, struct vectors * vecs) - c = reply; - - c += snprint_multipath_topology_json(c, maxlen, vecs); -- again = ((c - reply) == maxlen); -+ again = (c == reply + maxlen); - - REALLOC_REPLY(reply, again, maxlen); - } -@@ -238,7 +238,7 @@ show_map_json (char ** r, int * len, struct multipath * mpp, - c = reply; - - c += snprint_multipath_map_json(c, maxlen, mpp); -- again = ((c - reply) == maxlen); -+ again = (c == reply + maxlen); - - REALLOC_REPLY(reply, again, maxlen); - } -@@ -487,7 +487,7 @@ show_map (char ** r, int *len, struct multipath * mpp, char * style, - c += snprint_multipath(c, reply + maxlen - c, style, - mpp, pretty); - -- again = ((c - reply) == (maxlen - 1)); -+ again = (c == reply + maxlen - 1); - - REALLOC_REPLY(reply, again, maxlen); - } -@@ -533,7 +533,7 @@ show_maps (char ** r, int *len, struct vectors * vecs, char * style, - } - c += snprint_foreign_multipaths(c, reply + maxlen - c, - style, pretty); -- again = ((c - reply) == (maxlen - 1)); -+ again = (c == reply + maxlen - 1); - - REALLOC_REPLY(reply, again, maxlen); - } -@@ -1297,7 +1297,7 @@ show_blacklist (char ** r, int * len) - - c = reply; - c += snprint_blacklist_report(conf, c, maxlen); -- again = ((c - reply) == maxlen); -+ again = (c == reply + maxlen); - REALLOC_REPLY(reply, again, maxlen); - } - pthread_cleanup_pop(1); -@@ -1339,7 +1339,7 @@ show_devices (char ** r, int * len, struct vectors *vecs) - - c = reply; - c += snprint_devices(conf, c, maxlen, vecs); -- again = ((c - reply) == maxlen); -+ again = (c == reply + maxlen); - REALLOC_REPLY(reply, again, maxlen); - } - pthread_cleanup_pop(1); -diff --git a/multipathd/main.c b/multipathd/main.c -index 8baf9abe..6b7db2c0 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -2374,7 +2374,7 @@ checkerloop (void *ap) - conf = get_multipath_config(); - max_checkint = conf->max_checkint; - put_multipath_config(conf); -- if (diff_time.tv_sec > max_checkint) -+ if (diff_time.tv_sec > (time_t)max_checkint) - condlog(1, "path checkers took longer " - "than %lu seconds, consider " - "increasing max_polling_interval", --- -2.17.2 - diff --git a/0015-multipathd-avoid-sending-READY-1-to-systemd-on-early.patch b/0015-multipathd-avoid-sending-READY-1-to-systemd-on-early.patch new file mode 100644 index 0000000..c2d1475 --- /dev/null +++ b/0015-multipathd-avoid-sending-READY-1-to-systemd-on-early.patch @@ -0,0 +1,67 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 15 Sep 2020 10:23:05 +0200 +Subject: [PATCH] multipathd: avoid sending "READY=1" to systemd on early + shutdown + +If multipathd gets a shutdown request during initial reconfigure(), +it shouldn't send "READY=1" to systemd. Ensure this by sending +"READY=1" via post_config_state(). + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 16 +++++++--------- + 1 file changed, 7 insertions(+), 9 deletions(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index fa53e963..53a22a43 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -189,6 +189,8 @@ static void do_sd_notify(enum daemon_status old_state, + { + char notify_msg[MSG_SIZE]; + const char *msg; ++ static bool startup_done = false; ++ + /* + * Checkerloop switches back and forth between idle and running state. + * No need to tell systemd each time. +@@ -205,6 +207,11 @@ static void do_sd_notify(enum daemon_status old_state, + + if (msg && !safe_sprintf(notify_msg, "STATUS=%s", msg)) + sd_notify(0, notify_msg); ++ ++ if (new_state == DAEMON_IDLE && !startup_done) { ++ sd_notify(0, "READY=1"); ++ startup_done = true; ++ } + } + #endif + +@@ -2903,9 +2910,6 @@ child (__attribute__((unused)) void *param) + struct vectors * vecs; + struct multipath * mpp; + int i; +-#ifdef USE_SYSTEMD +- int startup_done = 0; +-#endif + int rc; + int pid_fd = -1; + struct config *conf; +@@ -3065,12 +3069,6 @@ child (__attribute__((unused)) void *param) + } + lock_cleanup_pop(vecs->lock); + post_config_state(DAEMON_IDLE); +-#ifdef USE_SYSTEMD +- if (!startup_done) { +- sd_notify(0, "READY=1"); +- startup_done = 1; +- } +-#endif + } + } + +-- +2.17.2 + diff --git a/0016-libmultipath-set_uint-fix-parsing-for-32bit.patch b/0016-libmultipath-set_uint-fix-parsing-for-32bit.patch deleted file mode 100644 index c621937..0000000 --- a/0016-libmultipath-set_uint-fix-parsing-for-32bit.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 11 May 2020 22:22:25 +0200 -Subject: [PATCH] libmultipath: set_uint: fix parsing for 32bit - -On architectures where sizeof(long) == sizeof(int), the code wouldn't -work as intended. Use strtoul instead. As strtoul happily parses -negative numbers as input, require the number to begin with a digit. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/dict.c | 11 +++++++---- - 1 file changed, 7 insertions(+), 4 deletions(-) - -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index 3e25e74f..0e9ea387 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -60,19 +60,22 @@ static int - set_uint(vector strvec, void *ptr) - { - unsigned int *uint_ptr = (unsigned int *)ptr; -- char *buff, *eptr; -- long res; -+ char *buff, *eptr, *p; -+ unsigned long res; - int rc; - - buff = set_value(strvec); - if (!buff) - return 1; - -- res = strtol(buff, &eptr, 10); -+ p = buff; -+ while (isspace(*p)) -+ p++; -+ res = strtoul(p, &eptr, 10); - if (eptr > buff) - while (isspace(*eptr)) - eptr++; -- if (*buff == '\0' || *eptr != '\0' || res < 0 || res > UINT_MAX) { -+ if (*buff == '\0' || *eptr != '\0' || !isdigit(*p) || res > UINT_MAX) { - condlog(1, "%s: invalid value for %s: \"%s\"", - __func__, (char*)VECTOR_SLOT(strvec, 0), buff); - rc = 1; --- -2.17.2 - diff --git a/0016-multipathd-send-STOPPING-1-to-systemd-on-shutdown.patch b/0016-multipathd-send-STOPPING-1-to-systemd-on-shutdown.patch new file mode 100644 index 0000000..b38cf2f --- /dev/null +++ b/0016-multipathd-send-STOPPING-1-to-systemd-on-shutdown.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 15 Sep 2020 10:47:52 +0200 +Subject: [PATCH] multipathd: send "STOPPING=1" to systemd on shutdown + +Inform systemd that the daemon is shutting down. See sd_notify(3). + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 53a22a43..c264351c 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -208,7 +208,9 @@ static void do_sd_notify(enum daemon_status old_state, + if (msg && !safe_sprintf(notify_msg, "STATUS=%s", msg)) + sd_notify(0, notify_msg); + +- if (new_state == DAEMON_IDLE && !startup_done) { ++ if (new_state == DAEMON_SHUTDOWN) ++ sd_notify(0, "STOPPING=1"); ++ else if (new_state == DAEMON_IDLE && !startup_done) { + sd_notify(0, "READY=1"); + startup_done = true; + } +-- +2.17.2 + diff --git a/0017-multipath-tools-tests-Makefile-add-lmpathcmd-to-LIBD.patch b/0017-multipath-tools-tests-Makefile-add-lmpathcmd-to-LIBD.patch deleted file mode 100644 index 282aa38..0000000 --- a/0017-multipath-tools-tests-Makefile-add-lmpathcmd-to-LIBD.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 11 May 2020 18:24:19 +0200 -Subject: [PATCH] multipath-tools tests/Makefile: add -lmpathcmd to LIBDEPS - -Make sure the linker finds libmpathcmd. - -Signed-off-by: Benjamin Marzinski ---- - tests/Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/tests/Makefile b/tests/Makefile -index 77ff3249..028c9ea7 100644 ---- a/tests/Makefile -+++ b/tests/Makefile -@@ -10,7 +10,7 @@ W_MISSING_INITIALIZERS := $(call TEST_MISSING_INITIALIZERS) - - CFLAGS += $(BIN_CFLAGS) -I$(multipathdir) -I$(mpathcmddir) \ - -Wno-unused-parameter $(W_MISSING_INITIALIZERS) --LIBDEPS += -L$(multipathdir) -lmultipath -lcmocka -+LIBDEPS += -L$(multipathdir) -L$(mpathcmddir) -lmultipath -lmpathcmd -lcmocka - - TESTS := uevent parser util dmevents hwtable blacklist unaligned vpd pgpolicy \ - alias directio --- -2.17.2 - diff --git a/0017-multipathd-send-RELOADING-1-to-systemd-on-DAEMON_CON.patch b/0017-multipathd-send-RELOADING-1-to-systemd-on-DAEMON_CON.patch new file mode 100644 index 0000000..76894d0 --- /dev/null +++ b/0017-multipathd-send-RELOADING-1-to-systemd-on-DAEMON_CON.patch @@ -0,0 +1,42 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 15 Sep 2020 10:57:22 +0200 +Subject: [PATCH] multipathd: send "RELOADING=1" to systemd on DAEMON_CONFIGURE + state + +The logic is as follows: child() sets DAEMON_IDLE status after +DAEMON_CONFIGURE when reconfigure() has finished. The only other state change +that can race with that is DAEMON_SHUTDOWN. Other state changes will wait for +DAEMON_IDLE first (see set_config_state()). When DAEMON_CONFIGURE is entered, +and we are not just starting up, send a "RELOADING=1" message to +systemd. After that, we must send "READY=1" when we're done reloading. Also +do that on startup, when DAEMON_IDLE is set for the first time. +See sd_notify(3). + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index c264351c..e3f2328d 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -210,10 +210,11 @@ static void do_sd_notify(enum daemon_status old_state, + + if (new_state == DAEMON_SHUTDOWN) + sd_notify(0, "STOPPING=1"); +- else if (new_state == DAEMON_IDLE && !startup_done) { ++ else if (new_state == DAEMON_IDLE && old_state == DAEMON_CONFIGURE) { + sd_notify(0, "READY=1"); + startup_done = true; +- } ++ } else if (new_state == DAEMON_CONFIGURE && startup_done) ++ sd_notify(0, "RELOADING=1"); + } + #endif + +-- +2.17.2 + diff --git a/0018-multipath-tools-tests-Makefile-Fix-OBJDEPS-for-hwtab.patch b/0018-multipath-tools-tests-Makefile-Fix-OBJDEPS-for-hwtab.patch deleted file mode 100644 index 5835089..0000000 --- a/0018-multipath-tools-tests-Makefile-Fix-OBJDEPS-for-hwtab.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 11 May 2020 23:44:19 +0200 -Subject: [PATCH] multipath tools tests/Makefile: Fix OBJDEPS for hwtable-test - -OBJDEPS needs to list object files that _call_ functions we want -to wrap, but it should _not_ list the object files where these -functions are defined; otherwise the linker might resolve these -symbols before they can be wrapped. - -(Observed on i586 with gcc 9.3.1, ld 2.34.0, where wrapping -prio_getprio() doesn't work with prio.o in OBJDEPS). - -Signed-off-by: Benjamin Marzinski ---- - tests/Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/tests/Makefile b/tests/Makefile -index 028c9ea7..1b8706a7 100644 ---- a/tests/Makefile -+++ b/tests/Makefile -@@ -41,7 +41,7 @@ endif - dmevents-test_LIBDEPS = -lpthread -ldevmapper -lurcu - hwtable-test_TESTDEPS := test-lib.o - hwtable-test_OBJDEPS := ../libmultipath/discovery.o ../libmultipath/blacklist.o \ -- ../libmultipath/prio.o ../libmultipath/callout.o ../libmultipath/structs.o -+ ../libmultipath/structs.o - hwtable-test_LIBDEPS := -ludev -lpthread -ldl - blacklist-test_TESTDEPS := test-log.o - blacklist-test_OBJDEPS := ../libmultipath/blacklist.o --- -2.17.2 - diff --git a/0018-multipathd-use-volatile-qualifier-for-running_state.patch b/0018-multipathd-use-volatile-qualifier-for-running_state.patch new file mode 100644 index 0000000..400298e --- /dev/null +++ b/0018-multipathd-use-volatile-qualifier-for-running_state.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 15 Sep 2020 12:44:59 +0200 +Subject: [PATCH] multipathd: use volatile qualifier for running_state + +While we access running_state only under the config_lock, +we sometimes do in a loop. Use the volatile qualifier to make +sure compilers can't optimize away the loads. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index e3f2328d..d081b3e9 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -126,7 +126,7 @@ int poll_dmevents = 0; + int poll_dmevents = 1; + #endif + /* Don't access this variable without holding config_lock */ +-enum daemon_status running_state = DAEMON_INIT; ++volatile enum daemon_status running_state = DAEMON_INIT; + pid_t daemon_pid; + pthread_mutex_t config_lock = PTHREAD_MUTEX_INITIALIZER; + pthread_cond_t config_cond; +-- +2.17.2 + diff --git a/0019-multipath-tools-tests-test-lib.c-drop-__wrap_is_clai.patch b/0019-multipath-tools-tests-test-lib.c-drop-__wrap_is_clai.patch deleted file mode 100644 index e5882f6..0000000 --- a/0019-multipath-tools-tests-test-lib.c-drop-__wrap_is_clai.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 11 May 2020 23:43:02 +0200 -Subject: [PATCH] multipath-tools tests/test-lib.c: drop - __wrap_is_claimed_by_foreign - -is_claimed_by_foreign() is an inline function and can't be wrapped. - -Signed-off-by: Benjamin Marzinski ---- - tests/test-lib.c | 6 ------ - 1 file changed, 6 deletions(-) - -diff --git a/tests/test-lib.c b/tests/test-lib.c -index 59275163..00bae58e 100644 ---- a/tests/test-lib.c -+++ b/tests/test-lib.c -@@ -56,12 +56,6 @@ int __wrap_execute_program(char *path, char *value, int len) - return 0; - } - --bool __wrap_is_claimed_by_foreign(struct udev_device *ud) --{ -- condlog(5, "%s: %p", __func__, ud); -- return false; --} -- - struct udev_list_entry - *__wrap_udev_device_get_properties_list_entry(struct udev_device *ud) - { --- -2.17.2 - diff --git a/0019-multipathd-generalize-and-fix-wait_for_state_change_.patch b/0019-multipathd-generalize-and-fix-wait_for_state_change_.patch new file mode 100644 index 0000000..73f99ec --- /dev/null +++ b/0019-multipathd-generalize-and-fix-wait_for_state_change_.patch @@ -0,0 +1,72 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 15 Sep 2020 12:46:36 +0200 +Subject: [PATCH] multipathd: generalize and fix wait_for_state_change_if() + +It's unlikely but not impossible that other threads change the state +while we're waiting, and if we grab the lock again, it's still not +what we wanted. We need to continue waiting until either the condition +is met, or time timeout expired. + +Moreover, generalize this code so that it can also be used in +set_config_state(). + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 25 ++++++++++++++++++------- + 1 file changed, 18 insertions(+), 7 deletions(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index d081b3e9..1fb0ee62 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -223,6 +223,23 @@ static void config_cleanup(__attribute__((unused)) void *arg) + pthread_mutex_unlock(&config_lock); + } + ++#define __wait_for_state_change(condition, ms) \ ++ ({ \ ++ struct timespec tmo; \ ++ int rc = 0; \ ++ \ ++ if (condition) { \ ++ get_monotonic_time(&tmo); \ ++ tmo.tv_nsec += (ms) * 1000 * 1000; \ ++ normalize_timespec(&tmo); \ ++ do \ ++ rc = pthread_cond_timedwait( \ ++ &config_cond, &config_lock, &tmo); \ ++ while (rc == 0 && (condition)); \ ++ } \ ++ rc; \ ++ }) ++ + /* + * If the current status is @oldstate, wait for at most @ms milliseconds + * for the state to change, and return the new state, which may still be +@@ -232,20 +249,14 @@ enum daemon_status wait_for_state_change_if(enum daemon_status oldstate, + unsigned long ms) + { + enum daemon_status st; +- struct timespec tmo; + + if (oldstate == DAEMON_SHUTDOWN) + return DAEMON_SHUTDOWN; + + pthread_mutex_lock(&config_lock); + pthread_cleanup_push(config_cleanup, NULL); ++ __wait_for_state_change(running_state == oldstate, ms); + st = running_state; +- if (st == oldstate && clock_gettime(CLOCK_MONOTONIC, &tmo) == 0) { +- tmo.tv_nsec += ms * 1000 * 1000; +- normalize_timespec(&tmo); +- (void)pthread_cond_timedwait(&config_cond, &config_lock, &tmo); +- st = running_state; +- } + pthread_cleanup_pop(1); + return st; + } +-- +2.17.2 + diff --git a/0020-multipath-tools-tests-directio-fix-Wmaybe-uninitaliz.patch b/0020-multipath-tools-tests-directio-fix-Wmaybe-uninitaliz.patch deleted file mode 100644 index 3bf6f75..0000000 --- a/0020-multipath-tools-tests-directio-fix-Wmaybe-uninitaliz.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 12 May 2020 00:11:39 +0200 -Subject: [PATCH] multipath-tools tests/directio: fix -Wmaybe-uninitalized - warning - -Initialize aio_grp to satisfy gcc. - -Signed-off-by: Benjamin Marzinski ---- - tests/directio.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/tests/directio.c b/tests/directio.c -index 3cd7a520..66aaf0eb 100644 ---- a/tests/directio.c -+++ b/tests/directio.c -@@ -316,7 +316,7 @@ static void test_init_free(void **state) - { - int i, count = 0; - struct checker c[4096] = {0}; -- struct aio_group *aio_grp; -+ struct aio_group *aio_grp = NULL; - - assert_true(list_empty(&aio_grp_list)); - will_return(__wrap_io_setup, 0); --- -2.17.2 - diff --git a/0020-multipathd-set_config_state-avoid-code-duplication.patch b/0020-multipathd-set_config_state-avoid-code-duplication.patch new file mode 100644 index 0000000..a5310f3 --- /dev/null +++ b/0020-multipathd-set_config_state-avoid-code-duplication.patch @@ -0,0 +1,55 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 15 Sep 2020 12:48:55 +0200 +Subject: [PATCH] multipathd: set_config_state(): avoid code duplication + +Use __post_config_state() and __wait_for_state_change(). This +way __post_config_state() is the only place where running_state +is ever changed, and we avoid code duplication. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 23 +++++------------------ + 1 file changed, 5 insertions(+), 18 deletions(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 1fb0ee62..39aea4ad 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -292,27 +292,14 @@ int set_config_state(enum daemon_status state) + pthread_cleanup_push(config_cleanup, NULL); + pthread_mutex_lock(&config_lock); + if (running_state != state) { +-#ifdef USE_SYSTEMD +- enum daemon_status old_state = running_state; +-#endif + + if (running_state == DAEMON_SHUTDOWN) + rc = EINVAL; +- else if (running_state != DAEMON_IDLE) { +- struct timespec ts; +- +- get_monotonic_time(&ts); +- ts.tv_sec += 1; +- rc = pthread_cond_timedwait(&config_cond, +- &config_lock, &ts); +- } +- if (!rc && (running_state != DAEMON_SHUTDOWN)) { +- running_state = state; +- pthread_cond_broadcast(&config_cond); +-#ifdef USE_SYSTEMD +- do_sd_notify(old_state, state); +-#endif +- } ++ else ++ rc = __wait_for_state_change( ++ running_state != DAEMON_IDLE, 1000); ++ if (!rc) ++ __post_config_state(state); + } + pthread_cleanup_pop(1); + return rc; +-- +2.17.2 + diff --git a/0021-libmultipath-move-libsg-into-libmultipath.patch b/0021-libmultipath-move-libsg-into-libmultipath.patch deleted file mode 100644 index e7cf278..0000000 --- a/0021-libmultipath-move-libsg-into-libmultipath.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 12 May 2020 16:46:15 +0200 -Subject: [PATCH] libmultipath: move libsg into libmultipath - -sg_read() is called from readsector0 and emc_clariion. Move it -to libmultipath/, where all common code resides. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/Makefile | 3 ++- - libmultipath/checkers/Makefile | 6 +++--- - libmultipath/{checkers => }/libsg.c | 0 - libmultipath/{checkers => }/libsg.h | 0 - libmultipath/prioritizers/Makefile | 2 +- - 5 files changed, 6 insertions(+), 5 deletions(-) - rename libmultipath/{checkers => }/libsg.c (100%) - rename libmultipath/{checkers => }/libsg.h (100%) - -diff --git a/libmultipath/Makefile b/libmultipath/Makefile -index ad690a49..f19b7ad2 100644 ---- a/libmultipath/Makefile -+++ b/libmultipath/Makefile -@@ -47,7 +47,8 @@ OBJS = memory.o parser.o vector.o devmapper.o callout.o \ - switchgroup.o uxsock.o print.o alias.o log_pthread.o \ - log.o configure.o structs_vec.o sysfs.o prio.o checkers.o \ - lock.o file.o wwids.o prioritizers/alua_rtpg.o prkey.o \ -- io_err_stat.o dm-generic.o generic.o foreign.o nvme-lib.o -+ io_err_stat.o dm-generic.o generic.o foreign.o nvme-lib.o \ -+ libsg.o - - all: $(LIBS) - -diff --git a/libmultipath/checkers/Makefile b/libmultipath/checkers/Makefile -index 02caea64..01c04510 100644 ---- a/libmultipath/checkers/Makefile -+++ b/libmultipath/checkers/Makefile -@@ -17,10 +17,10 @@ LIBS= \ - - all: $(LIBS) - --libcheckdirectio.so: libsg.o directio.o -+libcheckdirectio.so: directio.o - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ -laio - --libcheck%.so: libsg.o %.o -+libcheck%.so: %.o - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ - - install: -@@ -32,7 +32,7 @@ uninstall: - clean: dep_clean - $(RM) core *.a *.o *.gz *.so - --OBJS := $(LIBS:libcheck%.so=%.o) libsg.o directio.o -+OBJS := $(LIBS:libcheck%.so=%.o) - .SECONDARY: $(OBJS) - - include $(wildcard $(OBJS:.o=.d)) -diff --git a/libmultipath/checkers/libsg.c b/libmultipath/libsg.c -similarity index 100% -rename from libmultipath/checkers/libsg.c -rename to libmultipath/libsg.c -diff --git a/libmultipath/checkers/libsg.h b/libmultipath/libsg.h -similarity index 100% -rename from libmultipath/checkers/libsg.h -rename to libmultipath/libsg.h -diff --git a/libmultipath/prioritizers/Makefile b/libmultipath/prioritizers/Makefile -index 9d0fe03c..fc6e0e0c 100644 ---- a/libmultipath/prioritizers/Makefile -+++ b/libmultipath/prioritizers/Makefile -@@ -28,7 +28,7 @@ endif - - all: $(LIBS) - --libpriopath_latency.so: path_latency.o ../checkers/libsg.o -+libpriopath_latency.so: path_latency.o - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ -lm - - libprio%.so: %.o --- -2.17.2 - diff --git a/0021-multipathd-cancel-threads-early-during-shutdown.patch b/0021-multipathd-cancel-threads-early-during-shutdown.patch new file mode 100644 index 0000000..cc51513 --- /dev/null +++ b/0021-multipathd-cancel-threads-early-during-shutdown.patch @@ -0,0 +1,61 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 4 Jan 2019 17:10:25 +0100 +Subject: [PATCH] multipathd: cancel threads early during shutdown + +Cancel the other threads before taking vecs->lock. This avoids +delays during shutdown caused e.g. by the checker thread holding +the vecs lock. + +Note: this makes it possible that cancelled threads leak memory, +because they can now be cancelled before having released the vecs +lock. I believe this is acceptable, as only threads are affected +that are cancelled during multipathd shutdown. + +Cc: Chongyun Wu +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 17 +++++++++-------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 39aea4ad..d1f8cc1b 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -3073,23 +3073,24 @@ child (__attribute__((unused)) void *param) + } + } + +- lock(&vecs->lock); ++ pthread_cancel(check_thr); ++ pthread_cancel(uevent_thr); ++ pthread_cancel(uxlsnr_thr); ++ pthread_cancel(uevq_thr); ++ if (poll_dmevents) ++ pthread_cancel(dmevent_thr); ++ + conf = get_multipath_config(); + queue_without_daemon = conf->queue_without_daemon; + put_multipath_config(conf); ++ ++ lock(&vecs->lock); + if (queue_without_daemon == QUE_NO_DAEMON_OFF) + vector_foreach_slot(vecs->mpvec, mpp, i) + dm_queue_if_no_path(mpp->alias, 0); + remove_maps_and_stop_waiters(vecs); + unlock(&vecs->lock); + +- pthread_cancel(check_thr); +- pthread_cancel(uevent_thr); +- pthread_cancel(uxlsnr_thr); +- pthread_cancel(uevq_thr); +- if (poll_dmevents) +- pthread_cancel(dmevent_thr); +- + pthread_join(check_thr, NULL); + pthread_join(uevent_thr, NULL); + pthread_join(uxlsnr_thr, NULL); +-- +2.17.2 + diff --git a/0022-multipath-tools-Makefile-add-install-dependency.patch b/0022-multipath-tools-Makefile-add-install-dependency.patch deleted file mode 100644 index 95c80fd..0000000 --- a/0022-multipath-tools-Makefile-add-install-dependency.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 12 May 2020 22:13:51 +0200 -Subject: [PATCH] multipath-tools Makefile: add install dependency - -$(libdir) must exist before running "make install" on prioritizer, checker, -and foreign libraries. - -Cc: Christian Hesse -Signed-off-by: Benjamin Marzinski ---- - Makefile | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/Makefile b/Makefile -index fec3b73b..8bcaba66 100644 ---- a/Makefile -+++ b/Makefile -@@ -32,6 +32,10 @@ libmultipath libdmmp: libmpathcmd - libmpathpersist multipath multipathd: libmultipath - mpathpersist multipathd: libmpathpersist - -+libmultipath/checkers.install \ -+ libmultipath/prioritizers.install \ -+ libmultipath/foreign.install: libmultipath.install -+ - $(BUILDDIRS.clean): - $(MAKE) -C ${@:.clean=} clean - --- -2.17.2 - diff --git a/0022-multipath-tools-don-t-call-dm_lib_release-any-more.patch b/0022-multipath-tools-don-t-call-dm_lib_release-any-more.patch new file mode 100644 index 0000000..fe32b1a --- /dev/null +++ b/0022-multipath-tools-don-t-call-dm_lib_release-any-more.patch @@ -0,0 +1,165 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 15 Sep 2020 17:57:16 +0200 +Subject: [PATCH] multipath-tools: don't call dm_lib_release() any more + +The purpose of dm_lib_release() is to release stacked device node +operations in libdevmapper. This is functionality we don't need and +use any more, as we rely on udev to set up device nodes and symlinks. + +We always set DM_UDEV_DISABLE_LIBRARY_FALLBACK when we run dm tasks. +In the standard CREATE and REMOVE cases, libdevmapper doesn't +stack any operations if this flag is set. The only exceptions are + + a) RESUME operations with DM_ADD_NODE_ON_RESUME set. This happens +implicity when we create new maps + b) RENAME operations + +In both cases, we call dm_udev_wait() after the libdm operation, which +calls update_devs() and thus has the same effect as dm_lib_release(), +cleaning out stacked operations. + +OTOH, dm_lib_releases() accesses static variables in libdevmapper, so +calling it might be racy. + +Drop the calls to dm_lib_release(). + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + kpartx/kpartx.c | 1 - + libmpathpersist/mpath_persist.c | 1 - + multipath/main.c | 1 - + multipathd/cli_handlers.c | 2 -- + multipathd/main.c | 15 ++------------- + 5 files changed, 2 insertions(+), 18 deletions(-) + +diff --git a/kpartx/kpartx.c b/kpartx/kpartx.c +index 4a0aae93..6a7933fa 100644 +--- a/kpartx/kpartx.c ++++ b/kpartx/kpartx.c +@@ -681,7 +681,6 @@ main(int argc, char **argv){ + } + + end: +- dm_lib_release(); + dm_lib_exit(); + + return r; +diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c +index 4b3f3e0d..cc4a088d 100644 +--- a/libmpathpersist/mpath_persist.c ++++ b/libmpathpersist/mpath_persist.c +@@ -56,7 +56,6 @@ mpath_lib_init (void) + int + mpath_lib_exit (struct config *conf) + { +- dm_lib_release(); + dm_lib_exit(); + cleanup_prio(); + cleanup_checkers(); +diff --git a/multipath/main.c b/multipath/main.c +index 9e920d89..dc4974b9 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -1063,7 +1063,6 @@ main (int argc, char *argv[]) + condlog(3, "restart multipath configuration process"); + + out: +- dm_lib_release(); + dm_lib_exit(); + + cleanup_foreign(); +diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c +index 235e2a2e..54635738 100644 +--- a/multipathd/cli_handlers.c ++++ b/multipathd/cli_handlers.c +@@ -860,7 +860,6 @@ cli_add_map (void * v, char ** reply, int * len, void * data) + != CP_OK) + condlog(2, "%s: coalesce_paths failed", + param); +- dm_lib_release(); + FREE(refwwid); + } + } /*we attempt to create device only once*/ +@@ -1032,7 +1031,6 @@ cli_resize(void *v, char **reply, int *len, void *data) + if (resize_map(mpp, size, vecs) != 0) + return 1; + +- dm_lib_release(); + if (setup_multipath(vecs, mpp) != 0) + return 1; + sync_map_state(mpp); +diff --git a/multipathd/main.c b/multipathd/main.c +index d1f8cc1b..5cc34357 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -510,7 +510,6 @@ retry: + sleep(1); + goto retry; + } +- dm_lib_release(); + + fail: + if (new_map && (retries < 0 || wait_for_events(mpp, vecs))) { +@@ -611,10 +610,8 @@ coalesce_maps(struct vectors *vecs, vector nmpv) + vector_del_slot(ompv, i); + i--; + } +- else { +- dm_lib_release(); ++ else + condlog(2, "%s devmap removed", ompp->alias); +- } + } else if (reassign_maps) { + condlog(3, "%s: Reassign existing device-mapper" + " devices", ompp->alias); +@@ -660,10 +657,8 @@ flush_map(struct multipath * mpp, struct vectors * vecs, int nopaths) + } + return r; + } +- else { +- dm_lib_release(); ++ else + condlog(2, "%s: map flushed", mpp->alias); +- } + + orphan_paths(vecs->pathvec, mpp, "map flushed"); + remove_map_and_stop_waiter(mpp, vecs); +@@ -1080,7 +1075,6 @@ rescan: + else + goto fail_map; + } +- dm_lib_release(); + + if ((mpp->action == ACT_CREATE || + (mpp->action == ACT_NOTHING && start_waiter && !mpp->waiter)) && +@@ -1947,8 +1941,6 @@ int reload_and_sync_map(struct multipath *mpp, + { + if (reload_map(vecs, mpp, refresh, 1)) + return 1; +- +- dm_lib_release(); + if (setup_multipath(vecs, mpp) != 0) + return 2; + sync_map_state(mpp); +@@ -2631,8 +2623,6 @@ configure (struct vectors * vecs) + goto fail; + } + +- dm_lib_release(); +- + if (should_exit()) + goto fail; + +@@ -3115,7 +3105,6 @@ child (__attribute__((unused)) void *param) + if (poll_dmevents) + cleanup_dmevent_waiter(); + +- dm_lib_release(); + dm_lib_exit(); + + /* We're done here */ +-- +2.17.2 + diff --git a/0023-libmultipath-devmapper-refactor-libdm-version-determ.patch b/0023-libmultipath-devmapper-refactor-libdm-version-determ.patch new file mode 100644 index 0000000..b5e96b2 --- /dev/null +++ b/0023-libmultipath-devmapper-refactor-libdm-version-determ.patch @@ -0,0 +1,506 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 15 Sep 2020 23:12:15 +0200 +Subject: [PATCH] libmultipath: devmapper: refactor libdm version determination + +As one step towards bundling all possibly racy libdm init calls into a single +function, split the code for determining and checking versions of +libdm and kernel components. Provide a generic helper +libmp_get_version() that makes sure the versions are "lazily" initialized. + +External callers may use dm_prereq(), like before. +Minor API change: dm_prereq() does not nullify the argument any more +if an error is encountered. + +Remove the conf->version field, which isn't needed any more after this +change. This makes it necessary to fixup the hwtable test. Also, it +represents an incompatible ABI change as offsets in "struct config" are +changed, and two symbols removed. Bump the ABI major version to 2. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/config.h | 1 - + libmultipath/devmapper.c | 162 ++++++++++++++++++++---------- + libmultipath/devmapper.h | 10 +- + libmultipath/libmultipath.version | 5 +- + libmultipath/propsel.c | 10 +- + multipathd/dmevents.c | 2 +- + multipathd/main.c | 1 - + tests/Makefile | 2 +- + tests/hwtable.c | 3 - + tests/test-lib.c | 13 +++ + 10 files changed, 141 insertions(+), 68 deletions(-) + +diff --git a/libmultipath/config.h b/libmultipath/config.h +index 290aea58..7af19844 100644 +--- a/libmultipath/config.h ++++ b/libmultipath/config.h +@@ -192,7 +192,6 @@ struct config { + int find_multipaths_timeout; + int marginal_pathgroups; + int skip_delegate; +- unsigned int version[3]; + unsigned int sequence_nr; + + char * multipath_dir; +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index 0bc1d16e..3e36129b 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -26,6 +26,7 @@ + #include "sysfs.h" + #include "config.h" + #include "wwids.h" ++#include "version.h" + + #include "log_pthread.h" + #include +@@ -34,7 +35,13 @@ + #define MAX_WAIT 5 + #define LOOPS_PER_SEC 5 + ++#define INVALID_VERSION ~0U ++static unsigned int dm_library_version[3] = { INVALID_VERSION, }; ++static unsigned int dm_kernel_version[3] = { INVALID_VERSION, }; ++static unsigned int dm_mpath_target_version[3] = { INVALID_VERSION, }; ++ + static pthread_once_t dm_initialized = PTHREAD_ONCE_INIT; ++static pthread_once_t versions_initialized = PTHREAD_ONCE_INIT; + + static int dm_conf_verbosity; + +@@ -102,7 +109,7 @@ dm_write_log (int level, const char *file, int line, const char *f, ...) + return; + } + +-void dm_init(int v) ++static void dm_init(int v) + { + /* + * This maps libdm's standard loglevel _LOG_WARN (= 4), which is rather +@@ -112,61 +119,68 @@ void dm_init(int v) + dm_log_init(&dm_write_log); + } + ++static void init_dm_library_version(void) ++{ ++ char version[64]; ++ unsigned int v[3]; ++ ++ dm_get_library_version(version, sizeof(version)); ++ if (sscanf(version, "%u.%u.%u ", &v[0], &v[1], &v[2]) != 3) { ++ condlog(0, "invalid libdevmapper version %s", version); ++ return; ++ } ++ memcpy(dm_library_version, v, sizeof(dm_library_version)); ++ condlog(3, "libdevmapper version %u.%.2u.%.2u", ++ dm_library_version[0], dm_library_version[1], ++ dm_library_version[2]); ++} ++ + static int + dm_lib_prereq (void) + { +- char version[64]; +- int v[3]; ++ + #if defined(LIBDM_API_HOLD_CONTROL) +- int minv[3] = {1, 2, 111}; ++ unsigned int minv[3] = {1, 2, 111}; + #elif defined(LIBDM_API_GET_ERRNO) +- int minv[3] = {1, 2, 99}; ++ unsigned int minv[3] = {1, 2, 99}; + #elif defined(LIBDM_API_DEFERRED) +- int minv[3] = {1, 2, 89}; ++ unsigned int minv[3] = {1, 2, 89}; + #elif defined(DM_SUBSYSTEM_UDEV_FLAG0) +- int minv[3] = {1, 2, 82}; ++ unsigned int minv[3] = {1, 2, 82}; + #elif defined(LIBDM_API_COOKIE) +- int minv[3] = {1, 2, 38}; ++ unsigned int minv[3] = {1, 2, 38}; + #else +- int minv[3] = {1, 2, 8}; ++ unsigned int minv[3] = {1, 2, 8}; + #endif + +- dm_get_library_version(version, sizeof(version)); +- condlog(3, "libdevmapper version %s", version); +- if (sscanf(version, "%d.%d.%d ", &v[0], &v[1], &v[2]) != 3) { +- condlog(0, "invalid libdevmapper version %s", version); +- return 1; +- } +- +- if VERSION_GE(v, minv) ++ if (VERSION_GE(dm_library_version, minv)) + return 0; +- condlog(0, "libdevmapper version must be >= %d.%.2d.%.2d", ++ condlog(0, "libdevmapper version must be >= %u.%.2u.%.2u", + minv[0], minv[1], minv[2]); + return 1; + } + +-int +-dm_drv_version(unsigned int *v) ++static void init_dm_drv_version(void) + { + char buff[64]; +- +- v[0] = 0; +- v[1] = 0; +- v[2] = 0; ++ unsigned int v[3]; + + if (!dm_driver_version(buff, sizeof(buff))) { + condlog(0, "cannot get kernel dm version"); +- return 1; ++ return; + } + if (sscanf(buff, "%u.%u.%u ", &v[0], &v[1], &v[2]) != 3) { + condlog(0, "invalid kernel dm version '%s'", buff); +- return 1; ++ return; + } +- return 0; ++ memcpy(dm_kernel_version, v, sizeof(dm_library_version)); ++ condlog(3, "kernel device mapper v%u.%u.%u", ++ dm_kernel_version[0], ++ dm_kernel_version[1], ++ dm_kernel_version[2]); + } + +-int +-dm_tgt_version (unsigned int * version, char * str) ++static int dm_tgt_version (unsigned int *version, char *str) + { + int r = 2; + struct dm_task *dmt; +@@ -174,10 +188,11 @@ dm_tgt_version (unsigned int * version, char * str) + struct dm_versions *last_target; + unsigned int *v; + +- version[0] = 0; +- version[1] = 0; +- version[2] = 0; +- ++ /* ++ * We have to call dm_task_create() and not libmp_dm_task_create() ++ * here to avoid a recursive invocation of ++ * pthread_once(&dm_initialized), which would cause a deadlock. ++ */ + if (!(dmt = dm_task_create(DM_DEVICE_LIST_VERSIONS))) + return 1; + +@@ -213,26 +228,25 @@ out: + return r; + } + +-static int +-dm_tgt_prereq (unsigned int *ver) ++static void init_dm_mpath_version(void) + { +- unsigned int minv[3] = {1, 0, 3}; +- unsigned int version[3] = {0, 0, 0}; +- unsigned int * v = version; +- +- if (dm_tgt_version(v, TGT_MPATH)) { +- /* in doubt return not capable */ +- return 1; +- } ++ if (!dm_tgt_version(dm_mpath_target_version, TGT_MPATH)) ++ condlog(3, "DM multipath kernel driver v%u.%u.%u", ++ dm_mpath_target_version[0], ++ dm_mpath_target_version[1], ++ dm_mpath_target_version[2]); ++} + +- /* test request based multipath capability */ +- condlog(3, "DM multipath kernel driver v%u.%u.%u", +- v[0], v[1], v[2]); ++static int dm_tgt_prereq (unsigned int *ver) ++{ ++ unsigned int minv[3] = {1, 0, 3}; + +- if (VERSION_GE(v, minv)) { +- ver[0] = v[0]; +- ver[1] = v[1]; +- ver[2] = v[2]; ++ if (VERSION_GE(dm_mpath_target_version, minv)) { ++ if (ver) { ++ ver[0] = dm_mpath_target_version[0]; ++ ver[1] = dm_mpath_target_version[1]; ++ ver[2] = dm_mpath_target_version[2]; ++ } + return 0; + } + +@@ -241,13 +255,60 @@ dm_tgt_prereq (unsigned int *ver) + return 1; + } + ++static void _init_versions(void) ++{ ++ dlog(logsink, 3, VERSION_STRING); ++ init_dm_library_version(); ++ init_dm_drv_version(); ++ init_dm_mpath_version(); ++} ++ ++static int init_versions(void) { ++ pthread_once(&versions_initialized, _init_versions); ++ return (dm_library_version[0] == INVALID_VERSION || ++ dm_kernel_version[0] == INVALID_VERSION || ++ dm_mpath_target_version[0] == INVALID_VERSION); ++} ++ + int dm_prereq(unsigned int *v) + { ++ if (init_versions()) ++ return 1; + if (dm_lib_prereq()) + return 1; + return dm_tgt_prereq(v); + } + ++int libmp_get_version(int which, unsigned int version[3]) ++{ ++ unsigned int *src_version; ++ ++ init_versions(); ++ switch (which) { ++ case DM_LIBRARY_VERSION: ++ src_version = dm_library_version; ++ break; ++ case DM_KERNEL_VERSION: ++ src_version = dm_kernel_version; ++ break; ++ case DM_MPATH_TARGET_VERSION: ++ src_version = dm_mpath_target_version; ++ break; ++ case MULTIPATH_VERSION: ++ version[0] = (VERSION_CODE >> 16) & 0xff; ++ version[1] = (VERSION_CODE >> 8) & 0xff; ++ version[2] = VERSION_CODE & 0xff; ++ return 0; ++ default: ++ condlog(0, "%s: invalid value for 'which'", __func__); ++ return 1; ++ } ++ if (src_version[0] == INVALID_VERSION) ++ return 1; ++ memcpy(version, src_version, 3 * sizeof(*version)); ++ return 0; ++} ++ + static int libmp_dm_udev_sync = 0; + + void libmp_udev_set_sync_support(int on) +@@ -265,7 +326,6 @@ static void libmp_dm_init(void) + exit(1); + conf = get_multipath_config(); + verbosity = conf->verbosity; +- memcpy(conf->version, version, sizeof(version)); + put_multipath_config(conf); + dm_init(verbosity); + #ifdef LIBDM_API_HOLD_CONTROL +diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h +index f469c98a..a0bcd137 100644 +--- a/libmultipath/devmapper.h ++++ b/libmultipath/devmapper.h +@@ -33,13 +33,10 @@ enum { + DMP_NOT_FOUND, + }; + +-void dm_init(int verbosity); + int dm_prereq(unsigned int *v); + void skip_libmp_dm_init(void); + void libmp_udev_set_sync_support(int on); + struct dm_task *libmp_dm_task_create(int task); +-int dm_drv_version (unsigned int * version); +-int dm_tgt_version (unsigned int * version, char * str); + int dm_simplecmd_flush (int, const char *, uint16_t); + int dm_simplecmd_noflush (int, const char *, uint16_t); + int dm_addmap_create (struct multipath *mpp, char *params); +@@ -89,6 +86,13 @@ struct multipath *dm_get_multipath(const char *name); + #include + #define dm_task_get_errno(x) errno + #endif ++enum { ++ DM_LIBRARY_VERSION, ++ DM_KERNEL_VERSION, ++ DM_MPATH_TARGET_VERSION, ++ MULTIPATH_VERSION ++}; ++int libmp_get_version(int which, unsigned int version[3]); + + #define dm_log_error(lvl, cmd, dmt) \ + condlog(lvl, "%s: libdm task=%d error: %s", __func__, \ +diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version +index a6bf8218..ab5bb0ad 100644 +--- a/libmultipath/libmultipath.version ++++ b/libmultipath/libmultipath.version +@@ -31,7 +31,7 @@ + * The new version inherits the previous ones. + */ + +-LIBMULTIPATH_1.0.0 { ++LIBMULTIPATH_2.0.0 { + global: + /* symbols referenced by multipath and multipathd */ + add_foreign; +@@ -65,7 +65,6 @@ global: + disassemble_status; + dlog; + dm_cancel_deferred_remove; +- dm_drv_version; + dm_enablegroup; + dm_fail_path; + _dm_flush_map; +@@ -87,7 +86,6 @@ global: + dm_reinstate_path; + dm_simplecmd_noflush; + dm_switchgroup; +- dm_tgt_version; + domap; + ensure_directories_exist; + extract_hwe_from_path; +@@ -128,6 +126,7 @@ global: + is_path_valid; + is_quote; + libmp_dm_task_create; ++ libmp_get_version; + libmp_udev_set_sync_support; + load_config; + log_thread_reset; +diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c +index 40201344..3f2c2cfa 100644 +--- a/libmultipath/propsel.c ++++ b/libmultipath/propsel.c +@@ -735,9 +735,10 @@ out: + + int select_minio(struct config *conf, struct multipath *mp) + { +- unsigned int minv_dmrq[3] = {1, 1, 0}; ++ unsigned int minv_dmrq[3] = {1, 1, 0}, version[3]; + +- if (VERSION_GE(conf->version, minv_dmrq)) ++ if (!libmp_get_version(DM_MPATH_TARGET_VERSION, version) ++ && VERSION_GE(version, minv_dmrq)) + return select_minio_rq(conf, mp); + else + return select_minio_bio(conf, mp); +@@ -820,9 +821,10 @@ out: + int select_retain_hwhandler(struct config *conf, struct multipath *mp) + { + const char *origin; +- unsigned int minv_dm_retain[3] = {1, 5, 0}; ++ unsigned int minv_dm_retain[3] = {1, 5, 0}, version[3]; + +- if (!VERSION_GE(conf->version, minv_dm_retain)) { ++ if (!libmp_get_version(DM_MPATH_TARGET_VERSION, version) && ++ !VERSION_GE(version, minv_dm_retain)) { + mp->retain_hwhandler = RETAIN_HWHANDLER_OFF; + origin = "(setting: WARNING, requires kernel dm-mpath version >= 1.5.0)"; + goto out; +diff --git a/multipathd/dmevents.c b/multipathd/dmevents.c +index 5f2d210d..fc97c8a2 100644 +--- a/multipathd/dmevents.c ++++ b/multipathd/dmevents.c +@@ -60,7 +60,7 @@ int dmevent_poll_supported(void) + { + unsigned int v[3]; + +- if (dm_drv_version(v)) ++ if (libmp_get_version(DM_KERNEL_VERSION, v)) + return 0; + + if (VERSION_GE(v, DM_VERSION_FOR_ARM_POLL)) +diff --git a/multipathd/main.c b/multipathd/main.c +index 5cc34357..00b66ba4 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -2709,7 +2709,6 @@ reconfigure (struct vectors * vecs) + /* Re-read any timezone changes */ + tzset(); + +- dm_tgt_version(conf->version, TGT_MPATH); + if (verbosity) + conf->verbosity = verbosity; + if (bindings_read_only) +diff --git a/tests/Makefile b/tests/Makefile +index 9658c9fd..78777bec 100644 +--- a/tests/Makefile ++++ b/tests/Makefile +@@ -43,7 +43,7 @@ endif + dmevents-test_LIBDEPS = -lpthread -ldevmapper -lurcu + hwtable-test_TESTDEPS := test-lib.o + hwtable-test_OBJDEPS := ../libmultipath/discovery.o ../libmultipath/blacklist.o \ +- ../libmultipath/structs.o ++ ../libmultipath/structs.o ../libmultipath/propsel.o + hwtable-test_LIBDEPS := -ludev -lpthread -ldl + blacklist-test_TESTDEPS := test-log.o + blacklist-test_OBJDEPS := ../libmultipath/blacklist.o +diff --git a/tests/hwtable.c b/tests/hwtable.c +index 12660da2..57f832b7 100644 +--- a/tests/hwtable.c ++++ b/tests/hwtable.c +@@ -30,8 +30,6 @@ + #define N_CONF_FILES 2 + + static const char tmplate[] = "/tmp/hwtable-XXXXXX"; +-/* pretend new dm, use minio_rq */ +-static const unsigned int dm_tgt_version[3] = { 1, 1, 1 }; + + struct key_value { + const char *key; +@@ -360,7 +358,6 @@ static void write_device(FILE *ff, int nkv, const struct key_value *kv) + assert_ptr_not_equal(__cf, NULL); \ + assert_ptr_not_equal(__cf->hwtable, NULL); \ + __cf->verbosity = VERBOSITY; \ +- memcpy(&__cf->version, dm_tgt_version, sizeof(__cf->version)); \ + __cf; }) + + #define FREE_CONFIG(conf) do { \ +diff --git a/tests/test-lib.c b/tests/test-lib.c +index b7c09cc2..e7663f9a 100644 +--- a/tests/test-lib.c ++++ b/tests/test-lib.c +@@ -56,6 +56,15 @@ int __wrap_execute_program(char *path, char *value, int len) + return 0; + } + ++int __wrap_libmp_get_version(int which, unsigned int version[3]) ++{ ++ unsigned int *vers = mock_ptr_type(unsigned int *); ++ ++ condlog(4, "%s: %d", __func__, which); ++ memcpy(version, vers, 3 * sizeof(unsigned int)); ++ return 0; ++} ++ + struct udev_list_entry + *__wrap_udev_device_get_properties_list_entry(struct udev_device *ud) + { +@@ -339,6 +348,8 @@ struct multipath *__mock_multipath(struct vectors *vecs, struct path *pp) + struct multipath *mp; + struct config *conf; + struct mocked_path mop; ++ /* pretend new dm, use minio_rq, */ ++ static const unsigned int fake_dm_tgt_version[3] = { 1, 1, 1 }; + + mocked_path_from_path(&mop, pp); + /* pathinfo() call in adopt_paths */ +@@ -351,7 +362,9 @@ struct multipath *__mock_multipath(struct vectors *vecs, struct path *pp) + conf = get_multipath_config(); + select_pgpolicy(conf, mp); + select_no_path_retry(conf, mp); ++ will_return(__wrap_libmp_get_version, fake_dm_tgt_version); + select_retain_hwhandler(conf, mp); ++ will_return(__wrap_libmp_get_version, fake_dm_tgt_version); + select_minio(conf, mp); + put_multipath_config(conf); + +-- +2.17.2 + diff --git a/0023-libmultipath-make-libmp_dm_init-optional.patch b/0023-libmultipath-make-libmp_dm_init-optional.patch deleted file mode 100644 index 588fd87..0000000 --- a/0023-libmultipath-make-libmp_dm_init-optional.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 19 May 2020 12:08:40 -0500 -Subject: [PATCH] libmultipath: make libmp_dm_init optional - -Move dm_initialized out of libmp_dm_task_create(), and add -a function skip_libmp_dm_init() so that users of libmultipath can skip -initializing device-mapper. This is needed for other programs that -use libmultipath (or a library that depends on it) but want to control -how device-mapper is set up. - -Also make dm_prereq a global function. - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/devmapper.c | 17 +++++++++++++---- - libmultipath/devmapper.h | 3 ++- - 2 files changed, 15 insertions(+), 5 deletions(-) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index 13a1cf53..7ed494a1 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -33,6 +33,8 @@ - #define MAX_WAIT 5 - #define LOOPS_PER_SEC 5 - -+static pthread_once_t dm_initialized = PTHREAD_ONCE_INIT; -+ - static int dm_conf_verbosity; - - #ifdef LIBDM_API_DEFERRED -@@ -229,7 +231,7 @@ dm_tgt_prereq (unsigned int *ver) - return 1; - } - --static int dm_prereq(unsigned int *v) -+int dm_prereq(unsigned int *v) - { - if (dm_lib_prereq()) - return 1; -@@ -243,7 +245,7 @@ void libmp_udev_set_sync_support(int on) - libmp_dm_udev_sync = !!on; - } - --void libmp_dm_init(void) -+static void libmp_dm_init(void) - { - struct config *conf; - int verbosity; -@@ -262,11 +264,18 @@ void libmp_dm_init(void) - dm_udev_set_sync_support(libmp_dm_udev_sync); - } - -+static void _do_skip_libmp_dm_init(void) -+{ -+} -+ -+void skip_libmp_dm_init(void) -+{ -+ pthread_once(&dm_initialized, _do_skip_libmp_dm_init); -+} -+ - struct dm_task* - libmp_dm_task_create(int task) - { -- static pthread_once_t dm_initialized = PTHREAD_ONCE_INIT; -- - pthread_once(&dm_initialized, libmp_dm_init); - return dm_task_create(task); - } -diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h -index 7557a86b..17fc9faf 100644 ---- a/libmultipath/devmapper.h -+++ b/libmultipath/devmapper.h -@@ -28,7 +28,8 @@ - #define UUID_PREFIX_LEN (sizeof(UUID_PREFIX) - 1) - - void dm_init(int verbosity); --void libmp_dm_init(void); -+int dm_prereq(unsigned int *v); -+void skip_libmp_dm_init(void); - void libmp_udev_set_sync_support(int on); - struct dm_task *libmp_dm_task_create(int task); - int dm_drv_version (unsigned int * version); --- -2.17.2 - diff --git a/0024-libmultipath-make-sysfs_is_multipathed-able-to-retur.patch b/0024-libmultipath-make-sysfs_is_multipathed-able-to-retur.patch deleted file mode 100644 index 47c7a80..0000000 --- a/0024-libmultipath-make-sysfs_is_multipathed-able-to-retur.patch +++ /dev/null @@ -1,108 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 19 May 2020 12:08:41 -0500 -Subject: [PATCH] libmultipath: make sysfs_is_multipathed able to return wwid - -sysfs_is_multipathed reads the wwid of the dm device holding a path to -check if its a multipath device. Add code to optinally set pp->wwid to -that wwid. This will be used by a future patch. - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/sysfs.c | 24 +++++++++++++++++++----- - libmultipath/sysfs.h | 2 +- - multipath/main.c | 7 ++++--- - 3 files changed, 24 insertions(+), 9 deletions(-) - -diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c -index 62ec2ed7..12a82d95 100644 ---- a/libmultipath/sysfs.c -+++ b/libmultipath/sysfs.c -@@ -295,7 +295,7 @@ static int select_dm_devs(const struct dirent *di) - return fnmatch("dm-*", di->d_name, FNM_FILE_NAME) == 0; - } - --bool sysfs_is_multipathed(const struct path *pp) -+bool sysfs_is_multipathed(struct path *pp, bool set_wwid) - { - char pathbuf[PATH_MAX]; - struct scandir_result sr; -@@ -325,7 +325,7 @@ bool sysfs_is_multipathed(const struct path *pp) - for (i = 0; i < r && !found; i++) { - long fd; - int nr; -- char uuid[6]; -+ char uuid[WWID_SIZE + UUID_PREFIX_LEN]; - - if (safe_snprintf(pathbuf + n, sizeof(pathbuf) - n, - "/%s/dm/uuid", di[i]->d_name)) -@@ -339,12 +339,26 @@ bool sysfs_is_multipathed(const struct path *pp) - - pthread_cleanup_push(close_fd, (void *)fd); - nr = read(fd, uuid, sizeof(uuid)); -- if (nr == sizeof(uuid) && !memcmp(uuid, "mpath-", sizeof(uuid))) -+ if (nr > (int)UUID_PREFIX_LEN && -+ !memcmp(uuid, UUID_PREFIX, UUID_PREFIX_LEN)) - found = true; - else if (nr < 0) { -- condlog(1, "%s: error reading from %s: %s", -- __func__, pathbuf, strerror(errno)); -+ condlog(1, "%s: error reading from %s: %m", -+ __func__, pathbuf); - } -+ if (found && set_wwid) { -+ nr -= UUID_PREFIX_LEN; -+ memcpy(pp->wwid, uuid + UUID_PREFIX_LEN, nr); -+ if (nr == WWID_SIZE) { -+ condlog(4, "%s: overflow while reading from %s", -+ __func__, pathbuf); -+ pp->wwid[0] = '\0'; -+ } else { -+ pp->wwid[nr] = '\0'; -+ strchop(pp->wwid); -+ } -+ } -+ - pthread_cleanup_pop(1); - } - pthread_cleanup_pop(1); -diff --git a/libmultipath/sysfs.h b/libmultipath/sysfs.h -index 9ae30b39..72b39ab2 100644 ---- a/libmultipath/sysfs.h -+++ b/libmultipath/sysfs.h -@@ -14,5 +14,5 @@ ssize_t sysfs_bin_attr_get_value(struct udev_device *dev, const char *attr_name, - unsigned char * value, size_t value_len); - int sysfs_get_size (struct path *pp, unsigned long long * size); - int sysfs_check_holders(char * check_devt, char * new_devt); --bool sysfs_is_multipathed(const struct path *pp); -+bool sysfs_is_multipathed(struct path *pp, bool set_wwid); - #endif -diff --git a/multipath/main.c b/multipath/main.c -index cf9d2a28..545ead87 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -638,7 +638,8 @@ configure (struct config *conf, enum mpath_cmds cmd, - * Shortcut for find_multipaths smart: - * Quick check if path is already multipathed. - */ -- if (sysfs_is_multipathed(VECTOR_SLOT(pathvec, 0))) { -+ if (sysfs_is_multipathed(VECTOR_SLOT(pathvec, 0), -+ false)) { - r = RTVL_YES; - goto print_valid; - } -@@ -747,8 +748,8 @@ configure (struct config *conf, enum mpath_cmds cmd, - /* - * Check if we raced with multipathd - */ -- r = sysfs_is_multipathed(VECTOR_SLOT(pathvec, 0)) ? -- RTVL_YES : RTVL_NO; -+ r = sysfs_is_multipathed(VECTOR_SLOT(pathvec, 0), -+ false) ? RTVL_YES : RTVL_NO; - } - goto print_valid; - } --- -2.17.2 - diff --git a/0024-libmultipath-protect-racy-libdevmapper-calls-with-a-.patch b/0024-libmultipath-protect-racy-libdevmapper-calls-with-a-.patch new file mode 100644 index 0000000..026dd7c --- /dev/null +++ b/0024-libmultipath-protect-racy-libdevmapper-calls-with-a-.patch @@ -0,0 +1,437 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 15 Sep 2020 23:38:48 +0200 +Subject: [PATCH] libmultipath: protect racy libdevmapper calls with a mutex + +dm_udev_wait() and dm_task_run() may access global / static state +in libdevmapper. They need to be protected by a lock in in our +multithreaded library. + +The modified call sequence requires fixing the dmevents test: +devmapper.c must be added to dmevents-test_OBJDEPS to catch calls +to dm_task_run(). Also, the call to dmevent_poll_supported() in +setup() will cause init_versions() to be called, which requires +bypassing the wrappers in the test setup phase. + +Cc: lixiaokeng@huawei.com + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/devmapper.c | 73 +++++++++++++++++++------------ + libmultipath/devmapper.h | 2 + + libmultipath/libmultipath.version | 6 +++ + libmultipath/util.c | 5 +++ + libmultipath/util.h | 1 + + multipathd/dmevents.c | 2 +- + multipathd/waiter.c | 2 +- + tests/Makefile | 1 + + tests/dmevents.c | 12 +++++ + 9 files changed, 75 insertions(+), 29 deletions(-) + +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index 3e36129b..4eb6f539 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -42,6 +42,7 @@ static unsigned int dm_mpath_target_version[3] = { INVALID_VERSION, }; + + static pthread_once_t dm_initialized = PTHREAD_ONCE_INIT; + static pthread_once_t versions_initialized = PTHREAD_ONCE_INIT; ++static pthread_mutex_t libmp_dm_lock = PTHREAD_MUTEX_INITIALIZER; + + static int dm_conf_verbosity; + +@@ -59,16 +60,34 @@ static inline int dm_task_set_cookie(struct dm_task *dmt, uint32_t *c, int a) + return 1; + } + +-void dm_udev_wait(unsigned int c) ++static void libmp_udev_wait(unsigned int c) + { + } + +-void dm_udev_set_sync_support(int c) ++static void dm_udev_set_sync_support(int c) + { + } +- ++#else ++static void libmp_udev_wait(unsigned int c) ++{ ++ pthread_mutex_lock(&libmp_dm_lock); ++ pthread_cleanup_push(cleanup_mutex, &libmp_dm_lock); ++ dm_udev_wait(c); ++ pthread_cleanup_pop(1); ++} + #endif + ++int libmp_dm_task_run(struct dm_task *dmt) ++{ ++ int r; ++ ++ pthread_mutex_lock(&libmp_dm_lock); ++ pthread_cleanup_push(cleanup_mutex, &libmp_dm_lock); ++ r = dm_task_run(dmt); ++ pthread_cleanup_pop(1); ++ return r; ++} ++ + __attribute__((format(printf, 4, 5))) static void + dm_write_log (int level, const char *file, int line, const char *f, ...) + { +@@ -198,7 +217,7 @@ static int dm_tgt_version (unsigned int *version, char *str) + + dm_task_no_open_count(dmt); + +- if (!dm_task_run(dmt)) { ++ if (!libmp_dm_task_run(dmt)) { + dm_log_error(2, DM_DEVICE_LIST_VERSIONS, dmt); + condlog(0, "Can not communicate with kernel DM"); + goto out; +@@ -382,12 +401,12 @@ dm_simplecmd (int task, const char *name, int no_flush, int need_sync, uint16_t + DM_UDEV_DISABLE_LIBRARY_FALLBACK | udev_flags)) + goto out; + +- r = dm_task_run (dmt); ++ r = libmp_dm_task_run (dmt); + if (!r) + dm_log_error(2, task, dmt); + + if (udev_wait_flag) +- dm_udev_wait(cookie); ++ libmp_udev_wait(cookie); + out: + dm_task_destroy (dmt); + return r; +@@ -474,12 +493,12 @@ dm_addmap (int task, const char *target, struct multipath *mpp, + !dm_task_set_cookie(dmt, &cookie, udev_flags)) + goto freeout; + +- r = dm_task_run (dmt); ++ r = libmp_dm_task_run (dmt); + if (!r) + dm_log_error(2, task, dmt); + + if (task == DM_DEVICE_CREATE) +- dm_udev_wait(cookie); ++ libmp_udev_wait(cookie); + freeout: + if (prefixed_uuid) + FREE(prefixed_uuid); +@@ -589,7 +608,7 @@ do_get_info(const char *name, struct dm_info *info) + + dm_task_no_open_count(dmt); + +- if (!dm_task_run(dmt)) { ++ if (!libmp_dm_task_run(dmt)) { + dm_log_error(3, DM_DEVICE_INFO, dmt); + goto out; + } +@@ -630,7 +649,7 @@ int dm_get_map(const char *name, unsigned long long *size, char *outparams) + dm_task_no_open_count(dmt); + + errno = 0; +- if (!dm_task_run(dmt)) { ++ if (!libmp_dm_task_run(dmt)) { + dm_log_error(3, DM_DEVICE_TABLE, dmt); + if (dm_task_get_errno(dmt) == ENXIO) + r = DMP_NOT_FOUND; +@@ -672,7 +691,7 @@ dm_get_prefixed_uuid(const char *name, char *uuid, int uuid_len) + if (!dm_task_set_name (dmt, name)) + goto uuidout; + +- if (!dm_task_run(dmt)) { ++ if (!libmp_dm_task_run(dmt)) { + dm_log_error(3, DM_DEVICE_INFO, dmt); + goto uuidout; + } +@@ -743,7 +762,7 @@ int dm_get_status(const char *name, char *outstatus) + dm_task_no_open_count(dmt); + + errno = 0; +- if (!dm_task_run(dmt)) { ++ if (!libmp_dm_task_run(dmt)) { + dm_log_error(3, DM_DEVICE_STATUS, dmt); + if (dm_task_get_errno(dmt) == ENXIO) + r = DMP_NOT_FOUND; +@@ -796,7 +815,7 @@ int dm_type(const char *name, char *type) + + dm_task_no_open_count(dmt); + +- if (!dm_task_run(dmt)) { ++ if (!libmp_dm_task_run(dmt)) { + dm_log_error(3, DM_DEVICE_TABLE, dmt); + goto out; + } +@@ -840,7 +859,7 @@ int dm_is_mpath(const char *name) + + dm_task_no_open_count(dmt); + +- if (!dm_task_run(dmt)) { ++ if (!libmp_dm_task_run(dmt)) { + dm_log_error(3, DM_DEVICE_TABLE, dmt); + goto out_task; + } +@@ -904,7 +923,7 @@ dm_map_present_by_uuid(const char *uuid) + if (!dm_task_set_uuid(dmt, prefixed_uuid)) + goto out_task; + +- if (!dm_task_run(dmt)) { ++ if (!libmp_dm_task_run(dmt)) { + dm_log_error(3, DM_DEVICE_INFO, dmt); + goto out_task; + } +@@ -950,7 +969,7 @@ dm_get_opencount (const char * mapname) + if (!dm_task_set_name(dmt, mapname)) + goto out; + +- if (!dm_task_run(dmt)) { ++ if (!libmp_dm_task_run(dmt)) { + dm_log_error(3, DM_DEVICE_INFO, dmt); + goto out; + } +@@ -1110,7 +1129,7 @@ int dm_flush_maps (int need_suspend, int retries) + + dm_task_no_open_count(dmt); + +- if (!dm_task_run (dmt)) { ++ if (!libmp_dm_task_run (dmt)) { + dm_log_error(3, DM_DEVICE_LIST, dmt); + goto out; + } +@@ -1156,7 +1175,7 @@ dm_message(const char * mapname, char * message) + + dm_task_no_open_count(dmt); + +- if (!dm_task_run(dmt)) { ++ if (!libmp_dm_task_run(dmt)) { + dm_log_error(2, DM_DEVICE_TARGET_MSG, dmt); + goto out; + } +@@ -1276,7 +1295,7 @@ dm_get_maps (vector mp) + + dm_task_no_open_count(dmt); + +- if (!dm_task_run(dmt)) { ++ if (!libmp_dm_task_run(dmt)) { + dm_log_error(3, DM_DEVICE_LIST, dmt); + goto out; + } +@@ -1361,7 +1380,7 @@ dm_mapname(int major, int minor) + * daemon uev_trigger -> uev_add_map + */ + while (--loop) { +- r = dm_task_run(dmt); ++ r = libmp_dm_task_run(dmt); + + if (r) + break; +@@ -1406,7 +1425,7 @@ do_foreach_partmaps (const char * mapname, + + dm_task_no_open_count(dmt); + +- if (!dm_task_run(dmt)) { ++ if (!libmp_dm_task_run(dmt)) { + dm_log_error(3, DM_DEVICE_LIST, dmt); + goto out; + } +@@ -1641,11 +1660,11 @@ dm_rename (const char * old, char * new, char *delim, int skip_kpartx) + + if (!dm_task_set_cookie(dmt, &cookie, udev_flags)) + goto out; +- r = dm_task_run(dmt); ++ r = libmp_dm_task_run(dmt); + if (!r) + dm_log_error(2, DM_DEVICE_RENAME, dmt); + +- dm_udev_wait(cookie); ++ libmp_udev_wait(cookie); + + out: + dm_task_destroy(dmt); +@@ -1687,7 +1706,7 @@ int dm_reassign_table(const char *name, char *old, char *new) + + dm_task_no_open_count(dmt); + +- if (!dm_task_run(dmt)) { ++ if (!libmp_dm_task_run(dmt)) { + dm_log_error(3, DM_DEVICE_TABLE, dmt); + goto out; + } +@@ -1720,7 +1739,7 @@ int dm_reassign_table(const char *name, char *old, char *new) + if (modified) { + dm_task_no_open_count(reload_dmt); + +- if (!dm_task_run(reload_dmt)) { ++ if (!libmp_dm_task_run(reload_dmt)) { + dm_log_error(3, DM_DEVICE_RELOAD, reload_dmt); + condlog(3, "%s: failed to reassign targets", name); + goto out_reload; +@@ -1767,7 +1786,7 @@ int dm_reassign(const char *mapname) + + dm_task_no_open_count(dmt); + +- if (!dm_task_run(dmt)) { ++ if (!libmp_dm_task_run(dmt)) { + dm_log_error(3, DM_DEVICE_DEPS, dmt); + goto out; + } +@@ -1835,7 +1854,7 @@ int dm_setgeometry(struct multipath *mpp) + goto out; + } + +- r = dm_task_run(dmt); ++ r = libmp_dm_task_run(dmt); + if (!r) + dm_log_error(3, DM_DEVICE_SET_GEOMETRY, dmt); + out: +diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h +index a0bcd137..fa6b3c53 100644 +--- a/libmultipath/devmapper.h ++++ b/libmultipath/devmapper.h +@@ -93,6 +93,8 @@ enum { + MULTIPATH_VERSION + }; + int libmp_get_version(int which, unsigned int version[3]); ++struct dm_task; ++int libmp_dm_task_run(struct dm_task *dmt); + + #define dm_log_error(lvl, cmd, dmt) \ + condlog(lvl, "%s: libdm task=%d error: %s", __func__, \ +diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version +index ab5bb0ad..97acdbb2 100644 +--- a/libmultipath/libmultipath.version ++++ b/libmultipath/libmultipath.version +@@ -245,3 +245,9 @@ global: + local: + *; + }; ++ ++LIBMULTIPATH_2.1.0 { ++global: ++ libmp_dm_task_run; ++ cleanup_mutex; ++} LIBMULTIPATH_2.0.0; +diff --git a/libmultipath/util.c b/libmultipath/util.c +index 1f977792..0e37f3ff 100644 +--- a/libmultipath/util.c ++++ b/libmultipath/util.c +@@ -424,6 +424,11 @@ void cleanup_free_ptr(void *arg) + free(*p); + } + ++void cleanup_mutex(void *arg) ++{ ++ pthread_mutex_unlock(arg); ++} ++ + struct bitfield *alloc_bitfield(unsigned int maxbit) + { + unsigned int n; +diff --git a/libmultipath/util.h b/libmultipath/util.h +index ac19473e..e9b48f9f 100644 +--- a/libmultipath/util.h ++++ b/libmultipath/util.h +@@ -49,6 +49,7 @@ int should_exit(void); + + void close_fd(void *arg); + void cleanup_free_ptr(void *arg); ++void cleanup_mutex(void *arg); + + struct scandir_result { + struct dirent **di; +diff --git a/multipathd/dmevents.c b/multipathd/dmevents.c +index fc97c8a2..b561cbfd 100644 +--- a/multipathd/dmevents.c ++++ b/multipathd/dmevents.c +@@ -156,7 +156,7 @@ static int dm_get_events(void) + + dm_task_no_open_count(dmt); + +- if (!dm_task_run(dmt)) { ++ if (!libmp_dm_task_run(dmt)) { + dm_log_error(3, DM_DEVICE_LIST, dmt); + goto fail; + } +diff --git a/multipathd/waiter.c b/multipathd/waiter.c +index 3bc69807..bbe6c2a1 100644 +--- a/multipathd/waiter.c ++++ b/multipathd/waiter.c +@@ -118,7 +118,7 @@ static int waiteventloop (struct event_thread *waiter) + pthread_sigmask(SIG_UNBLOCK, &set, &oldset); + + pthread_testcancel(); +- r = dm_task_run(waiter->dmt); ++ r = libmp_dm_task_run(waiter->dmt); + if (!r) + dm_log_error(2, DM_DEVICE_WAITEVENT, waiter->dmt); + pthread_testcancel(); +diff --git a/tests/Makefile b/tests/Makefile +index 78777bec..908407ea 100644 +--- a/tests/Makefile ++++ b/tests/Makefile +@@ -40,6 +40,7 @@ endif + # linker input file). + # XYZ-test_LIBDEPS: Additional libs to link for this test + ++dmevents-test_OBJDEPS = ../libmultipath/devmapper.o + dmevents-test_LIBDEPS = -lpthread -ldevmapper -lurcu + hwtable-test_TESTDEPS := test-lib.o + hwtable-test_OBJDEPS := ../libmultipath/discovery.o ../libmultipath/blacklist.o \ +diff --git a/tests/dmevents.c b/tests/dmevents.c +index bee117ac..b7c5122b 100644 +--- a/tests/dmevents.c ++++ b/tests/dmevents.c +@@ -179,6 +179,8 @@ struct dm_names *build_dm_names(void) + return names; + } + ++static bool setup_done; ++ + static int setup(void **state) + { + if (dmevent_poll_supported()) { +@@ -186,6 +188,7 @@ static int setup(void **state) + *state = &data; + } else + *state = NULL; ++ setup_done = true; + return 0; + } + +@@ -262,14 +265,20 @@ struct dm_task *__wrap_libmp_dm_task_create(int task) + return mock_type(struct dm_task *); + } + ++int __real_dm_task_no_open_count(struct dm_task *dmt); + int __wrap_dm_task_no_open_count(struct dm_task *dmt) + { ++ if (!setup_done) ++ return __real_dm_task_no_open_count(dmt); + assert_ptr_equal((struct test_data *)dmt, &data); + return mock_type(int); + } + ++int __real_dm_task_run(struct dm_task *dmt); + int __wrap_dm_task_run(struct dm_task *dmt) + { ++ if (!setup_done) ++ return __real_dm_task_run(dmt); + assert_ptr_equal((struct test_data *)dmt, &data); + return mock_type(int); + } +@@ -291,8 +300,11 @@ struct dm_names * __wrap_dm_task_get_names(struct dm_task *dmt) + return data.names; + } + ++void __real_dm_task_destroy(struct dm_task *dmt); + void __wrap_dm_task_destroy(struct dm_task *dmt) + { ++ if (!setup_done) ++ return __real_dm_task_destroy(dmt); + assert_ptr_equal((struct test_data *)dmt, &data); + + if (data.names) { +-- +2.17.2 + diff --git a/0074-libmultipath-constify-file-argument-in-config-parser.patch b/0025-libmultipath-constify-file-argument-in-config-parser.patch similarity index 79% rename from 0074-libmultipath-constify-file-argument-in-config-parser.patch rename to 0025-libmultipath-constify-file-argument-in-config-parser.patch index ffef052..9470cf4 100644 --- a/0074-libmultipath-constify-file-argument-in-config-parser.patch +++ b/0025-libmultipath-constify-file-argument-in-config-parser.patch @@ -1,10 +1,9 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Martin Wilck -Date: Thu, 24 Sep 2020 15:37:07 +0200 +Date: Wed, 16 Sep 2020 12:02:01 +0200 Subject: [PATCH] libmultipath: constify file argument in config parser Reviewed-by: Benjamin Marzinski -Signed-off-by: Martin Wilck Signed-off-by: Benjamin Marzinski --- libmultipath/config.c | 3 +-- @@ -14,10 +13,10 @@ Signed-off-by: Benjamin Marzinski 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/libmultipath/config.c b/libmultipath/config.c -index a253a936..1818f8b9 100644 +index df0f8f45..5c91a09d 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c -@@ -718,8 +718,7 @@ static void set_max_checkint_from_watchdog(struct config *conf) +@@ -719,8 +719,7 @@ static void set_max_checkint_from_watchdog(struct config *conf) } #endif @@ -28,10 +27,10 @@ index a253a936..1818f8b9 100644 struct config *conf = alloc_config(); diff --git a/libmultipath/config.h b/libmultipath/config.h -index c7a73fba..78375f2f 100644 +index 7af19844..ace403b8 100644 --- a/libmultipath/config.h +++ b/libmultipath/config.h -@@ -253,7 +253,7 @@ void free_mptable (vector mptable); +@@ -251,7 +251,7 @@ void free_mptable (vector mptable); int store_hwe (vector hwtable, struct hwentry *); @@ -41,10 +40,10 @@ index c7a73fba..78375f2f 100644 void free_config (struct config * conf); extern struct config *get_multipath_config(void); diff --git a/libmultipath/parser.c b/libmultipath/parser.c -index a7285a35..d150e7b2 100644 +index ed6d5d6d..163ffbc9 100644 --- a/libmultipath/parser.c +++ b/libmultipath/parser.c -@@ -400,7 +400,7 @@ set_regex_value(vector strvec) +@@ -390,7 +390,7 @@ oom: /* non-recursive configuration stream handler */ static int kw_level = 0; @@ -53,16 +52,16 @@ index a7285a35..d150e7b2 100644 { char *tmp; int i; -@@ -444,7 +444,7 @@ is_sublevel_keyword(char *str) +@@ -434,7 +434,7 @@ is_sublevel_keyword(char *str) } int -validate_config_strvec(vector strvec, char *file) +validate_config_strvec(vector strvec, const char *file) { - char *str; + char *str = NULL; int i; -@@ -507,7 +507,8 @@ validate_config_strvec(vector strvec, char *file) +@@ -499,7 +499,8 @@ validate_config_strvec(vector strvec, char *file) } static int @@ -72,7 +71,7 @@ index a7285a35..d150e7b2 100644 { int i; int r = 0, t; -@@ -592,7 +593,7 @@ out: +@@ -584,7 +585,7 @@ out: /* Data initialization */ int @@ -82,13 +81,13 @@ index a7285a35..d150e7b2 100644 int r; FILE *stream; diff --git a/libmultipath/parser.h b/libmultipath/parser.h -index b7917052..b385fb9e 100644 +index 62906e98..06666ccf 100644 --- a/libmultipath/parser.h +++ b/libmultipath/parser.h -@@ -78,7 +78,7 @@ extern void free_keywords(vector keywords); +@@ -77,7 +77,7 @@ extern void dump_keywords(vector keydump, int level); + extern void free_keywords(vector keywords); extern vector alloc_strvec(char *string); extern void *set_value(vector strvec); - extern void *set_regex_value(vector strvec); -extern int process_file(struct config *conf, char *conf_file); +extern int process_file(struct config *conf, const char *conf_file); extern struct keyword * find_keyword(vector keywords, vector v, char * name); diff --git a/0025-multipath-centralize-validation-code.patch b/0025-multipath-centralize-validation-code.patch deleted file mode 100644 index c8f862c..0000000 --- a/0025-multipath-centralize-validation-code.patch +++ /dev/null @@ -1,777 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 19 May 2020 12:08:42 -0500 -Subject: [PATCH] multipath: centralize validation code - -This code pulls the multipath path validation code out of configure(), -and puts it into its own function, check_path_valid(). This function -calls a new libmultipath function, is_path_valid() to check just path -requested. This seperation exists so that is_path_valid() can be reused -by future code. This code will give almost the same answer as the -existing code, with the exception that now, if a device is currently -multipathed, it will always be a valid multipath path. - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/Makefile | 2 +- - libmultipath/devmapper.c | 45 ++++++ - libmultipath/devmapper.h | 1 + - libmultipath/structs.h | 24 +--- - libmultipath/valid.c | 118 ++++++++++++++++ - libmultipath/valid.h | 42 ++++++ - libmultipath/wwids.c | 10 +- - multipath/main.c | 296 +++++++++++++++++---------------------- - 8 files changed, 343 insertions(+), 195 deletions(-) - create mode 100644 libmultipath/valid.c - create mode 100644 libmultipath/valid.h - -diff --git a/libmultipath/Makefile b/libmultipath/Makefile -index f19b7ad2..e5dac5ea 100644 ---- a/libmultipath/Makefile -+++ b/libmultipath/Makefile -@@ -48,7 +48,7 @@ OBJS = memory.o parser.o vector.o devmapper.o callout.o \ - log.o configure.o structs_vec.o sysfs.o prio.o checkers.o \ - lock.o file.o wwids.o prioritizers/alua_rtpg.o prkey.o \ - io_err_stat.o dm-generic.o generic.o foreign.o nvme-lib.o \ -- libsg.o -+ libsg.o valid.o - - all: $(LIBS) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index 7ed494a1..27d52398 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -770,6 +770,51 @@ out: - return r; - } - -+/* -+ * Return -+ * 1 : map with uuid exists -+ * 0 : map with uuid doesn't exist -+ * -1 : error -+ */ -+int -+dm_map_present_by_uuid(const char *uuid) -+{ -+ struct dm_task *dmt; -+ struct dm_info info; -+ char prefixed_uuid[WWID_SIZE + UUID_PREFIX_LEN]; -+ int r = -1; -+ -+ if (!uuid || uuid[0] == '\0') -+ return 0; -+ -+ if (safe_sprintf(prefixed_uuid, UUID_PREFIX "%s", uuid)) -+ goto out; -+ -+ if (!(dmt = dm_task_create(DM_DEVICE_INFO))) -+ goto out; -+ -+ dm_task_no_open_count(dmt); -+ -+ if (!dm_task_set_uuid(dmt, prefixed_uuid)) -+ goto out_task; -+ -+ if (!dm_task_run(dmt)) -+ goto out_task; -+ -+ if (!dm_task_get_info(dmt, &info)) -+ goto out_task; -+ -+ r = !!info.exists; -+ -+out_task: -+ dm_task_destroy(dmt); -+out: -+ if (r < 0) -+ condlog(3, "%s: dm command failed in %s: %s", uuid, -+ __FUNCTION__, strerror(errno)); -+ return r; -+} -+ - static int - dm_dev_t (const char * mapname, char * dev_t, int len) - { -diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h -index 17fc9faf..5ed7edc5 100644 ---- a/libmultipath/devmapper.h -+++ b/libmultipath/devmapper.h -@@ -39,6 +39,7 @@ int dm_simplecmd_noflush (int, const char *, uint16_t); - int dm_addmap_create (struct multipath *mpp, char *params); - int dm_addmap_reload (struct multipath *mpp, char *params, int flush); - int dm_map_present (const char *); -+int dm_map_present_by_uuid(const char *uuid); - int dm_get_map(const char *, unsigned long long *, char *); - int dm_get_status(const char *, char *); - int dm_type(const char *, char *); -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index 9bd39eb1..d69bc2e9 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -101,29 +101,13 @@ enum yes_no_undef_states { - YNU_YES, - }; - --#define _FIND_MULTIPATHS_F (1 << 1) --#define _FIND_MULTIPATHS_I (1 << 2) --#define _FIND_MULTIPATHS_N (1 << 3) --/* -- * _FIND_MULTIPATHS_F must have the same value as YNU_YES. -- * Generate a compile time error if that isn't the case. -- */ --extern char ___error1___[-(_FIND_MULTIPATHS_F != YNU_YES)]; -- --#define find_multipaths_on(conf) \ -- (!!((conf)->find_multipaths & _FIND_MULTIPATHS_F)) --#define ignore_wwids_on(conf) \ -- (!!((conf)->find_multipaths & _FIND_MULTIPATHS_I)) --#define ignore_new_devs_on(conf) \ -- (!!((conf)->find_multipaths & _FIND_MULTIPATHS_N)) -- - enum find_multipaths_states { - FIND_MULTIPATHS_UNDEF = YNU_UNDEF, - FIND_MULTIPATHS_OFF = YNU_NO, -- FIND_MULTIPATHS_ON = _FIND_MULTIPATHS_F, -- FIND_MULTIPATHS_GREEDY = _FIND_MULTIPATHS_I, -- FIND_MULTIPATHS_SMART = _FIND_MULTIPATHS_F|_FIND_MULTIPATHS_I, -- FIND_MULTIPATHS_STRICT = _FIND_MULTIPATHS_F|_FIND_MULTIPATHS_N, -+ FIND_MULTIPATHS_ON = YNU_YES, -+ FIND_MULTIPATHS_GREEDY, -+ FIND_MULTIPATHS_SMART, -+ FIND_MULTIPATHS_STRICT, - __FIND_MULTIPATHS_LAST, - }; - -diff --git a/libmultipath/valid.c b/libmultipath/valid.c -new file mode 100644 -index 00000000..456b1f6e ---- /dev/null -+++ b/libmultipath/valid.c -@@ -0,0 +1,118 @@ -+/* -+ Copyright (c) 2020 Benjamin Marzinski, IBM -+ -+ This program is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public License -+ as published by the Free Software Foundation; either version 2 -+ of the License, or (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program. If not, see . -+ */ -+#include -+#include -+#include -+ -+#include "vector.h" -+#include "config.h" -+#include "debug.h" -+#include "util.h" -+#include "devmapper.h" -+#include "discovery.h" -+#include "wwids.h" -+#include "sysfs.h" -+#include "blacklist.h" -+#include "mpath_cmd.h" -+#include "valid.h" -+ -+int -+is_path_valid(const char *name, struct config *conf, struct path *pp, -+ bool check_multipathd) -+{ -+ int r; -+ int fd; -+ -+ if (!pp || !name || !conf) -+ return PATH_IS_ERROR; -+ -+ if (conf->find_multipaths <= FIND_MULTIPATHS_UNDEF || -+ conf->find_multipaths >= __FIND_MULTIPATHS_LAST) -+ return PATH_IS_ERROR; -+ -+ if (safe_sprintf(pp->dev, "%s", name)) -+ return PATH_IS_ERROR; -+ -+ if (sysfs_is_multipathed(pp, true)) { -+ if (pp->wwid[0] == '\0') -+ return PATH_IS_ERROR; -+ return PATH_IS_VALID_NO_CHECK; -+ } -+ -+ /* -+ * "multipath -u" may be run before the daemon is started. In this -+ * case, systemd might own the socket but might delay multipathd -+ * startup until some other unit (udev settle!) has finished -+ * starting. With many LUNs, the listen backlog may be exceeded, which -+ * would cause connect() to block. This causes udev workers calling -+ * "multipath -u" to hang, and thus creates a deadlock, until "udev -+ * settle" times out. To avoid this, call connect() in non-blocking -+ * mode here, and take EAGAIN as indication for a filled-up systemd -+ * backlog. -+ */ -+ -+ if (check_multipathd) { -+ fd = __mpath_connect(1); -+ if (fd < 0) { -+ if (errno != EAGAIN && !systemd_service_enabled(name)) { -+ condlog(3, "multipathd not running or enabled"); -+ return PATH_IS_NOT_VALID; -+ } -+ } else -+ mpath_disconnect(fd); -+ } -+ -+ pp->udev = udev_device_new_from_subsystem_sysname(udev, "block", name); -+ if (!pp->udev) -+ return PATH_IS_ERROR; -+ -+ r = pathinfo(pp, conf, DI_SYSFS | DI_WWID | DI_BLACKLIST); -+ if (r == PATHINFO_SKIPPED) -+ return PATH_IS_NOT_VALID; -+ else if (r) -+ return PATH_IS_ERROR; -+ -+ if (pp->wwid[0] == '\0') -+ return PATH_IS_NOT_VALID; -+ -+ if (pp->udev && pp->uid_attribute && -+ filter_property(conf, pp->udev, 3, pp->uid_attribute) > 0) -+ return PATH_IS_NOT_VALID; -+ -+ r = is_failed_wwid(pp->wwid); -+ if (r != WWID_IS_NOT_FAILED) { -+ if (r == WWID_IS_FAILED) -+ return PATH_IS_NOT_VALID; -+ return PATH_IS_ERROR; -+ } -+ -+ if (conf->find_multipaths == FIND_MULTIPATHS_GREEDY) -+ return PATH_IS_VALID; -+ -+ if (check_wwids_file(pp->wwid, 0) == 0) -+ return PATH_IS_VALID_NO_CHECK; -+ -+ if (dm_map_present_by_uuid(pp->wwid) == 1) -+ return PATH_IS_VALID; -+ -+ /* all these act like FIND_MULTIPATHS_STRICT for finding if a -+ * path is valid */ -+ if (conf->find_multipaths != FIND_MULTIPATHS_SMART) -+ return PATH_IS_NOT_VALID; -+ -+ return PATH_IS_MAYBE_VALID; -+} -diff --git a/libmultipath/valid.h b/libmultipath/valid.h -new file mode 100644 -index 00000000..ce1c7cbf ---- /dev/null -+++ b/libmultipath/valid.h -@@ -0,0 +1,42 @@ -+/* -+ Copyright (c) 2020 Benjamin Marzinski, IBM -+ -+ This program is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public License -+ as published by the Free Software Foundation; either version 2 -+ of the License, or (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program. If not, see . -+ */ -+#ifndef _VALID_H -+#define _VALID_H -+ -+/* -+ * PATH_IS_VALID_NO_CHECK is returned when multipath should claim -+ * the path, regardless of whether is has been released to systemd -+ * already. -+ * PATH_IS_VALID is returned by is_path_valid, when the path is -+ * valid only if it hasn't been released to systemd already. -+ * PATH_IS_MAYBE_VALID is returned when the the path would be valid -+ * if other paths with the same wwid existed. It is up to the caller -+ * to check for these other paths. -+ */ -+enum is_path_valid_result { -+ PATH_IS_ERROR = -1, -+ PATH_IS_NOT_VALID, -+ PATH_IS_VALID, -+ PATH_IS_VALID_NO_CHECK, -+ PATH_IS_MAYBE_VALID, -+ PATH_MAX_VALID_RESULT, /* only for bounds checking */ -+}; -+ -+int is_path_valid(const char *name, struct config *conf, struct path *pp, -+ bool check_multipathd); -+ -+#endif /* _VALID_D */ -diff --git a/libmultipath/wwids.c b/libmultipath/wwids.c -index 28a2150d..637cb0ab 100644 ---- a/libmultipath/wwids.c -+++ b/libmultipath/wwids.c -@@ -289,19 +289,19 @@ out: - int - should_multipath(struct path *pp1, vector pathvec, vector mpvec) - { -- int i, ignore_new_devs, find_multipaths; -+ int i, find_multipaths; - struct path *pp2; - struct config *conf; - - conf = get_multipath_config(); -- ignore_new_devs = ignore_new_devs_on(conf); -- find_multipaths = find_multipaths_on(conf); -+ find_multipaths = conf->find_multipaths; - put_multipath_config(conf); -- if (!find_multipaths && !ignore_new_devs) -+ if (find_multipaths == FIND_MULTIPATHS_OFF || -+ find_multipaths == FIND_MULTIPATHS_GREEDY) - return 1; - - condlog(4, "checking if %s should be multipathed", pp1->dev); -- if (!ignore_new_devs) { -+ if (find_multipaths != FIND_MULTIPATHS_STRICT) { - char tmp_wwid[WWID_SIZE]; - struct multipath *mp = find_mp_by_wwid(mpvec, pp1->wwid); - -diff --git a/multipath/main.c b/multipath/main.c -index 545ead87..953fab27 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -63,21 +63,18 @@ - #include "propsel.h" - #include "time-util.h" - #include "file.h" -+#include "valid.h" - - int logsink; - struct udev *udev; - struct config *multipath_conf; - - /* -- * Return values of configure(), print_cmd_valid(), and main(). -- * RTVL_{YES,NO} are synonyms for RTVL_{OK,FAIL} for the CMD_VALID_PATH case. -+ * Return values of configure(), check_path_valid(), and main(). - */ - enum { - RTVL_OK = 0, -- RTVL_YES = RTVL_OK, - RTVL_FAIL = 1, -- RTVL_NO = RTVL_FAIL, -- RTVL_MAYBE, /* only used internally, never returned */ - RTVL_RETRY, /* returned by configure(), not by main() */ - }; - -@@ -269,9 +266,6 @@ get_dm_mpvec (enum mpath_cmds cmd, vector curmp, vector pathvec, char * refwwid) - continue; - } - -- if (cmd == CMD_VALID_PATH) -- continue; -- - dm_get_map(mpp->alias, &mpp->size, params); - condlog(3, "params = %s", params); - dm_get_status(mpp->alias, status); -@@ -491,10 +485,11 @@ static int print_cmd_valid(int k, const vector pathvec, - struct timespec until; - struct path *pp; - -- if (k != RTVL_YES && k != RTVL_NO && k != RTVL_MAYBE) -- return RTVL_NO; -+ if (k != PATH_IS_VALID && k != PATH_IS_NOT_VALID && -+ k != PATH_IS_MAYBE_VALID) -+ return PATH_IS_NOT_VALID; - -- if (k == RTVL_MAYBE) { -+ if (k == PATH_IS_MAYBE_VALID) { - /* - * Caller ensures that pathvec[0] is the path to - * examine. -@@ -504,7 +499,7 @@ static int print_cmd_valid(int k, const vector pathvec, - wait = find_multipaths_check_timeout( - pp, pp->find_multipaths_timeout, &until); - if (wait != FIND_MULTIPATHS_WAITING) -- k = RTVL_NO; -+ k = PATH_IS_NOT_VALID; - } else if (pathvec != NULL && (pp = VECTOR_SLOT(pathvec, 0))) - wait = find_multipaths_check_timeout(pp, 0, &until); - if (wait == FIND_MULTIPATHS_WAITING) -@@ -513,9 +508,9 @@ static int print_cmd_valid(int k, const vector pathvec, - else if (wait == FIND_MULTIPATHS_WAIT_DONE) - printf("FIND_MULTIPATHS_WAIT_UNTIL=\"0\"\n"); - printf("DM_MULTIPATH_DEVICE_PATH=\"%d\"\n", -- k == RTVL_MAYBE ? 2 : k == RTVL_YES ? 1 : 0); -+ k == PATH_IS_MAYBE_VALID ? 2 : k == PATH_IS_VALID ? 1 : 0); - /* Never return RTVL_MAYBE */ -- return k == RTVL_NO ? RTVL_NO : RTVL_YES; -+ return k == PATH_IS_NOT_VALID ? PATH_IS_NOT_VALID : PATH_IS_VALID; - } - - /* -@@ -548,7 +543,6 @@ configure (struct config *conf, enum mpath_cmds cmd, - int di_flag = 0; - char * refwwid = NULL; - char * dev = NULL; -- bool released = released_to_systemd(); - - /* - * allocate core vectors to store paths and multipaths -@@ -573,7 +567,7 @@ configure (struct config *conf, enum mpath_cmds cmd, - cmd != CMD_REMOVE_WWID && - (filter_devnode(conf->blist_devnode, - conf->elist_devnode, dev) > 0)) { -- goto print_valid; -+ goto out; - } - - /* -@@ -581,14 +575,10 @@ configure (struct config *conf, enum mpath_cmds cmd, - * failing the translation is fatal (by policy) - */ - if (devpath) { -- int failed = get_refwwid(cmd, devpath, dev_type, -- pathvec, &refwwid); -+ get_refwwid(cmd, devpath, dev_type, pathvec, &refwwid); - if (!refwwid) { - condlog(4, "%s: failed to get wwid", devpath); -- if (failed == 2 && cmd == CMD_VALID_PATH) -- goto print_valid; -- else -- condlog(3, "scope is null"); -+ condlog(3, "scope is null"); - goto out; - } - if (cmd == CMD_REMOVE_WWID) { -@@ -614,53 +604,6 @@ configure (struct config *conf, enum mpath_cmds cmd, - goto out; - } - condlog(3, "scope limited to %s", refwwid); -- /* If you are ignoring the wwids file and find_multipaths is -- * set, you need to actually check if there are two available -- * paths to determine if this path should be multipathed. To -- * do this, we put off the check until after discovering all -- * the paths. -- * Paths listed in the wwids file are always considered valid. -- */ -- if (cmd == CMD_VALID_PATH) { -- if (is_failed_wwid(refwwid) == WWID_IS_FAILED) { -- r = RTVL_NO; -- goto print_valid; -- } -- if ((!find_multipaths_on(conf) && -- ignore_wwids_on(conf)) || -- check_wwids_file(refwwid, 0) == 0) -- r = RTVL_YES; -- if (!ignore_wwids_on(conf)) -- goto print_valid; -- /* At this point, either r==0 or find_multipaths_on. */ -- -- /* -- * Shortcut for find_multipaths smart: -- * Quick check if path is already multipathed. -- */ -- if (sysfs_is_multipathed(VECTOR_SLOT(pathvec, 0), -- false)) { -- r = RTVL_YES; -- goto print_valid; -- } -- -- /* -- * DM_MULTIPATH_DEVICE_PATH=="0" means that we have -- * been called for this device already, and have -- * released it to systemd. Unless the device is now -- * already multipathed (see above), we can't try to -- * grab it, because setting SYSTEMD_READY=0 would -- * cause file systems to be unmounted. -- * Leave DM_MULTIPATH_DEVICE_PATH="0". -- */ -- if (released) { -- r = RTVL_NO; -- goto print_valid; -- } -- if (r == RTVL_YES) -- goto print_valid; -- /* find_multipaths_on: Fall through to path detection */ -- } - } - - /* -@@ -701,59 +644,6 @@ configure (struct config *conf, enum mpath_cmds cmd, - goto out; - } - -- if (cmd == CMD_VALID_PATH) { -- struct path *pp; -- int fd; -- -- /* This only happens if find_multipaths and -- * ignore_wwids is set, and the path is not in WWIDs -- * file, not currently multipathed, and has -- * never been released to systemd. -- * If there is currently a multipath device matching -- * the refwwid, or there is more than one path matching -- * the refwwid, then the path is valid */ -- if (VECTOR_SIZE(curmp) != 0) { -- r = RTVL_YES; -- goto print_valid; -- } else if (VECTOR_SIZE(pathvec) > 1) -- r = RTVL_YES; -- else -- r = RTVL_MAYBE; -- -- /* -- * If opening the path with O_EXCL fails, the path -- * is in use (e.g. mounted during initramfs processing). -- * We know that it's not used by dm-multipath. -- * We may not set SYSTEMD_READY=0 on such devices, it -- * might cause systemd to umount the device. -- * Use O_RDONLY, because udevd would trigger another -- * uevent for close-after-write. -- * -- * The O_EXCL check is potentially dangerous, because it may -- * race with other tasks trying to access the device. Therefore -- * this code is only executed if the path hasn't been released -- * to systemd earlier (see above). -- * -- * get_refwwid() above stores the path we examine in slot 0. -- */ -- pp = VECTOR_SLOT(pathvec, 0); -- fd = open(udev_device_get_devnode(pp->udev), -- O_RDONLY|O_EXCL); -- if (fd >= 0) -- close(fd); -- else { -- condlog(3, "%s: path %s is in use: %s", -- __func__, pp->dev, -- strerror(errno)); -- /* -- * Check if we raced with multipathd -- */ -- r = sysfs_is_multipathed(VECTOR_SLOT(pathvec, 0), -- false) ? RTVL_YES : RTVL_NO; -- } -- goto print_valid; -- } -- - if (cmd != CMD_CREATE && cmd != CMD_DRY_RUN) { - r = RTVL_OK; - goto out; -@@ -766,10 +656,6 @@ configure (struct config *conf, enum mpath_cmds cmd, - conf->force_reload, cmd); - r = rc == CP_RETRY ? RTVL_RETRY : rc == CP_OK ? RTVL_OK : RTVL_FAIL; - --print_valid: -- if (cmd == CMD_VALID_PATH) -- r = print_cmd_valid(r, pathvec, conf); -- - out: - if (refwwid) - FREE(refwwid); -@@ -780,6 +666,112 @@ out: - return r; - } - -+static int -+check_path_valid(const char *name, struct config *conf, bool is_uevent) -+{ -+ int fd, r = PATH_IS_ERROR; -+ struct path *pp = NULL; -+ vector pathvec = NULL; -+ -+ pp = alloc_path(); -+ if (!pp) -+ return RTVL_FAIL; -+ -+ r = is_path_valid(name, conf, pp, is_uevent); -+ if (r <= PATH_IS_ERROR || r >= PATH_MAX_VALID_RESULT) -+ goto fail; -+ -+ /* set path values if is_path_valid() didn't */ -+ if (!pp->udev) -+ pp->udev = udev_device_new_from_subsystem_sysname(udev, "block", -+ name); -+ if (!pp->udev) -+ goto fail; -+ -+ if (!strlen(pp->dev_t)) { -+ dev_t devt = udev_device_get_devnum(pp->udev); -+ if (major(devt) == 0 && minor(devt) == 0) -+ goto fail; -+ snprintf(pp->dev_t, BLK_DEV_SIZE, "%d:%d", major(devt), -+ minor(devt)); -+ } -+ -+ pathvec = vector_alloc(); -+ if (!pathvec) -+ goto fail; -+ -+ if (store_path(pathvec, pp) != 0) { -+ free_path(pp); -+ goto fail; -+ } -+ -+ if ((r == PATH_IS_VALID || r == PATH_IS_MAYBE_VALID) && -+ released_to_systemd()) -+ r = PATH_IS_NOT_VALID; -+ -+ /* This state is only used to skip the released_to_systemd() check */ -+ if (r == PATH_IS_VALID_NO_CHECK) -+ r = PATH_IS_VALID; -+ -+ if (r != PATH_IS_MAYBE_VALID) -+ goto out; -+ -+ /* -+ * If opening the path with O_EXCL fails, the path -+ * is in use (e.g. mounted during initramfs processing). -+ * We know that it's not used by dm-multipath. -+ * We may not set SYSTEMD_READY=0 on such devices, it -+ * might cause systemd to umount the device. -+ * Use O_RDONLY, because udevd would trigger another -+ * uevent for close-after-write. -+ * -+ * The O_EXCL check is potentially dangerous, because it may -+ * race with other tasks trying to access the device. Therefore -+ * this code is only executed if the path hasn't been released -+ * to systemd earlier (see above). -+ */ -+ fd = open(udev_device_get_devnode(pp->udev), O_RDONLY|O_EXCL); -+ if (fd >= 0) -+ close(fd); -+ else { -+ condlog(3, "%s: path %s is in use: %m", __func__, pp->dev); -+ /* Check if we raced with multipathd */ -+ if (sysfs_is_multipathed(pp, false)) -+ r = PATH_IS_VALID; -+ else -+ r = PATH_IS_NOT_VALID; -+ goto out; -+ } -+ -+ /* For find_multipaths = SMART, if there is more than one path -+ * matching the refwwid, then the path is valid */ -+ if (path_discovery(pathvec, DI_SYSFS | DI_WWID) < 0) -+ goto fail; -+ filter_pathvec(pathvec, pp->wwid); -+ if (VECTOR_SIZE(pathvec) > 1) -+ r = PATH_IS_VALID; -+ else -+ r = PATH_IS_MAYBE_VALID; -+ -+out: -+ r = print_cmd_valid(r, pathvec, conf); -+ free_pathvec(pathvec, FREE_PATHS); -+ /* -+ * multipath -u must exit with status 0, otherwise udev won't -+ * import its output. -+ */ -+ if (!is_uevent && r == PATH_IS_NOT_VALID) -+ return RTVL_FAIL; -+ return RTVL_OK; -+ -+fail: -+ if (pathvec) -+ free_pathvec(pathvec, FREE_PATHS); -+ else -+ free_path(pp); -+ return RTVL_FAIL; -+} -+ - static int - get_dev_type(char *dev) { - struct stat buf; -@@ -861,32 +853,6 @@ out: - return r; - } - --static int test_multipathd_socket(void) --{ -- int fd; -- /* -- * "multipath -u" may be run before the daemon is started. In this -- * case, systemd might own the socket but might delay multipathd -- * startup until some other unit (udev settle!) has finished -- * starting. With many LUNs, the listen backlog may be exceeded, which -- * would cause connect() to block. This causes udev workers calling -- * "multipath -u" to hang, and thus creates a deadlock, until "udev -- * settle" times out. To avoid this, call connect() in non-blocking -- * mode here, and take EAGAIN as indication for a filled-up systemd -- * backlog. -- */ -- -- fd = __mpath_connect(1); -- if (fd == -1) { -- if (errno == EAGAIN) -- condlog(3, "daemon backlog exceeded"); -- else -- return 0; -- } else -- close(fd); -- return 1; --} -- - int - main (int argc, char *argv[]) - { -@@ -970,7 +936,11 @@ main (int argc, char *argv[]) - conf->force_reload = FORCE_RELOAD_YES; - break; - case 'i': -- conf->find_multipaths |= _FIND_MULTIPATHS_I; -+ if (conf->find_multipaths == FIND_MULTIPATHS_ON || -+ conf->find_multipaths == FIND_MULTIPATHS_STRICT) -+ conf->find_multipaths = FIND_MULTIPATHS_SMART; -+ else if (conf->find_multipaths == FIND_MULTIPATHS_OFF) -+ conf->find_multipaths = FIND_MULTIPATHS_GREEDY; - break; - case 't': - r = dump_config(conf, NULL, NULL) ? RTVL_FAIL : RTVL_OK; -@@ -1064,15 +1034,10 @@ main (int argc, char *argv[]) - condlog(0, "the -c option requires a path to check"); - goto out; - } -- if (cmd == CMD_VALID_PATH && -- dev_type == DEV_UEVENT) { -- if (!test_multipathd_socket()) { -- condlog(3, "%s: daemon is not running", dev); -- if (!systemd_service_enabled(dev)) { -- r = print_cmd_valid(RTVL_NO, NULL, conf); -- goto out; -- } -- } -+ if (cmd == CMD_VALID_PATH) { -+ char * name = convert_dev(dev, (dev_type == DEV_DEVNODE)); -+ r = check_path_valid(name, conf, dev_type == DEV_UEVENT); -+ goto out; - } - - if (cmd == CMD_REMOVE_WWID && !dev) { -@@ -1136,13 +1101,6 @@ out: - cleanup_prio(); - cleanup_checkers(); - -- /* -- * multipath -u must exit with status 0, otherwise udev won't -- * import its output. -- */ -- if (cmd == CMD_VALID_PATH && dev_type == DEV_UEVENT && r == RTVL_NO) -- r = RTVL_OK; -- - if (dev_type == DEV_UEVENT) - closelog(); - --- -2.17.2 - diff --git a/0026-Unit-tests-for-is_path_valid.patch b/0026-Unit-tests-for-is_path_valid.patch deleted file mode 100644 index 9ada368..0000000 --- a/0026-Unit-tests-for-is_path_valid.patch +++ /dev/null @@ -1,530 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 19 May 2020 12:08:43 -0500 -Subject: [PATCH] Unit tests for is_path_valid() - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - tests/Makefile | 4 +- - tests/valid.c | 486 +++++++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 489 insertions(+), 1 deletion(-) - create mode 100644 tests/valid.c - -diff --git a/tests/Makefile b/tests/Makefile -index 1b8706a7..125553b8 100644 ---- a/tests/Makefile -+++ b/tests/Makefile -@@ -13,7 +13,7 @@ CFLAGS += $(BIN_CFLAGS) -I$(multipathdir) -I$(mpathcmddir) \ - LIBDEPS += -L$(multipathdir) -L$(mpathcmddir) -lmultipath -lmpathcmd -lcmocka - - TESTS := uevent parser util dmevents hwtable blacklist unaligned vpd pgpolicy \ -- alias directio -+ alias directio valid - - .SILENT: $(TESTS:%=%.o) - .PRECIOUS: $(TESTS:%=%-test) -@@ -50,6 +50,8 @@ vpd-test_OBJDEPS := ../libmultipath/discovery.o - vpd-test_LIBDEPS := -ludev -lpthread -ldl - alias-test_TESTDEPS := test-log.o - alias-test_LIBDEPS := -lpthread -ldl -+valid-test_OBJDEPS := ../libmultipath/valid.o -+valid-test_LIBDEPS := -ludev -lpthread -ldl - ifneq ($(DIO_TEST_DEV),) - directio-test_LIBDEPS := -laio - endif -diff --git a/tests/valid.c b/tests/valid.c -new file mode 100644 -index 00000000..693c72c5 ---- /dev/null -+++ b/tests/valid.c -@@ -0,0 +1,486 @@ -+/* -+ * Copyright (c) 2020 Benjamin Marzinski, Redhat -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ * -+ */ -+ -+#define _GNU_SOURCE -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "globals.c" -+#include "util.h" -+#include "discovery.h" -+#include "wwids.h" -+#include "blacklist.h" -+#include "valid.h" -+ -+int test_fd; -+struct udev_device { -+ int unused; -+} test_udev; -+ -+bool __wrap_sysfs_is_multipathed(struct path *pp, bool set_wwid) -+{ -+ bool is_multipathed = mock_type(bool); -+ assert_non_null(pp); -+ assert_int_not_equal(strlen(pp->dev), 0); -+ if (is_multipathed && set_wwid) -+ strlcpy(pp->wwid, mock_ptr_type(char *), WWID_SIZE); -+ return is_multipathed; -+} -+ -+int __wrap___mpath_connect(int nonblocking) -+{ -+ bool connected = mock_type(bool); -+ assert_int_equal(nonblocking, 1); -+ if (connected) -+ return test_fd; -+ errno = mock_type(int); -+ return -1; -+} -+ -+int __wrap_systemd_service_enabled(const char *dev) -+{ -+ return (int)mock_type(bool); -+} -+ -+/* There's no point in checking the return value here */ -+int __wrap_mpath_disconnect(int fd) -+{ -+ assert_int_equal(fd, test_fd); -+ return 0; -+} -+ -+struct udev_device *__wrap_udev_device_new_from_subsystem_sysname(struct udev *udev, const char *subsystem, const char *sysname) -+{ -+ bool passed = mock_type(bool); -+ assert_string_equal(sysname, mock_ptr_type(char *)); -+ if (passed) -+ return &test_udev; -+ return NULL; -+} -+ -+int __wrap_pathinfo(struct path *pp, struct config *conf, int mask) -+{ -+ int ret = mock_type(int); -+ assert_string_equal(pp->dev, mock_ptr_type(char *)); -+ assert_int_equal(mask, DI_SYSFS | DI_WWID | DI_BLACKLIST); -+ if (ret == PATHINFO_OK) { -+ pp->uid_attribute = "ID_TEST"; -+ strlcpy(pp->wwid, mock_ptr_type(char *), WWID_SIZE); -+ } else -+ memset(pp->wwid, 0, WWID_SIZE); -+ return ret; -+} -+ -+int __wrap_filter_property(struct config *conf, struct udev_device *udev, -+ int lvl, const char *uid_attribute) -+{ -+ int ret = mock_type(int); -+ assert_string_equal(uid_attribute, "ID_TEST"); -+ return ret; -+} -+ -+int __wrap_is_failed_wwid(const char *wwid) -+{ -+ int ret = mock_type(int); -+ assert_string_equal(wwid, mock_ptr_type(char *)); -+ return ret; -+} -+ -+int __wrap_check_wwids_file(char *wwid, int write_wwid) -+{ -+ bool passed = mock_type(bool); -+ assert_int_equal(write_wwid, 0); -+ assert_string_equal(wwid, mock_ptr_type(char *)); -+ if (passed) -+ return 0; -+ else -+ return -1; -+} -+ -+int __wrap_dm_map_present_by_uuid(const char *uuid) -+{ -+ int ret = mock_type(int); -+ assert_string_equal(uuid, mock_ptr_type(char *)); -+ return ret; -+} -+ -+enum { -+ STAGE_IS_MULTIPATHED, -+ STAGE_CHECK_MULTIPATHD, -+ STAGE_GET_UDEV_DEVICE, -+ STAGE_PATHINFO, -+ STAGE_FILTER_PROPERTY, -+ STAGE_IS_FAILED, -+ STAGE_CHECK_WWIDS, -+ STAGE_UUID_PRESENT, -+}; -+ -+enum { -+ CHECK_MPATHD_RUNNING, -+ CHECK_MPATHD_EAGAIN, -+ CHECK_MPATHD_ENABLED, -+ CHECK_MPATHD_SKIP, -+}; -+ -+/* setup the test to continue past the given stage in is_path_valid() */ -+static void setup_passing(char *name, char *wwid, unsigned int check_multipathd, -+ unsigned int stage) -+{ -+ will_return(__wrap_sysfs_is_multipathed, false); -+ if (stage == STAGE_IS_MULTIPATHED) -+ return; -+ if (check_multipathd == CHECK_MPATHD_RUNNING) -+ will_return(__wrap___mpath_connect, true); -+ else if (check_multipathd == CHECK_MPATHD_EAGAIN) { -+ will_return(__wrap___mpath_connect, false); -+ will_return(__wrap___mpath_connect, EAGAIN); -+ } else if (check_multipathd == CHECK_MPATHD_ENABLED) { -+ will_return(__wrap___mpath_connect, false); -+ will_return(__wrap___mpath_connect, ECONNREFUSED); -+ will_return(__wrap_systemd_service_enabled, true); -+ } -+ /* nothing for CHECK_MPATHD_SKIP */ -+ if (stage == STAGE_CHECK_MULTIPATHD) -+ return; -+ will_return(__wrap_udev_device_new_from_subsystem_sysname, true); -+ will_return(__wrap_udev_device_new_from_subsystem_sysname, -+ name); -+ if (stage == STAGE_GET_UDEV_DEVICE) -+ return; -+ will_return(__wrap_pathinfo, PATHINFO_OK); -+ will_return(__wrap_pathinfo, name); -+ will_return(__wrap_pathinfo, wwid); -+ if (stage == STAGE_PATHINFO) -+ return; -+ will_return(__wrap_filter_property, MATCH_PROPERTY_BLIST_EXCEPT); -+ if (stage == STAGE_FILTER_PROPERTY) -+ return; -+ will_return(__wrap_is_failed_wwid, WWID_IS_NOT_FAILED); -+ will_return(__wrap_is_failed_wwid, wwid); -+ if (stage == STAGE_IS_FAILED) -+ return; -+ will_return(__wrap_check_wwids_file, false); -+ will_return(__wrap_check_wwids_file, wwid); -+ if (stage == STAGE_CHECK_WWIDS) -+ return; -+ will_return(__wrap_dm_map_present_by_uuid, 0); -+ will_return(__wrap_dm_map_present_by_uuid, wwid); -+} -+ -+static void test_bad_arguments(void **state) -+{ -+ struct path pp; -+ char too_long[FILE_NAME_SIZE + 1]; -+ -+ memset(&pp, 0, sizeof(pp)); -+ /* test NULL pointers */ -+ assert_int_equal(is_path_valid("test", &conf, NULL, true), -+ PATH_IS_ERROR); -+ assert_int_equal(is_path_valid("test", NULL, &pp, true), -+ PATH_IS_ERROR); -+ assert_int_equal(is_path_valid(NULL, &conf, &pp, true), -+ PATH_IS_ERROR); -+ /* test undefined find_multipaths */ -+ conf.find_multipaths = FIND_MULTIPATHS_UNDEF; -+ assert_int_equal(is_path_valid("test", &conf, &pp, true), -+ PATH_IS_ERROR); -+ /* test name too long */ -+ memset(too_long, 'x', sizeof(too_long)); -+ too_long[sizeof(too_long) - 1] = '\0'; -+ conf.find_multipaths = FIND_MULTIPATHS_STRICT; -+ assert_int_equal(is_path_valid(too_long, &conf, &pp, true), -+ PATH_IS_ERROR); -+} -+ -+static void test_sysfs_is_multipathed(void **state) -+{ -+ struct path pp; -+ char *name = "test"; -+ char *wwid = "test_wwid"; -+ -+ memset(&pp, 0, sizeof(pp)); -+ conf.find_multipaths = FIND_MULTIPATHS_STRICT; -+ /* test for already existing multiapthed device */ -+ will_return(__wrap_sysfs_is_multipathed, true); -+ will_return(__wrap_sysfs_is_multipathed, wwid); -+ assert_int_equal(is_path_valid(name, &conf, &pp, true), -+ PATH_IS_VALID_NO_CHECK); -+ assert_string_equal(pp.dev, name); -+ assert_string_equal(pp.wwid, wwid); -+ /* test for wwid device with empty wwid */ -+ will_return(__wrap_sysfs_is_multipathed, true); -+ will_return(__wrap_sysfs_is_multipathed, ""); -+ assert_int_equal(is_path_valid(name, &conf, &pp, true), -+ PATH_IS_ERROR); -+} -+ -+static void test_check_multipathd(void **state) -+{ -+ struct path pp; -+ char *name = "test"; -+ -+ memset(&pp, 0, sizeof(pp)); -+ conf.find_multipaths = FIND_MULTIPATHS_STRICT; -+ /* test failed check to see if multipathd is active */ -+ will_return(__wrap_sysfs_is_multipathed, false); -+ will_return(__wrap___mpath_connect, false); -+ will_return(__wrap___mpath_connect, ECONNREFUSED); -+ will_return(__wrap_systemd_service_enabled, false); -+ assert_int_equal(is_path_valid(name, &conf, &pp, true), -+ PATH_IS_NOT_VALID); -+ assert_string_equal(pp.dev, name); -+ /* test pass because service is enabled. fail getting udev */ -+ memset(&pp, 0, sizeof(pp)); -+ setup_passing(name, NULL, CHECK_MPATHD_ENABLED, STAGE_CHECK_MULTIPATHD); -+ will_return(__wrap_udev_device_new_from_subsystem_sysname, false); -+ will_return(__wrap_udev_device_new_from_subsystem_sysname, -+ name); -+ assert_int_equal(is_path_valid(name, &conf, &pp, true), -+ PATH_IS_ERROR); -+ assert_string_equal(pp.dev, name); -+ /* test pass because connect returned EAGAIN. fail getting udev */ -+ setup_passing(name, NULL, CHECK_MPATHD_EAGAIN, STAGE_CHECK_MULTIPATHD); -+ will_return(__wrap_udev_device_new_from_subsystem_sysname, false); -+ will_return(__wrap_udev_device_new_from_subsystem_sysname, -+ name); -+ assert_int_equal(is_path_valid(name, &conf, &pp, true), -+ PATH_IS_ERROR); -+ /* test pass because connect succeeded. fail getting udev */ -+ memset(&pp, 0, sizeof(pp)); -+ setup_passing(name, NULL, CHECK_MPATHD_RUNNING, STAGE_CHECK_MULTIPATHD); -+ will_return(__wrap_udev_device_new_from_subsystem_sysname, false); -+ will_return(__wrap_udev_device_new_from_subsystem_sysname, -+ name); -+ assert_int_equal(is_path_valid(name, &conf, &pp, true), -+ PATH_IS_ERROR); -+ assert_string_equal(pp.dev, name); -+} -+ -+static void test_pathinfo(void **state) -+{ -+ struct path pp; -+ char *name = "test"; -+ -+ memset(&pp, 0, sizeof(pp)); -+ conf.find_multipaths = FIND_MULTIPATHS_STRICT; -+ /* Test pathinfo blacklisting device */ -+ setup_passing(name, NULL, CHECK_MPATHD_SKIP, STAGE_GET_UDEV_DEVICE); -+ will_return(__wrap_pathinfo, PATHINFO_SKIPPED); -+ will_return(__wrap_pathinfo, name); -+ assert_int_equal(is_path_valid(name, &conf, &pp, false), -+ PATH_IS_NOT_VALID); -+ assert_string_equal(pp.dev, name); -+ assert_ptr_equal(pp.udev, &test_udev); -+ /* Test pathinfo failing */ -+ memset(&pp, 0, sizeof(pp)); -+ setup_passing(name, NULL, CHECK_MPATHD_SKIP, STAGE_GET_UDEV_DEVICE); -+ will_return(__wrap_pathinfo, PATHINFO_FAILED); -+ will_return(__wrap_pathinfo, name); -+ assert_int_equal(is_path_valid(name, &conf, &pp, false), -+ PATH_IS_ERROR); -+ /* Test blank wwid */ -+ memset(&pp, 0, sizeof(pp)); -+ setup_passing(name, NULL, CHECK_MPATHD_SKIP, STAGE_GET_UDEV_DEVICE); -+ will_return(__wrap_pathinfo, PATHINFO_OK); -+ will_return(__wrap_pathinfo, name); -+ will_return(__wrap_pathinfo, ""); -+ assert_int_equal(is_path_valid(name, &conf, &pp, false), -+ PATH_IS_NOT_VALID); -+} -+ -+static void test_filter_property(void **state) -+{ -+ struct path pp; -+ char *name = "test"; -+ char *wwid = "test-wwid"; -+ -+ /* test blacklist property */ -+ memset(&pp, 0, sizeof(pp)); -+ conf.find_multipaths = FIND_MULTIPATHS_STRICT; -+ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_PATHINFO); -+ will_return(__wrap_filter_property, MATCH_PROPERTY_BLIST); -+ assert_int_equal(is_path_valid(name, &conf, &pp, false), -+ PATH_IS_NOT_VALID); -+ assert_ptr_equal(pp.udev, &test_udev); -+ assert_string_equal(pp.wwid, wwid); -+ /* test missing property */ -+ memset(&pp, 0, sizeof(pp)); -+ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_PATHINFO); -+ will_return(__wrap_filter_property, MATCH_PROPERTY_BLIST_MISSING); -+ assert_int_equal(is_path_valid(name, &conf, &pp, false), -+ PATH_IS_NOT_VALID); -+ /* test MATCH_NOTHING fail on is_failed_wwid */ -+ memset(&pp, 0, sizeof(pp)); -+ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_PATHINFO); -+ will_return(__wrap_filter_property, MATCH_NOTHING); -+ will_return(__wrap_is_failed_wwid, WWID_IS_FAILED); -+ will_return(__wrap_is_failed_wwid, wwid); -+ assert_int_equal(is_path_valid(name, &conf, &pp, false), -+ PATH_IS_NOT_VALID); -+} -+ -+static void test_is_failed_wwid(void **state) -+{ -+ struct path pp; -+ char *name = "test"; -+ char *wwid = "test-wwid"; -+ -+ memset(&pp, 0, sizeof(pp)); -+ conf.find_multipaths = FIND_MULTIPATHS_STRICT; -+ /* Test wwid failed */ -+ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_FILTER_PROPERTY); -+ will_return(__wrap_is_failed_wwid, WWID_IS_FAILED); -+ will_return(__wrap_is_failed_wwid, wwid); -+ assert_int_equal(is_path_valid(name, &conf, &pp, false), -+ PATH_IS_NOT_VALID); -+ assert_string_equal(pp.dev, name); -+ assert_ptr_equal(pp.udev, &test_udev); -+ assert_string_equal(pp.wwid, wwid); -+ /* test is_failed_wwid error */ -+ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_FILTER_PROPERTY); -+ will_return(__wrap_is_failed_wwid, WWID_FAILED_ERROR); -+ will_return(__wrap_is_failed_wwid, wwid); -+ assert_int_equal(is_path_valid(name, &conf, &pp, false), -+ PATH_IS_ERROR); -+} -+ -+static void test_greedy(void **state) -+{ -+ struct path pp; -+ char *name = "test"; -+ char *wwid = "test-wwid"; -+ -+ /* test greedy success with checking multipathd */ -+ memset(&pp, 0, sizeof(pp)); -+ conf.find_multipaths = FIND_MULTIPATHS_GREEDY; -+ setup_passing(name, wwid, CHECK_MPATHD_RUNNING, STAGE_IS_FAILED); -+ assert_int_equal(is_path_valid(name, &conf, &pp, true), -+ PATH_IS_VALID); -+ assert_string_equal(pp.dev, name); -+ assert_ptr_equal(pp.udev, &test_udev); -+ assert_string_equal(pp.wwid, wwid); -+ /* test greedy success without checking multiapthd */ -+ memset(&pp, 0, sizeof(pp)); -+ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_IS_FAILED); -+ assert_int_equal(is_path_valid(name, &conf, &pp, false), -+ PATH_IS_VALID); -+} -+ -+static void test_check_wwids(void **state) -+{ -+ struct path pp; -+ char *name = "test"; -+ char *wwid = "test-wwid"; -+ -+ memset(&pp, 0, sizeof(pp)); -+ conf.find_multipaths = FIND_MULTIPATHS_STRICT; -+ setup_passing(name, wwid, CHECK_MPATHD_EAGAIN, STAGE_IS_FAILED); -+ will_return(__wrap_check_wwids_file, true); -+ will_return(__wrap_check_wwids_file, wwid); -+ assert_int_equal(is_path_valid(name, &conf, &pp, true), -+ PATH_IS_VALID_NO_CHECK); -+ assert_string_equal(pp.dev, name); -+ assert_ptr_equal(pp.udev, &test_udev); -+ assert_string_equal(pp.wwid, wwid); -+} -+ -+static void test_check_uuid_present(void **state) -+{ -+ struct path pp; -+ char *name = "test"; -+ char *wwid = "test-wwid"; -+ -+ memset(&pp, 0, sizeof(pp)); -+ conf.find_multipaths = FIND_MULTIPATHS_STRICT; -+ setup_passing(name, wwid, CHECK_MPATHD_ENABLED, STAGE_CHECK_WWIDS); -+ will_return(__wrap_dm_map_present_by_uuid, 1); -+ will_return(__wrap_dm_map_present_by_uuid, wwid); -+ assert_int_equal(is_path_valid(name, &conf, &pp, true), -+ PATH_IS_VALID); -+ assert_string_equal(pp.dev, name); -+ assert_ptr_equal(pp.udev, &test_udev); -+ assert_string_equal(pp.wwid, wwid); -+} -+ -+ -+static void test_find_multipaths(void **state) -+{ -+ struct path pp; -+ char *name = "test"; -+ char *wwid = "test-wwid"; -+ -+ /* test find_multipaths = FIND_MULTIPATHS_STRICT */ -+ memset(&pp, 0, sizeof(pp)); -+ conf.find_multipaths = FIND_MULTIPATHS_STRICT; -+ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_UUID_PRESENT); -+ assert_int_equal(is_path_valid(name, &conf, &pp, false), -+ PATH_IS_NOT_VALID); -+ assert_string_equal(pp.dev, name); -+ assert_ptr_equal(pp.udev, &test_udev); -+ assert_string_equal(pp.wwid, wwid); -+ /* test find_multipaths = FIND_MULTIPATHS_OFF */ -+ memset(&pp, 0, sizeof(pp)); -+ conf.find_multipaths = FIND_MULTIPATHS_OFF; -+ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_UUID_PRESENT); -+ assert_int_equal(is_path_valid(name, &conf, &pp, false), -+ PATH_IS_NOT_VALID); -+ /* test find_multipaths = FIND_MULTIPATHS_ON */ -+ memset(&pp, 0, sizeof(pp)); -+ conf.find_multipaths = FIND_MULTIPATHS_ON; -+ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_UUID_PRESENT); -+ assert_int_equal(is_path_valid(name, &conf, &pp, false), -+ PATH_IS_NOT_VALID); -+ /* test find_multipaths = FIND_MULTIPATHS_SMART */ -+ memset(&pp, 0, sizeof(pp)); -+ conf.find_multipaths = FIND_MULTIPATHS_SMART; -+ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_UUID_PRESENT); -+ assert_int_equal(is_path_valid(name, &conf, &pp, false), -+ PATH_IS_MAYBE_VALID); -+ assert_string_equal(pp.dev, name); -+ assert_ptr_equal(pp.udev, &test_udev); -+ assert_string_equal(pp.wwid, wwid); -+} -+ -+int test_valid(void) -+{ -+ const struct CMUnitTest tests[] = { -+ cmocka_unit_test(test_bad_arguments), -+ cmocka_unit_test(test_sysfs_is_multipathed), -+ cmocka_unit_test(test_check_multipathd), -+ cmocka_unit_test(test_pathinfo), -+ cmocka_unit_test(test_filter_property), -+ cmocka_unit_test(test_is_failed_wwid), -+ cmocka_unit_test(test_greedy), -+ cmocka_unit_test(test_check_wwids), -+ cmocka_unit_test(test_check_uuid_present), -+ cmocka_unit_test(test_find_multipaths), -+ }; -+ return cmocka_run_group_tests(tests, NULL, NULL); -+} -+ -+int main(void) -+{ -+ int ret = 0; -+ ret += test_valid(); -+ return ret; -+} --- -2.17.2 - diff --git a/0075-libmultipath-provide-defaults-for-get-put-_multipath.patch b/0026-libmultipath-provide-defaults-for-get-put-_multipath.patch similarity index 78% rename from 0075-libmultipath-provide-defaults-for-get-put-_multipath.patch rename to 0026-libmultipath-provide-defaults-for-get-put-_multipath.patch index 9fe50d0..e3375f0 100644 --- a/0075-libmultipath-provide-defaults-for-get-put-_multipath.patch +++ b/0026-libmultipath-provide-defaults-for-get-put-_multipath.patch @@ -1,6 +1,6 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Martin Wilck -Date: Thu, 24 Sep 2020 15:37:08 +0200 +Date: Wed, 16 Sep 2020 12:06:56 +0200 Subject: [PATCH] libmultipath: provide defaults for {get,put}_multipath_config Add an implementation of get_multipath_config() and put_multipath_config() @@ -14,24 +14,28 @@ It must be initialized with init_config() rather than load_config(), which always allocates a new struct for backward compatibility, and must be teared down using uninit_config(). -Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski Signed-off-by: Benjamin Marzinski --- - libmultipath/config.c | 72 +++++++++++++++++++++++++++++++++++++------ - libmultipath/config.h | 21 +++++++++++-- - 2 files changed, 80 insertions(+), 13 deletions(-) + libmultipath/config.c | 75 ++++++++++++++++++++++++++----- + libmultipath/config.h | 21 +++++++-- + libmultipath/libmultipath.version | 10 +++++ + 3 files changed, 93 insertions(+), 13 deletions(-) diff --git a/libmultipath/config.c b/libmultipath/config.c -index 1818f8b9..422e923d 100644 +index 5c91a09d..01b77dfe 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c -@@ -28,6 +28,23 @@ +@@ -27,6 +27,26 @@ + #include "mpath_cmd.h" #include "propsel.h" - #include "version.h" +static struct config __internal_config; +struct config *libmp_get_multipath_config(void) +{ ++ if (!__internal_config.hwtable) ++ /* not initialized */ ++ return NULL; + return &__internal_config; +} + @@ -49,7 +53,7 @@ index 1818f8b9..422e923d 100644 static int hwe_strmatch (const struct hwentry *hwe1, const struct hwentry *hwe2) { -@@ -575,17 +592,15 @@ restart: +@@ -574,17 +594,15 @@ restart: return; } @@ -70,7 +74,7 @@ index 1818f8b9..422e923d 100644 if (conf->multipath_dir) FREE(conf->multipath_dir); -@@ -649,7 +664,27 @@ free_config (struct config * conf) +@@ -650,7 +668,27 @@ free_config (struct config * conf) free_hwtable(conf->hwtable); free_hwe(conf->overrides); free_keywords(conf->keywords); @@ -99,7 +103,7 @@ index 1818f8b9..422e923d 100644 } /* if multipath fails to process the config directory, it should continue, -@@ -718,12 +753,29 @@ static void set_max_checkint_from_watchdog(struct config *conf) +@@ -719,12 +757,29 @@ static void set_max_checkint_from_watchdog(struct config *conf) } #endif @@ -130,7 +134,7 @@ index 1818f8b9..422e923d 100644 /* * internal defaults -@@ -911,10 +963,10 @@ struct config *load_config(const char *file) +@@ -896,10 +951,10 @@ struct config *load_config(const char *file) !conf->wwids_file || !conf->prkeys_file) goto out; @@ -145,10 +149,10 @@ index 1818f8b9..422e923d 100644 char *get_uid_attribute_by_attrs(struct config *conf, diff --git a/libmultipath/config.h b/libmultipath/config.h -index 78375f2f..83d179ac 100644 +index ace403b8..0329de29 100644 --- a/libmultipath/config.h +++ b/libmultipath/config.h -@@ -254,10 +254,25 @@ void free_mptable (vector mptable); +@@ -252,10 +252,25 @@ void free_mptable (vector mptable); int store_hwe (vector hwtable, struct hwentry *); struct config *load_config (const char *file); @@ -177,6 +181,24 @@ index 78375f2f..83d179ac 100644 int parse_uid_attrs(char *uid_attrs, struct config *conf); char *get_uid_attribute_by_attrs(struct config *conf, +diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version +index 97acdbb2..3e780fce 100644 +--- a/libmultipath/libmultipath.version ++++ b/libmultipath/libmultipath.version +@@ -251,3 +251,13 @@ global: + libmp_dm_task_run; + cleanup_mutex; + } LIBMULTIPATH_2.0.0; ++ ++LIBMULTIPATH_2.2.0 { ++global: ++ libmp_get_multipath_config; ++ get_multipath_config; ++ libmp_put_multipath_config; ++ put_multipath_config; ++ init_config; ++ uninit_config; ++} LIBMULTIPATH_2.1.0; -- 2.17.2 diff --git a/0076-libmpathpersist-allow-using-libmultipath-get-put-_mu.patch b/0027-libmpathpersist-allow-using-libmultipath-get-put-_mu.patch similarity index 81% rename from 0076-libmpathpersist-allow-using-libmultipath-get-put-_mu.patch rename to 0027-libmpathpersist-allow-using-libmultipath-get-put-_mu.patch index c36aa90..def8896 100644 --- a/0076-libmpathpersist-allow-using-libmultipath-get-put-_mu.patch +++ b/0027-libmpathpersist-allow-using-libmultipath-get-put-_mu.patch @@ -1,23 +1,38 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Martin Wilck -Date: Thu, 24 Sep 2020 15:37:09 +0200 +Date: Wed, 16 Sep 2020 12:11:46 +0200 Subject: [PATCH] libmpathpersist: allow using libmultipath {get,put}_multipath_config Provide an alternative init function libmpathpersist_init() which avoids allocating a new struct config, simply using libmultipath's -internal implementation. +internal implementation. This causes a minor version bump for +libmpathpersist. Reviewed-by: Benjamin Marzinski -Signed-off-by: Martin Wilck Signed-off-by: Benjamin Marzinski --- - libmpathpersist/mpath_persist.c | 42 ++++++++++++++++++++++++++++----- - libmpathpersist/mpath_persist.h | 28 ++++++++++++++++++++++ - 2 files changed, 64 insertions(+), 6 deletions(-) + libmpathpersist/libmpathpersist.version | 6 ++++ + libmpathpersist/mpath_persist.c | 42 +++++++++++++++++++++---- + libmpathpersist/mpath_persist.h | 28 +++++++++++++++++ + 3 files changed, 70 insertions(+), 6 deletions(-) +diff --git a/libmpathpersist/libmpathpersist.version b/libmpathpersist/libmpathpersist.version +index dc648ce6..e0748138 100644 +--- a/libmpathpersist/libmpathpersist.version ++++ b/libmpathpersist/libmpathpersist.version +@@ -30,3 +30,9 @@ global: + + local: *; + }; ++ ++LIBMPATHPERSIST_1.1.0 { ++global: ++ libmpathpersist_init; ++ libmpathpersist_exit; ++} LIBMPATHPERSIST_1.0.0; diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c -index a132f4e9..9dfc98cd 100644 +index cc4a088d..febf4758 100644 --- a/libmpathpersist/mpath_persist.c +++ b/libmpathpersist/mpath_persist.c @@ -37,6 +37,27 @@ @@ -48,7 +63,7 @@ index a132f4e9..9dfc98cd 100644 struct config * mpath_lib_init (void) { -@@ -47,21 +68,30 @@ mpath_lib_init (void) +@@ -47,20 +68,29 @@ mpath_lib_init (void) condlog(0, "Failed to initialize multipath config."); return NULL; } @@ -63,7 +78,6 @@ index a132f4e9..9dfc98cd 100644 -mpath_lib_exit (struct config *conf) +static void libmpathpersist_cleanup(void) { - dm_lib_release(); dm_lib_exit(); cleanup_prio(); cleanup_checkers(); diff --git a/0027-libmultipath-simplify-failed-wwid-code.patch b/0027-libmultipath-simplify-failed-wwid-code.patch deleted file mode 100644 index bb60d21..0000000 --- a/0027-libmultipath-simplify-failed-wwid-code.patch +++ /dev/null @@ -1,205 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 19 May 2020 12:08:44 -0500 -Subject: [PATCH] libmultipath: simplify failed wwid code - -The (is|mark|unmark)_failed_wwid code is needlessly complicated. -Locking a file is necssary if multiple processes could otherwise be -writing to it at the same time. That is not the case with the -failed_wwids files. They can simply be empty files in a directory. Even -with all the locking in place, two processes accessing or modifying a -file at the same time will still race. And even without the locking, if -two processes try to access or modify a file at the same time, they will -both see a reasonable result, and will leave the files in a valid state -afterwards. - -Instead of doing all the locking work (which made it necessary to write -a file, even just to check if a file existed), simply check for files -with lstat(), create them with open(), and remove them with unlink(). - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/wwids.c | 131 ++++++++++++++++++------------------------- - 1 file changed, 56 insertions(+), 75 deletions(-) - -diff --git a/libmultipath/wwids.c b/libmultipath/wwids.c -index 637cb0ab..aab5da8a 100644 ---- a/libmultipath/wwids.c -+++ b/libmultipath/wwids.c -@@ -6,6 +6,7 @@ - #include - #include - #include -+#include - - #include "util.h" - #include "checkers.h" -@@ -348,109 +349,89 @@ remember_wwid(char *wwid) - } - - static const char shm_dir[] = MULTIPATH_SHM_BASE "failed_wwids"; --static const char shm_lock[] = ".lock"; --static const char shm_header[] = "multipath shm lock file, don't edit"; --static char _shm_lock_path[sizeof(shm_dir)+sizeof(shm_lock)]; --static const char *shm_lock_path = &_shm_lock_path[0]; - --static void init_shm_paths(void) -+static void print_failed_wwid_result(const char * msg, const char *wwid, int r) - { -- snprintf(_shm_lock_path, sizeof(_shm_lock_path), -- "%s/%s", shm_dir, shm_lock); -+ switch(r) { -+ case WWID_FAILED_ERROR: -+ condlog(1, "%s: %s: %m", msg, wwid); -+ return; -+ case WWID_IS_FAILED: -+ case WWID_IS_NOT_FAILED: -+ condlog(4, "%s: %s is %s", msg, wwid, -+ r == WWID_IS_FAILED ? "failed" : "good"); -+ return; -+ case WWID_FAILED_CHANGED: -+ condlog(3, "%s: %s", msg, wwid); -+ } - } - --static pthread_once_t shm_path_once = PTHREAD_ONCE_INIT; -- --static int multipath_shm_open(bool rw) -+int is_failed_wwid(const char *wwid) - { -- int fd; -- int can_write; -- -- pthread_once(&shm_path_once, init_shm_paths); -- fd = open_file(shm_lock_path, &can_write, shm_header); -+ struct stat st; -+ char path[PATH_MAX]; -+ int r; - -- if (fd >= 0 && rw && !can_write) { -- close(fd); -- condlog(1, "failed to open %s for writing", shm_dir); -+ if (safe_sprintf(path, "%s/%s", shm_dir, wwid)) { -+ condlog(1, "%s: path name overflow", __func__); - return -1; - } - -- return fd; --} -- --static void multipath_shm_close(void *arg) --{ -- long fd = (long)arg; -+ if (lstat(path, &st) == 0) -+ r = WWID_IS_FAILED; -+ else if (errno == ENOENT) -+ r = WWID_IS_NOT_FAILED; -+ else -+ r = WWID_FAILED_ERROR; - -- close(fd); -- unlink(shm_lock_path); -+ print_failed_wwid_result("is_failed", wwid, r); -+ return r; - } - --static int _failed_wwid_op(const char *wwid, bool rw, -- int (*func)(const char *), const char *msg) -+int mark_failed_wwid(const char *wwid) - { - char path[PATH_MAX]; -- long lockfd; -- int r = -1; -+ int r, fd; - - if (safe_sprintf(path, "%s/%s", shm_dir, wwid)) { - condlog(1, "%s: path name overflow", __func__); - return -1; - } -- -- lockfd = multipath_shm_open(rw); -- if (lockfd == -1) -+ if (ensure_directories_exist(path, 0700) < 0) { -+ condlog(1, "%s: can't setup directories", __func__); - return -1; -+ } - -- pthread_cleanup_push(multipath_shm_close, (void *)lockfd); -- r = func(path); -- pthread_cleanup_pop(1); -- -- if (r == WWID_FAILED_ERROR) -- condlog(1, "%s: %s: %s", msg, wwid, strerror(errno)); -- else if (r == WWID_FAILED_CHANGED) -- condlog(3, "%s: %s", msg, wwid); -- else if (!rw) -- condlog(4, "%s: %s is %s", msg, wwid, -- r == WWID_IS_FAILED ? "failed" : "good"); -+ fd = open(path, O_RDONLY | O_CREAT | O_EXCL, S_IRUSR); -+ if (fd >= 0) { -+ close(fd); -+ r = WWID_FAILED_CHANGED; -+ } else if (errno == EEXIST) -+ r = WWID_FAILED_UNCHANGED; -+ else -+ r = WWID_FAILED_ERROR; - -+ print_failed_wwid_result("mark_failed", wwid, r); - return r; - } - --static int _is_failed(const char *path) -+int unmark_failed_wwid(const char *wwid) - { -- struct stat st; -+ char path[PATH_MAX]; -+ int r; - -- if (lstat(path, &st) == 0) -- return WWID_IS_FAILED; -+ if (safe_sprintf(path, "%s/%s", shm_dir, wwid)) { -+ condlog(1, "%s: path name overflow", __func__); -+ return -1; -+ } -+ -+ if (unlink(path) == 0) -+ r = WWID_FAILED_CHANGED; - else if (errno == ENOENT) -- return WWID_IS_NOT_FAILED; -+ r = WWID_FAILED_UNCHANGED; - else -- return WWID_FAILED_ERROR; --} -- --static int _mark_failed(const char *path) --{ -- /* Called from _failed_wwid_op: we know that shm_lock_path exists */ -- if (_is_failed(path) == WWID_IS_FAILED) -- return WWID_FAILED_UNCHANGED; -- return (link(shm_lock_path, path) == 0 ? WWID_FAILED_CHANGED : -- WWID_FAILED_ERROR); --} -+ r = WWID_FAILED_ERROR; - --static int _unmark_failed(const char *path) --{ -- if (_is_failed(path) == WWID_IS_NOT_FAILED) -- return WWID_FAILED_UNCHANGED; -- return (unlink(path) == 0 ? WWID_FAILED_CHANGED : WWID_FAILED_ERROR); --} -- --#define declare_failed_wwid_op(op, rw) \ --int op ## _wwid(const char *wwid) \ --{ \ -- return _failed_wwid_op(wwid, (rw), _ ## op, #op); \ -+ print_failed_wwid_result("unmark_failed", wwid, r); -+ return r; - } -- --declare_failed_wwid_op(is_failed, false) --declare_failed_wwid_op(mark_failed, true) --declare_failed_wwid_op(unmark_failed, true) --- -2.17.2 - diff --git a/0028-libmultipath-use-atomic-linkat-in-mark_failed_wwid.patch b/0028-libmultipath-use-atomic-linkat-in-mark_failed_wwid.patch deleted file mode 100644 index 6b9941a..0000000 --- a/0028-libmultipath-use-atomic-linkat-in-mark_failed_wwid.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 19 May 2020 12:08:45 -0500 -Subject: [PATCH] libmultipath: use atomic linkat() in mark_failed_wwid() - -This keeps (almost) the simplicity of the previous patch, while -making sure that the return value of mark_failed_wwid() -(WWID_FAILED_CHANGED vs. WWID_FAILED_UNCHANGED) is correct, even -if several processes access this WWID at the same time. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/wwids.c | 42 +++++++++++++++++++++++++++++------------- - 1 file changed, 29 insertions(+), 13 deletions(-) - -diff --git a/libmultipath/wwids.c b/libmultipath/wwids.c -index aab5da8a..61d9c39e 100644 ---- a/libmultipath/wwids.c -+++ b/libmultipath/wwids.c -@@ -374,7 +374,7 @@ int is_failed_wwid(const char *wwid) - - if (safe_sprintf(path, "%s/%s", shm_dir, wwid)) { - condlog(1, "%s: path name overflow", __func__); -- return -1; -+ return WWID_FAILED_ERROR; - } - - if (lstat(path, &st) == 0) -@@ -390,27 +390,43 @@ int is_failed_wwid(const char *wwid) - - int mark_failed_wwid(const char *wwid) - { -- char path[PATH_MAX]; -- int r, fd; -+ char tmpfile[WWID_SIZE + 2 * sizeof(long) + 1]; -+ int r = WWID_FAILED_ERROR, fd, dfd; - -- if (safe_sprintf(path, "%s/%s", shm_dir, wwid)) { -- condlog(1, "%s: path name overflow", __func__); -- return -1; -+ dfd = open(shm_dir, O_RDONLY|O_DIRECTORY); -+ if (dfd == -1 && errno == ENOENT) { -+ char path[sizeof(shm_dir) + 2]; -+ -+ /* arg for ensure_directories_exist() must not end with "/" */ -+ safe_sprintf(path, "%s/_", shm_dir); -+ ensure_directories_exist(path, 0700); -+ dfd = open(shm_dir, O_RDONLY|O_DIRECTORY); - } -- if (ensure_directories_exist(path, 0700) < 0) { -- condlog(1, "%s: can't setup directories", __func__); -- return -1; -+ if (dfd == -1) { -+ condlog(1, "%s: can't setup %s: %m", __func__, shm_dir); -+ return WWID_FAILED_ERROR; - } - -- fd = open(path, O_RDONLY | O_CREAT | O_EXCL, S_IRUSR); -- if (fd >= 0) { -+ safe_sprintf(tmpfile, "%s.%lx", wwid, (long)getpid()); -+ fd = openat(dfd, tmpfile, O_RDONLY | O_CREAT | O_EXCL, S_IRUSR); -+ if (fd >= 0) - close(fd); -+ else -+ goto out_closedir; -+ -+ if (linkat(dfd, tmpfile, dfd, wwid, 0) == 0) - r = WWID_FAILED_CHANGED; -- } else if (errno == EEXIST) -+ else if (errno == EEXIST) - r = WWID_FAILED_UNCHANGED; - else - r = WWID_FAILED_ERROR; - -+ if (unlinkat(dfd, tmpfile, 0) == -1) -+ condlog(2, "%s: failed to unlink %s/%s: %m", -+ __func__, shm_dir, tmpfile); -+ -+out_closedir: -+ close(dfd); - print_failed_wwid_result("mark_failed", wwid, r); - return r; - } -@@ -422,7 +438,7 @@ int unmark_failed_wwid(const char *wwid) - - if (safe_sprintf(path, "%s/%s", shm_dir, wwid)) { - condlog(1, "%s: path name overflow", __func__); -- return -1; -+ return WWID_FAILED_ERROR; - } - - if (unlink(path) == 0) --- -2.17.2 - diff --git a/0077-multipath-use-get_put-_multipath_config-from-libmult.patch b/0028-multipath-use-get_put-_multipath_config-from-libmult.patch similarity index 81% rename from 0077-multipath-use-get_put-_multipath_config-from-libmult.patch rename to 0028-multipath-use-get_put-_multipath_config-from-libmult.patch index 8f0f443..762daea 100644 --- a/0077-multipath-use-get_put-_multipath_config-from-libmult.patch +++ b/0028-multipath-use-get_put-_multipath_config-from-libmult.patch @@ -1,20 +1,19 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Martin Wilck -Date: Thu, 24 Sep 2020 15:37:10 +0200 +Date: Wed, 16 Sep 2020 12:27:09 +0200 Subject: [PATCH] multipath: use {get_put}_multipath_config from libmultipath Reviewed-by: Benjamin Marzinski -Signed-off-by: Martin Wilck Signed-off-by: Benjamin Marzinski --- multipath/main.c | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/multipath/main.c b/multipath/main.c -index ce48a932..879d7ac9 100644 +index dc4974b9..4bbfce9a 100644 --- a/multipath/main.c +++ b/multipath/main.c -@@ -67,7 +67,6 @@ +@@ -68,7 +68,6 @@ int logsink; struct udev *udev; @@ -22,7 +21,7 @@ index ce48a932..879d7ac9 100644 /* * Return values of configure(), check_path_valid(), and main(). -@@ -78,16 +77,6 @@ enum { +@@ -79,16 +78,6 @@ enum { RTVL_RETRY, /* returned by configure(), not by main() */ }; @@ -39,7 +38,7 @@ index ce48a932..879d7ac9 100644 static int dump_config (struct config *conf, vector hwes, vector mpvec) { -@@ -892,10 +881,9 @@ main (int argc, char *argv[]) +@@ -823,10 +812,9 @@ main (int argc, char *argv[]) udev = udev_new(); logsink = 0; @@ -51,8 +50,8 @@ index ce48a932..879d7ac9 100644 + conf = get_multipath_config(); conf->retrigger_tries = 0; conf->force_sync = 1; - while ((arg = getopt(argc, argv, ":aAdDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { -@@ -1148,8 +1136,8 @@ out_free_config: + while ((arg = getopt(argc, argv, ":adDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { +@@ -1078,8 +1066,8 @@ out_free_config: * the logging function (dm_write_log()), which is called there, * references the config. */ diff --git a/0029-fix-boolean-value-with-json-c-0.14.patch b/0029-fix-boolean-value-with-json-c-0.14.patch deleted file mode 100644 index 29bb90b..0000000 --- a/0029-fix-boolean-value-with-json-c-0.14.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: "mail@eworm.de" -Date: Sat, 25 Apr 2020 21:11:13 +0200 -Subject: [PATCH] fix boolean value with json-c 0.14 - -Upstream json-c removed the TRUE and FALSE defines in commit -0992aac61f8b087efd7094e9ac2b84fa9c040fcd. - -[mwilck]: Use stdbool.h, and keep the log message unchanged. - -Signed-off-by: Christian Hesse -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libdmmp/libdmmp_private.h | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/libdmmp/libdmmp_private.h b/libdmmp/libdmmp_private.h -index ac85b63f..b1a6ddea 100644 ---- a/libdmmp/libdmmp_private.h -+++ b/libdmmp/libdmmp_private.h -@@ -30,6 +30,7 @@ - #include - #include - #include -+#include - #include - - #include "libdmmp/libdmmp.h" -@@ -82,7 +83,7 @@ static out_type func_name(struct dmmp_context *ctx, const char *var_name) { \ - do { \ - json_type j_type = json_type_null; \ - json_object *j_obj_tmp = NULL; \ -- if (json_object_object_get_ex(j_obj, key, &j_obj_tmp) != TRUE) { \ -+ if (json_object_object_get_ex(j_obj, key, &j_obj_tmp) != true) { \ - _error(ctx, "Invalid JSON output from multipathd IPC: " \ - "key '%s' not found", key); \ - rc = DMMP_ERR_IPC_ERROR; \ --- -2.17.2 - diff --git a/0078-mpathpersist-use-get-put-_multipath_config-from-libm.patch b/0029-mpathpersist-use-get-put-_multipath_config-from-libm.patch similarity index 88% rename from 0078-mpathpersist-use-get-put-_multipath_config-from-libm.patch rename to 0029-mpathpersist-use-get-put-_multipath_config-from-libm.patch index cc601bb..6ab3c10 100644 --- a/0078-mpathpersist-use-get-put-_multipath_config-from-libm.patch +++ b/0029-mpathpersist-use-get-put-_multipath_config-from-libm.patch @@ -1,18 +1,17 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Martin Wilck -Date: Thu, 24 Sep 2020 15:37:11 +0200 +Date: Wed, 16 Sep 2020 12:39:01 +0200 Subject: [PATCH] mpathpersist: use {get,put}_multipath_config() from libmultipath Reviewed-by: Benjamin Marzinski -Signed-off-by: Martin Wilck Signed-off-by: Benjamin Marzinski --- mpathpersist/main.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/mpathpersist/main.c b/mpathpersist/main.c -index 28bfe410..0f0db4b8 100644 +index a6a3bcf6..278e48f7 100644 --- a/mpathpersist/main.c +++ b/mpathpersist/main.c @@ -43,17 +43,6 @@ void mpath_print_transport_id(struct prin_fulldescr *fdesc); @@ -33,7 +32,7 @@ index 28bfe410..0f0db4b8 100644 void rcu_register_thread_memb(void) {} -@@ -620,15 +609,14 @@ int main(int argc, char *argv[]) +@@ -653,15 +642,14 @@ int main(int argc, char *argv[]) } udev = udev_new(); diff --git a/0079-libmultipath-add-udev-and-logsink-symbols.patch b/0030-libmultipath-add-udev-and-logsink-symbols.patch similarity index 81% rename from 0079-libmultipath-add-udev-and-logsink-symbols.patch rename to 0030-libmultipath-add-udev-and-logsink-symbols.patch index 1b17a12..3bd9de0 100644 --- a/0079-libmultipath-add-udev-and-logsink-symbols.patch +++ b/0030-libmultipath-add-udev-and-logsink-symbols.patch @@ -1,6 +1,6 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Martin Wilck -Date: Thu, 24 Sep 2020 15:37:12 +0200 +Date: Wed, 16 Sep 2020 15:06:12 +0200 Subject: [PATCH] libmultipath: add udev and logsink symbols With these symbols added, applications using libmultipath don't @@ -16,21 +16,22 @@ libmultipath_init() can be skipped, but like before, udev should be initialized (using udev_new()) before making any libmultipath calls. -Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski Signed-off-by: Benjamin Marzinski --- - libmultipath/config.c | 46 +++++++++++++++++++++++++++++++++++++++++++ - libmultipath/config.h | 46 ++++++++++++++++++++++++++++++++++++++++++- - libmultipath/debug.c | 2 ++ - 3 files changed, 93 insertions(+), 1 deletion(-) + libmultipath/config.c | 41 +++++++++++++++++++++++++++ + libmultipath/config.h | 46 ++++++++++++++++++++++++++++++- + libmultipath/debug.c | 2 ++ + libmultipath/libmultipath.version | 8 ++++++ + 4 files changed, 96 insertions(+), 1 deletion(-) diff --git a/libmultipath/config.c b/libmultipath/config.c -index 422e923d..b3809433 100644 +index 01b77dfe..f74417c6 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c -@@ -28,6 +28,52 @@ +@@ -27,6 +27,47 @@ + #include "mpath_cmd.h" #include "propsel.h" - #include "version.h" +/* + * We don't support re-initialization after @@ -51,11 +52,6 @@ index 422e923d..b3809433 100644 + condlog(0, "%s: failed to initialize udev", __func__); +} + -+static void _libmultipath_init(void) -+{ -+ _udev_init(); -+} -+ +static bool _is_libmultipath_initialized(void) +{ + return !libmultipath_exit_called && !!udev; @@ -63,7 +59,7 @@ index 422e923d..b3809433 100644 + +int libmultipath_init(void) +{ -+ pthread_once(&_init_once, _libmultipath_init); ++ pthread_once(&_init_once, _udev_init); + return !_is_libmultipath_initialized(); +} + @@ -82,10 +78,10 @@ index 422e923d..b3809433 100644 struct config *libmp_get_multipath_config(void) { diff --git a/libmultipath/config.h b/libmultipath/config.h -index 83d179ac..089b2ac2 100644 +index 0329de29..f478df71 100644 --- a/libmultipath/config.h +++ b/libmultipath/config.h -@@ -235,7 +235,51 @@ struct config { +@@ -233,7 +233,51 @@ struct config { char *enable_foreign; }; @@ -151,6 +147,22 @@ index 4128cb90..b3a1de9e 100644 void dlog (int sink, int prio, const char * fmt, ...) { va_list ap; +diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version +index 3e780fce..0c300c81 100644 +--- a/libmultipath/libmultipath.version ++++ b/libmultipath/libmultipath.version +@@ -261,3 +261,11 @@ global: + init_config; + uninit_config; + } LIBMULTIPATH_2.1.0; ++ ++LIBMULTIPATH_2.3.0 { ++global: ++ udev; ++ logsink; ++ libmultipath_init; ++ libmultipath_exit; ++} LIBMULTIPATH_2.2.0; -- 2.17.2 diff --git a/0030-libmultipath-fix-condlog-NULL-argument-in-uevent_get.patch b/0030-libmultipath-fix-condlog-NULL-argument-in-uevent_get.patch deleted file mode 100644 index d8ae27d..0000000 --- a/0030-libmultipath-fix-condlog-NULL-argument-in-uevent_get.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 4 Jun 2020 18:20:06 -0500 -Subject: [PATCH] libmultipath: fix condlog NULL argument in uevent_get_env_var - -uevent_get_env_var() could call condlog with p == NULL. On gcc 10, -this triggers warnings like: - -In file included from uevent.c:47: -In function 'uevent_get_env_var', - inlined from 'uevent_get_wwid' at uevent.c:170:8: -debug.h:13:2: error: '%s' directive argument is null -[-Werror=format-overflow=] - 13 | dlog(logsink, prio, fmt "\n", ##args) - | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -uevent.c:132:2: note: in expansion of macro 'condlog' - 132 | condlog(4, "%s: %s -> '%s'", __func__, attr, p); - | ^~~~~~~ -uevent.c: In function 'uevent_get_wwid': -uevent.c:132:25: note: format string is defined here - 132 | condlog(4, "%s: %s -> '%s'", __func__, attr, p); - | ^~ - -If p is NULL, use "(null)" instead. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/uevent.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/uevent.c b/libmultipath/uevent.c -index d38e8a7f..e0d13b11 100644 ---- a/libmultipath/uevent.c -+++ b/libmultipath/uevent.c -@@ -129,7 +129,7 @@ static const char* uevent_get_env_var(const struct uevent *uev, - } - } - -- condlog(4, "%s: %s -> '%s'", __func__, attr, p); -+ condlog(4, "%s: %s -> '%s'", __func__, attr, p ?: "(null)"); - return p; - - invalid: --- -2.17.2 - diff --git a/0031-libmultipath-set-enable_foreign-to-NONE-by-default.patch b/0031-libmultipath-set-enable_foreign-to-NONE-by-default.patch deleted file mode 100644 index 7d2b886..0000000 --- a/0031-libmultipath-set-enable_foreign-to-NONE-by-default.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 21 Aug 2019 16:07:12 +0200 -Subject: [PATCH] libmultipath: set "enable_foreign" to NONE by default - -This has been requested by NetApp. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/defaults.h | 4 ++-- - multipath/multipath.conf.5 | 5 +++-- - 2 files changed, 5 insertions(+), 4 deletions(-) - -diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h -index e5ee6afe..01a501bd 100644 ---- a/libmultipath/defaults.h -+++ b/libmultipath/defaults.h -@@ -50,8 +50,8 @@ - #define DEFAULT_FIND_MULTIPATHS_TIMEOUT -10 - #define DEFAULT_UNKNOWN_FIND_MULTIPATHS_TIMEOUT 1 - #define DEFAULT_ALL_TG_PT ALL_TG_PT_OFF --/* Enable all foreign libraries by default */ --#define DEFAULT_ENABLE_FOREIGN "" -+/* Enable no foreign libraries by default */ -+#define DEFAULT_ENABLE_FOREIGN "NONE" - - #define CHECKINT_UNDEF UINT_MAX - #define DEFAULT_CHECKINT 5 -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 05a5e8ff..28cea88c 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -1228,10 +1228,11 @@ Enables or disables foreign libraries (see section - .I FOREIGN MULTIPATH SUPPORT - below). The value is a regular expression; foreign libraries are loaded - if their name (e.g. \(dqnvme\(dq) matches the expression. By default, --all foreign libraries are enabled. -+no foreign libraries are enabled. Set this to \(dqnvme\(dq to enable NVMe native -+multipath support, or \(dq.*\(dq to enable all foreign libraries. - .RS - .TP --The default is: \fB\(dq\(dq\fR (the empty regular expression) -+The default is: \fB\(dqNONE\(dq\fR - .RE - . - . --- -2.17.2 - diff --git a/0080-multipath-remove-logsink-and-udev.patch b/0031-multipath-remove-logsink-and-udev.patch similarity index 79% rename from 0080-multipath-remove-logsink-and-udev.patch rename to 0031-multipath-remove-logsink-and-udev.patch index 9c4b728..7ba8272 100644 --- a/0080-multipath-remove-logsink-and-udev.patch +++ b/0031-multipath-remove-logsink-and-udev.patch @@ -1,24 +1,23 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Martin Wilck -Date: Thu, 24 Sep 2020 15:37:13 +0200 +Date: Wed, 16 Sep 2020 16:06:17 +0200 Subject: [PATCH] multipath: remove logsink and udev We can use libmultipath's symbols now. Reviewed-by: Benjamin Marzinski -Signed-off-by: Martin Wilck Signed-off-by: Benjamin Marzinski --- multipath/main.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/multipath/main.c b/multipath/main.c -index 879d7ac9..322b30e0 100644 +index 4bbfce9a..9ae46ed5 100644 --- a/multipath/main.c +++ b/multipath/main.c -@@ -65,9 +65,6 @@ - #include "file.h" +@@ -66,9 +66,6 @@ #include "valid.h" + #include "alias.h" -int logsink; -struct udev *udev; @@ -26,7 +25,7 @@ index 879d7ac9..322b30e0 100644 /* * Return values of configure(), check_path_valid(), and main(). */ -@@ -879,7 +876,7 @@ main (int argc, char *argv[]) +@@ -810,7 +807,7 @@ main (int argc, char *argv[]) int retries = -1; bool enable_foreign = false; @@ -35,7 +34,7 @@ index 879d7ac9..322b30e0 100644 logsink = 0; if (init_config(DEFAULT_CONFIGFILE)) exit(RTVL_FAIL); -@@ -1138,7 +1135,7 @@ out_free_config: +@@ -1068,7 +1065,7 @@ out_free_config: */ put_multipath_config(conf); uninit_config(); diff --git a/0081-libmpathpersist-call-libmultipath_-init-exit.patch b/0032-libmpathpersist-call-libmultipath_-init-exit.patch similarity index 91% rename from 0081-libmpathpersist-call-libmultipath_-init-exit.patch rename to 0032-libmpathpersist-call-libmultipath_-init-exit.patch index 2163f02..9c52f9f 100644 --- a/0081-libmpathpersist-call-libmultipath_-init-exit.patch +++ b/0032-libmpathpersist-call-libmultipath_-init-exit.patch @@ -1,19 +1,19 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Martin Wilck -Date: Thu, 24 Sep 2020 15:37:14 +0200 +Date: Tue, 22 Sep 2020 14:23:14 +0200 Subject: [PATCH] libmpathpersist: call libmultipath_{init,exit}() Have libmpathpersist_{init,exit} do the udev initialization, too. -Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski Signed-off-by: Benjamin Marzinski --- - libmpathpersist/mpath_persist.c | 13 +++++++++---- + libmpathpersist/mpath_persist.c | 11 ++++++++--- libmpathpersist/mpath_persist.h | 9 ++++++--- - 2 files changed, 15 insertions(+), 7 deletions(-) + 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c -index 9dfc98cd..d1538195 100644 +index febf4758..e1d1cb76 100644 --- a/libmpathpersist/mpath_persist.c +++ b/libmpathpersist/mpath_persist.c @@ -48,6 +48,10 @@ int libmpathpersist_init(void) @@ -27,16 +27,14 @@ index 9dfc98cd..d1538195 100644 if (init_config(DEFAULT_CONFIGFILE)) { condlog(0, "Failed to initialize multipath config."); return 1; -@@ -74,24 +78,25 @@ mpath_lib_init (void) +@@ -74,23 +78,24 @@ mpath_lib_init (void) static void libmpathpersist_cleanup(void) { -- dm_lib_release(); - dm_lib_exit(); cleanup_prio(); cleanup_checkers(); + libmultipath_exit(); -+ dm_lib_release(); + dm_lib_exit(); } diff --git a/0032-multipath-add-e-option-to-enable-foreign-libraries.patch b/0032-multipath-add-e-option-to-enable-foreign-libraries.patch deleted file mode 100644 index 6e07152..0000000 --- a/0032-multipath-add-e-option-to-enable-foreign-libraries.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 2 Mar 2020 22:43:27 +0100 -Subject: [PATCH] multipath: add "-e" option to enable foreign libraries - -As we have set "enable_foreign" to "NONE" now by default, users -may find it useful to be able to switch on foreign multipath display -with an extra command line option even if foreign libraries are -not enabled in multipath.conf. Currently this makes only sense -with "multipath -ll", as the nvme library (and foreign libraries -in general) support only the display of status information. - -Suggested-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/main.c | 11 ++++++++++- - multipath/multipath.8 | 6 ++++++ - 2 files changed, 16 insertions(+), 1 deletion(-) - -diff --git a/multipath/main.c b/multipath/main.c -index 953fab27..c4740fab 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -145,6 +145,7 @@ usage (char * progname) - " -h print this usage text\n" - " -l show multipath topology (sysfs and DM info)\n" - " -ll show multipath topology (maximum info)\n" -+ " -e enable foreign libraries with -l/-ll\n" - " -f flush a multipath device map\n" - " -F flush all multipath device maps\n" - " -a add a device wwid to the wwids file\n" -@@ -865,6 +866,7 @@ main (int argc, char *argv[]) - char *dev = NULL; - struct config *conf; - int retries = -1; -+ bool enable_foreign = false; - - udev = udev_new(); - logsink = 0; -@@ -874,7 +876,7 @@ main (int argc, char *argv[]) - multipath_conf = conf; - conf->retrigger_tries = 0; - conf->force_sync = 1; -- while ((arg = getopt(argc, argv, ":adcChl::FfM:v:p:b:BrR:itTquUwW")) != EOF ) { -+ while ((arg = getopt(argc, argv, ":adcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { - switch(arg) { - case 1: printf("optarg : %s\n",optarg); - break; -@@ -971,6 +973,9 @@ main (int argc, char *argv[]) - case 'R': - retries = atoi(optarg); - break; -+ case 'e': -+ enable_foreign = true; -+ break; - case ':': - fprintf(stderr, "Missing option argument\n"); - usage(argv[0]); -@@ -1022,6 +1027,10 @@ main (int argc, char *argv[]) - condlog(0, "failed to initialize prioritizers"); - goto out; - } -+ -+ if ((cmd == CMD_LIST_SHORT || cmd == CMD_LIST_LONG) && enable_foreign) -+ conf->enable_foreign = ""; -+ - /* Failing here is non-fatal */ - init_foreign(conf->multipath_dir, conf->enable_foreign); - if (cmd == CMD_USABLE_PATHS) { -diff --git a/multipath/multipath.8 b/multipath/multipath.8 -index 9cdd05a3..6fb8645a 100644 ---- a/multipath/multipath.8 -+++ b/multipath/multipath.8 -@@ -223,6 +223,12 @@ The verbosity level also controls the level of log and debug messages printed to - Dry run, do not create or update devmaps. - . - .TP -+.B \-e -+Enable all foreign libraries. This overrides the -+.I enable_foreign -+option from \fBmultipath.conf(5)\fR. -+. -+.TP - .B \-i - Ignore WWIDs file when processing devices. If - \fIfind_multipaths strict\fR or \fIfind_multipaths no\fR is set in --- -2.17.2 - diff --git a/0033-libmultipath-remove-_blacklist_exceptions-functions.patch b/0033-libmultipath-remove-_blacklist_exceptions-functions.patch deleted file mode 100644 index 5fa6539..0000000 --- a/0033-libmultipath-remove-_blacklist_exceptions-functions.patch +++ /dev/null @@ -1,139 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 9 Jun 2020 16:35:27 -0500 -Subject: [PATCH] libmultipath: remove _blacklist_exceptions functions - -_blacklist_exceptions() and _blacklist_exceptions_device() are exactly -the same as _blacklist() and _blacklist_device(), so remove them, and -give the remaining functions to a more general name. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/blacklist.c | 62 ++++++++++------------------------------ - 1 file changed, 15 insertions(+), 47 deletions(-) - -diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c -index 00e8dbdb..c21a0e27 100644 ---- a/libmultipath/blacklist.c -+++ b/libmultipath/blacklist.c -@@ -101,21 +101,8 @@ int set_ble_device(vector blist, char * vendor, char * product, int origin) - return 0; - } - --int --_blacklist_exceptions (vector elist, const char * str) --{ -- int i; -- struct blentry * ele; -- -- vector_foreach_slot (elist, ele, i) { -- if (!regexec(&ele->regex, str, 0, NULL, 0)) -- return 1; -- } -- return 0; --} -- --int --_blacklist (vector blist, const char * str) -+static int -+match_reglist (vector blist, const char * str) - { - int i; - struct blentry * ble; -@@ -127,28 +114,9 @@ _blacklist (vector blist, const char * str) - return 0; - } - --int --_blacklist_exceptions_device(const struct _vector *elist, const char * vendor, -- const char * product) --{ -- int i; -- struct blentry_device * ble; -- -- vector_foreach_slot (elist, ble, i) { -- if (!ble->vendor && !ble->product) -- continue; -- if ((!ble->vendor || -- !regexec(&ble->vendor_reg, vendor, 0, NULL, 0)) && -- (!ble->product || -- !regexec(&ble->product_reg, product, 0, NULL, 0))) -- return 1; -- } -- return 0; --} -- --int --_blacklist_device (const struct _vector *blist, const char * vendor, -- const char * product) -+static int -+match_reglist_device (const struct _vector *blist, const char * vendor, -+ const char * product) - { - int i; - struct blentry_device * ble; -@@ -300,9 +268,9 @@ filter_device (vector blist, vector elist, char * vendor, char * product, - int r = MATCH_NOTHING; - - if (vendor && product) { -- if (_blacklist_exceptions_device(elist, vendor, product)) -+ if (match_reglist_device(elist, vendor, product)) - r = MATCH_DEVICE_BLIST_EXCEPT; -- else if (_blacklist_device(blist, vendor, product)) -+ else if (match_reglist_device(blist, vendor, product)) - r = MATCH_DEVICE_BLIST; - } - -@@ -316,9 +284,9 @@ filter_devnode (vector blist, vector elist, char * dev) - int r = MATCH_NOTHING; - - if (dev) { -- if (_blacklist_exceptions(elist, dev)) -+ if (match_reglist(elist, dev)) - r = MATCH_DEVNODE_BLIST_EXCEPT; -- else if (_blacklist(blist, dev)) -+ else if (match_reglist(blist, dev)) - r = MATCH_DEVNODE_BLIST; - } - -@@ -332,9 +300,9 @@ filter_wwid (vector blist, vector elist, char * wwid, char * dev) - int r = MATCH_NOTHING; - - if (wwid) { -- if (_blacklist_exceptions(elist, wwid)) -+ if (match_reglist(elist, wwid)) - r = MATCH_WWID_BLIST_EXCEPT; -- else if (_blacklist(blist, wwid)) -+ else if (match_reglist(blist, wwid)) - r = MATCH_WWID_BLIST; - } - -@@ -351,9 +319,9 @@ filter_protocol(vector blist, vector elist, struct path * pp) - if (pp) { - snprint_path_protocol(buf, sizeof(buf), pp); - -- if (_blacklist_exceptions(elist, buf)) -+ if (match_reglist(elist, buf)) - r = MATCH_PROTOCOL_BLIST_EXCEPT; -- else if (_blacklist(blist, buf)) -+ else if (match_reglist(blist, buf)) - r = MATCH_PROTOCOL_BLIST; - } - -@@ -422,11 +390,11 @@ filter_property(struct config *conf, struct udev_device *udev, int lvl, - if (check_missing_prop && !strcmp(env, uid_attribute)) - uid_attr_seen = true; - -- if (_blacklist_exceptions(conf->elist_property, env)) { -+ if (match_reglist(conf->elist_property, env)) { - r = MATCH_PROPERTY_BLIST_EXCEPT; - break; - } -- if (_blacklist(conf->blist_property, env)) { -+ if (match_reglist(conf->blist_property, env)) { - r = MATCH_PROPERTY_BLIST; - break; - } --- -2.17.2 - diff --git a/0082-mpathpersist-remove-logsink-and-udev.patch b/0033-mpathpersist-remove-logsink-and-udev.patch similarity index 86% rename from 0082-mpathpersist-remove-logsink-and-udev.patch rename to 0033-mpathpersist-remove-logsink-and-udev.patch index 8dde360..501f32f 100644 --- a/0082-mpathpersist-remove-logsink-and-udev.patch +++ b/0033-mpathpersist-remove-logsink-and-udev.patch @@ -1,19 +1,19 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Martin Wilck -Date: Thu, 24 Sep 2020 15:37:15 +0200 +Date: Wed, 16 Sep 2020 16:08:43 +0200 Subject: [PATCH] mpathpersist: remove logsink and udev We can use libmultipath's internal symbols now. The libmultipath initialization is taken care of by libmpathpersist_init(). -Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski Signed-off-by: Benjamin Marzinski --- mpathpersist/main.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/mpathpersist/main.c b/mpathpersist/main.c -index 0f0db4b8..a25b08f0 100644 +index 278e48f7..3c2e6576 100644 --- a/mpathpersist/main.c +++ b/mpathpersist/main.c @@ -42,13 +42,10 @@ void * mpath_alloc_prin_response(int prin_sa); @@ -30,7 +30,7 @@ index 0f0db4b8..a25b08f0 100644 static int verbose, loglevel, noisy; -@@ -608,16 +605,13 @@ int main(int argc, char *argv[]) +@@ -641,16 +638,13 @@ int main(int argc, char *argv[]) exit (1); } diff --git a/0034-libmultipath-fix-parser-issue-with-comments-in-strin.patch b/0034-libmultipath-fix-parser-issue-with-comments-in-strin.patch deleted file mode 100644 index 22cc22c..0000000 --- a/0034-libmultipath-fix-parser-issue-with-comments-in-strin.patch +++ /dev/null @@ -1,95 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 9 Jun 2020 16:35:28 -0500 -Subject: [PATCH] libmultipath: fix parser issue with comments in strings - -If a quoted string starts with '#' or '!', the parser will stop -parsing the line, thinking that it's a comment. It should only -be checking for comments outside of quoted strings. Fixed this and -added unit tests to verify it. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/parser.c | 4 +++- - tests/parser.c | 42 ++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 45 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/parser.c b/libmultipath/parser.c -index d478b177..11a6168c 100644 ---- a/libmultipath/parser.c -+++ b/libmultipath/parser.c -@@ -300,8 +300,10 @@ alloc_strvec(char *string) - (isspace((int) *cp) || !isascii((int) *cp))) - && *cp != '\0') - cp++; -- if (*cp == '\0' || *cp == '!' || *cp == '#') -+ if (*cp == '\0' || -+ (!in_string && (*cp == '!' || *cp == '#'))) { - return strvec; -+ } - } - out: - vector_free(strvec); -diff --git a/tests/parser.c b/tests/parser.c -index 29859dac..5772391e 100644 ---- a/tests/parser.c -+++ b/tests/parser.c -@@ -440,6 +440,46 @@ static void test18(void **state) - free_strvec(v); - } - -+static void test19(void **state) -+{ -+#define QUOTED19 "!value" -+ vector v = alloc_strvec("key \"" QUOTED19 "\""); -+ char *val; -+ -+ assert_int_equal(VECTOR_SIZE(v), 4); -+ assert_string_equal(VECTOR_SLOT(v, 0), "key"); -+ assert_true(is_quote(VECTOR_SLOT(v, 1))); -+ assert_string_equal(VECTOR_SLOT(v, 2), QUOTED19); -+ assert_true(is_quote(VECTOR_SLOT(v, 3))); -+ assert_int_equal(validate_config_strvec(v, test_file), 0); -+ -+ val = set_value(v); -+ assert_string_equal(val, QUOTED19); -+ -+ free(val); -+ free_strvec(v); -+} -+ -+static void test20(void **state) -+{ -+#define QUOTED20 "#value" -+ vector v = alloc_strvec("key \"" QUOTED20 "\""); -+ char *val; -+ -+ assert_int_equal(VECTOR_SIZE(v), 4); -+ assert_string_equal(VECTOR_SLOT(v, 0), "key"); -+ assert_true(is_quote(VECTOR_SLOT(v, 1))); -+ assert_string_equal(VECTOR_SLOT(v, 2), QUOTED20); -+ assert_true(is_quote(VECTOR_SLOT(v, 3))); -+ assert_int_equal(validate_config_strvec(v, test_file), 0); -+ -+ val = set_value(v); -+ assert_string_equal(val, QUOTED20); -+ -+ free(val); -+ free_strvec(v); -+} -+ - int test_config_parser(void) - { - const struct CMUnitTest tests[] = { -@@ -461,6 +501,8 @@ int test_config_parser(void) - cmocka_unit_test(test16), - cmocka_unit_test(test17), - cmocka_unit_test(test18), -+ cmocka_unit_test(test19), -+ cmocka_unit_test(test20), - }; - return cmocka_run_group_tests(tests, setup, teardown); - } --- -2.17.2 - diff --git a/0083-multipathd-remove-logsink-and-udev.patch b/0034-multipathd-remove-logsink-and-udev.patch similarity index 77% rename from 0083-multipathd-remove-logsink-and-udev.patch rename to 0034-multipathd-remove-logsink-and-udev.patch index a2b656b..25e929a 100644 --- a/0083-multipathd-remove-logsink-and-udev.patch +++ b/0034-multipathd-remove-logsink-and-udev.patch @@ -1,21 +1,21 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Martin Wilck -Date: Thu, 24 Sep 2020 15:37:16 +0200 +Date: Wed, 23 Sep 2020 11:28:22 +0200 Subject: [PATCH] multipathd: remove logsink and udev We can use the symbols from libmultipath now. -Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski Signed-off-by: Benjamin Marzinski --- multipathd/main.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/multipathd/main.c b/multipathd/main.c -index 48b62937..6a4b8b83 100644 +index 00b66ba4..c5c374b7 100644 --- a/multipathd/main.c +++ b/multipathd/main.c -@@ -113,7 +113,6 @@ struct mpath_event_param +@@ -115,7 +115,6 @@ struct mpath_event_param struct multipath *mpp; }; @@ -23,7 +23,7 @@ index 48b62937..6a4b8b83 100644 int uxsock_timeout; int verbosity; int bindings_read_only; -@@ -144,8 +143,6 @@ static inline enum daemon_status get_running_state(void) +@@ -151,8 +150,6 @@ int should_exit(void) */ struct vectors * gvecs; @@ -32,7 +32,7 @@ index 48b62937..6a4b8b83 100644 struct config *multipath_conf; /* Local variables */ -@@ -3009,8 +3006,6 @@ child (__attribute__((unused)) void *param) +@@ -3123,8 +3120,6 @@ child (__attribute__((unused)) void *param) conf = rcu_dereference(multipath_conf); rcu_assign_pointer(multipath_conf, NULL); call_rcu(&conf->rcu, rcu_free_config); @@ -41,7 +41,7 @@ index 48b62937..6a4b8b83 100644 pthread_attr_destroy(&waiter_attr); pthread_attr_destroy(&io_err_stat_attr); #ifdef _DEBUG_ -@@ -3114,7 +3109,9 @@ main (int argc, char *argv[]) +@@ -3228,7 +3223,9 @@ main (int argc, char *argv[]) pthread_cond_init_mono(&config_cond); diff --git a/0035-libmultipath-invert-regexes-that-start-with-exclamat.patch b/0035-libmultipath-invert-regexes-that-start-with-exclamat.patch deleted file mode 100644 index ff1331d..0000000 --- a/0035-libmultipath-invert-regexes-that-start-with-exclamat.patch +++ /dev/null @@ -1,435 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 9 Jun 2020 16:35:29 -0500 -Subject: [PATCH] libmultipath: invert regexes that start with exclamation - point - -The number of devices that multipath needs to blacklist keeps growing, -and the udev rules already have - -KERNEL!="sd*|dasd*|nvme*", GOTO="end_mpath" - -so they only work correctly with these device types. Instead of -individually blacklisting every type of device that can't be -multipathed, multipath's default blacklist should work like the udev -rule, and blacklist all devices that aren't scsi, dasd, or nvme. -Unfortunately, the c regex library doesn't support negative lookahead. -Instead, multipath should treat "!" at the beginning of -blacklist/exceptions regexes as inverse matching the rest of the regex. -If users need to match a literal '!' as the first character of their -regex, they can use "\!" instead. This allows multipath to change the -default devnode blacklist regex to "!^(sd[a-z]|dasd[a-z]|nvme[0-9])". - -Extra tests have been added to the blacklist unit tests to verify the -inverse matching code and the new default blacklist. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/blacklist.c | 41 +++++++++----- - libmultipath/blacklist.h | 3 + - multipath/multipath.conf.5 | 17 ++++-- - tests/blacklist.c | 110 +++++++++++++++++++++++++++++++++++++ - tests/test-lib.c | 2 +- - 5 files changed, 155 insertions(+), 18 deletions(-) - -diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c -index c21a0e27..db58ccca 100644 ---- a/libmultipath/blacklist.c -+++ b/libmultipath/blacklist.c -@@ -15,9 +15,24 @@ - #include "structs_vec.h" - #include "print.h" - -+char *check_invert(char *str, bool *invert) -+{ -+ if (str[0] == '!') { -+ *invert = true; -+ return str + 1; -+ } -+ if (str[0] == '\\' && str[1] == '!') { -+ *invert = false; -+ return str + 1; -+ } -+ *invert = false; -+ return str; -+} -+ - int store_ble(vector blist, char * str, int origin) - { - struct blentry * ble; -+ char *regex_str; - - if (!str) - return 0; -@@ -30,7 +45,8 @@ int store_ble(vector blist, char * str, int origin) - if (!ble) - goto out; - -- if (regcomp(&ble->regex, str, REG_EXTENDED|REG_NOSUB)) -+ regex_str = check_invert(str, &ble->invert); -+ if (regcomp(&ble->regex, regex_str, REG_EXTENDED|REG_NOSUB)) - goto out1; - - if (!vector_alloc_slot(blist)) -@@ -66,6 +82,7 @@ int alloc_ble_device(vector blist) - int set_ble_device(vector blist, char * vendor, char * product, int origin) - { - struct blentry_device * ble; -+ char *regex_str; - - if (!blist) - return 1; -@@ -76,7 +93,8 @@ int set_ble_device(vector blist, char * vendor, char * product, int origin) - return 1; - - if (vendor) { -- if (regcomp(&ble->vendor_reg, vendor, -+ regex_str = check_invert(vendor, &ble->vendor_invert); -+ if (regcomp(&ble->vendor_reg, regex_str, - REG_EXTENDED|REG_NOSUB)) { - FREE(vendor); - if (product) -@@ -86,7 +104,8 @@ int set_ble_device(vector blist, char * vendor, char * product, int origin) - ble->vendor = vendor; - } - if (product) { -- if (regcomp(&ble->product_reg, product, -+ regex_str = check_invert(product, &ble->product_invert); -+ if (regcomp(&ble->product_reg, regex_str, - REG_EXTENDED|REG_NOSUB)) { - FREE(product); - if (vendor) { -@@ -108,7 +127,7 @@ match_reglist (vector blist, const char * str) - struct blentry * ble; - - vector_foreach_slot (blist, ble, i) { -- if (!regexec(&ble->regex, str, 0, NULL, 0)) -+ if (!!regexec(&ble->regex, str, 0, NULL, 0) == ble->invert) - return 1; - } - return 0; -@@ -125,9 +144,11 @@ match_reglist_device (const struct _vector *blist, const char * vendor, - if (!ble->vendor && !ble->product) - continue; - if ((!ble->vendor || -- !regexec(&ble->vendor_reg, vendor, 0, NULL, 0)) && -+ !!regexec(&ble->vendor_reg, vendor, 0, NULL, 0) == -+ ble->vendor_invert) && - (!ble->product || -- !regexec(&ble->product_reg, product, 0, NULL, 0))) -+ !!regexec(&ble->product_reg, product, 0, NULL, 0) == -+ ble->product_invert)) - return 1; - } - return 0; -@@ -160,13 +181,7 @@ setup_default_blist (struct config * conf) - char * str; - int i; - -- str = STRDUP("^(ram|zram|raw|loop|fd|md|dm-|sr|scd|st|dcssblk)[0-9]"); -- if (!str) -- return 1; -- if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT)) -- return 1; -- -- str = STRDUP("^(td|hd|vd)[a-z]"); -+ str = STRDUP("!^(sd[a-z]|dasd[a-z]|nvme[0-9])"); - if (!str) - return 1; - if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT)) -diff --git a/libmultipath/blacklist.h b/libmultipath/blacklist.h -index 2d721f60..4305857d 100644 ---- a/libmultipath/blacklist.h -+++ b/libmultipath/blacklist.h -@@ -20,6 +20,7 @@ - struct blentry { - char * str; - regex_t regex; -+ bool invert; - int origin; - }; - -@@ -28,6 +29,8 @@ struct blentry_device { - char * product; - regex_t vendor_reg; - regex_t product_reg; -+ bool vendor_invert; -+ bool product_invert; - int origin; - }; - -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 28cea88c..5adaced6 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -1249,6 +1249,16 @@ being handled by multipath-tools. - .LP - . - . -+In the \fIblacklist\fR and \fIblacklist_exceptions\fR sections, starting a -+quoted value with an exclamation mark \fB"!"\fR will invert the matching -+of the rest of the regular expression. For instance, \fB"!^sd[a-z]"\fR will -+match all values that do not start with \fB"sd[a-z]"\fR. The exclamation mark -+can be escaped \fB"\\!"\fR to match a literal \fB!\fR at the start of a -+regular expression. \fBNote:\fR The exclamation mark must be inside quotes, -+otherwise it will be treated as starting a comment. -+.LP -+. -+. - The \fIblacklist_exceptions\fR section is used to revert the actions of the - \fIblacklist\fR section. This allows one to selectively include ("whitelist") devices which - would normally be excluded via the \fIblacklist\fR section. A common usage is -@@ -1265,10 +1275,9 @@ unless explicitly stated. - Regular expression matching the device nodes to be excluded/included. - .RS - .PP --The default \fIblacklist\fR consists of the regular expressions --"^(ram|zram|raw|loop|fd|md|dm-|sr|scd|st|dcssblk)[0-9]" and --"^(td|hd|vd)[a-z]". This causes virtual devices, non-disk devices, and some other --device types to be excluded from multipath handling by default. -+The default \fIblacklist\fR consists of the regular expression -+\fB"!^(sd[a-z]|dasd[a-z]|nvme[0-9])"\fR. This causes all device types other -+than scsi, dasd, and nvme to be excluded from multipath handling by default. - .RE - .TP - .B wwid -diff --git a/tests/blacklist.c b/tests/blacklist.c -index 6e7c1864..d5c40898 100644 ---- a/tests/blacklist.c -+++ b/tests/blacklist.c -@@ -60,20 +60,46 @@ __wrap_udev_list_entry_get_name(struct udev_list_entry *list_entry) - return *(const char **)list_entry; - } - -+vector elist_property_default; -+vector blist_devnode_default; - vector blist_devnode_sdb; -+vector blist_devnode_sdb_inv; - vector blist_all; - vector blist_device_foo_bar; -+vector blist_device_foo_inv_bar; -+vector blist_device_foo_bar_inv; - vector blist_device_all; - vector blist_wwid_xyzzy; -+vector blist_wwid_xyzzy_inv; - vector blist_protocol_fcp; -+vector blist_protocol_fcp_inv; - vector blist_property_wwn; -+vector blist_property_wwn_inv; - - static int setup(void **state) - { -+ struct config conf; -+ -+ memset(&conf, 0, sizeof(conf)); -+ conf.blist_devnode = vector_alloc(); -+ if (!conf.blist_devnode) -+ return -1; -+ conf.elist_property = vector_alloc(); -+ if (!conf.elist_property) -+ return -1; -+ if (setup_default_blist(&conf) != 0) -+ return -1; -+ elist_property_default = conf.elist_property; -+ blist_devnode_default = conf.blist_devnode; -+ - blist_devnode_sdb = vector_alloc(); - if (!blist_devnode_sdb || - store_ble(blist_devnode_sdb, strdup("sdb"), ORIGIN_CONFIG)) - return -1; -+ blist_devnode_sdb_inv = vector_alloc(); -+ if (!blist_devnode_sdb_inv || -+ store_ble(blist_devnode_sdb_inv, strdup("!sdb"), ORIGIN_CONFIG)) -+ return -1; - - blist_all = vector_alloc(); - if (!blist_all || store_ble(blist_all, strdup(".*"), ORIGIN_CONFIG)) -@@ -84,6 +110,18 @@ static int setup(void **state) - set_ble_device(blist_device_foo_bar, strdup("foo"), strdup("bar"), - ORIGIN_CONFIG)) - return -1; -+ blist_device_foo_inv_bar = vector_alloc(); -+ if (!blist_device_foo_inv_bar || -+ alloc_ble_device(blist_device_foo_inv_bar) || -+ set_ble_device(blist_device_foo_inv_bar, strdup("!foo"), -+ strdup("bar"), ORIGIN_CONFIG)) -+ return -1; -+ blist_device_foo_bar_inv = vector_alloc(); -+ if (!blist_device_foo_bar_inv || -+ alloc_ble_device(blist_device_foo_bar_inv) || -+ set_ble_device(blist_device_foo_bar_inv, strdup("foo"), -+ strdup("!bar"), ORIGIN_CONFIG)) -+ return -1; - - blist_device_all = vector_alloc(); - if (!blist_device_all || alloc_ble_device(blist_device_all) || -@@ -95,29 +133,50 @@ static int setup(void **state) - if (!blist_wwid_xyzzy || - store_ble(blist_wwid_xyzzy, strdup("xyzzy"), ORIGIN_CONFIG)) - return -1; -+ blist_wwid_xyzzy_inv = vector_alloc(); -+ if (!blist_wwid_xyzzy_inv || -+ store_ble(blist_wwid_xyzzy_inv, strdup("!xyzzy"), ORIGIN_CONFIG)) -+ return -1; - - blist_protocol_fcp = vector_alloc(); - if (!blist_protocol_fcp || - store_ble(blist_protocol_fcp, strdup("scsi:fcp"), ORIGIN_CONFIG)) - return -1; -+ blist_protocol_fcp_inv = vector_alloc(); -+ if (!blist_protocol_fcp_inv || -+ store_ble(blist_protocol_fcp_inv, strdup("!scsi:fcp"), -+ ORIGIN_CONFIG)) -+ return -1; - - blist_property_wwn = vector_alloc(); - if (!blist_property_wwn || - store_ble(blist_property_wwn, strdup("ID_WWN"), ORIGIN_CONFIG)) - return -1; -+ blist_property_wwn_inv = vector_alloc(); -+ if (!blist_property_wwn_inv || -+ store_ble(blist_property_wwn_inv, strdup("!ID_WWN"), ORIGIN_CONFIG)) -+ return -1; - - return 0; - } - - static int teardown(void **state) - { -+ free_blacklist(elist_property_default); -+ free_blacklist(blist_devnode_default); - free_blacklist(blist_devnode_sdb); -+ free_blacklist(blist_devnode_sdb_inv); - free_blacklist(blist_all); - free_blacklist_device(blist_device_foo_bar); -+ free_blacklist_device(blist_device_foo_inv_bar); -+ free_blacklist_device(blist_device_foo_bar_inv); - free_blacklist_device(blist_device_all); - free_blacklist(blist_wwid_xyzzy); -+ free_blacklist(blist_wwid_xyzzy_inv); - free_blacklist(blist_protocol_fcp); -+ free_blacklist(blist_protocol_fcp_inv); - free_blacklist(blist_property_wwn); -+ free_blacklist(blist_property_wwn_inv); - return 0; - } - -@@ -141,6 +200,11 @@ static void test_devnode_blacklist(void **state) - expect_condlog(3, "sdb: device node name blacklisted\n"); - assert_int_equal(filter_devnode(blist_devnode_sdb, NULL, "sdb"), - MATCH_DEVNODE_BLIST); -+ assert_int_equal(filter_devnode(blist_devnode_sdb_inv, NULL, "sdb"), -+ MATCH_NOTHING); -+ expect_condlog(3, "sdc: device node name blacklisted\n"); -+ assert_int_equal(filter_devnode(blist_devnode_sdb_inv, NULL, "sdc"), -+ MATCH_DEVNODE_BLIST); - } - - static void test_devnode_whitelist(void **state) -@@ -159,12 +223,39 @@ static void test_devnode_missing(void **state) - MATCH_NOTHING); - } - -+static void test_devnode_default(void **state) -+{ -+ assert_int_equal(filter_devnode(blist_devnode_default, NULL, "sdaa"), -+ MATCH_NOTHING); -+ assert_int_equal(filter_devnode(blist_devnode_default, NULL, "nvme0n1"), -+ MATCH_NOTHING); -+ assert_int_equal(filter_devnode(blist_devnode_default, NULL, "dasda"), -+ MATCH_NOTHING); -+ expect_condlog(3, "hda: device node name blacklisted\n"); -+ assert_int_equal(filter_devnode(blist_devnode_default, NULL, "hda"), -+ MATCH_DEVNODE_BLIST); -+} -+ - static void test_device_blacklist(void **state) - { - expect_condlog(3, "sdb: (foo:bar) vendor/product blacklisted\n"); - assert_int_equal(filter_device(blist_device_foo_bar, NULL, "foo", - "bar", "sdb"), - MATCH_DEVICE_BLIST); -+ assert_int_equal(filter_device(blist_device_foo_inv_bar, NULL, "foo", -+ "bar", "sdb"), -+ MATCH_NOTHING); -+ assert_int_equal(filter_device(blist_device_foo_bar_inv, NULL, "foo", -+ "bar", "sdb"), -+ MATCH_NOTHING); -+ expect_condlog(3, "sdb: (baz:bar) vendor/product blacklisted\n"); -+ assert_int_equal(filter_device(blist_device_foo_inv_bar, NULL, "baz", -+ "bar", "sdb"), -+ MATCH_DEVICE_BLIST); -+ expect_condlog(3, "sdb: (foo:baz) vendor/product blacklisted\n"); -+ assert_int_equal(filter_device(blist_device_foo_bar_inv, NULL, "foo", -+ "baz", "sdb"), -+ MATCH_DEVICE_BLIST); - } - - static void test_device_whitelist(void **state) -@@ -191,6 +282,11 @@ static void test_wwid_blacklist(void **state) - expect_condlog(3, "sdb: wwid xyzzy blacklisted\n"); - assert_int_equal(filter_wwid(blist_wwid_xyzzy, NULL, "xyzzy", "sdb"), - MATCH_WWID_BLIST); -+ assert_int_equal(filter_wwid(blist_wwid_xyzzy_inv, NULL, "xyzzy", -+ "sdb"), MATCH_NOTHING); -+ expect_condlog(3, "sdb: wwid plugh blacklisted\n"); -+ assert_int_equal(filter_wwid(blist_wwid_xyzzy_inv, NULL, "plugh", -+ "sdb"), MATCH_WWID_BLIST); - } - - static void test_wwid_whitelist(void **state) -@@ -218,6 +314,12 @@ static void test_protocol_blacklist(void **state) - expect_condlog(3, "sdb: protocol scsi:fcp blacklisted\n"); - assert_int_equal(filter_protocol(blist_protocol_fcp, NULL, &pp), - MATCH_PROTOCOL_BLIST); -+ assert_int_equal(filter_protocol(blist_protocol_fcp_inv, NULL, &pp), -+ MATCH_NOTHING); -+ pp.sg_id.proto_id = SCSI_PROTOCOL_ATA; -+ expect_condlog(3, "sdb: protocol scsi:ata blacklisted\n"); -+ assert_int_equal(filter_protocol(blist_protocol_fcp_inv, NULL, &pp), -+ MATCH_PROTOCOL_BLIST); - } - - static void test_protocol_whitelist(void **state) -@@ -245,10 +347,17 @@ static void test_protocol_missing(void **state) - static void test_property_blacklist(void **state) - { - static struct udev_device udev = { "sdb", { "ID_FOO", "ID_WWN", "ID_BAR", NULL } }; -+ static struct udev_device udev_inv = { "sdb", { "ID_WWN", NULL } }; - conf.blist_property = blist_property_wwn; - expect_condlog(3, "sdb: udev property ID_WWN blacklisted\n"); - assert_int_equal(filter_property(&conf, &udev, 3, "ID_SERIAL"), - MATCH_PROPERTY_BLIST); -+ conf.blist_property = blist_property_wwn_inv; -+ expect_condlog(3, "sdb: udev property ID_FOO blacklisted\n"); -+ assert_int_equal(filter_property(&conf, &udev, 3, "ID_SERIAL"), -+ MATCH_PROPERTY_BLIST); -+ assert_int_equal(filter_property(&conf, &udev_inv, 3, "ID_SERIAL"), -+ MATCH_NOTHING); - } - - /* the property check works different in that you check all the property -@@ -484,6 +593,7 @@ int test_blacklist(void) - cmocka_unit_test(test_devnode_blacklist), - cmocka_unit_test(test_devnode_whitelist), - cmocka_unit_test(test_devnode_missing), -+ cmocka_unit_test(test_devnode_default), - cmocka_unit_test(test_device_blacklist), - cmocka_unit_test(test_device_whitelist), - cmocka_unit_test(test_device_missing), -diff --git a/tests/test-lib.c b/tests/test-lib.c -index 00bae58e..b7c09cc2 100644 ---- a/tests/test-lib.c -+++ b/tests/test-lib.c -@@ -15,7 +15,7 @@ - #include "test-lib.h" - - const int default_mask = (DI_SYSFS|DI_BLACKLIST|DI_WWID|DI_CHECKER|DI_PRIO); --const char default_devnode[] = "sdTEST"; -+const char default_devnode[] = "sdxTEST"; - const char default_wwid[] = "TEST-WWID"; - /* default_wwid should be a substring of default_wwid_1! */ - const char default_wwid_1[] = "TEST-WWID-1"; --- -2.17.2 - diff --git a/0035-multipath-tools-add-Vexata-by-StorCentric-VX-arrays.patch b/0035-multipath-tools-add-Vexata-by-StorCentric-VX-arrays.patch new file mode 100644 index 0000000..c8fa5bb --- /dev/null +++ b/0035-multipath-tools-add-Vexata-by-StorCentric-VX-arrays.patch @@ -0,0 +1,40 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Wed, 16 Dec 2020 23:17:39 +0100 +Subject: [PATCH] multipath-tools: add Vexata(by StorCentric) VX arrays + +https://support.sas.com/resources/papers/performance-tuning-sas-vexata-systems.pdf + +Reviewed-by: Martin Wilck +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Signed-off-by: Benjamin Marzinski +--- + libmultipath/hwtable.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index cd65afcc..c1d6f7ae 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -1191,6 +1191,14 @@ static struct hwentry default_hw[] = { + .product = "Magnitude", + .pgpolicy = MULTIBUS, + .no_path_retry = 30, ++ }, ++ /* Vexata */ ++ { ++ /* VX */ ++ .vendor = "Vexata", ++ .product = "VX", ++ .pgpolicy = MULTIBUS, ++ .no_path_retry = 30, + }, + /* + * Promise Technology +-- +2.17.2 + diff --git a/0036-multipath-Fix-compiler-warnings-when-built-without-s.patch b/0036-multipath-Fix-compiler-warnings-when-built-without-s.patch deleted file mode 100644 index f631fdb..0000000 --- a/0036-multipath-Fix-compiler-warnings-when-built-without-s.patch +++ /dev/null @@ -1,111 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Marius Bakke -Date: Wed, 17 Jun 2020 01:11:26 +0200 -Subject: [PATCH] multipath: Fix compiler warnings when built without systemd. - -Add ifdef guards for code that is unused when systemd is not available. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/config.c | 6 ++++-- - multipathd/main.c | 10 +++++++++- - 2 files changed, 13 insertions(+), 3 deletions(-) - -diff --git a/libmultipath/config.c b/libmultipath/config.c -index b4d87689..658bec8b 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -696,9 +696,9 @@ process_config_dir(struct config *conf, char *dir) - pthread_cleanup_pop(1); - } - -+#ifdef USE_SYSTEMD - static void set_max_checkint_from_watchdog(struct config *conf) - { --#ifdef USE_SYSTEMD - char *envp = getenv("WATCHDOG_USEC"); - unsigned long checkint; - -@@ -714,8 +714,8 @@ static void set_max_checkint_from_watchdog(struct config *conf) - condlog(3, "enabling watchdog, interval %ld", checkint); - conf->use_watchdog = true; - } --#endif - } -+#endif - - struct config * - load_config (char * file) -@@ -789,7 +789,9 @@ load_config (char * file) - /* - * fill the voids left in the config file - */ -+#ifdef USE_SYSTEMD - set_max_checkint_from_watchdog(conf); -+#endif - if (conf->max_checkint == 0) { - if (conf->checkint == CHECKINT_UNDEF) - conf->checkint = DEFAULT_CHECKINT; -diff --git a/multipathd/main.c b/multipathd/main.c -index 6b7db2c0..205ddb32 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -176,6 +176,7 @@ daemon_status(void) - /* - * I love you too, systemd ... - */ -+#ifdef USE_SYSTEMD - static const char * - sd_notify_status(enum daemon_status state) - { -@@ -195,7 +196,6 @@ sd_notify_status(enum daemon_status state) - return NULL; - } - --#ifdef USE_SYSTEMD - static void do_sd_notify(enum daemon_status old_state, - enum daemon_status new_state) - { -@@ -247,7 +247,9 @@ enum daemon_status wait_for_state_change_if(enum daemon_status oldstate, - static void __post_config_state(enum daemon_status state) - { - if (state != running_state && running_state != DAEMON_SHUTDOWN) { -+#ifdef USE_SYSTEMD - enum daemon_status old_state = running_state; -+#endif - - running_state = state; - pthread_cond_broadcast(&config_cond); -@@ -272,7 +274,9 @@ int set_config_state(enum daemon_status state) - pthread_cleanup_push(config_cleanup, NULL); - pthread_mutex_lock(&config_lock); - if (running_state != state) { -+#ifdef USE_SYSTEMD - enum daemon_status old_state = running_state; -+#endif - - if (running_state == DAEMON_SHUTDOWN) - rc = EINVAL; -@@ -2280,7 +2284,9 @@ checkerloop (void *ap) - struct timespec last_time; - struct config *conf; - int foreign_tick = 0; -+#ifdef USE_SYSTEMD - bool use_watchdog; -+#endif - - pthread_cleanup_push(rcu_unregister, NULL); - rcu_register_thread(); -@@ -2294,7 +2300,9 @@ checkerloop (void *ap) - - /* use_watchdog is set from process environment and never changes */ - conf = get_multipath_config(); -+#ifdef USE_SYSTEMD - use_watchdog = conf->use_watchdog; -+#endif - put_multipath_config(conf); - - while (1) { --- -2.17.2 - diff --git a/0036-multipath-tools-Violin-and-Nexsan-were-bought-by-Sto.patch b/0036-multipath-tools-Violin-and-Nexsan-were-bought-by-Sto.patch new file mode 100644 index 0000000..006d74e --- /dev/null +++ b/0036-multipath-tools-Violin-and-Nexsan-were-bought-by-Sto.patch @@ -0,0 +1,45 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Wed, 16 Dec 2020 23:17:40 +0100 +Subject: [PATCH] multipath-tools: Violin and Nexsan were bought by StorCentric + +Reviewed-by: Martin Wilck +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Signed-off-by: Benjamin Marzinski +--- + libmultipath/hwtable.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index c1d6f7ae..a54cc0a3 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -1113,8 +1113,9 @@ static struct hwentry default_hw[] = { + .pgpolicy = MULTIBUS, + }, + /* +- * Imation/Nexsan ++ * StorCentric + */ ++ /* Nexsan */ + { + /* E-Series */ + .vendor = "NEXSAN", +@@ -1143,9 +1144,7 @@ static struct hwentry default_hw[] = { + .prio_name = PRIO_ALUA, + .no_path_retry = 30, + }, +- /* +- * Violin Systems +- */ ++ /* Violin Systems */ + { + /* 3000 / 6000 Series */ + .vendor = "VIOLIN", +-- +2.17.2 + diff --git a/0037-libmultipath-fix-memory-leaks-in-coalesce_paths.patch b/0037-libmultipath-fix-memory-leaks-in-coalesce_paths.patch new file mode 100644 index 0000000..0f67ead --- /dev/null +++ b/0037-libmultipath-fix-memory-leaks-in-coalesce_paths.patch @@ -0,0 +1,117 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: lixiaokeng +Date: Mon, 9 Nov 2020 12:32:05 +0800 +Subject: [PATCH] libmultipath: fix memory leaks in coalesce_paths + +When multipath -F are executed first and multipath -v2 or +-d are executed later, asan will warn memory leaks. The +reason is that the mpp allocated in coalesce_paths isn't +freed. Here we use newmp to store mpp. If newmp need not +be copied to mpvec, we free newmp at the end of the func. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Lixiaokeng +Signed-off-by: Zhiqiang Liu +Signed-off-by: Linfeilong +Signed-off-by: Benjamin Marzinski +--- + libmultipath/configure.c | 40 +++++++++++++++++++++++++++++----------- + 1 file changed, 29 insertions(+), 11 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index 1c8aac08..d36f0d0d 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -1139,7 +1139,7 @@ out: + * FORCE_RELOAD_WEAK: existing maps are compared to the current conf and only + * reloaded in DM if there's a difference. This is useful during startup. + */ +-int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, ++int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid, + int force_reload, enum mpath_cmds cmd) + { + int ret = CP_FAIL; +@@ -1151,6 +1151,7 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, + struct path * pp2; + vector curmp = vecs->mpvec; + vector pathvec = vecs->pathvec; ++ vector newmp; + struct config *conf; + int allow_queueing; + struct bitfield *size_mismatch_seen; +@@ -1171,6 +1172,15 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, + if (size_mismatch_seen == NULL) + return CP_FAIL; + ++ if (mpvec) ++ newmp = mpvec; ++ else ++ newmp = vector_alloc(); ++ if (!newmp) { ++ condlog(0, "can not allocate newmp"); ++ goto out; ++ } ++ + vector_foreach_slot (pathvec, pp1, k) { + int invalid; + +@@ -1283,8 +1293,14 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, + goto out; + } + } +- if (r == DOMAP_DRY) ++ if (r == DOMAP_DRY) { ++ if (!vector_alloc_slot(newmp)) { ++ remove_map(mpp, vecs->pathvec, vecs->mpvec, KEEP_VEC); ++ goto out; ++ } ++ vector_set_slot(newmp, mpp); + continue; ++ } + + if (r == DOMAP_EXIST && mpp->action == ACT_NOTHING && + force_reload == FORCE_RELOAD_WEAK) +@@ -1320,22 +1336,22 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, + print_multipath_topology(mpp, verbosity); + } + +- if (newmp) { +- if (mpp->action != ACT_REJECT) { +- if (!vector_alloc_slot(newmp)) +- goto out; +- vector_set_slot(newmp, mpp); ++ if (mpp->action != ACT_REJECT) { ++ if (!vector_alloc_slot(newmp)) { ++ remove_map(mpp, vecs->pathvec, vecs->mpvec, KEEP_VEC); ++ goto out; + } +- else +- remove_map(mpp, vecs->pathvec, vecs->mpvec, +- KEEP_VEC); ++ vector_set_slot(newmp, mpp); + } ++ else ++ remove_map(mpp, vecs->pathvec, vecs->mpvec, ++ KEEP_VEC); + } + /* + * Flush maps with only dead paths (ie not in sysfs) + * Keep maps with only failed paths + */ +- if (newmp) { ++ if (mpvec) { + vector_foreach_slot (newmp, mpp, i) { + char alias[WWID_SIZE]; + +@@ -1358,6 +1374,8 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, + ret = CP_OK; + out: + free(size_mismatch_seen); ++ if (!mpvec) ++ free_multipathvec(newmp, KEEP_PATHS); + return ret; + } + +-- +2.17.2 + diff --git a/0037-libmultipath-fix-sysfs-dev_loss_tmo-parsing.patch b/0037-libmultipath-fix-sysfs-dev_loss_tmo-parsing.patch deleted file mode 100644 index 0888750..0000000 --- a/0037-libmultipath-fix-sysfs-dev_loss_tmo-parsing.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 2 Jul 2020 19:38:24 -0500 -Subject: [PATCH] libmultipath: fix sysfs dev_loss_tmo parsing - -dev_loss_tmo is a u32 value. However the kernel sysfs code prints it as -a signed integer. This means that if dev_loss_tmo is above INT_MAX, the -sysfs value will be a negative number. Parsing this was causing -sysfs_set_rport_tmo() to fail. - -Signed-off-by: Benjamin Marzinski -Signed-off-by: Martin Wilck ---- - libmultipath/discovery.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index ffec5162..83a41a4a 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -583,7 +583,7 @@ sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp) - struct udev_device *rport_dev = NULL; - char value[16], *eptr; - char rport_id[32]; -- unsigned long long tmo = 0; -+ unsigned int tmo; - int ret; - - sprintf(rport_id, "rport-%d:%d-%d", -@@ -607,8 +607,8 @@ sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp) - "error %d", rport_id, -ret); - goto out; - } -- tmo = strtoull(value, &eptr, 0); -- if (value == eptr || tmo == ULLONG_MAX) { -+ tmo = strtoul(value, &eptr, 0); -+ if (value == eptr) { - condlog(0, "%s: Cannot parse dev_loss_tmo " - "attribute '%s'", rport_id, value); - goto out; --- -2.17.2 - diff --git a/0038-kpartx-read-devices-with-direct-IO.patch b/0038-kpartx-read-devices-with-direct-IO.patch deleted file mode 100644 index eaa91c3..0000000 --- a/0038-kpartx-read-devices-with-direct-IO.patch +++ /dev/null @@ -1,267 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 2 Jul 2020 19:38:25 -0500 -Subject: [PATCH] kpartx: read devices with direct IO - -If kpartx is used on top of shared storage, and a device has its -partition table changed on one machine, and then kpartx is run on -another, it may not see the new data, because the cache still contains -the old data, and there is nothing to tell the machine running kpartx to -invalidate it. To solve this, kpartx should read the devices using -direct io. - -One issue with how this code has been updated is that the original code -for getblock() always read 1024 bytes. The new code reads a logical -sector size chunk of the device, and returns a pointer to the 512 byte -sector that the caller asked for, within that (possibly larger) chunk. -This means that if the logical sector size is 512, then the code is now -only reading 512 bytes. Looking through the code for the various -partition types, I can't see a case where more than 512 bytes is needed -and getblock() is used. If anyone has a reason why this code should be -reading 1024 bytes at minmum, I can certainly change this. But when I -looked, I couldn't find a case where reading 512 bytes would cause a -problem. - -Signed-off-by: Benjamin Marzinski ---- - kpartx/dasd.c | 7 ++++--- - kpartx/gpt.c | 22 +++++++++---------- - kpartx/kpartx.c | 56 +++++++++++++++++++++++++++++++++++++++---------- - kpartx/kpartx.h | 2 ++ - 4 files changed, 61 insertions(+), 26 deletions(-) - -diff --git a/kpartx/dasd.c b/kpartx/dasd.c -index 14b9d3aa..f0398645 100644 ---- a/kpartx/dasd.c -+++ b/kpartx/dasd.c -@@ -22,6 +22,7 @@ - * along with this program. If not, see . - */ - -+#define _GNU_SOURCE - #include - #include - #include -@@ -117,13 +118,13 @@ read_dasd_pt(int fd, __attribute__((unused)) struct slice all, - - sprintf(pathname, "/dev/.kpartx-node-%u-%u", - (unsigned int)major(dev), (unsigned int)minor(dev)); -- if ((fd_dasd = open(pathname, O_RDONLY)) == -1) { -+ if ((fd_dasd = open(pathname, O_RDONLY | O_DIRECT)) == -1) { - /* Devicenode does not exist. Try to create one */ - if (mknod(pathname, 0600 | S_IFBLK, dev) == -1) { - /* Couldn't create a device node */ - return -1; - } -- fd_dasd = open(pathname, O_RDONLY); -+ fd_dasd = open(pathname, O_RDONLY | O_DIRECT); - /* - * The file will vanish when the last process (we) - * has ceased to access it. -@@ -175,7 +176,7 @@ read_dasd_pt(int fd, __attribute__((unused)) struct slice all, - * Get volume label, extract name and type. - */ - -- if (!(data = (unsigned char *)malloc(blocksize))) -+ if (aligned_malloc((void **)&data, blocksize, NULL)) - goto out; - - -diff --git a/kpartx/gpt.c b/kpartx/gpt.c -index 785b34ea..f7fefb70 100644 ---- a/kpartx/gpt.c -+++ b/kpartx/gpt.c -@@ -243,8 +243,7 @@ alloc_read_gpt_entries(int fd, gpt_header * gpt) - - if (!count) return NULL; - -- pte = (gpt_entry *)malloc(count); -- if (!pte) -+ if (aligned_malloc((void **)&pte, get_sector_size(fd), &count)) - return NULL; - memset(pte, 0, count); - -@@ -269,12 +268,11 @@ static gpt_header * - alloc_read_gpt_header(int fd, uint64_t lba) - { - gpt_header *gpt; -- gpt = (gpt_header *) -- malloc(sizeof (gpt_header)); -- if (!gpt) -+ size_t size = sizeof (gpt_header); -+ if (aligned_malloc((void **)&gpt, get_sector_size(fd), &size)) - return NULL; -- memset(gpt, 0, sizeof (*gpt)); -- if (!read_lba(fd, lba, gpt, sizeof (gpt_header))) { -+ memset(gpt, 0, size); -+ if (!read_lba(fd, lba, gpt, size)) { - free(gpt); - return NULL; - } -@@ -498,6 +496,7 @@ find_valid_gpt(int fd, gpt_header ** gpt, gpt_entry ** ptes) - gpt_header *pgpt = NULL, *agpt = NULL; - gpt_entry *pptes = NULL, *aptes = NULL; - legacy_mbr *legacymbr = NULL; -+ size_t size = sizeof(legacy_mbr); - uint64_t lastlba; - if (!gpt || !ptes) - return 0; -@@ -526,11 +525,10 @@ find_valid_gpt(int fd, gpt_header ** gpt, gpt_entry ** ptes) - } - - /* This will be added to the EFI Spec. per Intel after v1.02. */ -- legacymbr = malloc(sizeof (*legacymbr)); -- if (legacymbr) { -- memset(legacymbr, 0, sizeof (*legacymbr)); -- read_lba(fd, 0, (uint8_t *) legacymbr, -- sizeof (*legacymbr)); -+ if (aligned_malloc((void **)&legacymbr, get_sector_size(fd), -+ &size) == 0) { -+ memset(legacymbr, 0, size); -+ read_lba(fd, 0, (uint8_t *) legacymbr, size); - good_pmbr = is_pmbr_valid(legacymbr); - free(legacymbr); - legacymbr=NULL; -diff --git a/kpartx/kpartx.c b/kpartx/kpartx.c -index d3620c5c..c24ad6d9 100644 ---- a/kpartx/kpartx.c -+++ b/kpartx/kpartx.c -@@ -19,6 +19,7 @@ - * cva, 2002-10-26 - */ - -+#define _GNU_SOURCE - #include - #include - #include -@@ -41,7 +42,6 @@ - - #define SIZE(a) (sizeof(a)/sizeof((a)[0])) - --#define READ_SIZE 1024 - #define MAXTYPES 64 - #define MAXSLICES 256 - #define DM_TARGET "linear" -@@ -388,7 +388,7 @@ main(int argc, char **argv){ - set_delimiter(mapname, delim); - } - -- fd = open(device, O_RDONLY); -+ fd = open(device, O_RDONLY | O_DIRECT); - - if (fd == -1) { - perror(device); -@@ -690,9 +690,9 @@ xmalloc (size_t size) { - */ - - static int --sseek(int fd, unsigned int secnr) { -+sseek(int fd, unsigned int secnr, int secsz) { - off64_t in, out; -- in = ((off64_t) secnr << 9); -+ in = ((off64_t) secnr * secsz); - out = 1; - - if ((out = lseek64(fd, in, SEEK_SET)) != in) -@@ -703,6 +703,31 @@ sseek(int fd, unsigned int secnr) { - return 0; - } - -+int -+aligned_malloc(void **mem_p, size_t align, size_t *size_p) -+{ -+ static size_t pgsize = 0; -+ size_t size; -+ int err; -+ -+ if (!mem_p || !align || (size_p && !*size_p)) -+ return EINVAL; -+ -+ if (!pgsize) -+ pgsize = getpagesize(); -+ -+ if (size_p) -+ size = ((*size_p + align - 1) / align) * align; -+ else -+ size = pgsize; -+ -+ err = posix_memalign(mem_p, pgsize, size); -+ if (!err && size_p) -+ *size_p = size; -+ return err; -+} -+ -+/* always in sector size blocks */ - static - struct block { - unsigned int secnr; -@@ -710,30 +735,39 @@ struct block { - struct block *next; - } *blockhead; - -+/* blknr is always in 512 byte blocks */ - char * --getblock (int fd, unsigned int secnr) { -+getblock (int fd, unsigned int blknr) { -+ unsigned int secsz = get_sector_size(fd); -+ unsigned int blks_per_sec = secsz / 512; -+ unsigned int secnr = blknr / blks_per_sec; -+ unsigned int blk_off = (blknr % blks_per_sec) * 512; - struct block *bp; - - for (bp = blockhead; bp; bp = bp->next) - - if (bp->secnr == secnr) -- return bp->block; -+ return bp->block + blk_off; - -- if (sseek(fd, secnr)) -+ if (sseek(fd, secnr, secsz)) - return NULL; - - bp = xmalloc(sizeof(struct block)); - bp->secnr = secnr; - bp->next = blockhead; - blockhead = bp; -- bp->block = (char *) xmalloc(READ_SIZE); -+ if (aligned_malloc((void **)&bp->block, secsz, NULL)) { -+ fprintf(stderr, "aligned_malloc failed\n"); -+ exit(1); -+ } - -- if (read(fd, bp->block, READ_SIZE) != READ_SIZE) { -+ if (read(fd, bp->block, secsz) != secsz) { - fprintf(stderr, "read error, sector %d\n", secnr); -- bp->block = NULL; -+ blockhead = bp->next; -+ return NULL; - } - -- return bp->block; -+ return bp->block + blk_off; - } - - int -diff --git a/kpartx/kpartx.h b/kpartx/kpartx.h -index 67edeb82..727632c1 100644 ---- a/kpartx/kpartx.h -+++ b/kpartx/kpartx.h -@@ -1,6 +1,7 @@ - #ifndef _KPARTX_H - #define _KPARTX_H - -+#include - #include - #include - -@@ -61,6 +62,7 @@ extern ptreader read_mac_pt; - extern ptreader read_sun_pt; - extern ptreader read_ps3_pt; - -+int aligned_malloc(void **mem_p, size_t align, size_t *size_p); - char *getblock(int fd, unsigned int secnr); - - static inline unsigned int --- -2.17.2 - diff --git a/0038-multipath-tools-replace-hidden-tab-by-space-in-hwtab.patch b/0038-multipath-tools-replace-hidden-tab-by-space-in-hwtab.patch new file mode 100644 index 0000000..d51c502 --- /dev/null +++ b/0038-multipath-tools-replace-hidden-tab-by-space-in-hwtab.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Thu, 17 Dec 2020 16:49:38 +0100 +Subject: [PATCH] multipath-tools: replace hidden tab by space in hwtable + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Signed-off-by: Benjamin Marzinski +--- + libmultipath/hwtable.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index a54cc0a3..921aadc5 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -819,7 +819,7 @@ static struct hwentry default_hw[] = { + * + * The hwtable is searched backwards, so place this after "Generic NVMe" + */ +- .vendor = "NVME", ++ .vendor = "NVME", + .product = "^NetApp ONTAP Controller", + .pgpolicy = MULTIBUS, + .no_path_retry = NO_PATH_RETRY_QUEUE, +-- +2.17.2 + diff --git a/0039-kpartx-handle-alternate-bsd-disklabel-location.patch b/0039-kpartx-handle-alternate-bsd-disklabel-location.patch deleted file mode 100644 index 4b6e7e5..0000000 --- a/0039-kpartx-handle-alternate-bsd-disklabel-location.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 2 Jul 2020 19:38:26 -0500 -Subject: [PATCH] kpartx: handle alternate bsd disklabel location - -bsd disk labels can either be at the start of the second sector, or 64 -bytes into the first sector, but kpartx only handled the first case. -However the second case is what parted creates, and what the linux -kernel partition code expects. kpartx should handle both cases. - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - kpartx/bsd.c | 16 ++++++++++++++-- - 1 file changed, 14 insertions(+), 2 deletions(-) - -diff --git a/kpartx/bsd.c b/kpartx/bsd.c -index 0e661fbc..950b0f92 100644 ---- a/kpartx/bsd.c -+++ b/kpartx/bsd.c -@@ -1,6 +1,7 @@ - #include "kpartx.h" - #include - -+#define BSD_LABEL_OFFSET 64 - #define BSD_DISKMAGIC (0x82564557UL) /* The disk magic number */ - #define XBSD_MAXPARTITIONS 16 - #define BSD_FS_UNUSED 0 -@@ -60,8 +61,19 @@ read_bsd_pt(int fd, struct slice all, struct slice *sp, unsigned int ns) { - return -1; - - l = (struct bsd_disklabel *) bp; -- if (l->d_magic != BSD_DISKMAGIC) -- return -1; -+ if (l->d_magic != BSD_DISKMAGIC) { -+ /* -+ * BSD disklabels can also start 64 bytes offset from the -+ * start of the first sector -+ */ -+ bp = getblock(fd, offset); -+ if (bp == NULL) -+ return -1; -+ -+ l = (struct bsd_disklabel *)(bp + 64); -+ if (l->d_magic != BSD_DISKMAGIC) -+ return -1; -+ } - - max_partitions = 16; - if (l->d_npartitions < max_partitions) --- -2.17.2 - diff --git a/0039-multipathd-uxlsnr-avoid-deadlock-on-exit.patch b/0039-multipathd-uxlsnr-avoid-deadlock-on-exit.patch new file mode 100644 index 0000000..6f4fc00 --- /dev/null +++ b/0039-multipathd-uxlsnr-avoid-deadlock-on-exit.patch @@ -0,0 +1,105 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 22 Sep 2020 20:59:25 +0200 +Subject: [PATCH] multipathd: uxlsnr: avoid deadlock on exit + +The uxlsnr wouldn't always release the client lock when cancelled, +causing a deadlock in uxsock_cleanup(). While this hasn't been +caused by commit 3d611a2, the deadlock seems to have become much +more likely after that patch. Solving this means that we have to +treat reallocation failure of the pollfd array differently. +We will now just ignore any clients above the last valid pfd index. +That's a minor problem, as we're in an OOM situation anyway. + +Moreover, client_lock is not a "struct lock", but a plain +pthread_mutex_t. + +Fixes: 3d611a2 ("multipathd: cancel threads early during shutdown") +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipathd/uxlsnr.c | 24 ++++++++++++++---------- + 1 file changed, 14 insertions(+), 10 deletions(-) + +diff --git a/multipathd/uxlsnr.c b/multipathd/uxlsnr.c +index 1c5ce9d2..ce2b6800 100644 +--- a/multipathd/uxlsnr.c ++++ b/multipathd/uxlsnr.c +@@ -35,6 +35,7 @@ + #include "config.h" + #include "mpath_cmd.h" + #include "time-util.h" ++#include "util.h" + + #include "main.h" + #include "cli.h" +@@ -116,7 +117,7 @@ static void _dead_client(struct client *c) + + static void dead_client(struct client *c) + { +- pthread_cleanup_push(cleanup_lock, &client_lock); ++ pthread_cleanup_push(cleanup_mutex, &client_lock); + pthread_mutex_lock(&client_lock); + _dead_client(c); + pthread_cleanup_pop(1); +@@ -302,10 +303,11 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, long ux_sock, + sigdelset(&mask, SIGUSR1); + while (1) { + struct client *c, *tmp; +- int i, poll_count, num_clients; ++ int i, n_pfds, poll_count, num_clients; + + /* setup for a poll */ + pthread_mutex_lock(&client_lock); ++ pthread_cleanup_push(cleanup_mutex, &client_lock); + num_clients = 0; + list_for_each_entry(c, &clients, node) { + num_clients++; +@@ -322,14 +324,13 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, long ux_sock, + sizeof(struct pollfd)); + } + if (!new) { +- pthread_mutex_unlock(&client_lock); + condlog(0, "%s: failed to realloc %d poll fds", + "uxsock", 2 + num_clients); +- sched_yield(); +- continue; ++ num_clients = old_clients; ++ } else { ++ old_clients = num_clients; ++ polls = new; + } +- old_clients = num_clients; +- polls = new; + } + polls[0].fd = ux_sock; + polls[0].events = POLLIN; +@@ -347,11 +348,14 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, long ux_sock, + polls[i].fd = c->fd; + polls[i].events = POLLIN; + i++; ++ if (i >= 2 + num_clients) ++ break; + } +- pthread_mutex_unlock(&client_lock); ++ n_pfds = i; ++ pthread_cleanup_pop(1); + + /* most of our life is spent in this call */ +- poll_count = ppoll(polls, i, &sleep_time, &mask); ++ poll_count = ppoll(polls, n_pfds, &sleep_time, &mask); + + handle_signals(false); + if (poll_count == -1) { +@@ -384,7 +388,7 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, long ux_sock, + } + + /* see if a client wants to speak to us */ +- for (i = 2; i < num_clients + 2; i++) { ++ for (i = 2; i < n_pfds; i++) { + if (polls[i].revents & POLLIN) { + struct timespec start_time; + +-- +2.17.2 + diff --git a/0040-libmultipath-fix-checker-detection-for-nvme-devices.patch b/0040-libmultipath-fix-checker-detection-for-nvme-devices.patch deleted file mode 100644 index 1054e30..0000000 --- a/0040-libmultipath-fix-checker-detection-for-nvme-devices.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 2 Jul 2020 19:38:27 -0500 -Subject: [PATCH] libmultipath: fix checker detection for nvme devices - -In order to fix hwhandler autodetection, commit 8794a776 made -detect_alua() differentiate between failures to detect whether alua was -supported, and successfully detecting that it was not supported. -However, this causes nvme devices to get the TUR checker assigned to -them. This is because there is nothing in detect_alua() to make it only -work on scsi devices, and select_checker wasn't updated to handle -detect_alua() failing without setting pp->tpgs to TPGS_NONE. - -detect_alua() should automatically set pp->tpgs to TPGS_NONE and exit on -non-scsi devices. Also, select_checker() should not assume that a -devices is ALUA, simply because if failed to detect if alua was -supported. - -Fixes: 8794a776 "libmultipath: fix ALUA autodetection when paths are - down" -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/discovery.c | 6 ++++++ - libmultipath/propsel.c | 4 +++- - 2 files changed, 9 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 83a41a4a..aa5942c3 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -887,6 +887,12 @@ detect_alua(struct path * pp) - int tpgs; - unsigned int timeout; - -+ -+ if (pp->bus != SYSFS_BUS_SCSI) { -+ pp->tpgs = TPGS_NONE; -+ return; -+ } -+ - if (sysfs_get_timeout(pp, &timeout) <= 0) - timeout = DEF_TIMEOUT; - -diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c -index 897e48ca..d362beb4 100644 ---- a/libmultipath/propsel.c -+++ b/libmultipath/propsel.c -@@ -521,7 +521,9 @@ int select_checker(struct config *conf, struct path *pp) - if (check_rdac(pp)) { - ckr_name = RDAC; - goto out; -- } else if (path_get_tpgs(pp) != TPGS_NONE) { -+ } -+ path_get_tpgs(pp); -+ if (pp->tpgs != TPGS_NONE && pp->tpgs != TPGS_UNDEF) { - ckr_name = TUR; - goto out; - } --- -2.17.2 - diff --git a/0040-multipathd-Fix-liburcu-memory-leak.patch b/0040-multipathd-Fix-liburcu-memory-leak.patch new file mode 100644 index 0000000..8f04a66 --- /dev/null +++ b/0040-multipathd-Fix-liburcu-memory-leak.patch @@ -0,0 +1,98 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 23 Sep 2020 18:02:39 +0200 +Subject: [PATCH] multipathd: Fix liburcu memory leak + +Fix this leak in multipathd, reported by valgrind, that messes up +multipathd's otherwise clean leak report: + +==23823== 336 bytes in 1 blocks are possibly lost in loss record 3 of 3 +==23823== at 0x483AB65: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) +==23823== by 0x4012F16: _dl_allocate_tls (in /lib64/ld-2.31.so) +==23823== by 0x493BB8E: pthread_create@@GLIBC_2.2.5 (in /lib64/libpthread-2.31.so) +==23823== by 0x492A9A9: call_rcu_data_init (urcu-call-rcu-impl.h:437) +==23823== by 0x492AD2F: UnknownInlinedFun (urcu-call-rcu-impl.h:492) +==23823== by 0x492AD2F: create_call_rcu_data_memb (urcu-call-rcu-impl.h:504) +==23823== by 0x1164E3: child.constprop.0.isra.0 (main.c:2915) +==23823== by 0x10F50C: main (main.c:3335) +==23823== +==23823== LEAK SUMMARY: +==23823== definitely lost: 0 bytes in 0 blocks +==23823== indirectly lost: 0 bytes in 0 blocks +==23823== possibly lost: 336 bytes in 1 blocks + +The problem is caused by using liburcu's default RCU call handler, +which liburcu refuses to stop/join. See comments in the code. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 44 insertions(+), 1 deletion(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index c5c374b7..ce14bb66 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -2889,6 +2889,48 @@ set_oom_adj (void) + condlog(0, "couldn't adjust oom score"); + } + ++/* ++ * Use a non-default call_rcu_data for child(). ++ * ++ * We do this to avoid a memory leak from liburcu. ++ * liburcu never frees the default rcu handler (see comments on ++ * call_rcu_data_free() in urcu-call-rcu-impl.h), its thread ++ * can't be joined with pthread_join(), leaving a memory leak. ++ * ++ * Therefore we create our own, which can be destroyed and joined. ++ */ ++static struct call_rcu_data *setup_rcu(void) ++{ ++ struct call_rcu_data *crdp; ++ ++ rcu_init(); ++ rcu_register_thread(); ++ crdp = create_call_rcu_data(0UL, -1); ++ if (crdp != NULL) ++ set_thread_call_rcu_data(crdp); ++ return crdp; ++} ++ ++static struct call_rcu_data *mp_rcu_data; ++ ++static void cleanup_rcu(void) ++{ ++ pthread_t rcu_thread; ++ ++ /* Wait for any pending RCU calls */ ++ rcu_barrier(); ++ if (mp_rcu_data != NULL) { ++ rcu_thread = get_call_rcu_thread(mp_rcu_data); ++ /* detach this thread from the RCU thread */ ++ set_thread_call_rcu_data(NULL); ++ synchronize_rcu(); ++ /* tell RCU thread to exit */ ++ call_rcu_data_free(mp_rcu_data); ++ pthread_join(rcu_thread, NULL); ++ } ++ rcu_unregister_thread(); ++} ++ + static int + child (__attribute__((unused)) void *param) + { +@@ -2906,7 +2948,8 @@ child (__attribute__((unused)) void *param) + + mlockall(MCL_CURRENT | MCL_FUTURE); + signal_init(); +- rcu_init(); ++ mp_rcu_data = setup_rcu(); ++ atexit(cleanup_rcu); + + setup_thread_attr(&misc_attr, 64 * 1024, 0); + setup_thread_attr(&uevent_attr, DEFAULT_UEVENT_STACKSIZE * 1024, 0); +-- +2.17.2 + diff --git a/0041-libmultipath-make-dm_get_map-status-return-codes-sym.patch b/0041-libmultipath-make-dm_get_map-status-return-codes-sym.patch deleted file mode 100644 index 91c9a8b..0000000 --- a/0041-libmultipath-make-dm_get_map-status-return-codes-sym.patch +++ /dev/null @@ -1,322 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 2 Jul 2020 19:07:00 -0500 -Subject: [PATCH] libmultipath: make dm_get_map/status return codes symbolic - -dm_get_map() and dm_get_status() now use symbolic return codes. They -also differentiate between failing to get information from device-mapper -and not finding the requested device. These symboilc return codes are -also used by update_multipath_* functions. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/devmapper.c | 51 +++++++++++++++++++++++++------------- - libmultipath/devmapper.h | 6 +++++ - libmultipath/structs_vec.c | 45 +++++++++++++++++++-------------- - multipathd/main.c | 12 ++++----- - 4 files changed, 72 insertions(+), 42 deletions(-) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index 27d52398..24cc616a 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -534,36 +534,43 @@ int dm_map_present(const char * str) - - int dm_get_map(const char *name, unsigned long long *size, char *outparams) - { -- int r = 1; -+ int r = DMP_ERR; - struct dm_task *dmt; - uint64_t start, length; - char *target_type = NULL; - char *params = NULL; - - if (!(dmt = libmp_dm_task_create(DM_DEVICE_TABLE))) -- return 1; -+ return r; - - if (!dm_task_set_name(dmt, name)) - goto out; - - dm_task_no_open_count(dmt); - -- if (!dm_task_run(dmt)) -+ errno = 0; -+ if (!dm_task_run(dmt)) { -+ if (dm_task_get_errno(dmt) == ENXIO) -+ r = DMP_NOT_FOUND; - goto out; -+ } - -+ r = DMP_NOT_FOUND; - /* Fetch 1st target */ -- dm_get_next_target(dmt, NULL, &start, &length, -- &target_type, ¶ms); -+ if (dm_get_next_target(dmt, NULL, &start, &length, -+ &target_type, ¶ms) != NULL) -+ /* more than one target */ -+ goto out; - - if (size) - *size = length; - - if (!outparams) { -- r = 0; -+ r = DMP_OK; - goto out; - } - if (snprintf(outparams, PARAMS_SIZE, "%s", params) <= PARAMS_SIZE) -- r = 0; -+ r = DMP_OK; - out: - dm_task_destroy(dmt); - return r; -@@ -637,35 +644,45 @@ is_mpath_part(const char *part_name, const char *map_name) - - int dm_get_status(const char *name, char *outstatus) - { -- int r = 1; -+ int r = DMP_ERR; - struct dm_task *dmt; - uint64_t start, length; - char *target_type = NULL; - char *status = NULL; - - if (!(dmt = libmp_dm_task_create(DM_DEVICE_STATUS))) -- return 1; -+ return r; - - if (!dm_task_set_name(dmt, name)) - goto out; - - dm_task_no_open_count(dmt); - -- if (!dm_task_run(dmt)) -+ errno = 0; -+ if (!dm_task_run(dmt)) { -+ if (dm_task_get_errno(dmt) == ENXIO) -+ r = DMP_NOT_FOUND; - goto out; -+ } - -+ r = DMP_NOT_FOUND; - /* Fetch 1st target */ -- dm_get_next_target(dmt, NULL, &start, &length, -- &target_type, &status); -+ if (dm_get_next_target(dmt, NULL, &start, &length, -+ &target_type, &status) != NULL) -+ goto out; -+ -+ if (!target_type || strcmp(target_type, TGT_MPATH) != 0) -+ goto out; -+ - if (!status) { - condlog(2, "get null status."); - goto out; - } - - if (snprintf(outstatus, PARAMS_SIZE, "%s", status) <= PARAMS_SIZE) -- r = 0; -+ r = DMP_OK; - out: -- if (r) -+ if (r != DMP_OK) - condlog(0, "%s: error getting map status string", name); - - dm_task_destroy(dmt); -@@ -920,7 +937,7 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, - return 1; - - if (need_suspend && -- !dm_get_map(mapname, &mapsize, params) && -+ dm_get_map(mapname, &mapsize, params) == DMP_OK && - strstr(params, "queue_if_no_path")) { - if (!dm_queue_if_no_path(mapname, 0)) - queue_if_no_path = 1; -@@ -1129,7 +1146,7 @@ struct multipath *dm_get_multipath(const char *name) - if (!mpp->alias) - goto out; - -- if (dm_get_map(name, &mpp->size, NULL)) -+ if (dm_get_map(name, &mpp->size, NULL) != DMP_OK) - goto out; - - dm_get_uuid(name, mpp->wwid, WWID_SIZE); -@@ -1313,7 +1330,7 @@ do_foreach_partmaps (const char * mapname, - /* - * and we can fetch the map table from the kernel - */ -- !dm_get_map(names->name, &size, ¶ms[0]) && -+ dm_get_map(names->name, &size, ¶ms[0]) == DMP_OK && - - /* - * and the table maps over the multipath map -diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h -index 5ed7edc5..b2108638 100644 ---- a/libmultipath/devmapper.h -+++ b/libmultipath/devmapper.h -@@ -27,6 +27,12 @@ - #define UUID_PREFIX "mpath-" - #define UUID_PREFIX_LEN (sizeof(UUID_PREFIX) - 1) - -+enum { -+ DMP_ERR, -+ DMP_OK, -+ DMP_NOT_FOUND, -+}; -+ - void dm_init(int verbosity); - int dm_prereq(unsigned int *v); - void skip_libmp_dm_init(void); -diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c -index 077f2e42..8137ea21 100644 ---- a/libmultipath/structs_vec.c -+++ b/libmultipath/structs_vec.c -@@ -196,43 +196,47 @@ extract_hwe_from_path(struct multipath * mpp) - int - update_multipath_table (struct multipath *mpp, vector pathvec, int is_daemon) - { -+ int r = DMP_ERR; - char params[PARAMS_SIZE] = {0}; - - if (!mpp) -- return 1; -+ return r; - -- if (dm_get_map(mpp->alias, &mpp->size, params)) { -- condlog(3, "%s: cannot get map", mpp->alias); -- return 1; -+ r = dm_get_map(mpp->alias, &mpp->size, params); -+ if (r != DMP_OK) { -+ condlog(3, "%s: %s", mpp->alias, (r == DMP_ERR)? "error getting table" : "map not present"); -+ return r; - } - - if (disassemble_map(pathvec, params, mpp, is_daemon)) { - condlog(3, "%s: cannot disassemble map", mpp->alias); -- return 1; -+ return DMP_ERR; - } - -- return 0; -+ return DMP_OK; - } - - int - update_multipath_status (struct multipath *mpp) - { -+ int r = DMP_ERR; - char status[PARAMS_SIZE] = {0}; - - if (!mpp) -- return 1; -+ return r; - -- if (dm_get_status(mpp->alias, status)) { -- condlog(3, "%s: cannot get status", mpp->alias); -- return 1; -+ r = dm_get_status(mpp->alias, status); -+ if (r != DMP_OK) { -+ condlog(3, "%s: %s", mpp->alias, (r == DMP_ERR)? "error getting status" : "map not present"); -+ return r; - } - - if (disassemble_status(status, mpp)) { - condlog(3, "%s: cannot disassemble status", mpp->alias); -- return 1; -+ return DMP_ERR; - } - -- return 0; -+ return DMP_OK; - } - - void sync_paths(struct multipath *mpp, vector pathvec) -@@ -264,10 +268,10 @@ int - update_multipath_strings(struct multipath *mpp, vector pathvec, int is_daemon) - { - struct pathgroup *pgp; -- int i; -+ int i, r = DMP_ERR; - - if (!mpp) -- return 1; -+ return r; - - update_mpp_paths(mpp, pathvec); - condlog(4, "%s: %s", mpp->alias, __FUNCTION__); -@@ -276,18 +280,21 @@ update_multipath_strings(struct multipath *mpp, vector pathvec, int is_daemon) - free_pgvec(mpp->pg, KEEP_PATHS); - mpp->pg = NULL; - -- if (update_multipath_table(mpp, pathvec, is_daemon)) -- return 1; -+ r = update_multipath_table(mpp, pathvec, is_daemon); -+ if (r != DMP_OK) -+ return r; -+ - sync_paths(mpp, pathvec); - -- if (update_multipath_status(mpp)) -- return 1; -+ r = update_multipath_status(mpp); -+ if (r != DMP_OK) -+ return r; - - vector_foreach_slot(mpp->pg, pgp, i) - if (pgp->paths) - path_group_prio_update(pgp); - -- return 0; -+ return DMP_OK; - } - - static void enter_recovery_mode(struct multipath *mpp) -diff --git a/multipathd/main.c b/multipathd/main.c -index 205ddb32..ab141fed 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -418,7 +418,7 @@ int __setup_multipath(struct vectors *vecs, struct multipath *mpp, - goto out; - } - -- if (update_multipath_strings(mpp, vecs->pathvec, 1)) { -+ if (update_multipath_strings(mpp, vecs->pathvec, 1) != DMP_OK) { - condlog(0, "%s: failed to setup multipath", mpp->alias); - goto out; - } -@@ -557,9 +557,9 @@ add_map_without_path (struct vectors *vecs, const char *alias) - mpp->mpe = find_mpe(conf->mptable, mpp->wwid); - put_multipath_config(conf); - -- if (update_multipath_table(mpp, vecs->pathvec, 1)) -+ if (update_multipath_table(mpp, vecs->pathvec, 1) != DMP_OK) - goto out; -- if (update_multipath_status(mpp)) -+ if (update_multipath_status(mpp) != DMP_OK) - goto out; - - if (!vector_alloc_slot(vecs->mpvec)) -@@ -1350,8 +1350,8 @@ map_discovery (struct vectors * vecs) - return 1; - - vector_foreach_slot (vecs->mpvec, mpp, i) -- if (update_multipath_table(mpp, vecs->pathvec, 1) || -- update_multipath_status(mpp)) { -+ if (update_multipath_table(mpp, vecs->pathvec, 1) != DMP_OK || -+ update_multipath_status(mpp) != DMP_OK) { - remove_map(mpp, vecs, 1); - i--; - } -@@ -2091,7 +2091,7 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) - /* - * Synchronize with kernel state - */ -- if (update_multipath_strings(pp->mpp, vecs->pathvec, 1)) { -+ if (update_multipath_strings(pp->mpp, vecs->pathvec, 1) != DMP_OK) { - condlog(1, "%s: Could not synchronize with kernel state", - pp->dev); - pp->dmstate = PSTATE_UNDEF; --- -2.17.2 - diff --git a/0041-multipathd-move-handling-of-io_err_stat_attr-into-li.patch b/0041-multipathd-move-handling-of-io_err_stat_attr-into-li.patch new file mode 100644 index 0000000..329876d --- /dev/null +++ b/0041-multipathd-move-handling-of-io_err_stat_attr-into-li.patch @@ -0,0 +1,146 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 23 Sep 2020 10:33:12 +0200 +Subject: [PATCH] multipathd: move handling of io_err_stat_attr into + libmultipath + +This thread attribute can be dynamically initialized and destroyed. +No need to carry it along in multipathd. Removal of the symbol +requires to bump the ABI version to 3. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/io_err_stat.c | 7 +++++-- + libmultipath/libmultipath.version | 23 ++++++++--------------- + multipathd/main.c | 2 -- + 3 files changed, 13 insertions(+), 19 deletions(-) + +diff --git a/libmultipath/io_err_stat.c b/libmultipath/io_err_stat.c +index 58bc1dd2..5363049d 100644 +--- a/libmultipath/io_err_stat.c ++++ b/libmultipath/io_err_stat.c +@@ -34,6 +34,7 @@ + #include "lock.h" + #include "time-util.h" + #include "io_err_stat.h" ++#include "util.h" + + #define TIMEOUT_NO_IO_NSEC 10000000 /*10ms = 10000000ns*/ + #define FLAKY_PATHFAIL_THRESHOLD 2 +@@ -70,8 +71,7 @@ struct io_err_stat_path { + int err_rate_threshold; + }; + +-pthread_t io_err_stat_thr; +-pthread_attr_t io_err_stat_attr; ++static pthread_t io_err_stat_thr; + + static pthread_mutex_t io_err_thread_lock = PTHREAD_MUTEX_INITIALIZER; + static pthread_cond_t io_err_thread_cond = PTHREAD_COND_INITIALIZER; +@@ -727,6 +727,7 @@ static void *io_err_stat_loop(void *data) + int start_io_err_stat_thread(void *data) + { + int ret; ++ pthread_attr_t io_err_stat_attr; + + if (uatomic_read(&io_err_thread_running) == 1) + return 0; +@@ -739,6 +740,7 @@ int start_io_err_stat_thread(void *data) + if (!paths) + goto destroy_ctx; + ++ setup_thread_attr(&io_err_stat_attr, 32 * 1024, 0); + pthread_mutex_lock(&io_err_thread_lock); + pthread_cleanup_push(cleanup_unlock, &io_err_thread_lock); + +@@ -750,6 +752,7 @@ int start_io_err_stat_thread(void *data) + &io_err_thread_lock) == 0); + + pthread_cleanup_pop(1); ++ pthread_attr_destroy(&io_err_stat_attr); + + if (ret) { + io_err_stat_log(0, "cannot create io_error statistic thread"); +diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version +index 0c300c81..84beb7f0 100644 +--- a/libmultipath/libmultipath.version ++++ b/libmultipath/libmultipath.version +@@ -31,7 +31,7 @@ + * The new version inherits the previous ones. + */ + +-LIBMULTIPATH_2.0.0 { ++LIBMULTIPATH_3.0.0 { + global: + /* symbols referenced by multipath and multipathd */ + add_foreign; +@@ -121,7 +121,6 @@ global: + init_checkers; + init_foreign; + init_prio; +- io_err_stat_attr; + io_err_stat_handle_pathfail; + is_path_valid; + is_quote; +@@ -242,30 +241,24 @@ global: + free_scandir_result; + sysfs_attr_get_value; + +-local: +- *; +-}; +- +-LIBMULTIPATH_2.1.0 { +-global: ++ /* added in 2.1.0 */ + libmp_dm_task_run; + cleanup_mutex; +-} LIBMULTIPATH_2.0.0; + +-LIBMULTIPATH_2.2.0 { +-global: ++ /* added in 2.2.0 */ + libmp_get_multipath_config; + get_multipath_config; + libmp_put_multipath_config; + put_multipath_config; + init_config; + uninit_config; +-} LIBMULTIPATH_2.1.0; + +-LIBMULTIPATH_2.3.0 { +-global: ++ /* added in 2.3.0 */ + udev; + logsink; + libmultipath_init; + libmultipath_exit; +-} LIBMULTIPATH_2.2.0; ++ ++local: ++ *; ++}; +diff --git a/multipathd/main.c b/multipathd/main.c +index ce14bb66..abc6a9f7 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -2954,7 +2954,6 @@ child (__attribute__((unused)) void *param) + setup_thread_attr(&misc_attr, 64 * 1024, 0); + setup_thread_attr(&uevent_attr, DEFAULT_UEVENT_STACKSIZE * 1024, 0); + setup_thread_attr(&waiter_attr, 32 * 1024, 1); +- setup_thread_attr(&io_err_stat_attr, 32 * 1024, 0); + + if (logsink == 1) { + setup_thread_attr(&log_attr, 64 * 1024, 0); +@@ -3164,7 +3163,6 @@ child (__attribute__((unused)) void *param) + rcu_assign_pointer(multipath_conf, NULL); + call_rcu(&conf->rcu, rcu_free_config); + pthread_attr_destroy(&waiter_attr); +- pthread_attr_destroy(&io_err_stat_attr); + #ifdef _DEBUG_ + dbg_free_final(NULL); + #endif +-- +2.17.2 + diff --git a/0042-multipathd-fix-check_path-errors-with-removed-map.patch b/0042-multipathd-fix-check_path-errors-with-removed-map.patch deleted file mode 100644 index 155e93a..0000000 --- a/0042-multipathd-fix-check_path-errors-with-removed-map.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 2 Jul 2020 19:07:01 -0500 -Subject: [PATCH] multipathd: fix check_path errors with removed map - -If a multipath device is removed during, or immediately before the call -to check_path(), multipathd can behave incorrectly. A missing multpath -device will cause update_multipath_strings() to fail, setting -pp->dmstate to PSTATE_UNDEF. If the path is up, this state will cause -reinstate_path() to be called, which will also fail. This will trigger -a reload, restoring the recently removed device. - -If update_multipath_strings() fails because there is no multipath -device, check_path should just quit, since the remove dmevent and uevent -are likely already queued up. Also, I don't see any reason to reload the -multipath device if reinstate fails. This code was added by -fac68d7a99ef17d496079538a5c6836acd7911ab, which clamined that reinstate -could fail if the path was disabled. Looking through the current kernel -code, I can't see any reason why a reinstate would fail, where a reload -would help. If the path was missing from the multipath device, -update_multipath_strings() would already catch that, and quit -check_path() early, which make more sense to me than reloading does. - -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 44 +++++++++++++++++++------------------------- - 1 file changed, 19 insertions(+), 25 deletions(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index ab141fed..daf19a4e 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -1615,22 +1615,18 @@ fail_path (struct path * pp, int del_active) - /* - * caller must have locked the path list before calling that function - */ --static int -+static void - reinstate_path (struct path * pp) - { -- int ret = 0; -- - if (!pp->mpp) -- return 0; -+ return; - -- if (dm_reinstate_path(pp->mpp->alias, pp->dev_t)) { -+ if (dm_reinstate_path(pp->mpp->alias, pp->dev_t)) - condlog(0, "%s: reinstate failed", pp->dev_t); -- ret = 1; -- } else { -+ else { - condlog(2, "%s: reinstated", pp->dev_t); - update_queue_mode_add_path(pp->mpp); - } -- return ret; - } - - static void -@@ -2091,9 +2087,16 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) - /* - * Synchronize with kernel state - */ -- if (update_multipath_strings(pp->mpp, vecs->pathvec, 1) != DMP_OK) { -- condlog(1, "%s: Could not synchronize with kernel state", -- pp->dev); -+ ret = update_multipath_strings(pp->mpp, vecs->pathvec, 1); -+ if (ret != DMP_OK) { -+ if (ret == DMP_NOT_FOUND) { -+ /* multipath device missing. Likely removed */ -+ condlog(1, "%s: multipath device '%s' not found", -+ pp->dev, pp->mpp->alias); -+ return 0; -+ } else -+ condlog(1, "%s: Couldn't synchronize with kernel state", -+ pp->dev); - pp->dmstate = PSTATE_UNDEF; - } - /* if update_multipath_strings orphaned the path, quit early */ -@@ -2183,12 +2186,8 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) - /* - * reinstate this path - */ -- if (!disable_reinstate && reinstate_path(pp)) { -- condlog(3, "%s: reload map", pp->dev); -- ev_add_path(pp, vecs, 1); -- pp->tick = 1; -- return 0; -- } -+ if (!disable_reinstate) -+ reinstate_path(pp); - new_path_up = 1; - - if (oldchkrstate != PATH_UP && oldchkrstate != PATH_GHOST) -@@ -2204,15 +2203,10 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) - else if (newstate == PATH_UP || newstate == PATH_GHOST) { - if ((pp->dmstate == PSTATE_FAILED || - pp->dmstate == PSTATE_UNDEF) && -- !disable_reinstate) { -+ !disable_reinstate) - /* Clear IO errors */ -- if (reinstate_path(pp)) { -- condlog(3, "%s: reload map", pp->dev); -- ev_add_path(pp, vecs, 1); -- pp->tick = 1; -- return 0; -- } -- } else { -+ reinstate_path(pp); -+ else { - LOG_MSG(4, verbosity, pp); - if (pp->checkint != max_checkint) { - /* --- -2.17.2 - diff --git a/0042-multipathd-move-vecs-desctruction-into-cleanup-funct.patch b/0042-multipathd-move-vecs-desctruction-into-cleanup-funct.patch new file mode 100644 index 0000000..f65e6eb --- /dev/null +++ b/0042-multipathd-move-vecs-desctruction-into-cleanup-funct.patch @@ -0,0 +1,125 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 23 Sep 2020 18:05:40 +0200 +Subject: [PATCH] multipathd: move vecs desctruction into cleanup function + +This will make it easer to move the stuff around later. +The only functional change is that map destuction now happens after +joining all threads, which should actually improve robustness. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 64 +++++++++++++++++++++++++++++------------------ + 1 file changed, 40 insertions(+), 24 deletions(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index abc6a9f7..3da0d7cc 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -148,7 +148,7 @@ int should_exit(void) + /* + * global copy of vecs for use in sig handlers + */ +-struct vectors * gvecs; ++static struct vectors * gvecs; + + struct config *multipath_conf; + +@@ -2889,6 +2889,44 @@ set_oom_adj (void) + condlog(0, "couldn't adjust oom score"); + } + ++static void cleanup_maps(struct vectors *vecs) ++{ ++ int queue_without_daemon, i; ++ struct multipath *mpp; ++ struct config *conf; ++ ++ conf = get_multipath_config(); ++ queue_without_daemon = conf->queue_without_daemon; ++ put_multipath_config(conf); ++ if (queue_without_daemon == QUE_NO_DAEMON_OFF) ++ vector_foreach_slot(vecs->mpvec, mpp, i) ++ dm_queue_if_no_path(mpp->alias, 0); ++ remove_maps_and_stop_waiters(vecs); ++ vecs->mpvec = NULL; ++} ++ ++static void cleanup_paths(struct vectors *vecs) ++{ ++ free_pathvec(vecs->pathvec, FREE_PATHS); ++ vecs->pathvec = NULL; ++} ++ ++static void cleanup_vecs(void) ++{ ++ if (!gvecs) ++ return; ++ /* ++ * We can't take the vecs lock here, because exit() may ++ * have been called from the child() thread, holding the lock already. ++ * Anyway, by the time we get here, all threads that might access ++ * vecs should have been joined already (in cleanup_threads). ++ */ ++ cleanup_maps(gvecs); ++ cleanup_paths(gvecs); ++ pthread_mutex_destroy(&gvecs->lock.mutex); ++ FREE(gvecs); ++} ++ + /* + * Use a non-default call_rcu_data for child(). + * +@@ -2937,13 +2975,10 @@ child (__attribute__((unused)) void *param) + pthread_t check_thr, uevent_thr, uxlsnr_thr, uevq_thr, dmevent_thr; + pthread_attr_t log_attr, misc_attr, uevent_attr; + struct vectors * vecs; +- struct multipath * mpp; +- int i; + int rc; + int pid_fd = -1; + struct config *conf; + char *envp; +- int queue_without_daemon; + enum daemon_status state; + + mlockall(MCL_CURRENT | MCL_FUTURE); +@@ -3108,17 +3143,6 @@ child (__attribute__((unused)) void *param) + if (poll_dmevents) + pthread_cancel(dmevent_thr); + +- conf = get_multipath_config(); +- queue_without_daemon = conf->queue_without_daemon; +- put_multipath_config(conf); +- +- lock(&vecs->lock); +- if (queue_without_daemon == QUE_NO_DAEMON_OFF) +- vector_foreach_slot(vecs->mpvec, mpp, i) +- dm_queue_if_no_path(mpp->alias, 0); +- remove_maps_and_stop_waiters(vecs); +- unlock(&vecs->lock); +- + pthread_join(check_thr, NULL); + pthread_join(uevent_thr, NULL); + pthread_join(uxlsnr_thr, NULL); +@@ -3128,15 +3152,7 @@ child (__attribute__((unused)) void *param) + + stop_io_err_stat_thread(); + +- lock(&vecs->lock); +- free_pathvec(vecs->pathvec, FREE_PATHS); +- vecs->pathvec = NULL; +- unlock(&vecs->lock); +- +- pthread_mutex_destroy(&vecs->lock.mutex); +- FREE(vecs); +- vecs = NULL; +- ++ cleanup_vecs(); + cleanup_foreign(); + cleanup_checkers(); + cleanup_prio(); +-- +2.17.2 + diff --git a/0043-libmultipath-make-dm_flush_maps-only-return-0-on-suc.patch b/0043-libmultipath-make-dm_flush_maps-only-return-0-on-suc.patch deleted file mode 100644 index 4dce980..0000000 --- a/0043-libmultipath-make-dm_flush_maps-only-return-0-on-suc.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 2 Jul 2020 19:07:02 -0500 -Subject: [PATCH] libmultipath: make dm_flush_maps only return 0 on success - -dm_flush_maps() returned both 0 and 1 on error, depending on which part -of the function it was in, but the caller was always treating 0 as a -success. Make dm_flush_maps() always return 1 on error and 0 on success. - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/devmapper.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index 24cc616a..4c86b6d4 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -1007,13 +1007,13 @@ dm_flush_map_nopaths(const char * mapname, int deferred_remove) - - int dm_flush_maps (int retries) - { -- int r = 0; -+ int r = 1; - struct dm_task *dmt; - struct dm_names *names; - unsigned next = 0; - - if (!(dmt = libmp_dm_task_create (DM_DEVICE_LIST))) -- return 0; -+ return r; - - dm_task_no_open_count(dmt); - -@@ -1026,6 +1026,7 @@ int dm_flush_maps (int retries) - if (!names->dev) - goto out; - -+ r = 0; - do { - r |= dm_suspend_and_flush_map(names->name, retries); - next = names->next; --- -2.17.2 - diff --git a/0043-multipathd-make-some-globals-static.patch b/0043-multipathd-make-some-globals-static.patch new file mode 100644 index 0000000..6ae5835 --- /dev/null +++ b/0043-multipathd-make-some-globals-static.patch @@ -0,0 +1,45 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 23 Sep 2020 11:18:02 +0200 +Subject: [PATCH] multipathd: make some globals static + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 3da0d7cc..eb760a71 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -116,19 +116,19 @@ struct mpath_event_param + }; + + int uxsock_timeout; +-int verbosity; +-int bindings_read_only; ++static int verbosity; ++static int bindings_read_only; + int ignore_new_devs; + #ifdef NO_DMEVENTS_POLL +-int poll_dmevents = 0; ++static int poll_dmevents = 0; + #else +-int poll_dmevents = 1; ++static int poll_dmevents = 1; + #endif + /* Don't access this variable without holding config_lock */ +-volatile enum daemon_status running_state = DAEMON_INIT; ++static volatile enum daemon_status running_state = DAEMON_INIT; + pid_t daemon_pid; +-pthread_mutex_t config_lock = PTHREAD_MUTEX_INITIALIZER; +-pthread_cond_t config_cond; ++static pthread_mutex_t config_lock = PTHREAD_MUTEX_INITIALIZER; ++static pthread_cond_t config_cond; + + static inline enum daemon_status get_running_state(void) + { +-- +2.17.2 + diff --git a/0044-multipathd-add-del-maps-multipathd-command.patch b/0044-multipathd-add-del-maps-multipathd-command.patch deleted file mode 100644 index 9f32eb2..0000000 --- a/0044-multipathd-add-del-maps-multipathd-command.patch +++ /dev/null @@ -1,161 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 2 Jul 2020 19:07:03 -0500 -Subject: [PATCH] multipathd: add "del maps" multipathd command - -This will flush all multipath devices. - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/devmapper.c | 7 +++++-- - libmultipath/devmapper.h | 2 +- - multipath/main.c | 2 +- - multipathd/cli.c | 1 + - multipathd/cli_handlers.c | 19 +++++++++++++++++++ - multipathd/cli_handlers.h | 1 + - multipathd/main.c | 3 ++- - multipathd/main.h | 1 + - 8 files changed, 31 insertions(+), 5 deletions(-) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index 4c86b6d4..f597ff8b 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -1005,7 +1005,7 @@ dm_flush_map_nopaths(const char * mapname, int deferred_remove) - - #endif - --int dm_flush_maps (int retries) -+int dm_flush_maps (int need_suspend, int retries) - { - int r = 1; - struct dm_task *dmt; -@@ -1028,7 +1028,10 @@ int dm_flush_maps (int retries) - - r = 0; - do { -- r |= dm_suspend_and_flush_map(names->name, retries); -+ if (need_suspend) -+ r |= dm_suspend_and_flush_map(names->name, retries); -+ else -+ r |= dm_flush_map(names->name); - next = names->next; - names = (void *) names + next; - } while (next); -diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h -index b2108638..6dd178c8 100644 ---- a/libmultipath/devmapper.h -+++ b/libmultipath/devmapper.h -@@ -57,7 +57,7 @@ int dm_flush_map_nopaths(const char * mapname, int deferred_remove); - #define dm_suspend_and_flush_map(mapname, retries) \ - _dm_flush_map(mapname, 1, 0, 1, retries) - int dm_cancel_deferred_remove(struct multipath *mpp); --int dm_flush_maps (int retries); -+int dm_flush_maps (int need_suspend, int retries); - int dm_fail_path(const char * mapname, char * path); - int dm_reinstate_path(const char * mapname, char * path); - int dm_queue_if_no_path(const char *mapname, int enable); -diff --git a/multipath/main.c b/multipath/main.c -index c4740fab..d89f0a91 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -1096,7 +1096,7 @@ main (int argc, char *argv[]) - goto out; - } - else if (conf->remove == FLUSH_ALL) { -- r = dm_flush_maps(retries) ? RTVL_FAIL : RTVL_OK; -+ r = dm_flush_maps(1, retries) ? RTVL_FAIL : RTVL_OK; - goto out; - } - while ((r = configure(conf, cmd, dev_type, dev)) == RTVL_RETRY) -diff --git a/multipathd/cli.c b/multipathd/cli.c -index 800c0fbe..bdc9fb10 100644 ---- a/multipathd/cli.c -+++ b/multipathd/cli.c -@@ -568,6 +568,7 @@ cli_init (void) { - add_handler(DEL+PATH, NULL); - add_handler(ADD+MAP, NULL); - add_handler(DEL+MAP, NULL); -+ add_handler(DEL+MAPS, NULL); - add_handler(SWITCH+MAP+GROUP, NULL); - add_handler(RECONFIGURE, NULL); - add_handler(SUSPEND+MAP, NULL); -diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c -index 31c3d9fd..782bb003 100644 ---- a/multipathd/cli_handlers.c -+++ b/multipathd/cli_handlers.c -@@ -852,6 +852,25 @@ cli_del_map (void * v, char ** reply, int * len, void * data) - return rc; - } - -+int -+cli_del_maps (void *v, char **reply, int *len, void *data) -+{ -+ struct vectors * vecs = (struct vectors *)data; -+ struct multipath *mpp; -+ int i, ret = 0; -+ -+ condlog(2, "remove maps (operator)"); -+ vector_foreach_slot(vecs->mpvec, mpp, i) { -+ if (flush_map(mpp, vecs, 0)) -+ ret++; -+ else -+ i--; -+ } -+ /* flush any multipath maps that aren't currently known by multipathd */ -+ ret |= dm_flush_maps(0, 0); -+ return ret; -+} -+ - int - cli_reload(void *v, char **reply, int *len, void *data) - { -diff --git a/multipathd/cli_handlers.h b/multipathd/cli_handlers.h -index 0f451064..6f57b429 100644 ---- a/multipathd/cli_handlers.h -+++ b/multipathd/cli_handlers.h -@@ -26,6 +26,7 @@ int cli_add_path (void * v, char ** reply, int * len, void * data); - int cli_del_path (void * v, char ** reply, int * len, void * data); - int cli_add_map (void * v, char ** reply, int * len, void * data); - int cli_del_map (void * v, char ** reply, int * len, void * data); -+int cli_del_maps (void * v, char ** reply, int * len, void * data); - int cli_switch_group(void * v, char ** reply, int * len, void * data); - int cli_reconfigure(void * v, char ** reply, int * len, void * data); - int cli_resize(void * v, char ** reply, int * len, void * data); -diff --git a/multipathd/main.c b/multipathd/main.c -index daf19a4e..f014d2a1 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -635,7 +635,7 @@ sync_maps_state(vector mpvec) - sync_map_state(mpp); - } - --static int -+int - flush_map(struct multipath * mpp, struct vectors * vecs, int nopaths) - { - int r; -@@ -1555,6 +1555,7 @@ uxlsnrloop (void * ap) - set_handler_callback(DEL+PATH, cli_del_path); - set_handler_callback(ADD+MAP, cli_add_map); - set_handler_callback(DEL+MAP, cli_del_map); -+ set_handler_callback(DEL+MAPS, cli_del_maps); - set_handler_callback(SWITCH+MAP+GROUP, cli_switch_group); - set_unlocked_handler_callback(RECONFIGURE, cli_reconfigure); - set_handler_callback(SUSPEND+MAP, cli_suspend); -diff --git a/multipathd/main.h b/multipathd/main.h -index 7bb8463f..5dff17e5 100644 ---- a/multipathd/main.h -+++ b/multipathd/main.h -@@ -28,6 +28,7 @@ int ev_add_path (struct path *, struct vectors *, int); - int ev_remove_path (struct path *, struct vectors *, int); - int ev_add_map (char *, const char *, struct vectors *); - int ev_remove_map (char *, char *, int, struct vectors *); -+int flush_map(struct multipath *, struct vectors *, int); - int set_config_state(enum daemon_status); - void * mpath_alloc_prin_response(int prin_sa); - int prin_do_scsi_ioctl(char *, int rq_servact, struct prin_resp * resp, --- -2.17.2 - diff --git a/0044-multipathd-move-threads-destruction-into-separate-fu.patch b/0044-multipathd-move-threads-destruction-into-separate-fu.patch new file mode 100644 index 0000000..6c2251e --- /dev/null +++ b/0044-multipathd-move-threads-destruction-into-separate-fu.patch @@ -0,0 +1,164 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 23 Sep 2020 11:18:44 +0200 +Subject: [PATCH] multipathd: move threads destruction into separate function + +Also, introduce booleans that indicate a certain thread has +been started successfully. Using these booleans, we can avoid +crashing by cancelling threads that have never been started. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 76 +++++++++++++++++++++++++++++++---------------- + 1 file changed, 51 insertions(+), 25 deletions(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index eb760a71..9eb658d4 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -129,6 +129,9 @@ static volatile enum daemon_status running_state = DAEMON_INIT; + pid_t daemon_pid; + static pthread_mutex_t config_lock = PTHREAD_MUTEX_INITIALIZER; + static pthread_cond_t config_cond; ++static pthread_t check_thr, uevent_thr, uxlsnr_thr, uevq_thr, dmevent_thr; ++static bool check_thr_started, uevent_thr_started, uxlsnr_thr_started, ++ uevq_thr_started, dmevent_thr_started; + + static inline enum daemon_status get_running_state(void) + { +@@ -2927,6 +2930,39 @@ static void cleanup_vecs(void) + FREE(gvecs); + } + ++static void cleanup_threads(void) ++{ ++ stop_io_err_stat_thread(); ++ ++ if (check_thr_started) ++ pthread_cancel(check_thr); ++ if (uevent_thr_started) ++ pthread_cancel(uevent_thr); ++ if (uxlsnr_thr_started) ++ pthread_cancel(uxlsnr_thr); ++ if (uevq_thr_started) ++ pthread_cancel(uevq_thr); ++ if (dmevent_thr_started) ++ pthread_cancel(dmevent_thr); ++ ++ if (check_thr_started) ++ pthread_join(check_thr, NULL); ++ if (uevent_thr_started) ++ pthread_join(uevent_thr, NULL); ++ if (uxlsnr_thr_started) ++ pthread_join(uxlsnr_thr, NULL); ++ if (uevq_thr_started) ++ pthread_join(uevq_thr, NULL); ++ if (dmevent_thr_started) ++ pthread_join(dmevent_thr, NULL); ++ ++ /* ++ * As all threads are joined now, and we're in DAEMON_SHUTDOWN ++ * state, no new waiter threads will be created any more. ++ */ ++ pthread_attr_destroy(&waiter_attr); ++} ++ + /* + * Use a non-default call_rcu_data for child(). + * +@@ -2972,7 +3008,6 @@ static void cleanup_rcu(void) + static int + child (__attribute__((unused)) void *param) + { +- pthread_t check_thr, uevent_thr, uxlsnr_thr, uevq_thr, dmevent_thr; + pthread_attr_t log_attr, misc_attr, uevent_attr; + struct vectors * vecs; + int rc; +@@ -3070,9 +3105,12 @@ child (__attribute__((unused)) void *param) + condlog(0, "failed to create cli listener: %d", rc); + goto failed; + } +- else if (state != DAEMON_CONFIGURE) { +- condlog(0, "cli listener failed to start"); +- goto failed; ++ else { ++ uxlsnr_thr_started = true; ++ if (state != DAEMON_CONFIGURE) { ++ condlog(0, "cli listener failed to start"); ++ goto failed; ++ } + } + + if (poll_dmevents) { +@@ -3085,7 +3123,8 @@ child (__attribute__((unused)) void *param) + condlog(0, "failed to create dmevent waiter thread: %d", + rc); + goto failed; +- } ++ } else ++ dmevent_thr_started = true; + } + + /* +@@ -3094,7 +3133,8 @@ child (__attribute__((unused)) void *param) + if ((rc = pthread_create(&uevent_thr, &uevent_attr, ueventloop, udev))) { + condlog(0, "failed to create uevent thread: %d", rc); + goto failed; +- } ++ } else ++ uevent_thr_started = true; + pthread_attr_destroy(&uevent_attr); + + /* +@@ -3103,11 +3143,13 @@ child (__attribute__((unused)) void *param) + if ((rc = pthread_create(&check_thr, &misc_attr, checkerloop, vecs))) { + condlog(0,"failed to create checker loop thread: %d", rc); + goto failed; +- } ++ } else ++ check_thr_started = true; + if ((rc = pthread_create(&uevq_thr, &misc_attr, uevqloop, vecs))) { + condlog(0, "failed to create uevent dispatcher: %d", rc); + goto failed; +- } ++ } else ++ uevq_thr_started = true; + pthread_attr_destroy(&misc_attr); + + while (1) { +@@ -3136,22 +3178,7 @@ child (__attribute__((unused)) void *param) + } + } + +- pthread_cancel(check_thr); +- pthread_cancel(uevent_thr); +- pthread_cancel(uxlsnr_thr); +- pthread_cancel(uevq_thr); +- if (poll_dmevents) +- pthread_cancel(dmevent_thr); +- +- pthread_join(check_thr, NULL); +- pthread_join(uevent_thr, NULL); +- pthread_join(uxlsnr_thr, NULL); +- pthread_join(uevq_thr, NULL); +- if (poll_dmevents) +- pthread_join(dmevent_thr, NULL); +- +- stop_io_err_stat_thread(); +- ++ cleanup_threads(); + cleanup_vecs(); + cleanup_foreign(); + cleanup_checkers(); +@@ -3178,7 +3205,6 @@ child (__attribute__((unused)) void *param) + conf = rcu_dereference(multipath_conf); + rcu_assign_pointer(multipath_conf, NULL); + call_rcu(&conf->rcu, rcu_free_config); +- pthread_attr_destroy(&waiter_attr); + #ifdef _DEBUG_ + dbg_free_final(NULL); + #endif +-- +2.17.2 + diff --git a/0045-multipath-make-flushing-maps-work-like-other-command.patch b/0045-multipath-make-flushing-maps-work-like-other-command.patch deleted file mode 100644 index b7450ee..0000000 --- a/0045-multipath-make-flushing-maps-work-like-other-command.patch +++ /dev/null @@ -1,104 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 2 Jul 2020 19:07:04 -0500 -Subject: [PATCH] multipath: make flushing maps work like other commands - -The config structure doesn't need a special variable just for removes. -Multipath can just use the cmd variable, like it does for the other -commands. - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/config.h | 3 ++- - libmultipath/configure.h | 3 --- - multipath/main.c | 20 ++++++++++---------- - 3 files changed, 12 insertions(+), 14 deletions(-) - -diff --git a/libmultipath/config.h b/libmultipath/config.h -index ceecff2d..55569360 100644 ---- a/libmultipath/config.h -+++ b/libmultipath/config.h -@@ -38,6 +38,8 @@ enum mpath_cmds { - CMD_ADD_WWID, - CMD_USABLE_PATHS, - CMD_DUMP_CONFIG, -+ CMD_FLUSH_ONE, -+ CMD_FLUSH_ALL, - }; - - enum force_reload_types { -@@ -142,7 +144,6 @@ struct config { - unsigned int max_checkint; - bool use_watchdog; - int pgfailback; -- int remove; - int rr_weight; - int no_path_retry; - int user_friendly_names; -diff --git a/libmultipath/configure.h b/libmultipath/configure.h -index d7509000..0e33bf40 100644 ---- a/libmultipath/configure.h -+++ b/libmultipath/configure.h -@@ -45,9 +45,6 @@ enum { - CP_RETRY, - }; - --#define FLUSH_ONE 1 --#define FLUSH_ALL 2 -- - struct vectors; - - int setup_map (struct multipath * mpp, char * params, int params_size, -diff --git a/multipath/main.c b/multipath/main.c -index d89f0a91..101fd656 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -909,10 +909,10 @@ main (int argc, char *argv[]) - cmd = CMD_DRY_RUN; - break; - case 'f': -- conf->remove = FLUSH_ONE; -+ cmd = CMD_FLUSH_ONE; - break; - case 'F': -- conf->remove = FLUSH_ALL; -+ cmd = CMD_FLUSH_ALL; - break; - case 'l': - if (optarg && !strncmp(optarg, "l", 1)) -@@ -1053,6 +1053,10 @@ main (int argc, char *argv[]) - condlog(0, "the -w option requires a device"); - goto out; - } -+ if (cmd == CMD_FLUSH_ONE && dev_type != DEV_DEVMAP) { -+ condlog(0, "the -f option requires a map name to remove"); -+ goto out; -+ } - - switch(delegate_to_multipathd(cmd, dev, dev_type, conf)) { - case DELEGATE_OK: -@@ -1086,16 +1090,12 @@ main (int argc, char *argv[]) - } - if (retries < 0) - retries = conf->remove_retries; -- if (conf->remove == FLUSH_ONE) { -- if (dev_type == DEV_DEVMAP) { -- r = dm_suspend_and_flush_map(dev, retries) ? -- RTVL_FAIL : RTVL_OK; -- } else -- condlog(0, "must provide a map name to remove"); -- -+ if (cmd == CMD_FLUSH_ONE) { -+ r = dm_suspend_and_flush_map(dev, retries) ? -+ RTVL_FAIL : RTVL_OK; - goto out; - } -- else if (conf->remove == FLUSH_ALL) { -+ else if (cmd == CMD_FLUSH_ALL) { - r = dm_flush_maps(1, retries) ? RTVL_FAIL : RTVL_OK; - goto out; - } --- -2.17.2 - diff --git a/0045-multipathd-move-conf-destruction-into-separate-funct.patch b/0045-multipathd-move-conf-destruction-into-separate-funct.patch new file mode 100644 index 0000000..97125dc --- /dev/null +++ b/0045-multipathd-move-conf-destruction-into-separate-funct.patch @@ -0,0 +1,56 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 23 Sep 2020 12:38:50 +0200 +Subject: [PATCH] multipathd: move conf destruction into separate function + +Also removing the comment about dlog() and dm_write_log(). +dlog() can cope with get_multipath_config() returning NULL, +and dm_write_log() hasn't accessed the configuration for a while. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 20 +++++++++++--------- + 1 file changed, 11 insertions(+), 9 deletions(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 9eb658d4..07973e85 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -2892,6 +2892,16 @@ set_oom_adj (void) + condlog(0, "couldn't adjust oom score"); + } + ++static void cleanup_conf(void) { ++ struct config *conf; ++ ++ conf = rcu_dereference(multipath_conf); ++ if (!conf) ++ return; ++ rcu_assign_pointer(multipath_conf, NULL); ++ call_rcu(&conf->rcu, rcu_free_config); ++} ++ + static void cleanup_maps(struct vectors *vecs) + { + int queue_without_daemon, i; +@@ -3196,15 +3206,7 @@ child (__attribute__((unused)) void *param) + + if (logsink == 1) + log_thread_stop(); +- +- /* +- * Freeing config must be done after condlog() and dm_lib_exit(), +- * because logging functions like dlog() and dm_write_log() +- * reference the config. +- */ +- conf = rcu_dereference(multipath_conf); +- rcu_assign_pointer(multipath_conf, NULL); +- call_rcu(&conf->rcu, rcu_free_config); ++ cleanup_conf(); + #ifdef _DEBUG_ + dbg_free_final(NULL); + #endif +-- +2.17.2 + diff --git a/0046-multipath-delegate-flushing-maps-to-multipathd.patch b/0046-multipath-delegate-flushing-maps-to-multipathd.patch deleted file mode 100644 index 1a4a771..0000000 --- a/0046-multipath-delegate-flushing-maps-to-multipathd.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 2 Jul 2020 19:07:05 -0500 -Subject: [PATCH] multipath: delegate flushing maps to multipathd - -Since there can be problems with removing maps outside of multipathd, -multipath should attempt to delegate this command to multipathd. -However, multipathd doesn't attempt to suspend the device, in order -to avoid potential hangs. If delegating to multipathd fails, multipath -should try the remove itself. - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - multipath/main.c | 14 ++++++++++++++ - multipath/multipath.8 | 4 ++-- - 2 files changed, 16 insertions(+), 2 deletions(-) - -diff --git a/multipath/main.c b/multipath/main.c -index 101fd656..6a24e483 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -820,6 +820,20 @@ int delegate_to_multipathd(enum mpath_cmds cmd, - if (cmd == CMD_CREATE && conf->force_reload == FORCE_RELOAD_YES) { - p += snprintf(p, n, "reconfigure"); - } -+ else if (cmd == CMD_FLUSH_ONE && dev && dev_type == DEV_DEVMAP) { -+ p += snprintf(p, n, "del map %s", dev); -+ /* multipathd doesn't try as hard, to avoid potentially -+ * hanging. If it fails, retry with the regular multipath -+ * command */ -+ r = NOT_DELEGATED; -+ } -+ else if (cmd == CMD_FLUSH_ALL) { -+ p += snprintf(p, n, "del maps"); -+ /* multipathd doesn't try as hard, to avoid potentially -+ * hanging. If it fails, retry with the regular multipath -+ * command */ -+ r = NOT_DELEGATED; -+ } - /* Add other translations here */ - - if (strlen(command) == 0) -diff --git a/multipath/multipath.8 b/multipath/multipath.8 -index 6fb8645a..5b29a5d9 100644 ---- a/multipath/multipath.8 -+++ b/multipath/multipath.8 -@@ -125,11 +125,11 @@ the system. - Other operation modes are chosen by using one of the following command line switches: - .TP - .B \-f --Flush (remove) a multipath device map specified as parameter, if unused. -+Flush (remove) a multipath device map specified as parameter, if unused. This operation is delegated to the multipathd daemon if it's running. - . - .TP - .B \-F --Flush (remove) all unused multipath device maps. -+Flush (remove) all unused multipath device maps. This operation is delegated to the multipathd daemon if it's running. - . - .TP - .B \-l --- -2.17.2 - diff --git a/0046-multipathd-move-pid-destruction-into-separate-functi.patch b/0046-multipathd-move-pid-destruction-into-separate-functi.patch new file mode 100644 index 0000000..bbff859 --- /dev/null +++ b/0046-multipathd-move-pid-destruction-into-separate-functi.patch @@ -0,0 +1,42 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 23 Sep 2020 16:10:19 +0200 +Subject: [PATCH] multipathd: move pid destruction into separate function + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 07973e85..fc1f8d7f 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -2892,6 +2892,12 @@ set_oom_adj (void) + condlog(0, "couldn't adjust oom score"); + } + ++static void cleanup_pidfile(void) ++{ ++ condlog(3, "unlink pidfile"); ++ unlink(DEFAULT_PIDFILE); ++} ++ + static void cleanup_conf(void) { + struct config *conf; + +@@ -3199,9 +3205,7 @@ child (__attribute__((unused)) void *param) + dm_lib_exit(); + + /* We're done here */ +- condlog(3, "unlink pidfile"); +- unlink(DEFAULT_PIDFILE); +- ++ cleanup_pidfile(); + condlog(2, "--------shut down-------"); + + if (logsink == 1) +-- +2.17.2 + diff --git a/0047-multipath-add-option-to-skip-multipathd-delegation.patch b/0047-multipath-add-option-to-skip-multipathd-delegation.patch deleted file mode 100644 index 51284aa..0000000 --- a/0047-multipath-add-option-to-skip-multipathd-delegation.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 2 Jul 2020 19:07:06 -0500 -Subject: [PATCH] multipath: add option to skip multipathd delegation - -Add the -D option to allow users to skip delegating commands to -multipathd. - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/config.h | 1 + - multipath/main.c | 8 +++++++- - 2 files changed, 8 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/config.h b/libmultipath/config.h -index 55569360..92c61a0d 100644 ---- a/libmultipath/config.h -+++ b/libmultipath/config.h -@@ -190,6 +190,7 @@ struct config { - int ghost_delay; - int find_multipaths_timeout; - int marginal_pathgroups; -+ int skip_delegate; - unsigned int version[3]; - unsigned int sequence_nr; - -diff --git a/multipath/main.c b/multipath/main.c -index 6a24e483..4c43314e 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -817,6 +817,9 @@ int delegate_to_multipathd(enum mpath_cmds cmd, - *p = '\0'; - n = sizeof(command); - -+ if (conf->skip_delegate) -+ return NOT_DELEGATED; -+ - if (cmd == CMD_CREATE && conf->force_reload == FORCE_RELOAD_YES) { - p += snprintf(p, n, "reconfigure"); - } -@@ -890,7 +893,7 @@ main (int argc, char *argv[]) - multipath_conf = conf; - conf->retrigger_tries = 0; - conf->force_sync = 1; -- while ((arg = getopt(argc, argv, ":adcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { -+ while ((arg = getopt(argc, argv, ":adDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { - switch(arg) { - case 1: printf("optarg : %s\n",optarg); - break; -@@ -922,6 +925,9 @@ main (int argc, char *argv[]) - if (cmd == CMD_CREATE) - cmd = CMD_DRY_RUN; - break; -+ case 'D': -+ conf->skip_delegate = 1; -+ break; - case 'f': - cmd = CMD_FLUSH_ONE; - break; --- -2.17.2 - diff --git a/0047-multipathd-close-pidfile-on-exit.patch b/0047-multipathd-close-pidfile-on-exit.patch new file mode 100644 index 0000000..6c9c1b1 --- /dev/null +++ b/0047-multipathd-close-pidfile-on-exit.patch @@ -0,0 +1,45 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 23 Sep 2020 16:27:33 +0200 +Subject: [PATCH] multipathd: close pidfile on exit + +It seems we've been doing this only in the failure case, for ages. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index fc1f8d7f..f6b80668 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -132,6 +132,7 @@ static pthread_cond_t config_cond; + static pthread_t check_thr, uevent_thr, uxlsnr_thr, uevq_thr, dmevent_thr; + static bool check_thr_started, uevent_thr_started, uxlsnr_thr_started, + uevq_thr_started, dmevent_thr_started; ++static int pid_fd = -1; + + static inline enum daemon_status get_running_state(void) + { +@@ -2894,6 +2895,8 @@ set_oom_adj (void) + + static void cleanup_pidfile(void) + { ++ if (pid_fd >= 0) ++ close(pid_fd); + condlog(3, "unlink pidfile"); + unlink(DEFAULT_PIDFILE); + } +@@ -3027,7 +3030,6 @@ child (__attribute__((unused)) void *param) + pthread_attr_t log_attr, misc_attr, uevent_attr; + struct vectors * vecs; + int rc; +- int pid_fd = -1; + struct config *conf; + char *envp; + enum daemon_status state; +-- +2.17.2 + diff --git a/0048-libmultipath-add-device-to-hwtable.c.patch b/0048-libmultipath-add-device-to-hwtable.c.patch deleted file mode 100644 index 9d5e780..0000000 --- a/0048-libmultipath-add-device-to-hwtable.c.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Steve Schremmer -Date: Mon, 6 Jul 2020 20:22:35 +0000 -Subject: [PATCH] libmultipath: add device to hwtable.c - -Add FUJITSU ETERNUS_AHB defaults. - -Signed-off-by: Steve Schremmer -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/hwtable.c | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index d1fcfdb3..d680bdfc 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -428,6 +428,22 @@ static struct hwentry default_hw[] = { - .pgpolicy = MULTIBUS, - .no_path_retry = 10, - }, -+ { -+ /* -+ * ETERNUS AB/HB -+ * Maintainer: NetApp RDAC team -+ */ -+ .vendor = "FUJITSU", -+ .product = "ETERNUS_AHB", -+ .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, -+ }, - /* - * Hitachi Vantara - * --- -2.17.2 - diff --git a/0048-multipathd-add-helper-for-systemd-notification-at-ex.patch b/0048-multipathd-add-helper-for-systemd-notification-at-ex.patch new file mode 100644 index 0000000..bf3c462 --- /dev/null +++ b/0048-multipathd-add-helper-for-systemd-notification-at-ex.patch @@ -0,0 +1,60 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 23 Sep 2020 17:49:02 +0200 +Subject: [PATCH] multipathd: add helper for systemd notification at exit + +Add sd_notify_exit(). + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 22 +++++++++++++--------- + 1 file changed, 13 insertions(+), 9 deletions(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index f6b80668..07068e4a 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -3024,6 +3024,17 @@ static void cleanup_rcu(void) + rcu_unregister_thread(); + } + ++static int sd_notify_exit(int err) ++{ ++#ifdef USE_SYSTEMD ++ char msg[24]; ++ ++ snprintf(msg, sizeof(msg), "ERRNO=%d", err); ++ sd_notify(0, msg); ++#endif ++ return err; ++} ++ + static int + child (__attribute__((unused)) void *param) + { +@@ -3216,19 +3227,12 @@ child (__attribute__((unused)) void *param) + #ifdef _DEBUG_ + dbg_free_final(NULL); + #endif +- +-#ifdef USE_SYSTEMD +- sd_notify(0, "ERRNO=0"); +-#endif +- exit(0); ++ exit(sd_notify_exit(0)); + + failed: +-#ifdef USE_SYSTEMD +- sd_notify(0, "ERRNO=1"); +-#endif + if (pid_fd >= 0) + close(pid_fd); +- exit(1); ++ exit(sd_notify_exit(1)); + } + + static int +-- +2.17.2 + diff --git a/0049-master-libmultipath-fix-use-after-free-when-iscsi-lo.patch b/0049-master-libmultipath-fix-use-after-free-when-iscsi-lo.patch deleted file mode 100644 index bfb9f8f..0000000 --- a/0049-master-libmultipath-fix-use-after-free-when-iscsi-lo.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: lixiaokeng -Date: Mon, 13 Jul 2020 13:07:40 +0200 -Subject: [PATCH] master - libmultipath: fix use after free when iscsi logs in - -When two iscsi ips log in and out alternately and the following scripts run -at the same time, - -#!/bin/bash -interval=5 -while true -do - iscsiadm -m node -p 9.41.147.171 &> /dev/null - iscsiadm -m node -p 9.41.148.172 &> /dev/null - iscsiadm -m session &> /dev/null - rescan-scsi-bus.sh &> /dev/null - multipath -v2 &> /dev/null - multipath -ll &> /dev/null - sleep $interval -done - -multipathd will have a segfault after about 30 mins. - -The reason is that mpp->hwe is accessed after hwe is already freed. In -extract_hwe_from_path func, mpp->hwe is set to pp->hwe, so they points to the -same hwe. For some reasons, pp->mpp will be set to NULL in orphan_path func. -Then, pp and hwe will be freed with (pp->mpp == NULL) in free_path func -called by ev_remove_path func. However, mpp->hwe is not set to NULL while hwe -is already freed. So, when iscsi device logs in and new path is added to mpp, -mpp->hwe will be accessed in select_pgfailback func. Finally, use-after-free -problem occurs. - -The procedure details given as follows, -1.wait_dmevents thread -wait_dmevents - ->dmevent_loop - ->update_multipath - ->__setup_multipath - ->update_multipath_strings - -> sync_paths - ->orphan_path -2.uevqloop thread (iscsi log out, remove path) -uevqloop -->uevent_dispatch - ->service_uevq - ->uev_remove_path - ->ev_remove_path //pp->mpp is NULL - ->free_path(pp) - //pp->hew are freed but mpp->hwe is not set to NULL -3.ev_remove_path (iscsi log in, add path) -uevqloop -->uevent_dispatch - ->service_uevq - ->ev_add_path - ->select_pgfailback //mpp->hwe is accessed - -Here, we will set mpp->hwe to NULL before setting pp->map to NULL in orphan_path -func. - -Signed-off-by: Tianxiong Lu -Signed-off-by: lixiaokeng -Signed-off-by: Zhiqiang Liu -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/structs_vec.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c -index 8137ea21..430eaad7 100644 ---- a/libmultipath/structs_vec.c -+++ b/libmultipath/structs_vec.c -@@ -93,6 +93,8 @@ int adopt_paths(vector pathvec, struct multipath *mpp) - void orphan_path(struct path *pp, const char *reason) - { - condlog(3, "%s: orphan path, %s", pp->dev, reason); -+ if (pp->mpp && pp->mpp->hwe == pp->hwe) -+ pp->mpp->hwe = NULL; - pp->mpp = NULL; - pp->dmstate = PSTATE_UNDEF; - pp->uid_attribute = NULL; --- -2.17.2 - diff --git a/0049-multipathd-child-call-cleanups-in-failure-case-too.patch b/0049-multipathd-child-call-cleanups-in-failure-case-too.patch new file mode 100644 index 0000000..fba8169 --- /dev/null +++ b/0049-multipathd-child-call-cleanups-in-failure-case-too.patch @@ -0,0 +1,52 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 23 Sep 2020 17:57:16 +0200 +Subject: [PATCH] multipathd: child(): call cleanups in failure case, too + +So far we haven't called any cleanup code if child() failed. +Fix it. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 07068e4a..6b9e323e 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -3044,6 +3044,7 @@ child (__attribute__((unused)) void *param) + struct config *conf; + char *envp; + enum daemon_status state; ++ int exit_code = 1; + + mlockall(MCL_CURRENT | MCL_FUTURE); + signal_init(); +@@ -3207,6 +3208,8 @@ child (__attribute__((unused)) void *param) + } + } + ++ exit_code = 0; ++failed: + cleanup_threads(); + cleanup_vecs(); + cleanup_foreign(); +@@ -3227,12 +3230,7 @@ child (__attribute__((unused)) void *param) + #ifdef _DEBUG_ + dbg_free_final(NULL); + #endif +- exit(sd_notify_exit(0)); +- +-failed: +- if (pid_fd >= 0) +- close(pid_fd); +- exit(sd_notify_exit(1)); ++ return sd_notify_exit(exit_code); + } + + static int +-- +2.17.2 + diff --git a/0050-libmultipath-warn-if-freeing-path-that-holds-mpp-hwe.patch b/0050-libmultipath-warn-if-freeing-path-that-holds-mpp-hwe.patch deleted file mode 100644 index 3c286fa..0000000 --- a/0050-libmultipath-warn-if-freeing-path-that-holds-mpp-hwe.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 13 Jul 2020 13:07:41 +0200 -Subject: [PATCH] libmultipath: warn if freeing path that holds mpp->hwe - -This just adds an error message to the previous patch. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/structs_vec.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c -index 430eaad7..cde4dbe6 100644 ---- a/libmultipath/structs_vec.c -+++ b/libmultipath/structs_vec.c -@@ -93,8 +93,11 @@ int adopt_paths(vector pathvec, struct multipath *mpp) - void orphan_path(struct path *pp, const char *reason) - { - condlog(3, "%s: orphan path, %s", pp->dev, reason); -- if (pp->mpp && pp->mpp->hwe == pp->hwe) -+ if (pp->mpp && pp->hwe && pp->mpp->hwe == pp->hwe) { -+ condlog(0, "BUG: orphaning path %s that holds hwe of %s", -+ pp->dev, pp->mpp->alias); - pp->mpp->hwe = NULL; -+ } - pp->mpp = NULL; - pp->dmstate = PSTATE_UNDEF; - pp->uid_attribute = NULL; --- -2.17.2 - diff --git a/0050-multipathd-unwatch_all_dmevents-check-if-waiter-is-i.patch b/0050-multipathd-unwatch_all_dmevents-check-if-waiter-is-i.patch new file mode 100644 index 0000000..279109c --- /dev/null +++ b/0050-multipathd-unwatch_all_dmevents-check-if-waiter-is-i.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 23 Sep 2020 18:45:30 +0200 +Subject: [PATCH] multipathd: unwatch_all_dmevents: check if waiter is + initialized + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipathd/dmevents.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/multipathd/dmevents.c b/multipathd/dmevents.c +index b561cbfd..f52f5970 100644 +--- a/multipathd/dmevents.c ++++ b/multipathd/dmevents.c +@@ -257,6 +257,8 @@ void unwatch_all_dmevents(void) + struct dev_event *dev_evt; + int i; + ++ if (!waiter) ++ return; + pthread_mutex_lock(&waiter->events_lock); + vector_foreach_slot(waiter->events, dev_evt, i) + free(dev_evt); +-- +2.17.2 + diff --git a/0051-libmultipath-warn-about-NULL-value-of-mpp-hwe.patch b/0051-libmultipath-warn-about-NULL-value-of-mpp-hwe.patch deleted file mode 100644 index a50b9b2..0000000 --- a/0051-libmultipath-warn-about-NULL-value-of-mpp-hwe.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 13 Jul 2020 13:07:42 +0200 -Subject: [PATCH] libmultipath: warn about NULL value of mpp->hwe - -mpp->hwe is only accessed in propsel.c. It may become unset if -all paths of the mpp have been deleted. Access to mpp->hwe in this -case should be avoided. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/propsel.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c -index d362beb4..68228272 100644 ---- a/libmultipath/propsel.c -+++ b/libmultipath/propsel.c -@@ -65,7 +65,9 @@ do { \ - __do_set_from_vec(struct hwentry, var, (src)->hwe, dest) - - #define do_set_from_hwe(var, src, dest, msg) \ -- if (__do_set_from_hwe(var, src, dest)) { \ -+ if (!src->hwe) { \ -+ condlog(0, "BUG: do_set_from_hwe called with hwe == NULL"); \ -+ } else if (__do_set_from_hwe(var, src, dest)) { \ - origin = msg; \ - goto out; \ - } --- -2.17.2 - diff --git a/0051-multipathd-print-error-message-if-config-can-t-be-lo.patch b/0051-multipathd-print-error-message-if-config-can-t-be-lo.patch new file mode 100644 index 0000000..9cf6182 --- /dev/null +++ b/0051-multipathd-print-error-message-if-config-can-t-be-lo.patch @@ -0,0 +1,30 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 23 Sep 2020 18:45:51 +0200 +Subject: [PATCH] multipathd: print error message if config can't be loaded + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 6b9e323e..7ab3eab8 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -3074,8 +3074,10 @@ child (__attribute__((unused)) void *param) + condlog(2, "read " DEFAULT_CONFIGFILE); + + conf = load_config(DEFAULT_CONFIGFILE); +- if (!conf) ++ if (!conf) { ++ condlog(0, "failed to load configuration"); + goto failed; ++ } + + if (verbosity) + conf->verbosity = verbosity; +-- +2.17.2 + diff --git a/0052-libmultipath-add-libmp_dm_exit.patch b/0052-libmultipath-add-libmp_dm_exit.patch new file mode 100644 index 0000000..db24711 --- /dev/null +++ b/0052-libmultipath-add-libmp_dm_exit.patch @@ -0,0 +1,92 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 23 Sep 2020 21:02:45 +0200 +Subject: [PATCH] libmultipath: add libmp_dm_exit() + +This function prepares for calling dm_lib_exit() on program exit. +It undoes changes to libdm internals done by libmultipath. +It doesn't call dm_lib_exit(), as the caller may want to keep +libdm active. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/config.c | 1 + + libmultipath/config.h | 2 ++ + libmultipath/devmapper.c | 15 +++++++++++++++ + libmultipath/devmapper.h | 1 + + 4 files changed, 19 insertions(+) + +diff --git a/libmultipath/config.c b/libmultipath/config.c +index f74417c6..b9cb4131 100644 +--- a/libmultipath/config.c ++++ b/libmultipath/config.c +@@ -60,6 +60,7 @@ int libmultipath_init(void) + static void _libmultipath_exit(void) + { + libmultipath_exit_called = true; ++ libmp_dm_exit(); + udev_unref(udev); + } + +diff --git a/libmultipath/config.h b/libmultipath/config.h +index f478df71..5d460359 100644 +--- a/libmultipath/config.h ++++ b/libmultipath/config.h +@@ -271,6 +271,8 @@ int libmultipath_init(void); + * + * This function un-initializes libmultipath data structures. + * It is recommended to call this function at program exit. ++ * If the application also calls dm_lib_exit(), it should do so ++ * after libmultipath_exit(). + * + * Calls to libmultipath_init() after libmultipath_exit() will fail + * (in other words, libmultipath can't be re-initialized). +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index 4eb6f539..e60ab493 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -335,6 +335,20 @@ void libmp_udev_set_sync_support(int on) + libmp_dm_udev_sync = !!on; + } + ++static bool libmp_dm_init_called; ++void libmp_dm_exit(void) ++{ ++ if (!libmp_dm_init_called) ++ return; ++ ++ /* switch back to default libdm logging */ ++ dm_log_init(NULL); ++#ifdef LIBDM_API_HOLD_CONTROL ++ /* make sure control fd is closed in dm_lib_release() */ ++ dm_hold_control_dev(0); ++#endif ++} ++ + static void libmp_dm_init(void) + { + struct config *conf; +@@ -351,6 +365,7 @@ static void libmp_dm_init(void) + dm_hold_control_dev(1); + #endif + dm_udev_set_sync_support(libmp_dm_udev_sync); ++ libmp_dm_init_called = true; + } + + static void _do_skip_libmp_dm_init(void) +diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h +index fa6b3c53..e29b4d41 100644 +--- a/libmultipath/devmapper.h ++++ b/libmultipath/devmapper.h +@@ -35,6 +35,7 @@ enum { + + int dm_prereq(unsigned int *v); + void skip_libmp_dm_init(void); ++void libmp_dm_exit(void); + void libmp_udev_set_sync_support(int on); + struct dm_task *libmp_dm_task_create(int task); + int dm_simplecmd_flush (int, const char *, uint16_t); +-- +2.17.2 + diff --git a/0052-libmultipath-fix-mpp-hwe-handling-in-sync_paths.patch b/0052-libmultipath-fix-mpp-hwe-handling-in-sync_paths.patch deleted file mode 100644 index b9caf46..0000000 --- a/0052-libmultipath-fix-mpp-hwe-handling-in-sync_paths.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 13 Jul 2020 13:07:43 +0200 -Subject: [PATCH] libmultipath: fix mpp->hwe handling in sync_paths() - -This is anologous to - -1f96269 ("multipathd: fix mpp->hwe handling on path removal") -f6839eb ("multipathd: fix mpp->hwe handling when paths are freed") - -When paths are removed from a map, we need to make sure that -mpp->hwe doesn't become stale. - -Reported-by: Lixiaokeng -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/structs_vec.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c -index cde4dbe6..ede14297 100644 ---- a/libmultipath/structs_vec.c -+++ b/libmultipath/structs_vec.c -@@ -260,6 +260,8 @@ void sync_paths(struct multipath *mpp, vector pathvec) - } - if (!found) { - condlog(3, "%s dropped path %s", mpp->alias, pp->dev); -+ if (mpp->hwe == pp->hwe) -+ mpp->hwe = NULL; - vector_del_slot(mpp->paths, i--); - orphan_path(pp, "path removed externally"); - } -@@ -267,6 +269,8 @@ void sync_paths(struct multipath *mpp, vector pathvec) - update_mpp_paths(mpp, pathvec); - vector_foreach_slot (mpp->paths, pp, i) - pp->mpp = mpp; -+ if (mpp->hwe == NULL) -+ extract_hwe_from_path(mpp); - } - - int --- -2.17.2 - diff --git a/0053-Makefile.inc-trim-extra-information-from-systemd-ver.patch b/0053-Makefile.inc-trim-extra-information-from-systemd-ver.patch deleted file mode 100644 index 5c3f614..0000000 --- a/0053-Makefile.inc-trim-extra-information-from-systemd-ver.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 6 Jul 2020 13:21:12 -0500 -Subject: [PATCH] Makefile.inc: trim extra information from systemd version - -Some systemd versions print extra information in the -"pkg-config --modversion" output, which confuses make. Trim this -off. - -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Makefile.inc b/Makefile.inc -index e7256e3a..8ea3352d 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -37,7 +37,7 @@ endif - - ifndef SYSTEMD - ifeq ($(shell pkg-config --modversion libsystemd >/dev/null 2>&1 && echo 1), 1) -- SYSTEMD = $(shell pkg-config --modversion libsystemd) -+ SYSTEMD = $(shell pkg-config --modversion libsystemd | awk '{print $$1}') - else - ifeq ($(shell systemctl --version >/dev/null 2>&1 && echo 1), 1) - SYSTEMD = $(shell systemctl --version 2> /dev/null | \ --- -2.17.2 - diff --git a/0053-multipathd-fixup-libdm-deinitialization.patch b/0053-multipathd-fixup-libdm-deinitialization.patch new file mode 100644 index 0000000..b57a8cd --- /dev/null +++ b/0053-multipathd-fixup-libdm-deinitialization.patch @@ -0,0 +1,40 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 23 Sep 2020 21:06:13 +0200 +Subject: [PATCH] multipathd: fixup libdm deinitialization + +With libmp_dm_exit() in place, we can make sure that the +calls are made in the right order. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 7ab3eab8..4c4e2eab 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -3220,8 +3220,6 @@ failed: + if (poll_dmevents) + cleanup_dmevent_waiter(); + +- dm_lib_exit(); +- + /* We're done here */ + cleanup_pidfile(); + condlog(2, "--------shut down-------"); +@@ -3318,6 +3316,9 @@ main (int argc, char *argv[]) + + pthread_cond_init_mono(&config_cond); + ++ if (atexit(dm_lib_exit)) ++ condlog(3, "failed to register exit handler for libdm"); ++ + libmultipath_init(); + if (atexit(libmultipath_exit)) + condlog(3, "failed to register exit handler for libmultipath"); +-- +2.17.2 + diff --git a/0054-kpartx-fix-Wsign-compare-error.patch b/0054-kpartx-fix-Wsign-compare-error.patch deleted file mode 100644 index ffaa477..0000000 --- a/0054-kpartx-fix-Wsign-compare-error.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 6 Jul 2020 17:28:46 -0500 -Subject: [PATCH] kpartx: fix -Wsign-compare error - -Signed-off-by: Benjamin Marzinski ---- - kpartx/kpartx.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/kpartx/kpartx.c b/kpartx/kpartx.c -index c24ad6d9..653ce0c8 100644 ---- a/kpartx/kpartx.c -+++ b/kpartx/kpartx.c -@@ -738,7 +738,7 @@ struct block { - /* blknr is always in 512 byte blocks */ - char * - getblock (int fd, unsigned int blknr) { -- unsigned int secsz = get_sector_size(fd); -+ int secsz = get_sector_size(fd); - unsigned int blks_per_sec = secsz / 512; - unsigned int secnr = blknr / blks_per_sec; - unsigned int blk_off = (blknr % blks_per_sec) * 512; --- -2.17.2 - diff --git a/0054-libmultipath-log_thread_stop-check-if-logarea-is-ini.patch b/0054-libmultipath-log_thread_stop-check-if-logarea-is-ini.patch new file mode 100644 index 0000000..004016c --- /dev/null +++ b/0054-libmultipath-log_thread_stop-check-if-logarea-is-ini.patch @@ -0,0 +1,29 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 23 Sep 2020 21:04:04 +0200 +Subject: [PATCH] libmultipath: log_thread_stop(): check if logarea is + initialized + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/log_pthread.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/libmultipath/log_pthread.c b/libmultipath/log_pthread.c +index 15baef88..0c327ffc 100644 +--- a/libmultipath/log_pthread.c ++++ b/libmultipath/log_pthread.c +@@ -112,6 +112,9 @@ void log_thread_reset (void) + + void log_thread_stop (void) + { ++ if (!la) ++ return; ++ + logdbg(stderr,"enter log_thread_stop\n"); + + pthread_mutex_lock(&logev_lock); +-- +2.17.2 + diff --git a/0055-libmultipath-remove-code-duplication-in-path-countin.patch b/0055-libmultipath-remove-code-duplication-in-path-countin.patch deleted file mode 100644 index 699049a..0000000 --- a/0055-libmultipath-remove-code-duplication-in-path-countin.patch +++ /dev/null @@ -1,129 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 21 Jul 2020 01:12:05 -0500 -Subject: [PATCH] libmultipath: remove code duplication in path counting - -pathcountgr() is never used except by pathcount(), and neither is the -special case for PATH_WILD. Simplify this and make one function that is -used by both pathcount() and count_active_paths(). This will be used -again in a future patch. - -Also use count_active_paths() in mpath_persist. - -Signed-off-by: Benjamin Marzinski ---- - libmpathpersist/mpath_persist.c | 4 +-- - libmultipath/structs.c | 47 +++++++++++++-------------------- - libmultipath/structs.h | 1 - - 3 files changed, 21 insertions(+), 31 deletions(-) - -diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c -index 3da7a6cf..a132f4e9 100644 ---- a/libmpathpersist/mpath_persist.c -+++ b/libmpathpersist/mpath_persist.c -@@ -436,7 +436,7 @@ int mpath_prout_reg(struct multipath *mpp,int rq_servact, int rq_scope, - - 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); -+ active_pathcount = count_active_paths(mpp); - - if (active_pathcount == 0) { - condlog (0, "%s: no path available", mpp->wwid); -@@ -648,7 +648,7 @@ int mpath_prout_rel(struct multipath *mpp,int rq_servact, int rq_scope, - if (!mpp) - return MPATH_PR_DMMP_ERROR; - -- active_pathcount = pathcount (mpp, PATH_UP) + pathcount (mpp, PATH_GHOST); -+ active_pathcount = count_active_paths(mpp); - - struct threadinfo thread[active_pathcount]; - memset(thread, 0, sizeof(thread)); -diff --git a/libmultipath/structs.c b/libmultipath/structs.c -index 2dd378c4..3eac3d61 100644 ---- a/libmultipath/structs.c -+++ b/libmultipath/structs.c -@@ -455,49 +455,40 @@ find_path_by_devt (const struct _vector *pathvec, const char * dev_t) - return NULL; - } - --int pathcountgr(const struct pathgroup *pgp, int state) -+static int do_pathcount(const struct multipath *mpp, const int *states, -+ unsigned int nr_states) - { -+ struct pathgroup *pgp; - struct path *pp; - int count = 0; -- int i; -+ unsigned int i, j, k; - -- vector_foreach_slot (pgp->paths, pp, i) -- if ((pp->state == state) || (state == PATH_WILD)) -- count++; -+ if (!mpp->pg || !nr_states) -+ return count; - -+ vector_foreach_slot (mpp->pg, pgp, i) { -+ vector_foreach_slot (pgp->paths, pp, j) { -+ for (k = 0; k < nr_states; k++) { -+ if (pp->state == states[k]) { -+ count++; -+ break; -+ } -+ } -+ } -+ } - return count; - } - - int pathcount(const struct multipath *mpp, int state) - { -- struct pathgroup *pgp; -- int count = 0; -- int i; -- -- if (mpp->pg) { -- vector_foreach_slot (mpp->pg, pgp, i) -- count += pathcountgr(pgp, state); -- } -- return count; -+ return do_pathcount(mpp, &state, 1); - } - - int count_active_paths(const struct multipath *mpp) - { -- struct pathgroup *pgp; -- struct path *pp; -- int count = 0; -- int i, j; -- -- if (!mpp->pg) -- return 0; -+ int states[] = {PATH_UP, PATH_GHOST}; - -- vector_foreach_slot (mpp->pg, pgp, i) { -- vector_foreach_slot (pgp->paths, pp, j) { -- if (pp->state == PATH_UP || pp->state == PATH_GHOST) -- count++; -- } -- } -- return count; -+ return do_pathcount(mpp, states, 2); - } - - int pathcmp(const struct pathgroup *pgp, const struct pathgroup *cpgp) -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index d69bc2e9..0c03e711 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -446,7 +446,6 @@ struct path * find_path_by_devt (const struct _vector *pathvec, const char *devt - struct path * find_path_by_dev (const struct _vector *pathvec, const char *dev); - struct path * first_path (const struct multipath *mpp); - --int pathcountgr (const struct pathgroup *, int); - int pathcount (const struct multipath *, int); - int count_active_paths(const struct multipath *); - int pathcmp (const struct pathgroup *, const struct pathgroup *); --- -2.17.2 - diff --git a/0055-multipathd-add-cleanup_child-exit-handler.patch b/0055-multipathd-add-cleanup_child-exit-handler.patch new file mode 100644 index 0000000..8455a96 --- /dev/null +++ b/0055-multipathd-add-cleanup_child-exit-handler.patch @@ -0,0 +1,95 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 23 Sep 2020 21:08:19 +0200 +Subject: [PATCH] multipathd: add cleanup_child() exit handler + +cleanup_child() calls all cleanups in the right order, in an +exit handler. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 45 +++++++++++++++++++++++++-------------------- + 1 file changed, 25 insertions(+), 20 deletions(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 4c4e2eab..50cc3356 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -3024,6 +3024,27 @@ static void cleanup_rcu(void) + rcu_unregister_thread(); + } + ++static void cleanup_child(void) ++{ ++ cleanup_threads(); ++ cleanup_vecs(); ++ cleanup_foreign(); ++ cleanup_checkers(); ++ cleanup_prio(); ++ if (poll_dmevents) ++ cleanup_dmevent_waiter(); ++ ++ cleanup_pidfile(); ++ if (logsink == 1) ++ log_thread_stop(); ++ ++ cleanup_conf(); ++ ++#ifdef _DEBUG_ ++ dbg_free_final(NULL); ++#endif ++} ++ + static int sd_notify_exit(int err) + { + #ifdef USE_SYSTEMD +@@ -3049,7 +3070,9 @@ child (__attribute__((unused)) void *param) + mlockall(MCL_CURRENT | MCL_FUTURE); + signal_init(); + mp_rcu_data = setup_rcu(); +- atexit(cleanup_rcu); ++ ++ if (atexit(cleanup_rcu) || atexit(cleanup_child)) ++ fprintf(stderr, "failed to register cleanup handlers\n"); + + setup_thread_attr(&misc_attr, 64 * 1024, 0); + setup_thread_attr(&uevent_attr, DEFAULT_UEVENT_STACKSIZE * 1024, 0); +@@ -3063,8 +3086,6 @@ child (__attribute__((unused)) void *param) + pid_fd = pidfile_create(DEFAULT_PIDFILE, daemon_pid); + if (pid_fd < 0) { + condlog(1, "failed to create pidfile"); +- if (logsink == 1) +- log_thread_stop(); + exit(1); + } + +@@ -3212,24 +3233,8 @@ child (__attribute__((unused)) void *param) + + exit_code = 0; + failed: +- cleanup_threads(); +- cleanup_vecs(); +- cleanup_foreign(); +- cleanup_checkers(); +- cleanup_prio(); +- if (poll_dmevents) +- cleanup_dmevent_waiter(); +- +- /* We're done here */ +- cleanup_pidfile(); + condlog(2, "--------shut down-------"); +- +- if (logsink == 1) +- log_thread_stop(); +- cleanup_conf(); +-#ifdef _DEBUG_ +- dbg_free_final(NULL); +-#endif ++ /* All cleanup is done in the cleanup_child() exit handler */ + return sd_notify_exit(exit_code); + } + +-- +2.17.2 + diff --git a/0056-libmultipath-count-pending-paths-as-active-on-loads.patch b/0056-libmultipath-count-pending-paths-as-active-on-loads.patch deleted file mode 100644 index 5320297..0000000 --- a/0056-libmultipath-count-pending-paths-as-active-on-loads.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 21 Jul 2020 01:19:30 -0500 -Subject: [PATCH] libmultipath: count pending paths as active on loads - -When multipath loads a table, it signals to udev if there are no active -paths. Multipath wasn't counting pending paths as active. This meant -that if all the paths were pending, udev would treat the device as not -ready, and not run kpartx on it. Even if the pending paths later -because active and were reinstated, the kernel would not send a new -uevent, because from its point of view, they were always up. - -The alternative would be to continue to treat them as failed in the udev -rules, but then also tell the kernel that they were down, so that it -would trigger a uevent when they were reinstated. However, this could -lead to newly created multipath devices failing IO, simply because the -path checkers hadn't returned yet. Having udev assume that the the -device is up, like the kernel does, seems like the safer option. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/devmapper.c | 3 ++- - libmultipath/structs.c | 7 +++++++ - libmultipath/structs.h | 1 + - 3 files changed, 10 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index f597ff8b..126cd728 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -417,7 +417,8 @@ static uint16_t build_udev_flags(const struct multipath *mpp, int reload) - /* DM_UDEV_DISABLE_LIBRARY_FALLBACK is added in dm_addmap */ - return (mpp->skip_kpartx == SKIP_KPARTX_ON ? - MPATH_UDEV_NO_KPARTX_FLAG : 0) | -- ((count_active_paths(mpp) == 0 || mpp->ghost_delay_tick > 0) ? -+ ((count_active_pending_paths(mpp) == 0 || -+ mpp->ghost_delay_tick > 0) ? - MPATH_UDEV_NO_PATHS_FLAG : 0) | - (reload && !mpp->force_udev_reload ? - MPATH_UDEV_RELOAD_FLAG : 0); -diff --git a/libmultipath/structs.c b/libmultipath/structs.c -index 3eac3d61..0d1f969d 100644 ---- a/libmultipath/structs.c -+++ b/libmultipath/structs.c -@@ -491,6 +491,13 @@ int count_active_paths(const struct multipath *mpp) - return do_pathcount(mpp, states, 2); - } - -+int count_active_pending_paths(const struct multipath *mpp) -+{ -+ int states[] = {PATH_UP, PATH_GHOST, PATH_PENDING}; -+ -+ return do_pathcount(mpp, states, 3); -+} -+ - int pathcmp(const struct pathgroup *pgp, const struct pathgroup *cpgp) - { - int i, j; -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index 0c03e711..917e4083 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -448,6 +448,7 @@ struct path * first_path (const struct multipath *mpp); - - int pathcount (const struct multipath *, int); - int count_active_paths(const struct multipath *); -+int count_active_pending_paths(const struct multipath *); - int pathcmp (const struct pathgroup *, const struct pathgroup *); - int add_feature (char **, const char *); - int remove_feature (char **, const char *); --- -2.17.2 - diff --git a/0056-libmultipath-fix-log_thread-startup-and-teardown.patch b/0056-libmultipath-fix-log_thread-startup-and-teardown.patch new file mode 100644 index 0000000..106f19a --- /dev/null +++ b/0056-libmultipath-fix-log_thread-startup-and-teardown.patch @@ -0,0 +1,148 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 26 Oct 2020 16:44:32 +0100 +Subject: [PATCH] libmultipath: fix log_thread startup and teardown + +This fixes several issues with the log_thread. First, the running flag +logq_running should be set by the thread itself, not by +log_thread_start()/_stop(). Second, the thread was both cancelled and +terminated via a flag (again, logq_running). It's sufficient to just cancel +and join it. Third, the locking wasn't cancel-safe in some places. Forth, +log_thread_start() didn't wait for startup properly. Fifth, using (pthread_t)0 +is wrong (pthread_t is opaque; there's no guarantee that 0 is not a valid +pthread_t value). Sixth, pthread_cancel() was called under logq_lock, which +doesn't make sense to me. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/log_pthread.c | 62 +++++++++++++++++++++++++++----------- + 1 file changed, 45 insertions(+), 17 deletions(-) + +diff --git a/libmultipath/log_pthread.c b/libmultipath/log_pthread.c +index 0c327ffc..3a2566ae 100644 +--- a/libmultipath/log_pthread.c ++++ b/libmultipath/log_pthread.c +@@ -13,6 +13,7 @@ + #include "log_pthread.h" + #include "log.h" + #include "lock.h" ++#include "util.h" + + static pthread_t log_thr; + +@@ -56,35 +57,52 @@ static void flush_logqueue (void) + } while (empty == 0); + } + ++static void cleanup_log_thread(__attribute((unused)) void *arg) ++{ ++ logdbg(stderr, "log thread exiting"); ++ pthread_mutex_lock(&logev_lock); ++ logq_running = 0; ++ pthread_mutex_unlock(&logev_lock); ++} ++ + static void * log_thread (__attribute__((unused)) void * et) + { + int running; + + pthread_mutex_lock(&logev_lock); +- logq_running = 1; ++ running = logq_running; ++ if (!running) ++ logq_running = 1; ++ pthread_cond_signal(&logev_cond); + pthread_mutex_unlock(&logev_lock); ++ if (running) ++ /* already started */ ++ return NULL; ++ pthread_cleanup_push(cleanup_log_thread, NULL); + + mlockall(MCL_CURRENT | MCL_FUTURE); + logdbg(stderr,"enter log_thread\n"); + + while (1) { + pthread_mutex_lock(&logev_lock); +- if (logq_running && !log_messages_pending) ++ pthread_cleanup_push(cleanup_mutex, &logev_lock); ++ while (!log_messages_pending) ++ /* this is a cancellation point */ + pthread_cond_wait(&logev_cond, &logev_lock); + log_messages_pending = 0; +- running = logq_running; +- pthread_mutex_unlock(&logev_lock); +- if (!running) +- break; ++ pthread_cleanup_pop(1); ++ + flush_logqueue(); + } ++ pthread_cleanup_pop(1); + return NULL; + } + + void log_thread_start (pthread_attr_t *attr) + { +- logdbg(stderr,"enter log_thread_start\n"); ++ int running = 0; + ++ logdbg(stderr,"enter log_thread_start\n"); + pthread_mutex_init(&logq_lock, NULL); + pthread_mutex_init(&logev_lock, NULL); + pthread_cond_init(&logev_cond, NULL); +@@ -93,7 +111,15 @@ void log_thread_start (pthread_attr_t *attr) + fprintf(stderr,"can't initialize log buffer\n"); + exit(1); + } +- if (pthread_create(&log_thr, attr, log_thread, NULL)) { ++ ++ pthread_mutex_lock(&logev_lock); ++ pthread_cleanup_push(cleanup_mutex, &logev_lock); ++ if (!pthread_create(&log_thr, attr, log_thread, NULL)) ++ while (!(running = logq_running)) ++ pthread_cond_wait(&logev_cond, &logev_lock); ++ pthread_cleanup_pop(1); ++ ++ if (!running) { + fprintf(stderr,"can't start log thread\n"); + exit(1); + } +@@ -112,23 +138,25 @@ void log_thread_reset (void) + + void log_thread_stop (void) + { ++ int running; ++ + if (!la) + return; + + logdbg(stderr,"enter log_thread_stop\n"); + + pthread_mutex_lock(&logev_lock); +- logq_running = 0; +- pthread_cond_signal(&logev_cond); +- pthread_mutex_unlock(&logev_lock); +- +- pthread_mutex_lock(&logq_lock); +- pthread_cancel(log_thr); +- pthread_mutex_unlock(&logq_lock); +- pthread_join(log_thr, NULL); +- log_thr = (pthread_t)0; ++ pthread_cleanup_push(cleanup_mutex, &logev_lock); ++ running = logq_running; ++ if (running) { ++ pthread_cancel(log_thr); ++ pthread_cond_signal(&logev_cond); ++ } ++ pthread_cleanup_pop(1); + + flush_logqueue(); ++ if (running) ++ pthread_join(log_thr, NULL); + + pthread_mutex_destroy(&logq_lock); + pthread_mutex_destroy(&logev_lock); +-- +2.17.2 + diff --git a/0057-libmultipath-deal-with-flushing-no-maps.patch b/0057-libmultipath-deal-with-flushing-no-maps.patch deleted file mode 100644 index 0aee761..0000000 --- a/0057-libmultipath-deal-with-flushing-no-maps.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 21 Jul 2020 01:28:22 -0500 -Subject: [PATCH] libmultipath: deal with flushing no maps - -dm_flush_maps() was failing if there were no device-mapper devices at -all, instead of returning success, since there is nothing to do. - -Fixes: "libmultipath: make dm_flush_maps only return 0 on success" -Signed-off-by: Benjamin Marzinski ---- - libmultipath/devmapper.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index 126cd728..b8199cb5 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -1024,10 +1024,10 @@ int dm_flush_maps (int need_suspend, int retries) - if (!(names = dm_task_get_names (dmt))) - goto out; - -+ r = 0; - if (!names->dev) - goto out; - -- r = 0; - do { - if (need_suspend) - r |= dm_suspend_and_flush_map(names->name, retries); --- -2.17.2 - diff --git a/0057-multipathd-move-cleanup_-prio-checkers-foreign-to-li.patch b/0057-multipathd-move-cleanup_-prio-checkers-foreign-to-li.patch new file mode 100644 index 0000000..017034e --- /dev/null +++ b/0057-multipathd-move-cleanup_-prio-checkers-foreign-to-li.patch @@ -0,0 +1,93 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 23 Sep 2020 21:57:22 +0200 +Subject: [PATCH] multipathd: move cleanup_{prio,checkers,foreign} to + libmultipath_exit + +This requires another major ABI bump. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmpathpersist/mpath_persist.c | 2 -- + libmultipath/config.c | 4 ++++ + libmultipath/libmultipath.version | 5 +---- + multipathd/main.c | 3 --- + 4 files changed, 5 insertions(+), 9 deletions(-) + +diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c +index e1d1cb76..9ebf91dd 100644 +--- a/libmpathpersist/mpath_persist.c ++++ b/libmpathpersist/mpath_persist.c +@@ -78,8 +78,6 @@ mpath_lib_init (void) + + static void libmpathpersist_cleanup(void) + { +- cleanup_prio(); +- cleanup_checkers(); + libmultipath_exit(); + dm_lib_exit(); + } +diff --git a/libmultipath/config.c b/libmultipath/config.c +index b9cb4131..52b1447b 100644 +--- a/libmultipath/config.c ++++ b/libmultipath/config.c +@@ -26,6 +26,7 @@ + #include "devmapper.h" + #include "mpath_cmd.h" + #include "propsel.h" ++#include "foreign.h" + + /* + * We don't support re-initialization after +@@ -60,6 +61,9 @@ int libmultipath_init(void) + static void _libmultipath_exit(void) + { + libmultipath_exit_called = true; ++ cleanup_foreign(); ++ cleanup_checkers(); ++ cleanup_prio(); + libmp_dm_exit(); + udev_unref(udev); + } +diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version +index 84beb7f0..800cff22 100644 +--- a/libmultipath/libmultipath.version ++++ b/libmultipath/libmultipath.version +@@ -31,7 +31,7 @@ + * The new version inherits the previous ones. + */ + +-LIBMULTIPATH_3.0.0 { ++LIBMULTIPATH_4.0.0 { + global: + /* symbols referenced by multipath and multipathd */ + add_foreign; +@@ -51,10 +51,7 @@ global: + checker_name; + checker_state_name; + check_foreign; +- cleanup_checkers; +- cleanup_foreign; + cleanup_lock; +- cleanup_prio; + close_fd; + coalesce_paths; + convert_dev; +diff --git a/multipathd/main.c b/multipathd/main.c +index 50cc3356..4de0978e 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -3028,9 +3028,6 @@ static void cleanup_child(void) + { + cleanup_threads(); + cleanup_vecs(); +- cleanup_foreign(); +- cleanup_checkers(); +- cleanup_prio(); + if (poll_dmevents) + cleanup_dmevent_waiter(); + +-- +2.17.2 + diff --git a/0058-multipath-deal-with-delegation-failures-correctly.patch b/0058-multipath-deal-with-delegation-failures-correctly.patch deleted file mode 100644 index e8d0050..0000000 --- a/0058-multipath-deal-with-delegation-failures-correctly.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 21 Jul 2020 01:37:18 -0500 -Subject: [PATCH] multipath: deal with delegation failures correctly - -delegate_to_multipathd() was returning success, even if the multipathd -command failed. Also, if the command was set to fail with NOT_DELEGATED, -it shouldn't print any errors, since multipath will try to issue to -command itself. - -Fixes: "multipath: delegate flushing maps to multipathd" -Signed-off-by: Benjamin Marzinski ---- - multipath/main.c | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - -diff --git a/multipath/main.c b/multipath/main.c -index 4c43314e..3da692dc 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -861,9 +861,12 @@ int delegate_to_multipathd(enum mpath_cmds cmd, - goto out; - } - -- if (reply != NULL && *reply != '\0' && strcmp(reply, "ok\n")) -- printf("%s", reply); -- r = DELEGATE_OK; -+ if (reply != NULL && *reply != '\0') { -+ if (strcmp(reply, "fail\n")) -+ r = DELEGATE_OK; -+ if (r != NOT_DELEGATED && strcmp(reply, "ok\n")) -+ printf("%s", reply); -+ } - - out: - FREE(reply); --- -2.17.2 - diff --git a/0058-multipath-use-atexit-for-cleanup-handlers.patch b/0058-multipath-use-atexit-for-cleanup-handlers.patch new file mode 100644 index 0000000..444a39d --- /dev/null +++ b/0058-multipath-use-atexit-for-cleanup-handlers.patch @@ -0,0 +1,110 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 23 Sep 2020 00:30:02 +0200 +Subject: [PATCH] multipath: use atexit() for cleanup handlers + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/main.c | 37 ++++++++++++++++--------------------- + 1 file changed, 16 insertions(+), 21 deletions(-) + +diff --git a/multipath/main.c b/multipath/main.c +index 9ae46ed5..1949a1cd 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -452,13 +452,19 @@ static bool released_to_systemd(void) + return ret; + } + ++static struct vectors vecs; ++static void cleanup_vecs(void) ++{ ++ free_multipathvec(vecs.mpvec, KEEP_PATHS); ++ free_pathvec(vecs.pathvec, FREE_PATHS); ++} ++ + static int + configure (struct config *conf, enum mpath_cmds cmd, + enum devtypes dev_type, char *devpath) + { + vector curmp = NULL; + vector pathvec = NULL; +- struct vectors vecs; + int r = RTVL_FAIL, rc; + int di_flag = 0; + char * refwwid = NULL; +@@ -469,6 +475,7 @@ configure (struct config *conf, enum mpath_cmds cmd, + */ + curmp = vector_alloc(); + pathvec = vector_alloc(); ++ atexit(cleanup_vecs); + + if (!curmp || !pathvec) { + condlog(0, "can not allocate memory"); +@@ -580,9 +587,6 @@ out: + if (refwwid) + FREE(refwwid); + +- free_multipathvec(curmp, KEEP_PATHS); +- free_pathvec(pathvec, FREE_PATHS); +- + return r; + } + +@@ -808,9 +812,13 @@ main (int argc, char *argv[]) + bool enable_foreign = false; + + libmultipath_init(); ++ if (atexit(dm_lib_exit) || atexit(libmultipath_exit)) ++ condlog(1, "failed to register cleanup handler for libmultipath: %m"); + logsink = 0; + if (init_config(DEFAULT_CONFIGFILE)) + exit(RTVL_FAIL); ++ if (atexit(uninit_config)) ++ condlog(1, "failed to register cleanup handler for config: %m"); + conf = get_multipath_config(); + conf->retrigger_tries = 0; + conf->force_sync = 1; +@@ -887,7 +895,7 @@ main (int argc, char *argv[]) + break; + case 't': + r = dump_config(conf, NULL, NULL) ? RTVL_FAIL : RTVL_OK; +- goto out_free_config; ++ goto out; + case 'T': + cmd = CMD_DUMP_CONFIG; + break; +@@ -1048,26 +1056,13 @@ main (int argc, char *argv[]) + condlog(3, "restart multipath configuration process"); + + out: +- dm_lib_exit(); +- +- cleanup_foreign(); +- cleanup_prio(); +- cleanup_checkers(); ++ put_multipath_config(conf); ++ if (dev) ++ FREE(dev); + + if (dev_type == DEV_UEVENT) + closelog(); + +-out_free_config: +- /* +- * Freeing config must be done after dm_lib_exit(), because +- * the logging function (dm_write_log()), which is called there, +- * references the config. +- */ +- put_multipath_config(conf); +- uninit_config(); +- libmultipath_exit(); +- if (dev) +- FREE(dev); + #ifdef _DEBUG_ + dbg_free_final(NULL); + #endif +-- +2.17.2 + diff --git a/0059-mpathpersist-use-atexit-for-cleanup-handlers.patch b/0059-mpathpersist-use-atexit-for-cleanup-handlers.patch new file mode 100644 index 0000000..7494b34 --- /dev/null +++ b/0059-mpathpersist-use-atexit-for-cleanup-handlers.patch @@ -0,0 +1,32 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 23 Sep 2020 00:32:48 +0200 +Subject: [PATCH] mpathpersist: use atexit() for cleanup handlers + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + mpathpersist/main.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/mpathpersist/main.c b/mpathpersist/main.c +index 3c2e6576..14245cc3 100644 +--- a/mpathpersist/main.c ++++ b/mpathpersist/main.c +@@ -641,11 +641,10 @@ int main(int argc, char *argv[]) + if (libmpathpersist_init()) { + exit(1); + } ++ if (atexit((void(*)(void))libmpathpersist_exit)) ++ fprintf(stderr, "failed to register cleanup handler for libmpathpersist: %m"); + + ret = handle_args(argc, argv, 0); +- +- libmpathpersist_exit(); +- + return (ret >= 0) ? ret : MPATH_PR_OTHER; + } + +-- +2.17.2 + diff --git a/0060-multipath-fix-leak-in-check_path_valid.patch b/0060-multipath-fix-leak-in-check_path_valid.patch new file mode 100644 index 0000000..c96f4cb --- /dev/null +++ b/0060-multipath-fix-leak-in-check_path_valid.patch @@ -0,0 +1,95 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 23 Sep 2020 23:30:50 +0200 +Subject: [PATCH] multipath: fix leak in check_path_valid() + +If path status was successfully determined before calling store_pathvec(), +free_path() wasn't called. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/main.c | 30 ++++++++++++++++++++---------- + 1 file changed, 20 insertions(+), 10 deletions(-) + +diff --git a/multipath/main.c b/multipath/main.c +index 1949a1cd..043d8fa7 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -93,7 +93,7 @@ void rcu_register_thread_memb(void) {} + void rcu_unregister_thread_memb(void) {} + + static int +-filter_pathvec (vector pathvec, char * refwwid) ++filter_pathvec (vector pathvec, const char *refwwid) + { + int i; + struct path * pp; +@@ -594,8 +594,9 @@ static int + check_path_valid(const char *name, struct config *conf, bool is_uevent) + { + int fd, r = PATH_IS_ERROR; +- struct path *pp = NULL; ++ struct path *pp; + vector pathvec = NULL; ++ const char *wwid; + + pp = alloc_path(); + if (!pp) +@@ -664,14 +665,19 @@ check_path_valid(const char *name, struct config *conf, bool is_uevent) + + if (store_path(pathvec, pp) != 0) { + free_path(pp); ++ pp = NULL; + goto fail; ++ } else { ++ /* make sure path isn't freed twice */ ++ wwid = pp->wwid; ++ pp = NULL; + } + + /* For find_multipaths = SMART, if there is more than one path + * matching the refwwid, then the path is valid */ + if (path_discovery(pathvec, DI_SYSFS | DI_WWID) < 0) + goto fail; +- filter_pathvec(pathvec, pp->wwid); ++ filter_pathvec(pathvec, wwid); + if (VECTOR_SIZE(pathvec) > 1) + r = PATH_IS_VALID; + else +@@ -679,21 +685,25 @@ check_path_valid(const char *name, struct config *conf, bool is_uevent) + + out: + r = print_cmd_valid(r, pathvec, conf); +- free_pathvec(pathvec, FREE_PATHS); + /* + * multipath -u must exit with status 0, otherwise udev won't + * import its output. + */ + if (!is_uevent && r == PATH_IS_NOT_VALID) +- return RTVL_FAIL; +- return RTVL_OK; ++ r = RTVL_FAIL; ++ else ++ r = RTVL_OK; ++ goto cleanup; + + fail: +- if (pathvec) +- free_pathvec(pathvec, FREE_PATHS); +- else ++ r = RTVL_FAIL; ++ ++cleanup: ++ if (pp != NULL) + free_path(pp); +- return RTVL_FAIL; ++ if (pathvec != NULL) ++ free_pathvec(pathvec, FREE_PATHS); ++ return r; + } + + static int +-- +2.17.2 + diff --git a/0061-multipath-tools-mpath-tools.supp-file-with-valgrind-.patch b/0061-multipath-tools-mpath-tools.supp-file-with-valgrind-.patch new file mode 100644 index 0000000..4228be6 --- /dev/null +++ b/0061-multipath-tools-mpath-tools.supp-file-with-valgrind-.patch @@ -0,0 +1,62 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 24 Sep 2020 15:13:06 +0200 +Subject: [PATCH] multipath-tools: mpath-tools.supp: file with valgrind + suppressions + +These leaks are caused by other libraries (libsystemd, glibc, +libgcrypt) and should be ignored when debugging with valgrind + +Usage example: + +valgrind --suppressions=mpath-tools.supp \ + --leak-check=full --show-leak-kinds=all $COMMAND + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + third-party/valgrind/mpath-tools.supp | 32 +++++++++++++++++++++++++++ + 1 file changed, 32 insertions(+) + create mode 100644 third-party/valgrind/mpath-tools.supp + +diff --git a/third-party/valgrind/mpath-tools.supp b/third-party/valgrind/mpath-tools.supp +new file mode 100644 +index 00000000..0537fd56 +--- /dev/null ++++ b/third-party/valgrind/mpath-tools.supp +@@ -0,0 +1,32 @@ ++{ ++ glibc _dlerror_run leak: https://stackoverflow.com/questions/1542457/memory-leak-reported-by-valgrind-in-dlopen ++ Memcheck:Leak ++ match-leak-kinds: reachable ++ fun:calloc ++ fun:_dlerror_run ++ fun:dlopen* ++} ++ ++{ ++ systemd mempools are never freed: https://bugzilla.redhat.com/show_bug.cgi?id=1215670 ++ Memcheck:Leak ++ match-leak-kinds: reachable ++ fun:malloc ++ fun:mempool_alloc_tile ++ fun:mempool_alloc0_tile ++ fun:hashmap_base_new ++ fun:hashmap_base_ensure_allocated ++} ++ ++{ ++ libgcrypt library initialization ++ Memcheck:Leak ++ match-leak-kinds: reachable ++ fun:malloc ++ ... ++ fun:_gcry_xmalloc ++ ... ++ fun:global_init.* ++ ... ++ fun:_dl_init ++} +-- +2.17.2 + diff --git a/0062-libmultipath-use-libmp_verbosity-to-track-verbosity.patch b/0062-libmultipath-use-libmp_verbosity-to-track-verbosity.patch new file mode 100644 index 0000000..042929d --- /dev/null +++ b/0062-libmultipath-use-libmp_verbosity-to-track-verbosity.patch @@ -0,0 +1,441 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Sat, 26 Sep 2020 00:04:53 +0200 +Subject: [PATCH] libmultipath: use libmp_verbosity to track verbosity + +Introduce a new global variable to set the verbosity of libmultipath. +This avoids accessing the configuration in every dlog() call. +When libmultipath reads its configuration in init_config() or +load_config(), it will use the current value of libmp_verbosity +for logging. Immediately before returning, libmp_verbosity will be +overwritten with the verbosity value from the configuration file, +if it was set there. An application is free to set libmp_verbosity +back to the previous value or not after that, depending on whether +command line options or configuration file settings should take +precedence. + +Replace internal access to conf->verbosity with the new variable. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmpathpersist/mpath_persist.c | 5 +--- + libmultipath/config.c | 9 +++++-- + libmultipath/configure.c | 16 +++---------- + libmultipath/debug.c | 10 ++------ + libmultipath/debug.h | 1 + + libmultipath/devmapper.c | 7 +----- + libmultipath/libmultipath.version | 5 ++++ + multipath/main.c | 21 ++++++---------- + multipathd/main.c | 40 ++++++++++++++++++------------- + tests/alias.c | 1 + + tests/blacklist.c | 2 ++ + 11 files changed, 53 insertions(+), 64 deletions(-) + +diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c +index 9ebf91dd..79322e86 100644 +--- a/libmpathpersist/mpath_persist.c ++++ b/libmpathpersist/mpath_persist.c +@@ -170,10 +170,7 @@ void mpath_persistent_reserve_free_vecs(void) + + int mpath_persistent_reserve_init_vecs(int verbose) + { +- struct config *conf = get_multipath_config(); +- +- conf->verbosity = verbose; +- put_multipath_config(conf); ++ libmp_verbosity = verbose; + + if (curmp) + return MPATH_PR_SUCCESS; +diff --git a/libmultipath/config.c b/libmultipath/config.c +index 52b1447b..49e7fb81 100644 +--- a/libmultipath/config.c ++++ b/libmultipath/config.c +@@ -828,10 +828,14 @@ int _init_config (const char *file, struct config *conf) + conf = &__internal_config; + + /* +- * internal defaults ++ * Processing the config file will overwrite conf->verbosity if set ++ * When we return, we'll copy the config value back + */ +- conf->verbosity = DEFAULT_VERBOSITY; ++ conf->verbosity = libmp_verbosity; + ++ /* ++ * internal defaults ++ */ + get_sys_max_fds(&conf->max_fds); + conf->bindings_file = set_default(DEFAULT_BINDINGS_FILE); + conf->wwids_file = set_default(DEFAULT_WWIDS_FILE); +@@ -997,6 +1001,7 @@ int _init_config (const char *file, struct config *conf) + !conf->wwids_file || !conf->prkeys_file) + goto out; + ++ libmp_verbosity = conf->verbosity; + return 0; + out: + _uninit_config(conf); +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index d36f0d0d..20536e60 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -934,16 +934,12 @@ int domap(struct multipath *mpp, char *params, int is_daemon) + { + int r = DOMAP_FAIL; + struct config *conf; +- int verbosity; + + /* + * last chance to quit before touching the devmaps + */ + if (mpp->action == ACT_DRY_RUN) { +- conf = get_multipath_config(); +- verbosity = conf->verbosity; +- put_multipath_config(conf); +- print_multipath_topology(mpp, verbosity); ++ print_multipath_topology(mpp, libmp_verbosity); + return DOMAP_DRY; + } + +@@ -1327,14 +1323,8 @@ int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid, + "queue_if_no_path"); + } + +- if (!is_daemon && mpp->action != ACT_NOTHING) { +- int verbosity; +- +- conf = get_multipath_config(); +- verbosity = conf->verbosity; +- put_multipath_config(conf); +- print_multipath_topology(mpp, verbosity); +- } ++ if (!is_daemon && mpp->action != ACT_NOTHING) ++ print_multipath_topology(mpp, libmp_verbosity); + + if (mpp->action != ACT_REJECT) { + if (!vector_alloc_slot(newmp)) { +diff --git a/libmultipath/debug.c b/libmultipath/debug.c +index b3a1de9e..a1713b95 100644 +--- a/libmultipath/debug.c ++++ b/libmultipath/debug.c +@@ -16,21 +16,15 @@ + #include "debug.h" + + int logsink; ++int libmp_verbosity = DEFAULT_VERBOSITY; + + void dlog (int sink, int prio, const char * fmt, ...) + { + va_list ap; +- int thres; +- struct config *conf; + + va_start(ap, fmt); +- conf = get_multipath_config(); +- ANNOTATE_IGNORE_READS_BEGIN(); +- thres = (conf) ? conf->verbosity : DEFAULT_VERBOSITY; +- ANNOTATE_IGNORE_READS_END(); +- put_multipath_config(conf); + +- if (prio <= thres) { ++ if (prio <= libmp_verbosity) { + if (sink < 1) { + if (sink == 0) { + time_t t = time(NULL); +diff --git a/libmultipath/debug.h b/libmultipath/debug.h +index c6120c1d..1f3bc8be 100644 +--- a/libmultipath/debug.h ++++ b/libmultipath/debug.h +@@ -8,6 +8,7 @@ void dlog (int sink, int prio, const char * fmt, ...) + #include "log_pthread.h" + + extern int logsink; ++extern int libmp_verbosity; + + #define condlog(prio, fmt, args...) \ + dlog(logsink, prio, fmt "\n", ##args) +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index e60ab493..dfe95d2f 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -351,16 +351,11 @@ void libmp_dm_exit(void) + + static void libmp_dm_init(void) + { +- struct config *conf; +- int verbosity; + unsigned int version[3]; + + if (dm_prereq(version)) + exit(1); +- conf = get_multipath_config(); +- verbosity = conf->verbosity; +- put_multipath_config(conf); +- dm_init(verbosity); ++ dm_init(libmp_verbosity); + #ifdef LIBDM_API_HOLD_CONTROL + dm_hold_control_dev(1); + #endif +diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version +index 800cff22..67a7379f 100644 +--- a/libmultipath/libmultipath.version ++++ b/libmultipath/libmultipath.version +@@ -259,3 +259,8 @@ global: + local: + *; + }; ++ ++LIBMULTIPATH_4.1.0 { ++global: ++ libmp_verbosity; ++} LIBMULTIPATH_4.0.0; +diff --git a/multipath/main.c b/multipath/main.c +index 043d8fa7..98d93c58 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -208,22 +208,15 @@ get_dm_mpvec (enum mpath_cmds cmd, vector curmp, vector pathvec, char * refwwid) + mpp->bestpg = select_path_group(mpp); + + if (cmd == CMD_LIST_SHORT || +- cmd == CMD_LIST_LONG) { +- struct config *conf = get_multipath_config(); +- print_multipath_topology(mpp, conf->verbosity); +- put_multipath_config(conf); +- } ++ cmd == CMD_LIST_LONG) ++ print_multipath_topology(mpp, libmp_verbosity); + + if (cmd == CMD_CREATE) + reinstate_paths(mpp); + } + +- if (cmd == CMD_LIST_SHORT || cmd == CMD_LIST_LONG) { +- struct config *conf = get_multipath_config(); +- +- print_foreign_topology(conf->verbosity); +- put_multipath_config(conf); +- } ++ if (cmd == CMD_LIST_SHORT || cmd == CMD_LIST_LONG) ++ print_foreign_topology(libmp_verbosity); + + return 0; + } +@@ -552,7 +545,7 @@ configure (struct config *conf, enum mpath_cmds cmd, + if (path_discovery(pathvec, di_flag) < 0) + goto out; + +- if (conf->verbosity > 2) ++ if (libmp_verbosity > 2) + print_all_paths(pathvec, 1); + + get_path_layout(pathvec, 0); +@@ -843,7 +836,7 @@ main (int argc, char *argv[]) + exit(RTVL_FAIL); + } + +- conf->verbosity = atoi(optarg); ++ libmp_verbosity = atoi(optarg); + break; + case 'b': + conf->bindings_file = strdup(optarg); +@@ -974,7 +967,7 @@ main (int argc, char *argv[]) + } + if (dev_type == DEV_UEVENT) { + openlog("multipath", 0, LOG_DAEMON); +- setlogmask(LOG_UPTO(conf->verbosity + 3)); ++ setlogmask(LOG_UPTO(libmp_verbosity + 3)); + logsink = 1; + } + +diff --git a/multipathd/main.c b/multipathd/main.c +index 4de0978e..ba257515 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -88,10 +88,10 @@ + #define CMDSIZE 160 + #define MSG_SIZE 32 + +-#define LOG_MSG(lvl, verb, pp) \ ++#define LOG_MSG(lvl, pp) \ + do { \ + if (pp->mpp && checker_selected(&pp->checker) && \ +- lvl <= verb) { \ ++ lvl <= libmp_verbosity) { \ + if (pp->offline) \ + condlog(lvl, "%s: %s - path offline", \ + pp->mpp->alias, pp->dev); \ +@@ -2070,7 +2070,7 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) + int chkr_new_path_up = 0; + int disable_reinstate = 0; + int oldchkrstate = pp->chkrstate; +- int retrigger_tries, verbosity; ++ int retrigger_tries; + unsigned int checkint, max_checkint; + struct config *conf; + int marginal_pathgroups, marginal_changed = 0; +@@ -2090,7 +2090,6 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) + retrigger_tries = conf->retrigger_tries; + checkint = conf->checkint; + max_checkint = conf->max_checkint; +- verbosity = conf->verbosity; + marginal_pathgroups = conf->marginal_pathgroups; + put_multipath_config(conf); + +@@ -2152,7 +2151,7 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) + if (newstate == PATH_WILD || newstate == PATH_UNCHECKED) { + condlog(2, "%s: unusable path (%s) - checker failed", + pp->dev, checker_state_name(newstate)); +- LOG_MSG(2, verbosity, pp); ++ LOG_MSG(2, pp); + conf = get_multipath_config(); + pthread_cleanup_push(put_multipath_config, conf); + pathinfo(pp, conf, 0); +@@ -2257,7 +2256,7 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) + int oldstate = pp->state; + pp->state = newstate; + +- LOG_MSG(1, verbosity, pp); ++ LOG_MSG(1, pp); + + /* + * upon state change, reset the checkint +@@ -2321,7 +2320,7 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) + /* Clear IO errors */ + reinstate_path(pp); + else { +- LOG_MSG(4, verbosity, pp); ++ LOG_MSG(4, pp); + if (pp->checkint != max_checkint) { + /* + * double the next check delay. +@@ -2349,9 +2348,9 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) + log_checker_err = conf->log_checker_err; + put_multipath_config(conf); + if (log_checker_err == LOG_CHKR_ERR_ONCE) +- LOG_MSG(3, verbosity, pp); ++ LOG_MSG(3, pp); + else +- LOG_MSG(2, verbosity, pp); ++ LOG_MSG(2, pp); + } + } + +@@ -2696,6 +2695,10 @@ reconfigure (struct vectors * vecs) + if (!conf) + return 1; + ++ if (verbosity) ++ libmp_verbosity = verbosity; ++ setlogmask(LOG_UPTO(libmp_verbosity + 3)); ++ + /* + * free old map and path vectors ... they use old conf state + */ +@@ -2710,8 +2713,6 @@ reconfigure (struct vectors * vecs) + /* Re-read any timezone changes */ + tzset(); + +- if (verbosity) +- conf->verbosity = verbosity; + if (bindings_read_only) + conf->bindings_read_only = bindings_read_only; + check_alias_settings(conf); +@@ -3091,14 +3092,18 @@ child (__attribute__((unused)) void *param) + condlog(2, "--------start up--------"); + condlog(2, "read " DEFAULT_CONFIGFILE); + ++ if (verbosity) ++ libmp_verbosity = verbosity; + conf = load_config(DEFAULT_CONFIGFILE); ++ if (verbosity) ++ libmp_verbosity = verbosity; ++ setlogmask(LOG_UPTO(libmp_verbosity + 3)); ++ + if (!conf) { + condlog(0, "failed to load configuration"); + goto failed; + } + +- if (verbosity) +- conf->verbosity = verbosity; + if (bindings_read_only) + conf->bindings_read_only = bindings_read_only; + uxsock_timeout = conf->uxsock_timeout; +@@ -3117,7 +3122,6 @@ child (__attribute__((unused)) void *param) + + if (poll_dmevents) + poll_dmevents = dmevent_poll_supported(); +- setlogmask(LOG_UPTO(conf->verbosity + 3)); + + envp = getenv("LimitNOFILE"); + +@@ -3339,7 +3343,7 @@ main (int argc, char *argv[]) + !isdigit(optarg[0])) + exit(1); + +- verbosity = atoi(optarg); ++ libmp_verbosity = verbosity = atoi(optarg); + break; + case 's': + logsink = -1; +@@ -3350,7 +3354,7 @@ main (int argc, char *argv[]) + if (!conf) + exit(1); + if (verbosity) +- conf->verbosity = verbosity; ++ libmp_verbosity = verbosity; + uxsock_timeout = conf->uxsock_timeout; + err = uxclnt(optarg, uxsock_timeout + 100); + free_config(conf); +@@ -3376,11 +3380,13 @@ main (int argc, char *argv[]) + char * c = s; + + logsink = 0; ++ if (verbosity) ++ libmp_verbosity = verbosity; + conf = load_config(DEFAULT_CONFIGFILE); + if (!conf) + exit(1); + if (verbosity) +- conf->verbosity = verbosity; ++ libmp_verbosity = verbosity; + uxsock_timeout = conf->uxsock_timeout; + memset(cmd, 0x0, CMDSIZE); + while (optind < argc) { +diff --git a/tests/alias.c b/tests/alias.c +index 7fda679d..0311faa6 100644 +--- a/tests/alias.c ++++ b/tests/alias.c +@@ -735,6 +735,7 @@ static int test_allocate_binding(void) + int main(void) + { + int ret = 0; ++ libmp_verbosity = conf.verbosity; + + ret += test_format_devname(); + ret += test_scan_devname(); +diff --git a/tests/blacklist.c b/tests/blacklist.c +index 84a3ba2f..0b42e255 100644 +--- a/tests/blacklist.c ++++ b/tests/blacklist.c +@@ -22,6 +22,7 @@ + #include "globals.c" + #include "blacklist.h" + #include "test-log.h" ++#include "debug.h" + + struct udev_device { + const char *sysname; +@@ -152,6 +153,7 @@ static int setup(void **state) + store_ble(blist_property_wwn_inv, "!ID_WWN", ORIGIN_CONFIG)) + return -1; + ++ libmp_verbosity = conf.verbosity = 4; + return 0; + } + +-- +2.17.2 + diff --git a/0063-libmultipath-introduce-symbolic-values-for-logsink.patch b/0063-libmultipath-introduce-symbolic-values-for-logsink.patch new file mode 100644 index 0000000..24cf615 --- /dev/null +++ b/0063-libmultipath-introduce-symbolic-values-for-logsink.patch @@ -0,0 +1,185 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Sat, 26 Sep 2020 00:32:05 +0200 +Subject: [PATCH] libmultipath: introduce symbolic values for logsink + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/debug.c | 4 ++-- + libmultipath/debug.h | 6 ++++++ + libmultipath/devmapper.c | 4 ++-- + multipath/main.c | 4 ++-- + multipathd/main.c | 17 ++++++++--------- + tests/globals.c | 3 ++- + tests/hwtable.c | 2 +- + 7 files changed, 23 insertions(+), 17 deletions(-) + +diff --git a/libmultipath/debug.c b/libmultipath/debug.c +index a1713b95..f9b77552 100644 +--- a/libmultipath/debug.c ++++ b/libmultipath/debug.c +@@ -25,8 +25,8 @@ void dlog (int sink, int prio, const char * fmt, ...) + va_start(ap, fmt); + + if (prio <= libmp_verbosity) { +- if (sink < 1) { +- if (sink == 0) { ++ if (sink != LOGSINK_SYSLOG) { ++ if (sink == LOGSINK_STDERR_WITH_TIME) { + time_t t = time(NULL); + struct tm *tb = localtime(&t); + char buff[16]; +diff --git a/libmultipath/debug.h b/libmultipath/debug.h +index 1f3bc8be..b6ce70a7 100644 +--- a/libmultipath/debug.h ++++ b/libmultipath/debug.h +@@ -12,3 +12,9 @@ extern int libmp_verbosity; + + #define condlog(prio, fmt, args...) \ + dlog(logsink, prio, fmt "\n", ##args) ++ ++enum { ++ LOGSINK_STDERR_WITH_TIME = 0, ++ LOGSINK_STDERR_WITHOUT_TIME = -1, ++ LOGSINK_SYSLOG = 1, ++}; +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index dfe95d2f..f8b180e1 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -104,8 +104,8 @@ dm_write_log (int level, const char *file, int line, const char *f, ...) + return; + + va_start(ap, f); +- if (logsink < 1) { +- if (logsink == 0) { ++ if (logsink != LOGSINK_SYSLOG) { ++ if (logsink == LOGSINK_STDERR_WITH_TIME) { + time_t t = time(NULL); + struct tm *tb = localtime(&t); + char buff[16]; +diff --git a/multipath/main.c b/multipath/main.c +index 98d93c58..9ac42869 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -817,7 +817,7 @@ main (int argc, char *argv[]) + libmultipath_init(); + if (atexit(dm_lib_exit) || atexit(libmultipath_exit)) + condlog(1, "failed to register cleanup handler for libmultipath: %m"); +- logsink = 0; ++ logsink = LOGSINK_STDERR_WITH_TIME; + if (init_config(DEFAULT_CONFIGFILE)) + exit(RTVL_FAIL); + if (atexit(uninit_config)) +@@ -968,7 +968,7 @@ main (int argc, char *argv[]) + if (dev_type == DEV_UEVENT) { + openlog("multipath", 0, LOG_DAEMON); + setlogmask(LOG_UPTO(libmp_verbosity + 3)); +- logsink = 1; ++ logsink = LOGSINK_SYSLOG; + } + + set_max_fds(conf->max_fds); +diff --git a/multipathd/main.c b/multipathd/main.c +index ba257515..867f0f84 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -2780,7 +2780,7 @@ handle_signals(bool nonfatal) + } + if (log_reset_sig) { + condlog(2, "reset log (signal)"); +- if (logsink == 1) ++ if (logsink == LOGSINK_SYSLOG) + log_thread_reset(); + } + reconfig_sig = 0; +@@ -3033,7 +3033,7 @@ static void cleanup_child(void) + cleanup_dmevent_waiter(); + + cleanup_pidfile(); +- if (logsink == 1) ++ if (logsink == LOGSINK_SYSLOG) + log_thread_stop(); + + cleanup_conf(); +@@ -3076,7 +3076,7 @@ child (__attribute__((unused)) void *param) + setup_thread_attr(&uevent_attr, DEFAULT_UEVENT_STACKSIZE * 1024, 0); + setup_thread_attr(&waiter_attr, 32 * 1024, 1); + +- if (logsink == 1) { ++ if (logsink == LOGSINK_SYSLOG) { + setup_thread_attr(&log_attr, 64 * 1024, 0); + log_thread_start(&log_attr); + pthread_attr_destroy(&log_attr); +@@ -3307,7 +3307,7 @@ main (int argc, char *argv[]) + ANNOTATE_BENIGN_RACE_SIZED(&uxsock_timeout, sizeof(uxsock_timeout), + "Suppress complaints about this scalar variable"); + +- logsink = 1; ++ logsink = LOGSINK_SYSLOG; + + if (getuid() != 0) { + fprintf(stderr, "need to be root\n"); +@@ -3334,9 +3334,8 @@ main (int argc, char *argv[]) + switch(arg) { + case 'd': + foreground = 1; +- if (logsink > 0) +- logsink = 0; +- //debug=1; /* ### comment me out ### */ ++ if (logsink == LOGSINK_SYSLOG) ++ logsink = LOGSINK_STDERR_WITH_TIME; + break; + case 'v': + if (sizeof(optarg) > sizeof(char *) || +@@ -3346,7 +3345,7 @@ main (int argc, char *argv[]) + libmp_verbosity = verbosity = atoi(optarg); + break; + case 's': +- logsink = -1; ++ logsink = LOGSINK_STDERR_WITHOUT_TIME; + break; + case 'k': + logsink = 0; +@@ -3379,7 +3378,7 @@ main (int argc, char *argv[]) + char * s = cmd; + char * c = s; + +- logsink = 0; ++ logsink = LOGSINK_STDERR_WITH_TIME; + if (verbosity) + libmp_verbosity = verbosity; + conf = load_config(DEFAULT_CONFIGFILE); +diff --git a/tests/globals.c b/tests/globals.c +index 8add5eb7..fc0c07ad 100644 +--- a/tests/globals.c ++++ b/tests/globals.c +@@ -1,9 +1,10 @@ + #include "structs.h" + #include "config.h" ++#include "debug.h" + + /* Required globals */ + struct udev *udev; +-int logsink = -1; ++int logsink = LOGSINK_STDERR_WITHOUT_TIME; + struct config conf = { + .verbosity = 4, + }; +diff --git a/tests/hwtable.c b/tests/hwtable.c +index 57f832b7..4dd0873b 100644 +--- a/tests/hwtable.c ++++ b/tests/hwtable.c +@@ -53,7 +53,7 @@ struct hwt_state { + + static struct config *_conf; + struct udev *udev; +-int logsink = -1; ++int logsink = LOGSINK_STDERR_WITHOUT_TIME; + + struct config *get_multipath_config(void) + { +-- +2.17.2 + diff --git a/0064-libmultipath-simplify-dlog.patch b/0064-libmultipath-simplify-dlog.patch new file mode 100644 index 0000000..af47833 --- /dev/null +++ b/0064-libmultipath-simplify-dlog.patch @@ -0,0 +1,152 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Sat, 26 Sep 2020 00:39:22 +0200 +Subject: [PATCH] libmultipath: simplify dlog() + +By checking the log level in condlog() directly, we can simplify +dlog(). Also, it's now possible to limit the log level at compile +time by setting MAX_VERBOSITY, enabling the compiler to optimize +away log messages with higher loglevel. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/debug.c | 30 +++++++++++++----------------- + libmultipath/debug.h | 20 ++++++++++++++++---- + libmultipath/devmapper.c | 4 +++- + tests/test-log.c | 4 ++-- + tests/test-log.h | 3 ++- + 5 files changed, 36 insertions(+), 25 deletions(-) + +diff --git a/libmultipath/debug.c b/libmultipath/debug.c +index f9b77552..429f2699 100644 +--- a/libmultipath/debug.c ++++ b/libmultipath/debug.c +@@ -18,29 +18,25 @@ + int logsink; + int libmp_verbosity = DEFAULT_VERBOSITY; + +-void dlog (int sink, int prio, const char * fmt, ...) ++void dlog(int prio, const char * fmt, ...) + { + va_list ap; + + va_start(ap, fmt); ++ if (logsink != LOGSINK_SYSLOG) { ++ if (logsink == LOGSINK_STDERR_WITH_TIME) { ++ time_t t = time(NULL); ++ struct tm *tb = localtime(&t); ++ char buff[16]; + +- if (prio <= libmp_verbosity) { +- if (sink != LOGSINK_SYSLOG) { +- if (sink == LOGSINK_STDERR_WITH_TIME) { +- time_t t = time(NULL); +- struct tm *tb = localtime(&t); +- char buff[16]; +- +- strftime(buff, sizeof(buff), +- "%b %d %H:%M:%S", tb); +- buff[sizeof(buff)-1] = '\0'; +- +- fprintf(stderr, "%s | ", buff); +- } +- vfprintf(stderr, fmt, ap); ++ strftime(buff, sizeof(buff), ++ "%b %d %H:%M:%S", tb); ++ buff[sizeof(buff)-1] = '\0'; ++ fprintf(stderr, "%s | ", buff); + } +- else +- log_safe(prio + 3, fmt, ap); ++ vfprintf(stderr, fmt, ap); + } ++ else ++ log_safe(prio + 3, fmt, ap); + va_end(ap); + } +diff --git a/libmultipath/debug.h b/libmultipath/debug.h +index b6ce70a7..705a5d73 100644 +--- a/libmultipath/debug.h ++++ b/libmultipath/debug.h +@@ -1,5 +1,7 @@ +-void dlog (int sink, int prio, const char * fmt, ...) +- __attribute__((format(printf, 3, 4))); ++#ifndef _DEBUG_H ++#define _DEBUG_H ++void dlog (int prio, const char *fmt, ...) ++ __attribute__((format(printf, 2, 3))); + + + #include +@@ -10,11 +12,21 @@ void dlog (int sink, int prio, const char * fmt, ...) + extern int logsink; + extern int libmp_verbosity; + +-#define condlog(prio, fmt, args...) \ +- dlog(logsink, prio, fmt "\n", ##args) ++#ifndef MAX_VERBOSITY ++#define MAX_VERBOSITY 4 ++#endif + + enum { + LOGSINK_STDERR_WITH_TIME = 0, + LOGSINK_STDERR_WITHOUT_TIME = -1, + LOGSINK_SYSLOG = 1, + }; ++ ++#define condlog(prio, fmt, args...) \ ++ do { \ ++ int __p = (prio); \ ++ \ ++ if (__p <= MAX_VERBOSITY && __p <= libmp_verbosity) \ ++ dlog(__p, fmt "\n", ##args); \ ++ } while (0) ++#endif /* _DEBUG_H */ +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index f8b180e1..4977b311 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -276,7 +276,9 @@ static int dm_tgt_prereq (unsigned int *ver) + + static void _init_versions(void) + { +- dlog(logsink, 3, VERSION_STRING); ++ /* Can't use condlog here because of how VERSION_STRING is defined */ ++ if (3 <= libmp_verbosity) ++ dlog(3, VERSION_STRING); + init_dm_library_version(); + init_dm_drv_version(); + init_dm_mpath_version(); +diff --git a/tests/test-log.c b/tests/test-log.c +index 1c901cba..14f25b9b 100644 +--- a/tests/test-log.c ++++ b/tests/test-log.c +@@ -7,8 +7,8 @@ + #include "log.h" + #include "test-log.h" + +-__attribute__((format(printf, 3, 0))) +-void __wrap_dlog (int sink, int prio, const char * fmt, ...) ++__attribute__((format(printf, 2, 0))) ++void __wrap_dlog (int prio, const char * fmt, ...) + { + char buff[MAX_MSG_SIZE]; + va_list ap; +diff --git a/tests/test-log.h b/tests/test-log.h +index 2c878c63..6d22cd23 100644 +--- a/tests/test-log.h ++++ b/tests/test-log.h +@@ -1,7 +1,8 @@ + #ifndef _TEST_LOG_H + #define _TEST_LOG_H + +-void __wrap_dlog (int sink, int prio, const char * fmt, ...); ++__attribute__((format(printf, 2, 0))) ++void __wrap_dlog (int prio, const char * fmt, ...); + void expect_condlog(int prio, char *string); + + #endif +-- +2.17.2 + diff --git a/0065-RH-warn-on-invalid-regex-instead-of-failing.patch b/0065-RH-warn-on-invalid-regex-instead-of-failing.patch deleted file mode 100644 index 4bdd97e..0000000 --- a/0065-RH-warn-on-invalid-regex-instead-of-failing.patch +++ /dev/null @@ -1,121 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 6 Nov 2017 21:39:28 -0600 -Subject: [PATCH] RH: warn on invalid regex instead of failing - -multipath.conf used to allow "*" as a match everything regular expression, -instead of requiring ".*". Instead of erroring when the old style -regular expressions are used, it should print a warning and convert -them. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/dict.c | 27 +++++++++++++++++++++------ - libmultipath/parser.c | 13 +++++++++++++ - libmultipath/parser.h | 1 + - 3 files changed, 35 insertions(+), 6 deletions(-) - -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index 0e9ea387..184d4b22 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -103,6 +103,21 @@ set_str(vector strvec, void *ptr) - return 0; - } - -+static int -+set_regex(vector strvec, void *ptr) -+{ -+ char **str_ptr = (char **)ptr; -+ -+ if (*str_ptr) -+ FREE(*str_ptr); -+ *str_ptr = set_regex_value(strvec); -+ -+ if (!*str_ptr) -+ return 1; -+ -+ return 0; -+} -+ - static int - set_yes_no(vector strvec, void *ptr) - { -@@ -1504,7 +1519,7 @@ ble_ ## option ## _handler (struct config *conf, vector strvec) \ - if (!conf->option) \ - return 1; \ - \ -- buff = set_value(strvec); \ -+ buff = set_regex_value(strvec); \ - if (!buff) \ - return 1; \ - \ -@@ -1520,7 +1535,7 @@ ble_ ## option ## _ ## name ## _handler (struct config *conf, vector strvec) \ - if (!conf->option) \ - return 1; \ - \ -- buff = set_value(strvec); \ -+ buff = set_regex_value(strvec); \ - if (!buff) \ - return 1; \ - \ -@@ -1623,16 +1638,16 @@ device_handler(struct config *conf, vector strvec) - return 0; - } - --declare_hw_handler(vendor, set_str) -+declare_hw_handler(vendor, set_regex) - declare_hw_snprint(vendor, print_str) - --declare_hw_handler(product, set_str) -+declare_hw_handler(product, set_regex) - declare_hw_snprint(product, print_str) - --declare_hw_handler(revision, set_str) -+declare_hw_handler(revision, set_regex) - declare_hw_snprint(revision, print_str) - --declare_hw_handler(bl_product, set_str) -+declare_hw_handler(bl_product, set_regex) - declare_hw_snprint(bl_product, print_str) - - declare_hw_handler(hwhandler, set_str) -diff --git a/libmultipath/parser.c b/libmultipath/parser.c -index 11a6168c..a7285a35 100644 ---- a/libmultipath/parser.c -+++ b/libmultipath/parser.c -@@ -384,6 +384,19 @@ oom: - return NULL; - } - -+void * -+set_regex_value(vector strvec) -+{ -+ char *buff = set_value(strvec); -+ -+ if (buff && strcmp("*", buff) == 0) { -+ condlog(0, "Invalid regular expression \"*\" in multipath.conf. Using \".*\""); -+ FREE(buff); -+ return strdup(".*"); -+ } -+ return buff; -+} -+ - /* non-recursive configuration stream handler */ - static int kw_level = 0; - -diff --git a/libmultipath/parser.h b/libmultipath/parser.h -index 62906e98..b7917052 100644 ---- a/libmultipath/parser.h -+++ b/libmultipath/parser.h -@@ -77,6 +77,7 @@ extern void dump_keywords(vector keydump, int level); - extern void free_keywords(vector keywords); - extern vector alloc_strvec(char *string); - extern void *set_value(vector strvec); -+extern void *set_regex_value(vector strvec); - extern int process_file(struct config *conf, char *conf_file); - extern struct keyword * find_keyword(vector keywords, vector v, char * name); - int snprint_keyword(char *buff, int len, char *fmt, struct keyword *kw, --- -2.17.2 - diff --git a/0065-multipathd-common-code-for-k-and-command-args.patch b/0065-multipathd-common-code-for-k-and-command-args.patch new file mode 100644 index 0000000..1fc5a75 --- /dev/null +++ b/0065-multipathd-common-code-for-k-and-command-args.patch @@ -0,0 +1,87 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Sat, 26 Sep 2020 00:43:12 +0200 +Subject: [PATCH] multipathd: common code for "-k" and command args + +'multipathd -k"cmd"' and 'multipath cmd' are the same thing. +Treat it with common code. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 37 +++++++++++++++++++------------------ + 1 file changed, 19 insertions(+), 18 deletions(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 867f0f84..b6a5f5b7 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -3301,6 +3301,8 @@ main (int argc, char *argv[]) + int err; + int foreground = 0; + struct config *conf; ++ char *opt_k_arg = NULL; ++ bool opt_k = false; + + ANNOTATE_BENIGN_RACE_SIZED(&multipath_conf, sizeof(multipath_conf), + "Manipulated through RCU"); +@@ -3348,16 +3350,9 @@ main (int argc, char *argv[]) + logsink = LOGSINK_STDERR_WITHOUT_TIME; + break; + case 'k': +- logsink = 0; +- conf = load_config(DEFAULT_CONFIGFILE); +- if (!conf) +- exit(1); +- if (verbosity) +- libmp_verbosity = verbosity; +- uxsock_timeout = conf->uxsock_timeout; +- err = uxclnt(optarg, uxsock_timeout + 100); +- free_config(conf); +- return err; ++ opt_k = true; ++ opt_k_arg = optarg; ++ break; + case 'B': + bindings_read_only = 1; + break; +@@ -3373,7 +3368,7 @@ main (int argc, char *argv[]) + exit(1); + } + } +- if (optind < argc) { ++ if (opt_k || optind < argc) { + char cmd[CMDSIZE]; + char * s = cmd; + char * c = s; +@@ -3388,14 +3383,20 @@ main (int argc, char *argv[]) + libmp_verbosity = verbosity; + uxsock_timeout = conf->uxsock_timeout; + memset(cmd, 0x0, CMDSIZE); +- while (optind < argc) { +- if (strchr(argv[optind], ' ')) +- c += snprintf(c, s + CMDSIZE - c, "\"%s\" ", argv[optind]); +- else +- c += snprintf(c, s + CMDSIZE - c, "%s ", argv[optind]); +- optind++; ++ if (opt_k) ++ s = opt_k_arg; ++ else { ++ while (optind < argc) { ++ if (strchr(argv[optind], ' ')) ++ c += snprintf(c, s + CMDSIZE - c, ++ "\"%s\" ", argv[optind]); ++ else ++ c += snprintf(c, s + CMDSIZE - c, ++ "%s ", argv[optind]); ++ optind++; ++ } ++ c += snprintf(c, s + CMDSIZE - c, "\n"); + } +- c += snprintf(c, s + CMDSIZE - c, "\n"); + err = uxclnt(s, uxsock_timeout + 100); + free_config(conf); + return err; +-- +2.17.2 + diff --git a/0066-multipathd-sanitize-uxsock_listen.patch b/0066-multipathd-sanitize-uxsock_listen.patch new file mode 100644 index 0000000..d7efc72 --- /dev/null +++ b/0066-multipathd-sanitize-uxsock_listen.patch @@ -0,0 +1,157 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Sat, 26 Sep 2020 15:22:34 +0200 +Subject: [PATCH] multipathd: sanitize uxsock_listen() + +We were allocating 1025 poll fds, which is weird. Change it to a power of two, +and make this more easily customizable in general. Use POLLFDS_BASE rather +than the hard-coded "2" for the number of fds we poll besides client +connections. Introduce a maximum number of clients that can connect. When +this number is reached, we simply stop polling the accept socket, so that new +connections aren't accepted any more. Don't attempt to realloc() the pollfd +array if the number of clients decreases. It's unlikely to ever be more than +one or two pages. Finally, there's no need to wake up every 5s. Our signal +handling is robust. Just sleep forever in ppoll() if nothing happens. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipathd/uxlsnr.c | 70 ++++++++++++++++++++++++++++----------------- + 1 file changed, 43 insertions(+), 27 deletions(-) + +diff --git a/multipathd/uxlsnr.c b/multipathd/uxlsnr.c +index ce2b6800..cd462b6d 100644 +--- a/multipathd/uxlsnr.c ++++ b/multipathd/uxlsnr.c +@@ -41,14 +41,25 @@ + #include "cli.h" + #include "uxlsnr.h" + +-static struct timespec sleep_time = {5, 0}; +- + struct client { + struct list_head node; + int fd; + }; + +-#define MIN_POLLS 1023 ++/* The number of fds we poll on, other than individual client connections */ ++#define POLLFDS_BASE 2 ++#define POLLFD_CHUNK (4096 / sizeof(struct pollfd)) ++/* Minimum mumber of pollfds to reserve for clients */ ++#define MIN_POLLS (POLLFD_CHUNK - POLLFDS_BASE) ++/* ++ * Max number of client connections allowed ++ * During coldplug, there may be a large number of "multipath -u" ++ * processes connecting. ++ */ ++#define MAX_CLIENTS (16384 - POLLFDS_BASE) ++ ++/* Compile-time error if POLLFD_CHUNK is too small */ ++static __attribute__((unused)) char ___a[-(MIN_POLLS <= 0)]; + + static LIST_HEAD(clients); + static pthread_mutex_t client_lock = PTHREAD_MUTEX_INITIALIZER; +@@ -282,13 +293,13 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, long ux_sock, + char *inbuf; + char *reply; + sigset_t mask; +- int old_clients = MIN_POLLS; ++ int max_pfds = MIN_POLLS + POLLFDS_BASE; + /* conf->sequence_nr will be 1 when uxsock_listen is first called */ + unsigned int sequence_nr = 0; + struct watch_descriptors wds = { .conf_wd = -1, .dir_wd = -1 }; + + condlog(3, "uxsock: startup listener"); +- polls = (struct pollfd *)MALLOC((MIN_POLLS + 2) * sizeof(struct pollfd)); ++ polls = MALLOC(max_pfds * sizeof(*polls)); + if (!polls) { + condlog(0, "uxsock: failed to allocate poll fds"); + exit_daemon(); +@@ -312,28 +323,33 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, long ux_sock, + list_for_each_entry(c, &clients, node) { + num_clients++; + } +- if (num_clients != old_clients) { ++ if (num_clients + POLLFDS_BASE > max_pfds) { + struct pollfd *new; +- if (num_clients <= MIN_POLLS && old_clients > MIN_POLLS) { +- new = REALLOC(polls, (2 + MIN_POLLS) * +- sizeof(struct pollfd)); +- } else if (num_clients <= MIN_POLLS && old_clients <= MIN_POLLS) { +- new = polls; +- } else { +- new = REALLOC(polls, (2 + num_clients) * +- sizeof(struct pollfd)); +- } +- if (!new) { +- condlog(0, "%s: failed to realloc %d poll fds", +- "uxsock", 2 + num_clients); +- num_clients = old_clients; +- } else { +- old_clients = num_clients; ++ int n_new = max_pfds + POLLFD_CHUNK; ++ ++ new = REALLOC(polls, n_new * sizeof(*polls)); ++ if (new) { ++ max_pfds = n_new; + polls = new; ++ } else { ++ condlog(1, "%s: realloc failure, %d clients not served", ++ __func__, ++ num_clients + POLLFDS_BASE - max_pfds); ++ num_clients = max_pfds - POLLFDS_BASE; + } + } +- polls[0].fd = ux_sock; +- polls[0].events = POLLIN; ++ if (num_clients < MAX_CLIENTS) { ++ polls[0].fd = ux_sock; ++ polls[0].events = POLLIN; ++ } else { ++ /* ++ * New clients can't connect, num_clients won't grow ++ * to MAX_CLIENTS or higher ++ */ ++ condlog(1, "%s: max client connections reached, pausing polling", ++ __func__); ++ polls[0].fd = -1; ++ } + + reset_watch(notify_fd, &wds, &sequence_nr); + if (notify_fd == -1 || (wds.conf_wd == -1 && wds.dir_wd == -1)) +@@ -343,19 +359,19 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, long ux_sock, + polls[1].events = POLLIN; + + /* setup the clients */ +- i = 2; ++ i = POLLFDS_BASE; + list_for_each_entry(c, &clients, node) { + polls[i].fd = c->fd; + polls[i].events = POLLIN; + i++; +- if (i >= 2 + num_clients) ++ if (i >= max_pfds) + break; + } + n_pfds = i; + pthread_cleanup_pop(1); + + /* most of our life is spent in this call */ +- poll_count = ppoll(polls, n_pfds, &sleep_time, &mask); ++ poll_count = ppoll(polls, n_pfds, NULL, &mask); + + handle_signals(false); + if (poll_count == -1) { +@@ -388,7 +404,7 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, long ux_sock, + } + + /* see if a client wants to speak to us */ +- for (i = 2; i < n_pfds; i++) { ++ for (i = POLLFDS_BASE; i < n_pfds; i++) { + if (polls[i].revents & POLLIN) { + struct timespec start_time; + +-- +2.17.2 + diff --git a/0067-libmultipath-fix-race-between-log_safe-and-log_threa.patch b/0067-libmultipath-fix-race-between-log_safe-and-log_threa.patch new file mode 100644 index 0000000..29f5ce7 --- /dev/null +++ b/0067-libmultipath-fix-race-between-log_safe-and-log_threa.patch @@ -0,0 +1,107 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 15 Oct 2020 16:13:14 +0200 +Subject: [PATCH] libmultipath: fix race between log_safe and log_thread_stop() + +log_safe() could race with log_thread_stop(); simply +checking the value of log_thr has never been safe. By converting the +mutexes to static initializers, we avoid having to destroy them, and thus +possibly accessing a destroyed mutex in log_safe(). Furthermore, taking +both the logev_lock and the logq_lock makes sure the logarea isn't freed +while we are writing to it. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/log_pthread.c | 48 +++++++++++++++++++++----------------- + 1 file changed, 26 insertions(+), 22 deletions(-) + +diff --git a/libmultipath/log_pthread.c b/libmultipath/log_pthread.c +index 3a2566ae..0d48c52c 100644 +--- a/libmultipath/log_pthread.c ++++ b/libmultipath/log_pthread.c +@@ -17,31 +17,42 @@ + + static pthread_t log_thr; + +-static pthread_mutex_t logq_lock; +-static pthread_mutex_t logev_lock; +-static pthread_cond_t logev_cond; ++/* logev_lock must not be taken with logq_lock held */ ++static pthread_mutex_t logq_lock = PTHREAD_MUTEX_INITIALIZER; ++static pthread_mutex_t logev_lock = PTHREAD_MUTEX_INITIALIZER; ++static pthread_cond_t logev_cond = PTHREAD_COND_INITIALIZER; + + static int logq_running; + static int log_messages_pending; + + void log_safe (int prio, const char * fmt, va_list ap) + { ++ bool running; ++ + if (prio > LOG_DEBUG) + prio = LOG_DEBUG; + +- if (log_thr == (pthread_t)0) { +- vsyslog(prio, fmt, ap); +- return; +- } ++ /* ++ * logev_lock protects logq_running. By holding it, we avoid a race ++ * with log_thread_stop() -> log_close(), which would free the logarea. ++ */ ++ pthread_mutex_lock(&logev_lock); ++ pthread_cleanup_push(cleanup_mutex, &logev_lock); ++ running = logq_running; + +- pthread_mutex_lock(&logq_lock); +- log_enqueue(prio, fmt, ap); +- pthread_mutex_unlock(&logq_lock); ++ if (running) { ++ pthread_mutex_lock(&logq_lock); ++ pthread_cleanup_push(cleanup_mutex, &logq_lock); ++ log_enqueue(prio, fmt, ap); ++ pthread_cleanup_pop(1); + +- pthread_mutex_lock(&logev_lock); +- log_messages_pending = 1; +- pthread_cond_signal(&logev_cond); +- pthread_mutex_unlock(&logev_lock); ++ log_messages_pending = 1; ++ pthread_cond_signal(&logev_cond); ++ } ++ pthread_cleanup_pop(1); ++ ++ if (!running) ++ vsyslog(prio, fmt, ap); + } + + static void flush_logqueue (void) +@@ -103,9 +114,6 @@ void log_thread_start (pthread_attr_t *attr) + int running = 0; + + logdbg(stderr,"enter log_thread_start\n"); +- pthread_mutex_init(&logq_lock, NULL); +- pthread_mutex_init(&logev_lock, NULL); +- pthread_cond_init(&logev_cond, NULL); + + if (log_init("multipathd", 0)) { + fprintf(stderr,"can't initialize log buffer\n"); +@@ -154,13 +162,9 @@ void log_thread_stop (void) + } + pthread_cleanup_pop(1); + +- flush_logqueue(); + if (running) + pthread_join(log_thr, NULL); + +- pthread_mutex_destroy(&logq_lock); +- pthread_mutex_destroy(&logev_lock); +- pthread_cond_destroy(&logev_cond); +- ++ flush_logqueue(); + log_close(); + } +-- +2.17.2 + diff --git a/0070-multipath-add-libmpathvalid-library.patch b/0068-multipath-add-libmpathvalid-library.patch similarity index 52% rename from 0070-multipath-add-libmpathvalid-library.patch rename to 0068-multipath-add-libmpathvalid-library.patch index b3863cd..24ba4ac 100644 --- a/0070-multipath-add-libmpathvalid-library.patch +++ b/0068-multipath-add-libmpathvalid-library.patch @@ -1,13 +1,13 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski -Date: Wed, 13 May 2020 17:04:24 -0500 +Date: Wed, 21 Oct 2020 16:39:23 -0500 Subject: [PATCH] multipath: add libmpathvalid library This library allows other programs to check if a path should be claimed -by multipath. It exports an init and exit function, that need to be -called before any other functions can be called, a pointer to a struct -config, that stores the configuration which is dealt with in the -init and exit functions, and two more functions. +by multipath. It exports an init function, that needs to be called +before and after all other library calls, an exit function, that needs +to be called after all library calls, a function to reread the multipath +configuration files, and two more functions. mpath_get_mode() get the configured find_multipaths mode. mpath_is_path() returns whether the device is claimed by multipath, and @@ -17,25 +17,26 @@ existing paths to see if another has the same wwid, it expects the caller to pass in an array of the already known path wwids, and checks if the current path matches any of those. -The library also doesn't set up the device-mapper log fuctions. It -leaves this up to the caller. +The library also doesn't set up the device-mapper library. It leaves +this up to the caller. Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck --- Makefile | 3 +- - Makefile.inc | 1 + - libmpathvalid/Makefile | 38 +++++++ + libmpathvalid/Makefile | 39 ++++++ libmpathvalid/libmpathvalid.version | 10 ++ - libmpathvalid/mpath_valid.c | 168 ++++++++++++++++++++++++++++ - libmpathvalid/mpath_valid.h | 57 ++++++++++ - 6 files changed, 276 insertions(+), 1 deletion(-) + libmpathvalid/mpath_valid.c | 202 ++++++++++++++++++++++++++++ + libmpathvalid/mpath_valid.h | 155 +++++++++++++++++++++ + libmultipath/libmultipath.version | 6 + + 6 files changed, 414 insertions(+), 1 deletion(-) create mode 100644 libmpathvalid/Makefile create mode 100644 libmpathvalid/libmpathvalid.version create mode 100644 libmpathvalid/mpath_valid.c create mode 100644 libmpathvalid/mpath_valid.h diff --git a/Makefile b/Makefile -index 8bcaba66..f157a549 100644 +index 4a3491da..f127ff91 100644 --- a/Makefile +++ b/Makefile @@ -9,6 +9,7 @@ BUILDDIRS := \ @@ -55,29 +56,18 @@ index 8bcaba66..f157a549 100644 mpathpersist multipathd: libmpathpersist libmultipath/checkers.install \ -diff --git a/Makefile.inc b/Makefile.inc -index e2f5d0dc..936e5833 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -66,6 +66,7 @@ libdir = $(prefix)/$(LIB)/multipath - unitdir = $(prefix)/$(SYSTEMDPATH)/systemd/system - mpathpersistdir = $(TOPDIR)/libmpathpersist - mpathcmddir = $(TOPDIR)/libmpathcmd -+mpathvaliddir = $(TOPDIR)/libmpathvalid - thirdpartydir = $(TOPDIR)/third-party - libdmmpdir = $(TOPDIR)/libdmmp - nvmedir = $(TOPDIR)/libmultipath/nvme diff --git a/libmpathvalid/Makefile b/libmpathvalid/Makefile new file mode 100644 -index 00000000..70b97eca +index 00000000..6bea4bcd --- /dev/null +++ b/libmpathvalid/Makefile -@@ -0,0 +1,38 @@ +@@ -0,0 +1,39 @@ +include ../Makefile.inc + +SONAME = 0 +DEVLIB = libmpathvalid.so +LIBS = $(DEVLIB).$(SONAME) ++VERSION_SCRIPT := libmpathvalid.version + +CFLAGS += $(LIB_CFLAGS) -I$(multipathdir) -I$(mpathcmddir) + @@ -88,7 +78,7 @@ index 00000000..70b97eca + +all: $(LIBS) + -+$(LIBS): $(OBJS) ++$(LIBS): $(OBJS) $(VERSION_SCRIPT) + $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ -o $@ $(OBJS) $(LIBDEPS) -Wl,--version-script=libmpathvalid.version + $(LN) $(LIBS) $(DEVLIB) + @@ -113,14 +103,14 @@ index 00000000..70b97eca + $(RM) $(OBJS:.o=.d) diff --git a/libmpathvalid/libmpathvalid.version b/libmpathvalid/libmpathvalid.version new file mode 100644 -index 00000000..4d8a8ba4 +index 00000000..3bd0d3c5 --- /dev/null +++ b/libmpathvalid/libmpathvalid.version @@ -0,0 +1,10 @@ +MPATH_1.0 { + global: -+ mpathvalid_conf; + mpathvalid_init; ++ mpathvalid_reload_config; + mpathvalid_exit; + mpathvalid_is_path; + mpathvalid_get_mode; @@ -129,10 +119,10 @@ index 00000000..4d8a8ba4 +}; diff --git a/libmpathvalid/mpath_valid.c b/libmpathvalid/mpath_valid.c new file mode 100644 -index 00000000..6153e8b7 +index 00000000..7073d17d --- /dev/null +++ b/libmpathvalid/mpath_valid.c -@@ -0,0 +1,168 @@ +@@ -0,0 +1,202 @@ +#include +#include +#include @@ -150,11 +140,10 @@ index 00000000..6153e8b7 +#include "mpath_cmd.h" +#include "valid.h" +#include "mpath_valid.h" ++#include "debug.h" + -+static struct config default_config = { .verbosity = -1 }; -+struct config *mpathvalid_conf = &default_config; -+ -+static unsigned int get_conf_mode(struct config *conf) ++static unsigned int ++get_conf_mode(struct config *conf) +{ + if (conf->find_multipaths == FIND_MULTIPATHS_SMART) + return MPATH_SMART; @@ -163,7 +152,8 @@ index 00000000..6153e8b7 + return MPATH_STRICT; +} + -+static void set_conf_mode(struct config *conf, unsigned int mode) ++static void ++set_conf_mode(struct config *conf, unsigned int mode) +{ + if (mode == MPATH_SMART) + conf->find_multipaths = FIND_MULTIPATHS_SMART; @@ -173,20 +163,23 @@ index 00000000..6153e8b7 + conf->find_multipaths = FIND_MULTIPATHS_STRICT; +} + -+unsigned int mpathvalid_get_mode(void) ++unsigned int ++mpathvalid_get_mode(void) +{ + int mode; + struct config *conf; + + conf = get_multipath_config(); + if (!conf) -+ return -1; -+ mode = get_conf_mode(conf); ++ mode = MPATH_MODE_ERROR; ++ else ++ mode = get_conf_mode(conf); + put_multipath_config(conf); + return mode; +} + -+static int convert_result(int result) { ++static int ++convert_result(int result) { + switch (result) { + case PATH_IS_ERROR: + return MPATH_IS_ERROR; @@ -202,39 +195,66 @@ index 00000000..6153e8b7 + return MPATH_IS_ERROR; +} + ++static void ++set_log_style(int log_style) ++{ ++ /* ++ * convert MPATH_LOG_* to LOGSINK_* ++ * currently there is no work to do here. ++ */ ++ logsink = log_style; ++} ++ ++static int ++load_default_config(int verbosity) ++{ ++ /* need to set verbosity here to control logging during init_config() */ ++ libmp_verbosity = verbosity; ++ if (init_config(DEFAULT_CONFIGFILE)) ++ return -1; ++ /* Need to override verbosity from init_config() */ ++ libmp_verbosity = verbosity; ++ ++ return 0; ++} ++ +int -+mpathvalid_init(int verbosity) ++mpathvalid_init(int verbosity, int log_style) +{ + unsigned int version[3]; -+ struct config *conf; + -+ default_config.verbosity = verbosity; -+ skip_libmp_dm_init(); -+ conf = load_config(DEFAULT_CONFIGFILE); -+ if (!conf) ++ set_log_style(log_style); ++ if (libmultipath_init()) + return -1; -+ conf->verbosity = verbosity; -+ if (dm_prereq(version)) -+ goto fail; -+ memcpy(conf->version, version, sizeof(version)); + -+ mpathvalid_conf = conf; ++ skip_libmp_dm_init(); ++ if (load_default_config(verbosity)) ++ goto fail; ++ ++ if (dm_prereq(version)) ++ goto fail_config; ++ + return 0; ++ ++fail_config: ++ uninit_config(); +fail: -+ free_config(conf); ++ libmultipath_exit(); + return -1; +} + +int ++mpathvalid_reload_config(void) ++{ ++ uninit_config(); ++ return load_default_config(libmp_verbosity); ++} ++ ++int +mpathvalid_exit(void) +{ -+ struct config *conf = mpathvalid_conf; -+ -+ default_config.verbosity = -1; -+ if (mpathvalid_conf == &default_config) -+ return 0; -+ mpathvalid_conf = &default_config; -+ free_config(conf); ++ uninit_config(); ++ libmultipath_exit(); + return 0; +} + @@ -250,15 +270,16 @@ index 00000000..6153e8b7 + const char **path_wwids, unsigned int nr_paths) +{ + struct config *conf; -+ int r = MPATH_IS_ERROR; ++ int find_multipaths_saved, r = MPATH_IS_ERROR; + unsigned int i; + struct path *pp; + -+ if (!name || mode >= MPATH_MAX_MODE) ++ if (!name || mode >= MPATH_MODE_ERROR) + return r; -+ + if (nr_paths > 0 && !path_wwids) + return r; ++ if (!udev) ++ return r; + + pp = alloc_path(); + if (!pp) @@ -271,16 +292,19 @@ index 00000000..6153e8b7 + } + + conf = get_multipath_config(); -+ if (!conf || conf == &default_config) ++ if (!conf) + goto out_wwid; ++ find_multipaths_saved = conf->find_multipaths; + if (mode != MPATH_DEFAULT) + set_conf_mode(conf, mode); + r = convert_result(is_path_valid(name, conf, pp, true)); ++ conf->find_multipaths = find_multipaths_saved; + put_multipath_config(conf); + + if (r == MPATH_IS_MAYBE_VALID) { + for (i = 0; i < nr_paths; i++) { -+ if (strncmp(path_wwids[i], pp->wwid, WWID_SIZE) == 0) { ++ if (path_wwids[i] && ++ strncmp(path_wwids[i], pp->wwid, WWID_SIZE) == 0) { + r = MPATH_IS_VALID; + break; + } @@ -303,10 +327,10 @@ index 00000000..6153e8b7 +} diff --git a/libmpathvalid/mpath_valid.h b/libmpathvalid/mpath_valid.h new file mode 100644 -index 00000000..7fd8aa47 +index 00000000..63de4e1c --- /dev/null +++ b/libmpathvalid/mpath_valid.h -@@ -0,0 +1,57 @@ +@@ -0,0 +1,155 @@ +/* + * Copyright (C) 2015 Red Hat, Inc. + * @@ -338,11 +362,16 @@ index 00000000..7fd8aa47 + MPATH_STRICT, + MPATH_SMART, + MPATH_GREEDY, -+ MPATH_MAX_MODE, /* used only for bounds checking */ ++ MPATH_MODE_ERROR, +}; + -+/* MPATH_IS_VALID_NO_CHECK is used to skip checks to see if the device -+ * has already been unclaimed by multipath in the past */ ++/* ++ * MPATH_IS_VALID_NO_CHECK is used to indicate that it is safe to skip ++ * checks to see if the device has already been released to the system ++ * for use by things other that multipath. ++ * MPATH_IS_MAYBE_VALID is used to indicate that this device would ++ * be a valid multipath path device if another device with the same ++ * wwid existed */ +enum mpath_valid_result { + MPATH_IS_ERROR = -1, + MPATH_IS_NOT_VALID, @@ -351,19 +380,126 @@ index 00000000..7fd8aa47 + MPATH_IS_MAYBE_VALID, +}; + -+struct config; -+extern struct config *mpathvalid_conf; -+int mpathvalid_init(int verbosity); ++enum mpath_valid_log_style { ++ MPATH_LOG_STDERR = -1, /* log to STDERR */ ++ MPATH_LOG_STDERR_TIMESTAMP, /* log to STDERR, with timestamps */ ++ MPATH_LOG_SYSLOG, /* log to system log */ ++}; ++ ++enum mpath_valid_verbosity { ++ MPATH_LOG_PRIO_NOLOG = -1, /* log nothing */ ++ MPATH_LOG_PRIO_ERR, ++ MPATH_LOG_PRIO_WARN, ++ MPATH_LOG_PRIO_NOTICE, ++ MPATH_LOG_PRIO_INFO, ++ MPATH_LOG_PRIO_DEBUG, ++}; ++ ++/* Function declarations */ ++ ++/* ++ * DESCRIPTION: ++ * Initialize the device mapper multipath configuration. This ++ * function must be invoked before calling any other ++ * libmpathvalid functions. Call mpathvalid_exit() to cleanup. ++ * @verbosity: the logging level (mpath_valid_verbosity) ++ * @log_style: the logging style (mpath_valid_log_style) ++ * ++ * RESTRICTIONS: ++ * Calling mpathvalid_init() after calling mpathvalid_exit() has no ++ * effect. ++ * ++ * RETURNS: 0 = Success, -1 = Failure ++ */ ++int mpathvalid_init(int verbosity, int log_style); ++ ++ ++/* ++ * DESCRIPTION: ++ * Reread the multipath configuration files and reinitalize ++ * the device mapper multipath configuration. This function can ++ * be called as many times as necessary. ++ * ++ * RETURNS: 0 = Success, -1 = Failure ++ */ ++int mpathvalid_reload_config(void); ++ ++ ++/* ++ * DESCRIPTION: ++ * Release the device mapper multipath configuration. This ++ * function must be called to cleanup resoures allocated by ++ * mpathvalid_init(). After calling this function, no futher ++ * libmpathvalid functions may be called. ++ * ++ * RETURNS: 0 = Success, -1 = Failure ++ */ +int mpathvalid_exit(void); ++ ++/* ++ * DESCRIPTION: ++ * Return the configured find_multipaths claim mode, using the ++ * configuration from either mpathvalid_init() or ++ * mpathvalid_reload_config() ++ * ++ * RETURNS: ++ * MPATH_STRICT, MPATH_SMART, MPATH_GREEDY, or MPATH_MODE_ERROR ++ * ++ * MPATH_STRICT = find_multiapths (yes|on|no|off) ++ * MPATH_SMART = find_multipaths smart ++ * MPATH_GREEDY = find_multipaths greedy ++ * MPATH_MODE_ERROR = multipath configuration not initialized ++ */ +unsigned int mpathvalid_get_mode(void); ++/* ++ * DESCRIPTION: ++ * Return whether device-mapper multipath claims a path device, ++ * using the configuration read from either mpathvalid_init() or ++ * mpathvalid_reload_config(). If the device is either claimed or ++ * potentially claimed (MPATH_IS_VALID, MPATH_IS_VALID_NO_CHECK, ++ * or MPATH_IS_MAYBE_VALID) and wwid is not NULL, then *wiid will ++ * be set to point to the wwid of device. If set, *wwid must be ++ * freed by the caller. path_wwids is an obptional parameter that ++ * points to an array of wwids, that were returned from previous ++ * calls to mpathvalid_is_path(). These are wwids of existing ++ * devices that are or potentially are claimed by device-mapper ++ * multipath. path_wwids is used with the MPATH_SMART claim mode, ++ * to claim devices when another device with the same wwid exists. ++ * nr_paths must either be set to the number of elements of ++ * path_wwids, or 0, if path_wwids is NULL. ++ * @name: The kernel name of the device. input argument ++ * @mode: the find_multipaths claim mode (mpath_valid_mode). input argument ++ * @wwid: address of a pointer to the path wwid, or NULL. Output argument. ++ * Set if path is/may be claimed. If set, must be freed by caller ++ * @path_wwids: Array of pointers to path wwids, or NULL. input argument ++ * @nr_paths: number of elements in path_wwids array. input argument. ++ * ++ * RETURNS: device claim result (mpath_valid_result) ++ * Also sets *wwid if wwid is not NULL, and the claim result is ++ * MPATH_IS_VALID, MPATH_IS_VALID_NO_CHECK, or ++ * MPATH_IS_MAYBE_VALID ++ */ +int mpathvalid_is_path(const char *name, unsigned int mode, char **wwid, + const char **path_wwids, unsigned int nr_paths); + -+ +#ifdef __cplusplus +} +#endif +#endif /* LIB_PATH_VALID_H */ +diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version +index 67a7379f..2e3583f5 100644 +--- a/libmultipath/libmultipath.version ++++ b/libmultipath/libmultipath.version +@@ -264,3 +264,9 @@ LIBMULTIPATH_4.1.0 { + global: + libmp_verbosity; + } LIBMULTIPATH_4.0.0; ++ ++LIBMULTIPATH_4.2.0 { ++global: ++ dm_prereq; ++ skip_libmp_dm_init; ++} LIBMULTIPATH_4.1.0; -- 2.17.2 diff --git a/0069-RH-work-around-gcc-10-format-truncation-issue.patch b/0069-RH-work-around-gcc-10-format-truncation-issue.patch deleted file mode 100644 index c501ce9..0000000 --- a/0069-RH-work-around-gcc-10-format-truncation-issue.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 29 May 2020 17:21:21 -0500 -Subject: [PATCH] RH: work around gcc 10 format-truncation issue - -gcc 10 was returning false positives on some architectures, when trying -to determine if a snprintf() function could silently truncate its -output. Instead of changing the code to pretend that this is possible, -make these warnings, instead of errors. - -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 479523bc..e2f5d0dc 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -109,7 +109,7 @@ endif - WARNFLAGS := -Werror -Wextra -Wformat=2 -Werror=implicit-int \ - -Werror=implicit-function-declaration -Werror=format-security \ - $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) \ -- -Wstrict-prototypes -+ -Wstrict-prototypes -Wno-error=format-truncation - CFLAGS := $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ - -DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" \ - -MMD -MP --- -2.17.2 - diff --git a/0069-multipath-tools-tests-and-unit-tests-for-libmpathval.patch b/0069-multipath-tools-tests-and-unit-tests-for-libmpathval.patch new file mode 100644 index 0000000..cd24d4e --- /dev/null +++ b/0069-multipath-tools-tests-and-unit-tests-for-libmpathval.patch @@ -0,0 +1,532 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 21 Oct 2020 16:39:24 -0500 +Subject: [PATCH] multipath-tools tests: and unit tests for libmpathvalid + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + Makefile.inc | 1 + + tests/Makefile | 5 +- + tests/mpathvalid.c | 467 +++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 472 insertions(+), 1 deletion(-) + create mode 100644 tests/mpathvalid.c + +diff --git a/Makefile.inc b/Makefile.inc +index e05f3a91..13587a9f 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -66,6 +66,7 @@ libdir = $(prefix)/$(LIB)/multipath + unitdir = $(prefix)/$(SYSTEMDPATH)/systemd/system + mpathpersistdir = $(TOPDIR)/libmpathpersist + mpathcmddir = $(TOPDIR)/libmpathcmd ++mpathvaliddir = $(TOPDIR)/libmpathvalid + thirdpartydir = $(TOPDIR)/third-party + libdmmpdir = $(TOPDIR)/libdmmp + nvmedir = $(TOPDIR)/libmultipath/nvme +diff --git a/tests/Makefile b/tests/Makefile +index 908407ea..54da774e 100644 +--- a/tests/Makefile ++++ b/tests/Makefile +@@ -13,7 +13,7 @@ CFLAGS += $(BIN_CFLAGS) -I$(multipathdir) -I$(mpathcmddir) \ + LIBDEPS += -L. -L$(mpathcmddir) -lmultipath -lmpathcmd -lcmocka + + TESTS := uevent parser util dmevents hwtable blacklist unaligned vpd pgpolicy \ +- alias directio valid devt ++ alias directio valid devt mpathvalid + HELPERS := test-lib.o test-log.o + + .SILENT: $(TESTS:%=%.o) +@@ -31,6 +31,7 @@ endif + ifneq ($(DIO_TEST_DEV),) + directio-test_FLAGS := -DDIO_TEST_DEV=\"$(DIO_TEST_DEV)\" + endif ++mpathvalid-test_FLAGS := -I$(mpathvaliddir) + + # test-specific linker flags + # XYZ-test_TESTDEPS: test libraries containing __wrap_xyz functions +@@ -56,6 +57,8 @@ alias-test_LIBDEPS := -lpthread -ldl + valid-test_OBJDEPS := ../libmultipath/valid.o + valid-test_LIBDEPS := -ludev -lpthread -ldl + devt-test_LIBDEPS := -ludev ++mpathvalid-test_LIBDEPS := -ludev -lpthread -ldl ++mpathvalid-test_OBJDEPS := ../libmpathvalid/mpath_valid.o + ifneq ($(DIO_TEST_DEV),) + directio-test_LIBDEPS := -laio + endif +diff --git a/tests/mpathvalid.c b/tests/mpathvalid.c +new file mode 100644 +index 00000000..5ffabb9d +--- /dev/null ++++ b/tests/mpathvalid.c +@@ -0,0 +1,467 @@ ++/* ++ * Copyright (c) 2020 Benjamin Marzinski, Red Hat ++ * ++ * SPDX-License-Identifier: GPL-2.0-or-later ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "structs.h" ++#include "config.h" ++#include "mpath_valid.h" ++#include "util.h" ++#include "debug.h" ++ ++const char *test_dev = "test_name"; ++#define TEST_WWID "WWID_123" ++#define CONF_TEMPLATE "mpathvalid-testconf-XXXXXXXX" ++char conf_name[] = CONF_TEMPLATE; ++bool initialized; ++ ++#if 0 ++static int mode_to_findmp(unsigned int mode) ++{ ++ switch (mode) { ++ case MPATH_SMART: ++ return FIND_MULTIPATHS_SMART; ++ case MPATH_GREEDY: ++ return FIND_MULTIPATHS_GREEDY; ++ case MPATH_STRICT: ++ return FIND_MULTIPATHS_STRICT; ++ } ++ fail_msg("invalid mode: %u", mode); ++ return FIND_MULTIPATHS_UNDEF; ++} ++#endif ++ ++static unsigned int findmp_to_mode(int findmp) ++{ ++ switch (findmp) { ++ case FIND_MULTIPATHS_SMART: ++ return MPATH_SMART; ++ case FIND_MULTIPATHS_GREEDY: ++ return MPATH_GREEDY; ++ case FIND_MULTIPATHS_STRICT: ++ case FIND_MULTIPATHS_OFF: ++ case FIND_MULTIPATHS_ON: ++ return MPATH_STRICT; ++ } ++ fail_msg("invalid find_multipaths value: %d", findmp); ++ return MPATH_DEFAULT; ++} ++ ++int __wrap_is_path_valid(const char *name, struct config *conf, struct path *pp, ++ bool check_multipathd) ++{ ++ int r = mock_type(int); ++ int findmp = mock_type(int); ++ ++ assert_ptr_equal(name, test_dev); ++ assert_ptr_not_equal(conf, NULL); ++ assert_ptr_not_equal(pp, NULL); ++ assert_true(check_multipathd); ++ ++ assert_int_equal(findmp, conf->find_multipaths); ++ if (r == MPATH_IS_ERROR || r == MPATH_IS_NOT_VALID) ++ return r; ++ ++ strlcpy(pp->wwid, mock_ptr_type(char *), WWID_SIZE); ++ return r; ++} ++ ++int __wrap_libmultipath_init(void) ++{ ++ int r = mock_type(int); ++ ++ assert_false(initialized); ++ if (r != 0) ++ return r; ++ initialized = true; ++ return 0; ++} ++ ++void __wrap_libmultipath_exit(void) ++{ ++ assert_true(initialized); ++ initialized = false; ++} ++ ++int __wrap_dm_prereq(unsigned int *v) ++{ ++ assert_ptr_not_equal(v, NULL); ++ return mock_type(int); ++} ++ ++int __real_init_config(const char *file); ++ ++int __wrap_init_config(const char *file) ++{ ++ int r = mock_type(int); ++ struct config *conf; ++ ++ assert_ptr_equal(file, DEFAULT_CONFIGFILE); ++ if (r != 0) ++ return r; ++ ++ assert_string_not_equal(conf_name, CONF_TEMPLATE); ++ r = __real_init_config(conf_name); ++ conf = get_multipath_config(); ++ assert_ptr_not_equal(conf, NULL); ++ assert_int_equal(conf->find_multipaths, mock_type(int)); ++ return 0; ++} ++ ++static const char * const find_multipaths_optvals[] = { ++ [FIND_MULTIPATHS_OFF] = "off", ++ [FIND_MULTIPATHS_ON] = "on", ++ [FIND_MULTIPATHS_STRICT] = "strict", ++ [FIND_MULTIPATHS_GREEDY] = "greedy", ++ [FIND_MULTIPATHS_SMART] = "smart", ++}; ++ ++void make_config_file(int findmp) ++{ ++ int r, fd; ++ char buf[64]; ++ ++ assert_true(findmp > FIND_MULTIPATHS_UNDEF && ++ findmp < __FIND_MULTIPATHS_LAST); ++ ++ r = snprintf(buf, sizeof(buf), "defaults {\nfind_multipaths %s\n}\n", ++ find_multipaths_optvals[findmp]); ++ assert_true(r > 0 && (long unsigned int)r < sizeof(buf)); ++ ++ memcpy(conf_name, CONF_TEMPLATE, sizeof(conf_name)); ++ fd = mkstemp(conf_name); ++ assert_true(fd >= 0); ++ assert_int_equal(safe_write(fd, buf, r), 0); ++ assert_int_equal(close(fd), 0); ++} ++ ++int setup(void **state) ++{ ++ initialized = false; ++ udev = udev_new(); ++ if (udev == NULL) ++ return -1; ++ return 0; ++} ++ ++int teardown(void **state) ++{ ++ struct config *conf; ++ conf = get_multipath_config(); ++ put_multipath_config(conf); ++ if (conf) ++ uninit_config(); ++ if (strcmp(conf_name, CONF_TEMPLATE) != 0) ++ unlink(conf_name); ++ udev_unref(udev); ++ udev = NULL; ++ return 0; ++} ++ ++static void check_config(bool valid_config) ++{ ++ struct config *conf; ++ ++ conf = get_multipath_config(); ++ put_multipath_config(conf); ++ if (valid_config) ++ assert_ptr_not_equal(conf, NULL); ++} ++ ++/* libmultipath_init fails */ ++static void test_mpathvalid_init_bad1(void **state) ++{ ++ will_return(__wrap_libmultipath_init, 1); ++ assert_int_equal(mpathvalid_init(MPATH_LOG_PRIO_DEBUG, ++ MPATH_LOG_STDERR), -1); ++ assert_false(initialized); ++ check_config(false); ++} ++ ++/* init_config fails */ ++static void test_mpathvalid_init_bad2(void **state) ++{ ++ will_return(__wrap_libmultipath_init, 0); ++ will_return(__wrap_init_config, 1); ++ assert_int_equal(mpathvalid_init(MPATH_LOG_PRIO_ERR, ++ MPATH_LOG_STDERR_TIMESTAMP), -1); ++ assert_false(initialized); ++ check_config(false); ++} ++ ++/* dm_prereq fails */ ++static void test_mpathvalid_init_bad3(void **state) ++{ ++ make_config_file(FIND_MULTIPATHS_STRICT); ++ will_return(__wrap_libmultipath_init, 0); ++ will_return(__wrap_init_config, 0); ++ will_return(__wrap_init_config, FIND_MULTIPATHS_STRICT); ++ will_return(__wrap_dm_prereq, 1); ++ assert_int_equal(mpathvalid_init(MPATH_LOG_STDERR, MPATH_LOG_PRIO_ERR), ++ -1); ++ assert_false(initialized); ++ check_config(false); ++} ++ ++static void check_mpathvalid_init(int findmp, int prio, int log_style) ++{ ++ make_config_file(findmp); ++ will_return(__wrap_libmultipath_init, 0); ++ will_return(__wrap_init_config, 0); ++ will_return(__wrap_init_config, findmp); ++ will_return(__wrap_dm_prereq, 0); ++ assert_int_equal(mpathvalid_init(prio, log_style), 0); ++ assert_true(initialized); ++ check_config(true); ++ assert_int_equal(logsink, log_style); ++ assert_int_equal(libmp_verbosity, prio); ++ assert_int_equal(findmp_to_mode(findmp), mpathvalid_get_mode()); ++} ++ ++static void check_mpathvalid_exit(void) ++{ ++ assert_int_equal(mpathvalid_exit(), 0); ++ assert_false(initialized); ++ check_config(false); ++} ++ ++static void test_mpathvalid_init_good1(void **state) ++{ ++ check_mpathvalid_init(FIND_MULTIPATHS_OFF, MPATH_LOG_PRIO_ERR, ++ MPATH_LOG_STDERR_TIMESTAMP); ++} ++ ++static void test_mpathvalid_init_good2(void **state) ++{ ++ check_mpathvalid_init(FIND_MULTIPATHS_STRICT, MPATH_LOG_PRIO_DEBUG, ++ MPATH_LOG_STDERR); ++} ++ ++static void test_mpathvalid_init_good3(void **state) ++{ ++ check_mpathvalid_init(FIND_MULTIPATHS_ON, MPATH_LOG_PRIO_NOLOG, ++ MPATH_LOG_SYSLOG); ++} ++ ++static void test_mpathvalid_exit(void **state) ++{ ++ check_mpathvalid_init(FIND_MULTIPATHS_ON, MPATH_LOG_PRIO_ERR, ++ MPATH_LOG_STDERR); ++ check_mpathvalid_exit(); ++} ++ ++/* fails if config hasn't been set */ ++static void test_mpathvalid_get_mode_bad(void **state) ++{ ++#if 1 ++ assert_int_equal(mpathvalid_get_mode(), MPATH_MODE_ERROR); ++#else ++ assert_int_equal(mpathvalid_get_mode(), 1); ++#endif ++} ++ ++/*fails if config hasn't been set */ ++static void test_mpathvalid_reload_config_bad1(void **state) ++{ ++#if 1 ++ will_return(__wrap_init_config, 1); ++#endif ++ assert_int_equal(mpathvalid_reload_config(), -1); ++ check_config(false); ++} ++ ++/* init_config fails */ ++static void test_mpathvalid_reload_config_bad2(void **state) ++{ ++ check_mpathvalid_init(FIND_MULTIPATHS_ON, MPATH_LOG_PRIO_ERR, ++ MPATH_LOG_STDERR); ++ will_return(__wrap_init_config, 1); ++ assert_int_equal(mpathvalid_reload_config(), -1); ++ check_config(false); ++ check_mpathvalid_exit(); ++} ++ ++static void check_mpathvalid_reload_config(int findmp) ++{ ++ assert_string_not_equal(conf_name, CONF_TEMPLATE); ++ unlink(conf_name); ++ make_config_file(findmp); ++ will_return(__wrap_init_config, 0); ++ will_return(__wrap_init_config, findmp); ++ assert_int_equal(mpathvalid_reload_config(), 0); ++ check_config(true); ++ assert_int_equal(findmp_to_mode(findmp), mpathvalid_get_mode()); ++} ++ ++static void test_mpathvalid_reload_config_good(void **state) ++{ ++ check_mpathvalid_init(FIND_MULTIPATHS_OFF, MPATH_LOG_PRIO_ERR, ++ MPATH_LOG_STDERR); ++ check_mpathvalid_reload_config(FIND_MULTIPATHS_ON); ++ check_mpathvalid_reload_config(FIND_MULTIPATHS_GREEDY); ++ check_mpathvalid_reload_config(FIND_MULTIPATHS_SMART); ++ check_mpathvalid_reload_config(FIND_MULTIPATHS_STRICT); ++ check_mpathvalid_exit(); ++} ++ ++/* NULL name */ ++static void test_mpathvalid_is_path_bad1(void **state) ++{ ++ assert_int_equal(mpathvalid_is_path(NULL, MPATH_STRICT, NULL, NULL, 0), ++ MPATH_IS_ERROR); ++} ++ ++/* bad mode */ ++static void test_mpathvalid_is_path_bad2(void **state) ++{ ++ assert_int_equal(mpathvalid_is_path(test_dev, MPATH_MODE_ERROR, NULL, ++ NULL, 0), MPATH_IS_ERROR); ++} ++ ++/* NULL path_wwids and non-zero nr_paths */ ++static void test_mpathvalid_is_path_bad3(void **state) ++{ ++ assert_int_equal(mpathvalid_is_path(test_dev, MPATH_MODE_ERROR, NULL, ++ NULL, 1), MPATH_IS_ERROR); ++} ++ ++/*fails if config hasn't been set */ ++static void test_mpathvalid_is_path_bad4(void **state) ++{ ++#if 0 ++ will_return(__wrap_is_path_valid, MPATH_IS_ERROR); ++ will_return(__wrap_is_path_valid, FIND_MULTIPATHS_STRICT); ++#endif ++ assert_int_equal(mpathvalid_is_path(test_dev, MPATH_STRICT, NULL, ++ NULL, 0), MPATH_IS_ERROR); ++} ++ ++/* is_path_valid fails */ ++static void test_mpathvalid_is_path_bad5(void **state) ++{ ++ check_mpathvalid_init(FIND_MULTIPATHS_OFF, MPATH_LOG_PRIO_ERR, ++ MPATH_LOG_STDERR); ++ will_return(__wrap_is_path_valid, MPATH_IS_ERROR); ++ will_return(__wrap_is_path_valid, FIND_MULTIPATHS_GREEDY); ++ assert_int_equal(mpathvalid_is_path(test_dev, MPATH_GREEDY, NULL, ++ NULL, 0), MPATH_IS_ERROR); ++ check_mpathvalid_exit(); ++} ++ ++static void test_mpathvalid_is_path_good1(void **state) ++{ ++ char *wwid; ++ check_mpathvalid_init(FIND_MULTIPATHS_STRICT, MPATH_LOG_PRIO_ERR, ++ MPATH_LOG_STDERR); ++ will_return(__wrap_is_path_valid, MPATH_IS_NOT_VALID); ++ will_return(__wrap_is_path_valid, FIND_MULTIPATHS_STRICT); ++ assert_int_equal(mpathvalid_is_path(test_dev, MPATH_DEFAULT, &wwid, ++ NULL, 0), MPATH_IS_NOT_VALID); ++ assert_ptr_equal(wwid, NULL); ++ check_mpathvalid_exit(); ++} ++ ++static void test_mpathvalid_is_path_good2(void **state) ++{ ++ const char *wwids[] = { "WWID_A", "WWID_B", "WWID_C", "WWID_D" }; ++ char *wwid; ++ check_mpathvalid_init(FIND_MULTIPATHS_ON, MPATH_LOG_PRIO_ERR, ++ MPATH_LOG_STDERR); ++ will_return(__wrap_is_path_valid, MPATH_IS_VALID); ++ will_return(__wrap_is_path_valid, FIND_MULTIPATHS_ON); ++ will_return(__wrap_is_path_valid, TEST_WWID); ++ assert_int_equal(mpathvalid_is_path(test_dev, MPATH_DEFAULT, &wwid, ++ wwids, 4), MPATH_IS_VALID); ++ assert_string_equal(wwid, TEST_WWID); ++} ++ ++static void test_mpathvalid_is_path_good3(void **state) ++{ ++ const char *wwids[] = { "WWID_A", "WWID_B", "WWID_C", "WWID_D" }; ++ char *wwid; ++ check_mpathvalid_init(FIND_MULTIPATHS_OFF, MPATH_LOG_PRIO_ERR, ++ MPATH_LOG_STDERR); ++ will_return(__wrap_is_path_valid, MPATH_IS_VALID); ++ will_return(__wrap_is_path_valid, FIND_MULTIPATHS_SMART); ++ will_return(__wrap_is_path_valid, TEST_WWID); ++ assert_int_equal(mpathvalid_is_path(test_dev, MPATH_SMART, &wwid, ++ wwids, 4), MPATH_IS_VALID); ++ assert_string_equal(wwid, TEST_WWID); ++} ++ ++/* mabybe valid with no matching paths */ ++static void test_mpathvalid_is_path_good4(void **state) ++{ ++ const char *wwids[] = { "WWID_A", "WWID_B", "WWID_C", "WWID_D" }; ++ char *wwid; ++ check_mpathvalid_init(FIND_MULTIPATHS_SMART, MPATH_LOG_PRIO_ERR, ++ MPATH_LOG_STDERR); ++ will_return(__wrap_is_path_valid, MPATH_IS_MAYBE_VALID); ++ will_return(__wrap_is_path_valid, FIND_MULTIPATHS_SMART); ++ will_return(__wrap_is_path_valid, TEST_WWID); ++ assert_int_equal(mpathvalid_is_path(test_dev, MPATH_DEFAULT, &wwid, ++ wwids, 4), MPATH_IS_MAYBE_VALID); ++ assert_string_equal(wwid, TEST_WWID); ++} ++ ++/* maybe valid with matching paths */ ++static void test_mpathvalid_is_path_good5(void **state) ++{ ++ const char *wwids[] = { "WWID_A", "WWID_B", TEST_WWID, "WWID_D" }; ++ char *wwid; ++ check_mpathvalid_init(FIND_MULTIPATHS_SMART, MPATH_LOG_PRIO_ERR, ++ MPATH_LOG_STDERR); ++ will_return(__wrap_is_path_valid, MPATH_IS_MAYBE_VALID); ++ will_return(__wrap_is_path_valid, FIND_MULTIPATHS_SMART); ++ will_return(__wrap_is_path_valid, TEST_WWID); ++ assert_int_equal(mpathvalid_is_path(test_dev, MPATH_DEFAULT, &wwid, ++ wwids, 4), MPATH_IS_VALID); ++ assert_string_equal(wwid, TEST_WWID); ++} ++ ++#define setup_test(name) \ ++ cmocka_unit_test_setup_teardown(name, setup, teardown) ++ ++int test_mpathvalid(void) ++{ ++ const struct CMUnitTest tests[] = { ++ setup_test(test_mpathvalid_init_bad1), ++ setup_test(test_mpathvalid_init_bad2), ++ setup_test(test_mpathvalid_init_bad3), ++ setup_test(test_mpathvalid_init_good1), ++ setup_test(test_mpathvalid_init_good2), ++ setup_test(test_mpathvalid_init_good3), ++ setup_test(test_mpathvalid_exit), ++ setup_test(test_mpathvalid_get_mode_bad), ++ setup_test(test_mpathvalid_reload_config_bad1), ++ setup_test(test_mpathvalid_reload_config_bad2), ++ setup_test(test_mpathvalid_reload_config_good), ++ setup_test(test_mpathvalid_is_path_bad1), ++ setup_test(test_mpathvalid_is_path_bad2), ++ setup_test(test_mpathvalid_is_path_bad3), ++ setup_test(test_mpathvalid_is_path_bad4), ++ setup_test(test_mpathvalid_is_path_bad5), ++ setup_test(test_mpathvalid_is_path_good1), ++ setup_test(test_mpathvalid_is_path_good2), ++ setup_test(test_mpathvalid_is_path_good3), ++ setup_test(test_mpathvalid_is_path_good4), ++ setup_test(test_mpathvalid_is_path_good5), ++ }; ++ return cmocka_run_group_tests(tests, NULL, NULL); ++} ++ ++int main(void) ++{ ++ int r = 0; ++ ++ r += test_mpathvalid(); ++ return r; ++} +-- +2.17.2 + diff --git a/0071-libmultipath-add-uid-failback-for-dasd-devices.patch b/0070-libmultipath-add-uid-failback-for-dasd-devices.patch similarity index 90% rename from 0071-libmultipath-add-uid-failback-for-dasd-devices.patch rename to 0070-libmultipath-add-uid-failback-for-dasd-devices.patch index 2515095..c052217 100644 --- a/0071-libmultipath-add-uid-failback-for-dasd-devices.patch +++ b/0070-libmultipath-add-uid-failback-for-dasd-devices.patch @@ -1,11 +1,12 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski -Date: Tue, 19 May 2020 15:55:15 -0500 +Date: Wed, 21 Oct 2020 16:39:25 -0500 Subject: [PATCH] libmultipath: add uid failback for dasd devices Add failback code to get the uid for dasd devices from sysfs. Copied from dasdinfo +Reviewed-by: Martin Wilck Signed-off-by: Benjamin Marzinski --- libmultipath/defaults.h | 1 + @@ -13,7 +14,7 @@ Signed-off-by: Benjamin Marzinski 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h -index 984d8dd8..6a678a83 100644 +index 39a5e415..947ba467 100644 --- a/libmultipath/defaults.h +++ b/libmultipath/defaults.h @@ -8,6 +8,7 @@ @@ -25,10 +26,10 @@ index 984d8dd8..6a678a83 100644 #define DEFAULT_MULTIPATHDIR "/" LIB_STRING "/multipath" #define DEFAULT_SELECTOR "service-time 0" diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index aa5942c3..002d3d18 100644 +index e7084664..877e8f2b 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c -@@ -1920,12 +1920,44 @@ get_vpd_uid(struct path * pp) +@@ -1959,12 +1959,44 @@ get_vpd_uid(struct path * pp) return get_vpd_sysfs(parent, 0x83, pp->wwid, WWID_SIZE); } @@ -74,7 +75,7 @@ index aa5942c3..002d3d18 100644 len = get_vpd_uid(pp); *origin = "sysfs"; if (len < 0 && path_state == PATH_UP) { -@@ -1970,6 +2002,9 @@ static bool has_uid_fallback(struct path *pp) +@@ -2012,6 +2044,9 @@ static bool has_uid_fallback(struct path *pp) !strcmp(pp->uid_attribute, ""))) || (pp->bus == SYSFS_BUS_NVME && (!strcmp(pp->uid_attribute, DEFAULT_NVME_UID_ATTRIBUTE) || diff --git a/0086-libmultipath-change-log-level-for-null-uid_attribute.patch b/0071-libmultipath-change-log-level-for-null-uid_attribute.patch similarity index 50% rename from 0086-libmultipath-change-log-level-for-null-uid_attribute.patch rename to 0071-libmultipath-change-log-level-for-null-uid_attribute.patch index 8567bc3..3fa6b93 100644 --- a/0086-libmultipath-change-log-level-for-null-uid_attribute.patch +++ b/0071-libmultipath-change-log-level-for-null-uid_attribute.patch @@ -1,6 +1,6 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski -Date: Tue, 22 Sep 2020 16:03:31 -0500 +Date: Wed, 21 Oct 2020 16:39:26 -0500 Subject: [PATCH] libmultipath: change log level for null uid_attribute If uid_attribute is explicitly set to an empty string, multipath should @@ -8,20 +8,34 @@ log the uid at the default log level, since using the fallback code is the expected behavior. Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck --- - libmultipath/discovery.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) + libmultipath/discovery.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 002d3d18..77468524 100644 +index 877e8f2b..c74f13bf 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c -@@ -2058,7 +2058,8 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev, +@@ -2086,8 +2086,11 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev, + len = strlen(pp->wwid); + origin = "callout"; + } else { +- bool udev_available = udev && pp->uid_attribute ++ bool valid_uid_attr = pp->uid_attribute + && *pp->uid_attribute; ++ bool empty_uid_attr = pp->uid_attribute ++ && !*pp->uid_attribute; ++ bool udev_available = udev && valid_uid_attr; + + if (udev_available) { + len = get_udev_uid(pp, pp->uid_attribute, udev); +@@ -2097,7 +2100,8 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev, } if ((!udev_available || (len <= 0 && allow_fallback)) && has_uid_fallback(pp)) { - used_fallback = 1; -+ if (udev_available || !(udev && pp->uid_attribute)) ++ if (!udev || !empty_uid_attr) + used_fallback = 1; len = uid_fallback(pp, path_state, &origin); } diff --git a/0072-libmultipath-add-ignore_udev_uid-option.patch b/0072-libmultipath-add-ignore_udev_uid-option.patch deleted file mode 100644 index d9cf8a7..0000000 --- a/0072-libmultipath-add-ignore_udev_uid-option.patch +++ /dev/null @@ -1,192 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 20 May 2020 16:46:55 -0500 -Subject: [PATCH] libmultipath: add ignore_udev_uid option - -Setting this option to yes will force multipath to get the uid by using -the fallback sysfs methods, instead of getting it from udev. This will -cause devices that can't get their uid from the standard locations to -not get a uid. It will also disable uevent merging. - -It will not stop uevents from being resent for device that failed to -get a WWID, although I'm on the fence about the benefit of this. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/config.h | 1 + - libmultipath/dict.c | 4 ++++ - libmultipath/discovery.c | 17 +++++++++++------ - libmultipath/discovery.h | 8 +++++++- - libmultipath/uevent.c | 2 +- - multipath/multipath.conf.5 | 13 +++++++++++++ - multipathd/main.c | 7 ++++++- - 7 files changed, 43 insertions(+), 9 deletions(-) - -diff --git a/libmultipath/config.h b/libmultipath/config.h -index 160867cd..c7a73fba 100644 ---- a/libmultipath/config.h -+++ b/libmultipath/config.h -@@ -192,6 +192,7 @@ struct config { - int find_multipaths_timeout; - int marginal_pathgroups; - int skip_delegate; -+ int ignore_udev_uid; - unsigned int version[3]; - unsigned int sequence_nr; - -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index 184d4b22..9a0729bf 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -1406,6 +1406,9 @@ declare_hw_snprint(all_tg_pt, print_yes_no_undef) - declare_def_handler(marginal_pathgroups, set_yes_no) - declare_def_snprint(marginal_pathgroups, print_yes_no) - -+declare_def_handler(ignore_udev_uid, set_yes_no) -+declare_def_snprint(ignore_udev_uid, print_yes_no) -+ - static int - def_uxsock_timeout_handler(struct config *conf, vector strvec) - { -@@ -1816,6 +1819,7 @@ init_keywords(vector keywords) - install_keyword("enable_foreign", &def_enable_foreign_handler, - &snprint_def_enable_foreign); - install_keyword("marginal_pathgroups", &def_marginal_pathgroups_handler, &snprint_def_marginal_pathgroups); -+ install_keyword("ignore_udev_uid", &def_ignore_udev_uid_handler, &snprint_def_ignore_udev_uid); - __deprecated install_keyword("default_selector", &def_selector_handler, NULL); - __deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL); - __deprecated install_keyword("default_uid_attribute", &def_uid_attribute_handler, NULL); -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 002d3d18..f0e92227 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -2010,7 +2010,7 @@ static bool has_uid_fallback(struct path *pp) - - int - get_uid (struct path * pp, int path_state, struct udev_device *udev, -- int allow_fallback) -+ int fallback) - { - char *c; - const char *origin = "unknown"; -@@ -2043,7 +2043,9 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev, - } else - len = strlen(pp->wwid); - origin = "callout"; -- } else { -+ } else if (fallback == UID_FALLBACK_FORCE) -+ len = uid_fallback(pp, path_state, &origin); -+ else { - bool udev_available = udev && pp->uid_attribute - && *pp->uid_attribute; - -@@ -2056,8 +2058,9 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev, - else - origin = "udev"; - } -- if ((!udev_available || (len <= 0 && allow_fallback)) -- && has_uid_fallback(pp)) { -+ if ((!udev_available || -+ (len <= 0 && fallback == UID_FALLBACK_ALLOW)) && -+ has_uid_fallback(pp)) { - used_fallback = 1; - len = uid_fallback(pp, path_state, &origin); - } -@@ -2197,8 +2200,10 @@ int pathinfo(struct path *pp, struct config *conf, int mask) - } - - if ((mask & DI_WWID) && !strlen(pp->wwid)) { -- get_uid(pp, path_state, pp->udev, -- (pp->retriggers >= conf->retrigger_tries)); -+ int fallback = conf->ignore_udev_uid? UID_FALLBACK_FORCE : -+ (pp->retriggers >= conf->retrigger_tries)? -+ UID_FALLBACK_ALLOW : UID_FALLBACK_NONE; -+ get_uid(pp, path_state, pp->udev, fallback); - if (!strlen(pp->wwid)) { - if (pp->bus == SYSFS_BUS_UNDEF) - return PATHINFO_SKIPPED; -diff --git a/libmultipath/discovery.h b/libmultipath/discovery.h -index 6444887d..ca8542d6 100644 ---- a/libmultipath/discovery.h -+++ b/libmultipath/discovery.h -@@ -54,8 +54,14 @@ ssize_t sysfs_get_inquiry(struct udev_device *udev, - unsigned char *buff, size_t len); - int sysfs_get_asymmetric_access_state(struct path *pp, - char *buff, int buflen); -+ -+enum { -+ UID_FALLBACK_NONE, -+ UID_FALLBACK_ALLOW, -+ UID_FALLBACK_FORCE, -+}; - int get_uid(struct path * pp, int path_state, struct udev_device *udev, -- int allow_fallback); -+ int fallback); - - /* - * discovery bitmask -diff --git a/libmultipath/uevent.c b/libmultipath/uevent.c -index e0d13b11..d67129d1 100644 ---- a/libmultipath/uevent.c -+++ b/libmultipath/uevent.c -@@ -179,7 +179,7 @@ uevent_need_merge(void) - bool need_merge = false; - - conf = get_multipath_config(); -- if (VECTOR_SIZE(&conf->uid_attrs) > 0) -+ if (!conf->ignore_udev_uid && VECTOR_SIZE(&conf->uid_attrs) > 0) - need_merge = true; - put_multipath_config(conf); - -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 42a192f6..175ca095 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -286,6 +286,19 @@ The default is: \fB\fR - . - . - .TP -+.B ignore_udev_uid -+Setting this option to yes will force multipath to ignore the the uid_attrs -+and uid_attribute settings, and generate the WWID by the \fIsysfs\fR -+method. This will cause devices that cannot get their WWID from the standard -+locations for their device type to not get a WWID; see \fBWWID generation\fR -+below. -+.RS -+.TP -+The default is: \fBno\fR -+.RE -+. -+. -+.TP - .B prio - The name of the path priority routine. The specified routine - should return a numeric value specifying the relative priority -diff --git a/multipathd/main.c b/multipathd/main.c -index f014d2a1..48b62937 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -1226,6 +1226,7 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) - if (pp) { - struct multipath *mpp = pp->mpp; - char wwid[WWID_SIZE]; -+ int fallback; - - if (pp->initialized == INIT_REQUESTED_UDEV) { - needs_reinit = 1; -@@ -1237,7 +1238,11 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) - goto out; - - strcpy(wwid, pp->wwid); -- rc = get_uid(pp, pp->state, uev->udev, 0); -+ conf = get_multipath_config(); -+ fallback = conf->ignore_udev_uid? UID_FALLBACK_FORCE: -+ UID_FALLBACK_NONE; -+ put_multipath_config(conf); -+ rc = get_uid(pp, pp->state, uev->udev, fallback); - - if (rc != 0) - strcpy(pp->wwid, wwid); --- -2.17.2 - diff --git a/0072-libmultipath-move-fast_io_fail-defines-to-structs.h.patch b/0072-libmultipath-move-fast_io_fail-defines-to-structs.h.patch new file mode 100644 index 0000000..8346fa2 --- /dev/null +++ b/0072-libmultipath-move-fast_io_fail-defines-to-structs.h.patch @@ -0,0 +1,160 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 17 Dec 2020 16:50:59 -0600 +Subject: [PATCH] libmultipath: move fast_io_fail defines to structs.h + +Since fast_io_fail is part of the multipath struct, its symbolic values +belong in structs.h. Also, make it an instance of a general enum, which +will be used again in future patches, and change the set/print functions +which use it to use the general enum instead. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/config.h | 8 -------- + libmultipath/dict.c | 30 +++++++++++++++--------------- + libmultipath/dict.h | 2 +- + libmultipath/propsel.c | 2 +- + libmultipath/structs.h | 17 +++++++++++++++++ + 5 files changed, 34 insertions(+), 25 deletions(-) + +diff --git a/libmultipath/config.h b/libmultipath/config.h +index 5d460359..661dd586 100644 +--- a/libmultipath/config.h ++++ b/libmultipath/config.h +@@ -10,14 +10,6 @@ + #define ORIGIN_DEFAULT 0 + #define ORIGIN_CONFIG 1 + +-/* +- * In kernel, fast_io_fail == 0 means immediate failure on rport delete. +- * OTOH '0' means not-configured in various places in multipath-tools. +- */ +-#define MP_FAST_IO_FAIL_UNSET (0) +-#define MP_FAST_IO_FAIL_OFF (-1) +-#define MP_FAST_IO_FAIL_ZERO (-2) +- + enum devtypes { + DEV_NONE, + DEV_DEVT, +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index f12c2e5c..f4357da1 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -822,7 +822,7 @@ declare_mp_attr_handler(gid, set_gid) + declare_mp_attr_snprint(gid, print_gid) + + static int +-set_fast_io_fail(vector strvec, void *ptr) ++set_undef_off_zero(vector strvec, void *ptr) + { + char * buff; + int *int_ptr = (int *)ptr; +@@ -832,36 +832,36 @@ set_fast_io_fail(vector strvec, void *ptr) + return 1; + + if (strcmp(buff, "off") == 0) +- *int_ptr = MP_FAST_IO_FAIL_OFF; ++ *int_ptr = UOZ_OFF; + else if (sscanf(buff, "%d", int_ptr) != 1 || +- *int_ptr < MP_FAST_IO_FAIL_ZERO) +- *int_ptr = MP_FAST_IO_FAIL_UNSET; ++ *int_ptr < UOZ_ZERO) ++ *int_ptr = UOZ_UNDEF; + else if (*int_ptr == 0) +- *int_ptr = MP_FAST_IO_FAIL_ZERO; ++ *int_ptr = UOZ_ZERO; + + FREE(buff); + return 0; + } + + int +-print_fast_io_fail(char * buff, int len, long v) ++print_undef_off_zero(char * buff, int len, long v) + { +- if (v == MP_FAST_IO_FAIL_UNSET) ++ if (v == UOZ_UNDEF) + return 0; +- if (v == MP_FAST_IO_FAIL_OFF) ++ if (v == UOZ_OFF) + return snprintf(buff, len, "\"off\""); +- if (v == MP_FAST_IO_FAIL_ZERO) ++ if (v == UOZ_ZERO) + return snprintf(buff, len, "0"); + return snprintf(buff, len, "%ld", v); + } + +-declare_def_handler(fast_io_fail, set_fast_io_fail) +-declare_def_snprint_defint(fast_io_fail, print_fast_io_fail, ++declare_def_handler(fast_io_fail, set_undef_off_zero) ++declare_def_snprint_defint(fast_io_fail, print_undef_off_zero, + DEFAULT_FAST_IO_FAIL) +-declare_ovr_handler(fast_io_fail, set_fast_io_fail) +-declare_ovr_snprint(fast_io_fail, print_fast_io_fail) +-declare_hw_handler(fast_io_fail, set_fast_io_fail) +-declare_hw_snprint(fast_io_fail, print_fast_io_fail) ++declare_ovr_handler(fast_io_fail, set_undef_off_zero) ++declare_ovr_snprint(fast_io_fail, print_undef_off_zero) ++declare_hw_handler(fast_io_fail, set_undef_off_zero) ++declare_hw_snprint(fast_io_fail, print_undef_off_zero) + + static int + set_dev_loss(vector strvec, void *ptr) +diff --git a/libmultipath/dict.h b/libmultipath/dict.h +index a40ac66f..a917e1ca 100644 +--- a/libmultipath/dict.h ++++ b/libmultipath/dict.h +@@ -13,7 +13,7 @@ int print_rr_weight(char *buff, int len, long v); + int print_pgfailback(char *buff, int len, long v); + 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_undef_off_zero(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, uint8_t + flags, int source); +diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c +index 3f2c2cfa..67d025cf 100644 +--- a/libmultipath/propsel.c ++++ b/libmultipath/propsel.c +@@ -754,7 +754,7 @@ int select_fast_io_fail(struct config *conf, struct multipath *mp) + mp_set_conf(fast_io_fail); + mp_set_default(fast_io_fail, DEFAULT_FAST_IO_FAIL); + out: +- print_fast_io_fail(buff, 12, mp->fast_io_fail); ++ print_undef_off_zero(buff, 12, mp->fast_io_fail); + condlog(3, "%s: fast_io_fail_tmo = %s %s", mp->alias, buff, origin); + return 0; + } +diff --git a/libmultipath/structs.h b/libmultipath/structs.h +index 4ce30551..cfa7b649 100644 +--- a/libmultipath/structs.h ++++ b/libmultipath/structs.h +@@ -219,6 +219,23 @@ enum vpd_vendor_ids { + VPD_VP_ARRAY_SIZE, /* This must remain the last entry */ + }; + ++/* ++ * Multipath treats 0 as undefined for optional config parameters. ++ * Use this for cases where 0 is a valid option for systems multipath ++ * is communicating with ++ */ ++enum undefined_off_zero { ++ UOZ_UNDEF = 0, ++ UOZ_OFF = -1, ++ UOZ_ZERO = -2, ++}; ++ ++enum fast_io_fail_states { ++ MP_FAST_IO_FAIL_UNSET = UOZ_UNDEF, ++ MP_FAST_IO_FAIL_OFF = UOZ_OFF, ++ MP_FAST_IO_FAIL_ZERO = UOZ_ZERO, ++}; ++ + struct vpd_vendor_page { + int pg; + const char *name; +-- +2.17.2 + diff --git a/0073-libmultipath-add-eh_deadline-multipath.conf-paramete.patch b/0073-libmultipath-add-eh_deadline-multipath.conf-paramete.patch new file mode 100644 index 0000000..f5b1d8a --- /dev/null +++ b/0073-libmultipath-add-eh_deadline-multipath.conf-paramete.patch @@ -0,0 +1,338 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 17 Dec 2020 16:51:00 -0600 +Subject: [PATCH] libmultipath: add eh_deadline multipath.conf parameter + +There are times a fc rport is never lost, meaning that fast_io_fail_tmo +and dev_loss_tmo never trigger, but scsi commands still hang. This can +cause problems in cases where users have strict timing requirements, and +the easiest way to solve these issues is to set eh_deadline. Since it's +already possible to set fast_io_fail_tmo and dev_loss_tmo from +multipath.conf, and have multipath take care of setting it correctly for +the scsi devices in sysfs, it makes sense to allow users to set +eh_deadline here as well. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/config.c | 2 ++ + libmultipath/config.h | 2 ++ + libmultipath/configure.c | 1 + + libmultipath/dict.c | 10 +++++++ + libmultipath/discovery.c | 60 +++++++++++++++++++++++++++++++++----- + libmultipath/propsel.c | 17 +++++++++++ + libmultipath/propsel.h | 1 + + libmultipath/structs.h | 7 +++++ + multipath/multipath.conf.5 | 16 ++++++++++ + 9 files changed, 109 insertions(+), 7 deletions(-) + +diff --git a/libmultipath/config.c b/libmultipath/config.c +index 49e7fb81..9f3cb38d 100644 +--- a/libmultipath/config.c ++++ b/libmultipath/config.c +@@ -424,6 +424,7 @@ merge_hwe (struct hwentry * dst, struct hwentry * src) + merge_num(flush_on_last_del); + merge_num(fast_io_fail); + merge_num(dev_loss); ++ merge_num(eh_deadline); + merge_num(user_friendly_names); + merge_num(retain_hwhandler); + merge_num(detect_prio); +@@ -579,6 +580,7 @@ store_hwe (vector hwtable, struct hwentry * dhwe) + hwe->flush_on_last_del = dhwe->flush_on_last_del; + hwe->fast_io_fail = dhwe->fast_io_fail; + hwe->dev_loss = dhwe->dev_loss; ++ hwe->eh_deadline = dhwe->eh_deadline; + hwe->user_friendly_names = dhwe->user_friendly_names; + hwe->retain_hwhandler = dhwe->retain_hwhandler; + hwe->detect_prio = dhwe->detect_prio; +diff --git a/libmultipath/config.h b/libmultipath/config.h +index 661dd586..9ce37f16 100644 +--- a/libmultipath/config.h ++++ b/libmultipath/config.h +@@ -63,6 +63,7 @@ struct hwentry { + int flush_on_last_del; + int fast_io_fail; + unsigned int dev_loss; ++ int eh_deadline; + int user_friendly_names; + int retain_hwhandler; + int detect_prio; +@@ -148,6 +149,7 @@ struct config { + int attribute_flags; + int fast_io_fail; + unsigned int dev_loss; ++ int eh_deadline; + int log_checker_err; + int allow_queueing; + int allow_usb_devices; +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index 20536e60..c076be72 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -368,6 +368,7 @@ int setup_map(struct multipath *mpp, char *params, int params_size, + select_gid(conf, mpp); + select_fast_io_fail(conf, mpp); + select_dev_loss(conf, mpp); ++ select_eh_deadline(conf, mpp); + select_reservation_key(conf, mpp); + select_deferred_remove(conf, mpp); + select_marginal_path_err_sample_time(conf, mpp); +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index f4357da1..bab96146 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -899,6 +899,13 @@ declare_ovr_snprint(dev_loss, print_dev_loss) + declare_hw_handler(dev_loss, set_dev_loss) + declare_hw_snprint(dev_loss, print_dev_loss) + ++declare_def_handler(eh_deadline, set_undef_off_zero) ++declare_def_snprint(eh_deadline, print_undef_off_zero) ++declare_ovr_handler(eh_deadline, set_undef_off_zero) ++declare_ovr_snprint(eh_deadline, print_undef_off_zero) ++declare_hw_handler(eh_deadline, set_undef_off_zero) ++declare_hw_snprint(eh_deadline, print_undef_off_zero) ++ + static int + set_pgpolicy(vector strvec, void *ptr) + { +@@ -1771,6 +1778,7 @@ init_keywords(vector keywords) + install_keyword("gid", &def_gid_handler, &snprint_def_gid); + install_keyword("fast_io_fail_tmo", &def_fast_io_fail_handler, &snprint_def_fast_io_fail); + install_keyword("dev_loss_tmo", &def_dev_loss_handler, &snprint_def_dev_loss); ++ install_keyword("eh_deadline", &def_eh_deadline_handler, &snprint_def_eh_deadline); + install_keyword("bindings_file", &def_bindings_file_handler, &snprint_def_bindings_file); + install_keyword("wwids_file", &def_wwids_file_handler, &snprint_def_wwids_file); + install_keyword("prkeys_file", &def_prkeys_file_handler, &snprint_def_prkeys_file); +@@ -1880,6 +1888,7 @@ init_keywords(vector keywords) + install_keyword("flush_on_last_del", &hw_flush_on_last_del_handler, &snprint_hw_flush_on_last_del); + install_keyword("fast_io_fail_tmo", &hw_fast_io_fail_handler, &snprint_hw_fast_io_fail); + install_keyword("dev_loss_tmo", &hw_dev_loss_handler, &snprint_hw_dev_loss); ++ install_keyword("eh_deadline", &hw_eh_deadline_handler, &snprint_hw_eh_deadline); + install_keyword("user_friendly_names", &hw_user_friendly_names_handler, &snprint_hw_user_friendly_names); + install_keyword("retain_attached_hw_handler", &hw_retain_hwhandler_handler, &snprint_hw_retain_hwhandler); + install_keyword("detect_prio", &hw_detect_prio_handler, &snprint_hw_detect_prio); +@@ -1920,6 +1929,7 @@ init_keywords(vector keywords) + install_keyword("flush_on_last_del", &ovr_flush_on_last_del_handler, &snprint_ovr_flush_on_last_del); + install_keyword("fast_io_fail_tmo", &ovr_fast_io_fail_handler, &snprint_ovr_fast_io_fail); + install_keyword("dev_loss_tmo", &ovr_dev_loss_handler, &snprint_ovr_dev_loss); ++ install_keyword("eh_deadline", &ovr_eh_deadline_handler, &snprint_ovr_eh_deadline); + install_keyword("user_friendly_names", &ovr_user_friendly_names_handler, &snprint_ovr_user_friendly_names); + install_keyword("retain_attached_hw_handler", &ovr_retain_hwhandler_handler, &snprint_ovr_retain_hwhandler); + install_keyword("detect_prio", &ovr_detect_prio_handler, &snprint_ovr_detect_prio); +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index c74f13bf..add7bb97 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -587,6 +587,42 @@ sysfs_get_asymmetric_access_state(struct path *pp, char *buff, int buflen) + return !!preferred; + } + ++static int ++sysfs_set_eh_deadline(struct multipath *mpp, struct path *pp) ++{ ++ struct udev_device *hostdev; ++ char host_name[HOST_NAME_LEN], value[16]; ++ int ret, len; ++ ++ if (mpp->eh_deadline == EH_DEADLINE_UNSET) ++ return 0; ++ ++ sprintf(host_name, "host%d", pp->sg_id.host_no); ++ hostdev = udev_device_new_from_subsystem_sysname(udev, ++ "scsi_host", host_name); ++ if (!hostdev) ++ return 1; ++ ++ if (mpp->eh_deadline == EH_DEADLINE_OFF) ++ len = sprintf(value, "off"); ++ else if (mpp->eh_deadline == EH_DEADLINE_ZERO) ++ len = sprintf(value, "0"); ++ else ++ len = sprintf(value, "%d", mpp->eh_deadline); ++ ++ ret = sysfs_attr_set_value(hostdev, "eh_deadline", ++ value, len + 1); ++ /* ++ * not all scsi drivers support setting eh_deadline, so failing ++ * is totally reasonable ++ */ ++ if (ret <= 0) ++ condlog(3, "%s: failed to set eh_deadline to %s, error %d", udev_device_get_sysname(hostdev), value, -ret); ++ ++ udev_device_unref(hostdev); ++ return (ret <= 0); ++} ++ + static void + sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp) + { +@@ -596,6 +632,10 @@ sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp) + unsigned int tmo; + int ret; + ++ if (mpp->dev_loss == DEV_LOSS_TMO_UNSET && ++ mpp->fast_io_fail == MP_FAST_IO_FAIL_UNSET) ++ return; ++ + sprintf(rport_id, "rport-%d:%d-%d", + pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.transport_id); + rport_dev = udev_device_new_from_subsystem_sysname(udev, +@@ -703,6 +743,11 @@ sysfs_set_session_tmo(struct multipath *mpp, struct path *pp) + char session_id[64]; + char value[11]; + ++ if (mpp->dev_loss != DEV_LOSS_TMO_UNSET) ++ condlog(3, "%s: ignoring dev_loss_tmo on iSCSI", pp->dev); ++ if (mpp->fast_io_fail == MP_FAST_IO_FAIL_UNSET) ++ return; ++ + sprintf(session_id, "session%d", pp->sg_id.transport_id); + session_dev = udev_device_new_from_subsystem_sysname(udev, + "iscsi_session", session_id); +@@ -714,9 +759,6 @@ sysfs_set_session_tmo(struct multipath *mpp, struct path *pp) + condlog(4, "target%d:%d:%d -> %s", pp->sg_id.host_no, + pp->sg_id.channel, pp->sg_id.scsi_id, session_id); + +- if (mpp->dev_loss != DEV_LOSS_TMO_UNSET) { +- condlog(3, "%s: ignoring dev_loss_tmo on iSCSI", pp->dev); +- } + if (mpp->fast_io_fail != MP_FAST_IO_FAIL_UNSET) { + if (mpp->fast_io_fail == MP_FAST_IO_FAIL_OFF) { + condlog(3, "%s: can't switch off fast_io_fail_tmo " +@@ -744,6 +786,8 @@ sysfs_set_nexus_loss_tmo(struct multipath *mpp, struct path *pp) + char end_dev_id[64]; + char value[11]; + ++ if (mpp->dev_loss == DEV_LOSS_TMO_UNSET) ++ return; + sprintf(end_dev_id, "end_device-%d:%d", + pp->sg_id.host_no, pp->sg_id.transport_id); + sas_dev = udev_device_new_from_subsystem_sysname(udev, +@@ -801,7 +845,8 @@ sysfs_set_scsi_tmo (struct multipath *mpp, unsigned int checkint) + mpp->fast_io_fail = MP_FAST_IO_FAIL_OFF; + } + if (mpp->dev_loss == DEV_LOSS_TMO_UNSET && +- mpp->fast_io_fail == MP_FAST_IO_FAIL_UNSET) ++ mpp->fast_io_fail == MP_FAST_IO_FAIL_UNSET && ++ mpp->eh_deadline == EH_DEADLINE_UNSET) + return 0; + + vector_foreach_slot(mpp->paths, pp, i) { +@@ -814,17 +859,18 @@ sysfs_set_scsi_tmo (struct multipath *mpp, unsigned int checkint) + switch (pp->sg_id.proto_id) { + case SCSI_PROTOCOL_FCP: + sysfs_set_rport_tmo(mpp, pp); +- continue; ++ break; + case SCSI_PROTOCOL_ISCSI: + sysfs_set_session_tmo(mpp, pp); +- continue; ++ break; + case SCSI_PROTOCOL_SAS: + sysfs_set_nexus_loss_tmo(mpp, pp); +- continue; ++ break; + default: + if (!err_path) + err_path = pp; + } ++ sysfs_set_eh_deadline(mpp, pp); + } + + if (err_path) { +diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c +index 67d025cf..fa4ac5d9 100644 +--- a/libmultipath/propsel.c ++++ b/libmultipath/propsel.c +@@ -775,6 +775,23 @@ out: + return 0; + } + ++int select_eh_deadline(struct config *conf, struct multipath *mp) ++{ ++ const char *origin; ++ char buff[12]; ++ ++ mp_set_ovr(eh_deadline); ++ mp_set_hwe(eh_deadline); ++ mp_set_conf(eh_deadline); ++ mp->eh_deadline = EH_DEADLINE_UNSET; ++ /* not changing sysfs in default cause, so don't print anything */ ++ return 0; ++out: ++ print_undef_off_zero(buff, 12, mp->eh_deadline); ++ condlog(3, "%s: eh_deadline = %s %s", mp->alias, buff, origin); ++ return 0; ++} ++ + int select_flush_on_last_del(struct config *conf, struct multipath *mp) + { + const char *origin; +diff --git a/libmultipath/propsel.h b/libmultipath/propsel.h +index 3d6edd8a..a68bacf0 100644 +--- a/libmultipath/propsel.h ++++ b/libmultipath/propsel.h +@@ -17,6 +17,7 @@ int select_uid(struct config *conf, struct multipath *mp); + int select_gid(struct config *conf, struct multipath *mp); + int select_fast_io_fail(struct config *conf, struct multipath *mp); + int select_dev_loss(struct config *conf, struct multipath *mp); ++int select_eh_deadline(struct config *conf, struct multipath *mp); + int select_reservation_key(struct config *conf, struct multipath *mp); + int select_retain_hwhandler (struct config *conf, struct multipath * mp); + int select_detect_prio(struct config *conf, struct path * pp); +diff --git a/libmultipath/structs.h b/libmultipath/structs.h +index cfa7b649..d6ff6762 100644 +--- a/libmultipath/structs.h ++++ b/libmultipath/structs.h +@@ -236,6 +236,12 @@ enum fast_io_fail_states { + MP_FAST_IO_FAIL_ZERO = UOZ_ZERO, + }; + ++enum eh_deadline_states { ++ EH_DEADLINE_UNSET = UOZ_UNDEF, ++ EH_DEADLINE_OFF = UOZ_OFF, ++ EH_DEADLINE_ZERO = UOZ_ZERO, ++}; ++ + struct vpd_vendor_page { + int pg; + const char *name; +@@ -356,6 +362,7 @@ struct multipath { + int ghost_delay; + int ghost_delay_tick; + unsigned int dev_loss; ++ int eh_deadline; + uid_t uid; + gid_t gid; + mode_t mode; +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 +index 7242d39b..ea66a01e 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5 +@@ -717,6 +717,22 @@ The default is: \fB600\fR + . + . + .TP ++.B eh_deadline ++Specify the maximum number of seconds the SCSI layer will spend doing error ++handling when scsi devices fail. After this timeout the scsi layer will perform ++a full HBA reset. Setting this may be necessary in cases where the rport is ++never lost, so \fIfast_io_fail_tmo\fR and \fIdev_loss_tmo\fR will never ++trigger, but (frequently do to load) scsi commands still hang. \fBNote:\fR when ++the scsi error handler performs the HBA reset, all target paths on that HBA ++will be affected. eh_deadline should only be set in cases where all targets on ++the affected HBAs are multipathed. ++.RS ++.TP ++The default is: \fB\fR ++.RE ++. ++. ++.TP + .B bindings_file + The full pathname of the binding file to be used when the user_friendly_names + option is set. +-- +2.17.2 + diff --git a/0073-libmultipath-util-constify-function-arguments.patch b/0073-libmultipath-util-constify-function-arguments.patch deleted file mode 100644 index d1a0763..0000000 --- a/0073-libmultipath-util-constify-function-arguments.patch +++ /dev/null @@ -1,111 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 8 Jul 2020 09:23:20 +0200 -Subject: [PATCH] libmultipath: util: constify function arguments - -Use "const" for function arguments where possible. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/dmparser.c | 2 +- - libmultipath/util.c | 12 ++++++------ - libmultipath/util.h | 10 +++++----- - 3 files changed, 12 insertions(+), 12 deletions(-) - -diff --git a/libmultipath/dmparser.c b/libmultipath/dmparser.c -index b856a07f..27581cde 100644 ---- a/libmultipath/dmparser.c -+++ b/libmultipath/dmparser.c -@@ -18,7 +18,7 @@ - #define WORD_SIZE 64 - - static int --merge_words(char **dst, char *word) -+merge_words(char **dst, const char *word) - { - char * p = *dst; - int len, dstlen; -diff --git a/libmultipath/util.c b/libmultipath/util.c -index 51c38c87..67e7a42f 100644 ---- a/libmultipath/util.c -+++ b/libmultipath/util.c -@@ -52,7 +52,7 @@ basenamecpy (const char *src, char *dst, size_t size) - } - - int --filepresent (char * run) { -+filepresent (const char *run) { - struct stat buf; - - if(!stat(run, &buf)) -@@ -60,7 +60,7 @@ filepresent (char * run) { - return 0; - } - --char *get_next_string(char **temp, char *split_char) -+char *get_next_string(char **temp, const char *split_char) - { - char *token = NULL; - token = strsep(temp, split_char); -@@ -70,9 +70,9 @@ char *get_next_string(char **temp, char *split_char) - } - - int --get_word (char * sentence, char ** word) -+get_word (const char *sentence, char **word) - { -- char * p; -+ const char *p; - int len; - int skip = 0; - -@@ -381,7 +381,7 @@ int get_linux_version_code(void) - return _linux_version_code; - } - --int parse_prkey(char *ptr, uint64_t *prkey) -+int parse_prkey(const char *ptr, uint64_t *prkey) - { - if (!ptr) - return 1; -@@ -398,7 +398,7 @@ int parse_prkey(char *ptr, uint64_t *prkey) - return 0; - } - --int parse_prkey_flags(char *ptr, uint64_t *prkey, uint8_t *flags) -+int parse_prkey_flags(const char *ptr, uint64_t *prkey, uint8_t *flags) - { - char *flagstr; - -diff --git a/libmultipath/util.h b/libmultipath/util.h -index 56bd78c7..c19c5ac3 100644 ---- a/libmultipath/util.h -+++ b/libmultipath/util.h -@@ -9,9 +9,9 @@ - - size_t strchop(char *); - int basenamecpy (const char *src, char *dst, size_t size); --int filepresent (char * run); --char *get_next_string(char **temp, char *split_char); --int get_word (char * sentence, char ** word); -+int filepresent (const char *run); -+char *get_next_string(char **temp, const char *split_char); -+int get_word (const char * sentence, char ** word); - size_t strlcpy(char *dst, const char *src, size_t size); - size_t strlcat(char *dst, const char *src, size_t size); - int devt2devname (char *, int, char *); -@@ -20,8 +20,8 @@ char *convert_dev(char *dev, int is_path_device); - 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 parse_prkey(const char *ptr, uint64_t *prkey); -+int parse_prkey_flags(const char *ptr, uint64_t *prkey, uint8_t *flags); - int safe_write(int fd, const void *buf, size_t count); - void set_max_fds(rlim_t max_fds); - --- -2.17.2 - diff --git a/0074-multipathd-remove-redundant-vector_free-int-configur.patch b/0074-multipathd-remove-redundant-vector_free-int-configur.patch new file mode 100644 index 0000000..c9947f5 --- /dev/null +++ b/0074-multipathd-remove-redundant-vector_free-int-configur.patch @@ -0,0 +1,37 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 17 Dec 2020 16:51:01 -0600 +Subject: [PATCH] multipathd: remove redundant vector_free() int configure + +remove_maps(vecs) already calls vector_free(vecs->mpvec) + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + multipathd/main.c | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index b6a5f5b7..2eab4854 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -2634,14 +2634,10 @@ configure (struct vectors * vecs) + } + + /* +- * purge dm of old maps ++ * purge dm of old maps and save new set of maps formed by ++ * considering current path state + */ + remove_maps(vecs); +- +- /* +- * save new set of maps formed by considering current path state +- */ +- vector_free(vecs->mpvec); + vecs->mpvec = mpvec; + + /* +-- +2.17.2 + diff --git a/0075-libmultipath-factor-out-code-to-get-vpd-page-data.patch b/0075-libmultipath-factor-out-code-to-get-vpd-page-data.patch new file mode 100644 index 0000000..fe2ea50 --- /dev/null +++ b/0075-libmultipath-factor-out-code-to-get-vpd-page-data.patch @@ -0,0 +1,66 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 17 Dec 2020 16:51:02 -0600 +Subject: [PATCH] libmultipath: factor out code to get vpd page data + +A future patch will reuse the code to get the vpd page data, so factor +it out from get_vpd_sgio(). + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/discovery.c | 27 +++++++++++++++++++-------- + 1 file changed, 19 insertions(+), 8 deletions(-) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index add7bb97..f901e9ff 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -1321,14 +1321,13 @@ get_vpd_sysfs (struct udev_device *parent, int pg, char * str, int maxlen) + return len; + } + +-int +-get_vpd_sgio (int fd, int pg, int vend_id, char * str, int maxlen) ++static int ++fetch_vpd_page(int fd, int pg, unsigned char *buff, int maxlen) + { +- int len, buff_len; +- unsigned char buff[4096]; ++ int buff_len; + +- memset(buff, 0x0, 4096); +- if (sgio_get_vpd(buff, 4096, fd, pg) < 0) { ++ memset(buff, 0x0, maxlen); ++ if (sgio_get_vpd(buff, maxlen, fd, pg) < 0) { + int lvl = pg == 0x80 || pg == 0x83 ? 3 : 4; + + condlog(lvl, "failed to issue vpd inquiry for pg%02x", +@@ -1342,10 +1341,22 @@ get_vpd_sgio (int fd, int pg, int vend_id, char * str, int maxlen) + return -ENODATA; + } + buff_len = get_unaligned_be16(&buff[2]) + 4; +- if (buff_len > 4096) { ++ if (buff_len > maxlen) { + condlog(3, "vpd pg%02x page truncated", pg); +- buff_len = 4096; ++ buff_len = maxlen; + } ++ return buff_len; ++} ++ ++int ++get_vpd_sgio (int fd, int pg, int vend_id, char * str, int maxlen) ++{ ++ int len, buff_len; ++ unsigned char buff[4096]; ++ ++ buff_len = fetch_vpd_page(fd, pg, buff, sizeof(buff)); ++ if (buff_len < 0) ++ return buff_len; + if (pg == 0x80) + len = parse_vpd_pg80(buff, str, maxlen); + else if (pg == 0x83) +-- +2.17.2 + diff --git a/0076-libmultipath-limit-reading-0xc9-vpd-page.patch b/0076-libmultipath-limit-reading-0xc9-vpd-page.patch new file mode 100644 index 0000000..6208fe5 --- /dev/null +++ b/0076-libmultipath-limit-reading-0xc9-vpd-page.patch @@ -0,0 +1,91 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 17 Dec 2020 16:51:03 -0600 +Subject: [PATCH] libmultipath: limit reading 0xc9 vpd page + +Only rdac arrays support 0xC9 vpd page inquiries. All other arrays will +return a failure. Only do the rdac inquiry when detecting array +capabilities if the array's path checker is explicitly set to rdac, or +the path checker is not set, and the array reports that it supports vpd +page 0xC9 in the Supported VPD Pages (0x00) vpd page. + +Multipath was doing the check if either the path checker was set to +rdac, or no path checker was set. This means that for almost all +non-rdac arrays, multipath was issuing a bad inquiry. This was annoying +users. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/discovery.c | 17 +++++++++++++++++ + libmultipath/discovery.h | 1 + + libmultipath/propsel.c | 10 ++++++---- + 3 files changed, 24 insertions(+), 4 deletions(-) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index f901e9ff..e818585a 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -1348,6 +1348,23 @@ fetch_vpd_page(int fd, int pg, unsigned char *buff, int maxlen) + return buff_len; + } + ++/* based on sg_inq.c from sg3_utils */ ++bool ++is_vpd_page_supported(int fd, int pg) ++{ ++ int i, len; ++ unsigned char buff[4096]; ++ ++ len = fetch_vpd_page(fd, 0x00, buff, sizeof(buff)); ++ if (len < 0) ++ return false; ++ ++ for (i = 4; i < len; ++i) ++ if (buff[i] == pg) ++ return true; ++ return false; ++} ++ + int + get_vpd_sgio (int fd, int pg, int vend_id, char * str, int maxlen) + { +diff --git a/libmultipath/discovery.h b/libmultipath/discovery.h +index 6444887d..d3193daf 100644 +--- a/libmultipath/discovery.h ++++ b/libmultipath/discovery.h +@@ -56,6 +56,7 @@ int sysfs_get_asymmetric_access_state(struct path *pp, + char *buff, int buflen); + int get_uid(struct path * pp, int path_state, struct udev_device *udev, + int allow_fallback); ++bool is_vpd_page_supported(int fd, int pg); + + /* + * discovery bitmask +diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c +index fa4ac5d9..f771a830 100644 +--- a/libmultipath/propsel.c ++++ b/libmultipath/propsel.c +@@ -496,13 +496,15 @@ check_rdac(struct path * pp) + { + int len; + char buff[44]; +- const char *checker_name; ++ const char *checker_name = NULL; + + if (pp->bus != SYSFS_BUS_SCSI) + return 0; +- /* Avoid ioctl if this is likely not an RDAC array */ +- if (__do_set_from_hwe(checker_name, pp, checker_name) && +- strcmp(checker_name, RDAC)) ++ /* Avoid checking 0xc9 if this is likely not an RDAC array */ ++ if (!__do_set_from_hwe(checker_name, pp, checker_name) && ++ !is_vpd_page_supported(pp->fd, 0xC9)) ++ return 0; ++ if (checker_name && strcmp(checker_name, RDAC)) + return 0; + len = get_vpd_sgio(pp->fd, 0xC9, 0, buff, 44); + if (len <= 0) +-- +2.17.2 + diff --git a/0077-libmultipath-move-logq_lock-handling-to-log.c.patch b/0077-libmultipath-move-logq_lock-handling-to-log.c.patch new file mode 100644 index 0000000..ae9385f --- /dev/null +++ b/0077-libmultipath-move-logq_lock-handling-to-log.c.patch @@ -0,0 +1,141 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 26 Oct 2020 22:01:18 +0100 +Subject: [PATCH] libmultipath: move logq_lock handling to log.c + +logq_lock protects internal data structures of log.c, and should +be handled there. This patch doesn't change functionality, except +improving cancel-safety somewhat. +Reviewed-by: Benjamin Marzinski + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/log.c | 34 ++++++++++++++++++++++++++++++++-- + libmultipath/log_pthread.c | 9 --------- + 2 files changed, 32 insertions(+), 11 deletions(-) + +diff --git a/libmultipath/log.c b/libmultipath/log.c +index debd36de..7f337879 100644 +--- a/libmultipath/log.c ++++ b/libmultipath/log.c +@@ -9,13 +9,16 @@ + #include + #include + #include ++#include + + #include "memory.h" + #include "log.h" ++#include "util.h" + + #define ALIGN(len, s) (((len)+(s)-1)/(s)*(s)) + + struct logarea* la; ++static pthread_mutex_t logq_lock = PTHREAD_MUTEX_INITIALIZER; + + #if LOGDBG + static void dump_logarea (void) +@@ -101,12 +104,17 @@ void log_close (void) + + void log_reset (char *program_name) + { ++ pthread_mutex_lock(&logq_lock); ++ pthread_cleanup_push(cleanup_mutex, &logq_lock); ++ + closelog(); + tzset(); + openlog(program_name, 0, LOG_DAEMON); ++ ++ pthread_cleanup_pop(1); + } + +-int log_enqueue (int prio, const char * fmt, va_list ap) ++static int _log_enqueue(int prio, const char * fmt, va_list ap) + { + int len, fwd; + char buff[MAX_MSG_SIZE]; +@@ -165,7 +173,18 @@ int log_enqueue (int prio, const char * fmt, va_list ap) + return 0; + } + +-int log_dequeue (void * buff) ++int log_enqueue(int prio, const char *fmt, va_list ap) ++{ ++ int ret; ++ ++ pthread_mutex_lock(&logq_lock); ++ pthread_cleanup_push(cleanup_mutex, &logq_lock); ++ ret = _log_enqueue(prio, fmt, ap); ++ pthread_cleanup_pop(1); ++ return ret; ++} ++ ++static int _log_dequeue(void *buff) + { + struct logmsg * src = (struct logmsg *)la->head; + struct logmsg * dst = (struct logmsg *)buff; +@@ -194,6 +213,17 @@ int log_dequeue (void * buff) + return 0; + } + ++int log_dequeue(void *buff) ++{ ++ int ret; ++ ++ pthread_mutex_lock(&logq_lock); ++ pthread_cleanup_push(cleanup_mutex, &logq_lock); ++ ret = _log_dequeue(buff); ++ pthread_cleanup_pop(1); ++ return ret; ++} ++ + /* + * this one can block under memory pressure + */ +diff --git a/libmultipath/log_pthread.c b/libmultipath/log_pthread.c +index 0d48c52c..65992101 100644 +--- a/libmultipath/log_pthread.c ++++ b/libmultipath/log_pthread.c +@@ -18,7 +18,6 @@ + static pthread_t log_thr; + + /* logev_lock must not be taken with logq_lock held */ +-static pthread_mutex_t logq_lock = PTHREAD_MUTEX_INITIALIZER; + static pthread_mutex_t logev_lock = PTHREAD_MUTEX_INITIALIZER; + static pthread_cond_t logev_cond = PTHREAD_COND_INITIALIZER; + +@@ -41,10 +40,7 @@ void log_safe (int prio, const char * fmt, va_list ap) + running = logq_running; + + if (running) { +- pthread_mutex_lock(&logq_lock); +- pthread_cleanup_push(cleanup_mutex, &logq_lock); + log_enqueue(prio, fmt, ap); +- pthread_cleanup_pop(1); + + log_messages_pending = 1; + pthread_cond_signal(&logev_cond); +@@ -60,9 +56,7 @@ static void flush_logqueue (void) + int empty; + + do { +- pthread_mutex_lock(&logq_lock); + empty = log_dequeue(la->buff); +- pthread_mutex_unlock(&logq_lock); + if (!empty) + log_syslog(la->buff); + } while (empty == 0); +@@ -138,10 +132,7 @@ void log_thread_start (pthread_attr_t *attr) + void log_thread_reset (void) + { + logdbg(stderr,"resetting log\n"); +- +- pthread_mutex_lock(&logq_lock); + log_reset("multipathd"); +- pthread_mutex_unlock(&logq_lock); + } + + void log_thread_stop (void) +-- +2.17.2 + diff --git a/0078-libmultipath-protect-logarea-with-logq_lock.patch b/0078-libmultipath-protect-logarea-with-logq_lock.patch new file mode 100644 index 0000000..e27aa64 --- /dev/null +++ b/0078-libmultipath-protect-logarea-with-logq_lock.patch @@ -0,0 +1,110 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 26 Oct 2020 22:13:40 +0100 +Subject: [PATCH] libmultipath: protect logarea with logq_lock + +Make sure the global logarea (la) is only allocated and freed +hile holding logq_lock. This avoids invalid memory access. + +This patch makes free_logarea() static. libmultipath.version +is unchanged, as free_logarea() wasn't exported anyway. +Reviewed-by: Benjamin Marzinski + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/log.c | 32 +++++++++++++++++++++++--------- + libmultipath/log.h | 1 - + 2 files changed, 23 insertions(+), 10 deletions(-) + +diff --git a/libmultipath/log.c b/libmultipath/log.c +index 7f337879..95c8f01a 100644 +--- a/libmultipath/log.c ++++ b/libmultipath/log.c +@@ -77,16 +77,23 @@ static int logarea_init (int size) + + int log_init(char *program_name, int size) + { ++ int ret = 1; ++ + logdbg(stderr,"enter log_init\n"); ++ ++ pthread_mutex_lock(&logq_lock); ++ pthread_cleanup_push(cleanup_mutex, &logq_lock); ++ + openlog(program_name, 0, LOG_DAEMON); ++ if (!la) ++ ret = logarea_init(size); + +- if (logarea_init(size)) +- return 1; ++ pthread_cleanup_pop(1); + +- return 0; ++ return ret; + } + +-void free_logarea (void) ++static void free_logarea (void) + { + FREE(la->start); + FREE(la->buff); +@@ -96,9 +103,14 @@ void free_logarea (void) + + void log_close (void) + { +- free_logarea(); ++ pthread_mutex_lock(&logq_lock); ++ pthread_cleanup_push(cleanup_mutex, &logq_lock); ++ ++ if (la) ++ free_logarea(); + closelog(); + ++ pthread_cleanup_pop(1); + return; + } + +@@ -175,11 +187,12 @@ static int _log_enqueue(int prio, const char * fmt, va_list ap) + + int log_enqueue(int prio, const char *fmt, va_list ap) + { +- int ret; ++ int ret = 1; + + pthread_mutex_lock(&logq_lock); + pthread_cleanup_push(cleanup_mutex, &logq_lock); +- ret = _log_enqueue(prio, fmt, ap); ++ if (la) ++ ret = _log_enqueue(prio, fmt, ap); + pthread_cleanup_pop(1); + return ret; + } +@@ -215,11 +228,12 @@ static int _log_dequeue(void *buff) + + int log_dequeue(void *buff) + { +- int ret; ++ int ret = 1; + + pthread_mutex_lock(&logq_lock); + pthread_cleanup_push(cleanup_mutex, &logq_lock); +- ret = _log_dequeue(buff); ++ if (la) ++ ret = _log_dequeue(buff); + pthread_cleanup_pop(1); + return ret; + } +diff --git a/libmultipath/log.h b/libmultipath/log.h +index d2448f6a..fa224e4d 100644 +--- a/libmultipath/log.h ++++ b/libmultipath/log.h +@@ -39,6 +39,5 @@ int log_enqueue (int prio, const char * fmt, va_list ap) + int log_dequeue (void *); + void log_syslog (void *); + void dump_logmsg (void *); +-void free_logarea (void); + + #endif /* LOG_H */ +-- +2.17.2 + diff --git a/0079-libmultipath-prevent-DSO-unloading-with-astray-check.patch b/0079-libmultipath-prevent-DSO-unloading-with-astray-check.patch new file mode 100644 index 0000000..31fd8b4 --- /dev/null +++ b/0079-libmultipath-prevent-DSO-unloading-with-astray-check.patch @@ -0,0 +1,284 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 5 Nov 2020 12:43:25 +0100 +Subject: [PATCH] libmultipath: prevent DSO unloading with astray checker + threads + +The multipathd tur checker thread is designed to be able to finish at +any time, even after the tur checker itself has been freed. The +multipathd shutdown code makes sure all the checkers have been freed +before freeing the checker_class and calling dlclose() to unload the +DSO, but this doesn't guarantee that the checker threads have finished. +If one hasn't, the DSO will get unloaded while the thread still running +code from it, causing a segfault. + +This patch fixes the issue by further incrementing the DSO's refcount +for every running thread. To avoid race conditions leading to segfaults, +the thread's entrypoint must be in libmultipath, not in the DSO itself. +Therefore we add a new optional checker method, libcheck_thread(). +Checkers defining this method may create a detached thread with +entrypoint checker_thread_entry(), which will call the DSO's +libcheck_thread and take care of the refcount handling. + +Reported-by: Benjamin Marzinski +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/checkers.c | 68 +++++++++++++++++++++++++++---- + libmultipath/checkers.h | 25 ++++++++++++ + libmultipath/checkers/tur.c | 12 +++--- + libmultipath/libmultipath.version | 5 +++ + 4 files changed, 97 insertions(+), 13 deletions(-) + +diff --git a/libmultipath/checkers.c b/libmultipath/checkers.c +index 18b1f5eb..2dd9915d 100644 +--- a/libmultipath/checkers.c ++++ b/libmultipath/checkers.c +@@ -3,6 +3,8 @@ + #include + #include + #include ++#include ++#include + + #include "debug.h" + #include "checkers.h" +@@ -20,6 +22,7 @@ struct checker_class { + int (*mp_init)(struct checker *); /* to allocate the mpcontext */ + void (*free)(struct checker *); /* to free the context */ + void (*reset)(void); /* to reset the global variables */ ++ void *(*thread)(void *); /* async thread entry point */ + const char **msgtable; + short msgtable_size; + }; +@@ -55,19 +58,32 @@ static struct checker_class *alloc_checker_class(void) + c = MALLOC(sizeof(struct checker_class)); + if (c) { + INIT_LIST_HEAD(&c->node); +- c->refcount = 1; ++ uatomic_set(&c->refcount, 1); + } + return c; + } + ++/* Use uatomic_{sub,add}_return() to ensure proper memory barriers */ ++static int checker_class_ref(struct checker_class *cls) ++{ ++ return uatomic_add_return(&cls->refcount, 1); ++} ++ ++static int checker_class_unref(struct checker_class *cls) ++{ ++ return uatomic_sub_return(&cls->refcount, 1); ++} ++ + void free_checker_class(struct checker_class *c) + { ++ int cnt; ++ + if (!c) + return; +- c->refcount--; +- if (c->refcount) { +- condlog(4, "%s checker refcount %d", +- c->name, c->refcount); ++ cnt = checker_class_unref(c); ++ if (cnt != 0) { ++ condlog(cnt < 0 ? 1 : 4, "%s checker refcount %d", ++ c->name, cnt); + return; + } + condlog(3, "unloading %s checker", c->name); +@@ -161,7 +177,8 @@ static struct checker_class *add_checker_class(const char *multipath_dir, + + c->mp_init = (int (*)(struct checker *)) dlsym(c->handle, "libcheck_mp_init"); + c->reset = (void (*)(void)) dlsym(c->handle, "libcheck_reset"); +- /* These 2 functions can be NULL. call dlerror() to clear out any ++ c->thread = (void *(*)(void*)) dlsym(c->handle, "libcheck_thread"); ++ /* These 3 functions can be NULL. call dlerror() to clear out any + * error string */ + dlerror(); + +@@ -347,6 +364,43 @@ bad_id: + return generic_msg[CHECKER_MSGID_NONE]; + } + ++static void checker_cleanup_thread(void *arg) ++{ ++ struct checker_class *cls = arg; ++ ++ (void)checker_class_unref(cls); ++ rcu_unregister_thread(); ++} ++ ++static void *checker_thread_entry(void *arg) ++{ ++ struct checker_context *ctx = arg; ++ void *rv; ++ ++ rcu_register_thread(); ++ pthread_cleanup_push(checker_cleanup_thread, ctx->cls); ++ rv = ctx->cls->thread(ctx); ++ pthread_cleanup_pop(1); ++ return rv; ++} ++ ++int start_checker_thread(pthread_t *thread, const pthread_attr_t *attr, ++ struct checker_context *ctx) ++{ ++ int rv; ++ ++ assert(ctx && ctx->cls && ctx->cls->thread); ++ /* Take a ref here, lest the class be freed before the thread starts */ ++ (void)checker_class_ref(ctx->cls); ++ rv = pthread_create(thread, attr, checker_thread_entry, ctx); ++ if (rv != 0) { ++ condlog(1, "failed to start checker thread for %s: %m", ++ ctx->cls->name); ++ checker_class_unref(ctx->cls); ++ } ++ return rv; ++} ++ + void checker_clear_message (struct checker *c) + { + if (!c) +@@ -371,7 +425,7 @@ void checker_get(const char *multipath_dir, struct checker *dst, + if (!src) + return; + +- src->refcount++; ++ (void)checker_class_ref(dst->cls); + } + + int init_checkers(const char *multipath_dir) +diff --git a/libmultipath/checkers.h b/libmultipath/checkers.h +index 9d5f90b9..2fd1d1c6 100644 +--- a/libmultipath/checkers.h ++++ b/libmultipath/checkers.h +@@ -1,6 +1,7 @@ + #ifndef _CHECKERS_H + #define _CHECKERS_H + ++#include + #include "list.h" + #include "memory.h" + #include "defaults.h" +@@ -148,6 +149,28 @@ void checker_set_async (struct checker *); + void checker_set_fd (struct checker *, int); + void checker_enable (struct checker *); + void checker_disable (struct checker *); ++/* ++ * start_checker_thread(): start async path checker thread ++ * ++ * This function provides a wrapper around pthread_create(). ++ * The created thread will call the DSO's "libcheck_thread" function with the ++ * checker context as argument. ++ * ++ * Rationale: ++ * Path checkers that do I/O may hang forever. To avoid blocking, some ++ * checkers therefore use asyncronous, detached threads for checking ++ * the paths. These threads may continue hanging if multipathd is stopped. ++ * In this case, we can't unload the checker DSO at exit. In order to ++ * avoid race conditions and crashes, the entry point of the thread ++ * needs to be in libmultipath, not in the DSO itself. ++ * ++ * @param arg: pointer to struct checker_context. ++ */ ++struct checker_context { ++ struct checker_class *cls; ++}; ++int start_checker_thread (pthread_t *thread, const pthread_attr_t *attr, ++ struct checker_context *ctx); + int checker_check (struct checker *, int); + int checker_is_sync(const struct checker *); + const char *checker_name (const struct checker *); +@@ -164,6 +187,8 @@ void checker_get(const char *, struct checker *, const char *); + int libcheck_check(struct checker *); + int libcheck_init(struct checker *); + void libcheck_free(struct checker *); ++void *libcheck_thread(struct checker_context *ctx); ++ + /* + * msgid => message map. + * +diff --git a/libmultipath/checkers/tur.c b/libmultipath/checkers/tur.c +index e886fcf8..a4b4a213 100644 +--- a/libmultipath/checkers/tur.c ++++ b/libmultipath/checkers/tur.c +@@ -15,7 +15,6 @@ + #include + #include + #include +-#include + #include + + #include "checkers.h" +@@ -55,6 +54,7 @@ struct tur_checker_context { + pthread_cond_t active; + int holders; /* uatomic access only */ + int msgid; ++ struct checker_context ctx; + }; + + int libcheck_init (struct checker * c) +@@ -74,6 +74,7 @@ int libcheck_init (struct checker * c) + pthread_mutex_init(&ct->lock, NULL); + if (fstat(c->fd, &sb) == 0) + ct->devt = sb.st_rdev; ++ ct->ctx.cls = c->cls; + c->context = ct; + + return 0; +@@ -204,7 +205,6 @@ static void cleanup_func(void *data) + holders = uatomic_sub_return(&ct->holders, 1); + if (!holders) + cleanup_context(ct); +- rcu_unregister_thread(); + } + + /* +@@ -251,15 +251,15 @@ static void tur_deep_sleep(const struct tur_checker_context *ct) + #define tur_deep_sleep(x) do {} while (0) + #endif /* TUR_TEST_MAJOR */ + +-static void *tur_thread(void *ctx) ++void *libcheck_thread(struct checker_context *ctx) + { +- struct tur_checker_context *ct = ctx; ++ struct tur_checker_context *ct = ++ container_of(ctx, struct tur_checker_context, ctx); + int state, running; + short msgid; + + /* This thread can be canceled, so setup clean up */ + tur_thread_cleanup_push(ct); +- rcu_register_thread(); + + condlog(4, "%d:%d : tur checker starting up", major(ct->devt), + minor(ct->devt)); +@@ -394,7 +394,7 @@ int libcheck_check(struct checker * c) + uatomic_set(&ct->running, 1); + tur_set_async_timeout(c); + setup_thread_attr(&attr, 32 * 1024, 1); +- r = pthread_create(&ct->thread, &attr, tur_thread, ct); ++ r = start_checker_thread(&ct->thread, &attr, &ct->ctx); + pthread_attr_destroy(&attr); + if (r) { + uatomic_sub(&ct->holders, 1); +diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version +index 2e3583f5..751099dc 100644 +--- a/libmultipath/libmultipath.version ++++ b/libmultipath/libmultipath.version +@@ -270,3 +270,8 @@ global: + dm_prereq; + skip_libmp_dm_init; + } LIBMULTIPATH_4.1.0; ++ ++LIBMULTIPATH_4.3.0 { ++global: ++ start_checker_thread; ++} LIBMULTIPATH_4.2.0; +-- +2.17.2 + diff --git a/0080-libmultipath-force-map-reload-if-udev-incomplete.patch b/0080-libmultipath-force-map-reload-if-udev-incomplete.patch new file mode 100644 index 0000000..913c438 --- /dev/null +++ b/0080-libmultipath-force-map-reload-if-udev-incomplete.patch @@ -0,0 +1,151 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 14 Dec 2020 18:22:55 +0100 +Subject: [PATCH] libmultipath: force map reload if udev incomplete + +We've recently observed various cases of incompletely processed uevents +during initrd processing. Typically, this would leave a dm device in +the state it had after the initial "add" uevent, which is basically unusable, +because udevd had been killed by systemd before processing the subsequent +"change" event. After switching root, the coldplug event would re-read +the db file, which would be in unusable state, and would not do anything. +In such cases, a RELOAD action with force_udev_reload=1 is in order to +make udev re-process the device completely (DM_UDEV_PRIMARY_SOURCE_FLAG=1 and +DM_SUBSYSTEM_UDEV_FLAG0=0). + +The previous commits + +2b25a9e libmultipath: select_action(): force udev reload for uninitialized maps +cb10d38 multipathd: uev_trigger(): handle incomplete ADD events + +addressed the same issue, but incompletely. They would miss cases where the +map was configured correctly but none of the RELOAD criteria were met. +This patch partially reverts 2b25a9e by converting select_reload_action() into +a trivial helper. Instead, we now check for incompletely initialized udev now +before checking any of the other reload criteria. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/configure.c | 45 ++++++++++++++++++++++++++-------------- + 1 file changed, 29 insertions(+), 16 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index c076be72..d9fd9cb8 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -696,12 +696,11 @@ sysfs_set_max_sectors_kb(struct multipath *mpp, int is_reload) + return err; + } + +-static void +-select_reload_action(struct multipath *mpp, const struct multipath *cmpp, +- const char *reason) ++static bool is_udev_ready(struct multipath *cmpp) + { + struct udev_device *mpp_ud; + const char *env; ++ bool rc; + + /* + * MPATH_DEVICE_READY != 1 can mean two things: +@@ -713,14 +712,20 @@ select_reload_action(struct multipath *mpp, const struct multipath *cmpp, + */ + + mpp_ud = get_udev_for_mpp(cmpp); ++ if (!mpp_ud) ++ return true; + env = udev_device_get_property_value(mpp_ud, "MPATH_DEVICE_READY"); +- if ((!env || strcmp(env, "1")) && count_active_paths(mpp) > 0) +- mpp->force_udev_reload = 1; ++ rc = (env != NULL && !strcmp(env, "1")); + udev_device_unref(mpp_ud); ++ condlog(4, "%s: %s: \"%s\" -> %d\n", __func__, cmpp->alias, env, rc); ++ return rc; ++} ++ ++static void ++select_reload_action(struct multipath *mpp, const char *reason) ++{ + mpp->action = ACT_RELOAD; +- condlog(3, "%s: set ACT_RELOAD (%s%s)", mpp->alias, +- mpp->force_udev_reload ? "forced, " : "", +- reason); ++ condlog(3, "%s: set ACT_RELOAD (%s)", mpp->alias, reason); + } + + void select_action (struct multipath *mpp, const struct _vector *curmp, +@@ -789,10 +794,18 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, + return; + } + ++ if (!is_udev_ready(cmpp) && count_active_paths(mpp) > 0) { ++ mpp->force_udev_reload = 1; ++ mpp->action = ACT_RELOAD; ++ condlog(3, "%s: set ACT_RELOAD (udev incomplete)", ++ mpp->alias); ++ return; ++ } ++ + if (mpp->no_path_retry != NO_PATH_RETRY_UNDEF && + !!strstr(mpp->features, "queue_if_no_path") != + !!strstr(cmpp->features, "queue_if_no_path")) { +- select_reload_action(mpp, cmpp, "no_path_retry change"); ++ select_reload_action(mpp, "no_path_retry change"); + return; + } + if ((mpp->retain_hwhandler != RETAIN_HWHANDLER_ON || +@@ -800,7 +813,7 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, + (strlen(cmpp->hwhandler) != strlen(mpp->hwhandler) || + strncmp(cmpp->hwhandler, mpp->hwhandler, + strlen(mpp->hwhandler)))) { +- select_reload_action(mpp, cmpp, "hwhandler change"); ++ select_reload_action(mpp, "hwhandler change"); + return; + } + +@@ -808,7 +821,7 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, + !!strstr(mpp->features, "retain_attached_hw_handler") != + !!strstr(cmpp->features, "retain_attached_hw_handler") && + get_linux_version_code() < KERNEL_VERSION(4, 3, 0)) { +- select_reload_action(mpp, cmpp, "retain_hwhandler change"); ++ select_reload_action(mpp, "retain_hwhandler change"); + return; + } + +@@ -820,7 +833,7 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, + remove_feature(&cmpp_feat, "queue_if_no_path"); + remove_feature(&cmpp_feat, "retain_attached_hw_handler"); + if (strncmp(mpp_feat, cmpp_feat, PARAMS_SIZE)) { +- select_reload_action(mpp, cmpp, "features change"); ++ select_reload_action(mpp, "features change"); + FREE(cmpp_feat); + FREE(mpp_feat); + return; +@@ -831,19 +844,19 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, + + if (!cmpp->selector || strncmp(cmpp->selector, mpp->selector, + strlen(mpp->selector))) { +- select_reload_action(mpp, cmpp, "selector change"); ++ select_reload_action(mpp, "selector change"); + return; + } + if (cmpp->minio != mpp->minio) { +- select_reload_action(mpp, cmpp, "minio change"); ++ select_reload_action(mpp, "minio change"); + return; + } + if (!cmpp->pg || VECTOR_SIZE(cmpp->pg) != VECTOR_SIZE(mpp->pg)) { +- select_reload_action(mpp, cmpp, "path group number change"); ++ select_reload_action(mpp, "path group number change"); + return; + } + if (pgcmp(mpp, cmpp)) { +- select_reload_action(mpp, cmpp, "path group topology change"); ++ select_reload_action(mpp, "path group topology change"); + return; + } + if (cmpp->nextpg != mpp->bestpg) { +-- +2.17.2 + diff --git a/0081-multipath-tools-avoid-access-to-etc-localtime.patch b/0081-multipath-tools-avoid-access-to-etc-localtime.patch new file mode 100644 index 0000000..1e67613 --- /dev/null +++ b/0081-multipath-tools-avoid-access-to-etc-localtime.patch @@ -0,0 +1,112 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 15 Dec 2020 17:09:49 +0100 +Subject: [PATCH] multipath-tools: avoid access to /etc/localtime + +If the root file system is multipathed, and IO is queued because all paths +are failed, multipathd may block trying to access the root FS, and thus be +unable to reinstate paths. One file that is frequently accessed is +/etc/localtime. Avoid that by printing monotonic timestamps instead. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/debug.c | 14 ++++++++------ + libmultipath/devmapper.c | 12 ++++++------ + libmultipath/log.c | 1 - + multipathd/main.c | 3 --- + 4 files changed, 14 insertions(+), 16 deletions(-) + +diff --git a/libmultipath/debug.c b/libmultipath/debug.c +index 429f2699..510e15e5 100644 +--- a/libmultipath/debug.c ++++ b/libmultipath/debug.c +@@ -14,6 +14,8 @@ + #include "config.h" + #include "defaults.h" + #include "debug.h" ++#include "time-util.h" ++#include "util.h" + + int logsink; + int libmp_verbosity = DEFAULT_VERBOSITY; +@@ -25,13 +27,13 @@ void dlog(int prio, const char * fmt, ...) + va_start(ap, fmt); + if (logsink != LOGSINK_SYSLOG) { + if (logsink == LOGSINK_STDERR_WITH_TIME) { +- time_t t = time(NULL); +- struct tm *tb = localtime(&t); +- char buff[16]; ++ struct timespec ts; ++ char buff[32]; + +- strftime(buff, sizeof(buff), +- "%b %d %H:%M:%S", tb); +- buff[sizeof(buff)-1] = '\0'; ++ get_monotonic_time(&ts); ++ safe_sprintf(buff, "%ld.%06ld", ++ (long)ts.tv_sec, ++ ts.tv_nsec/1000); + fprintf(stderr, "%s | ", buff); + } + vfprintf(stderr, fmt, ap); +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index 4977b311..095cbc0c 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -27,6 +27,7 @@ + #include "config.h" + #include "wwids.h" + #include "version.h" ++#include "time-util.h" + + #include "log_pthread.h" + #include +@@ -106,13 +107,12 @@ dm_write_log (int level, const char *file, int line, const char *f, ...) + va_start(ap, f); + if (logsink != LOGSINK_SYSLOG) { + if (logsink == LOGSINK_STDERR_WITH_TIME) { +- time_t t = time(NULL); +- struct tm *tb = localtime(&t); +- char buff[16]; +- +- strftime(buff, sizeof(buff), "%b %d %H:%M:%S", tb); +- buff[sizeof(buff)-1] = '\0'; ++ struct timespec ts; ++ char buff[32]; + ++ get_monotonic_time(&ts); ++ safe_sprintf(buff, "%ld.%06ld", ++ (long)ts.tv_sec, ts.tv_nsec/1000); + fprintf(stderr, "%s | ", buff); + } + fprintf(stderr, "libdevmapper: %s(%i): ", file, line); +diff --git a/libmultipath/log.c b/libmultipath/log.c +index 95c8f01a..6498c88c 100644 +--- a/libmultipath/log.c ++++ b/libmultipath/log.c +@@ -120,7 +120,6 @@ void log_reset (char *program_name) + pthread_cleanup_push(cleanup_mutex, &logq_lock); + + closelog(); +- tzset(); + openlog(program_name, 0, LOG_DAEMON); + + pthread_cleanup_pop(1); +diff --git a/multipathd/main.c b/multipathd/main.c +index 2eab4854..4417860b 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -2706,9 +2706,6 @@ reconfigure (struct vectors * vecs) + delete_all_foreign(); + + reset_checker_classes(); +- /* Re-read any timezone changes */ +- tzset(); +- + if (bindings_read_only) + conf->bindings_read_only = bindings_read_only; + check_alias_settings(conf); +-- +2.17.2 + diff --git a/0082-multipath-tools-make-sure-plugin-DSOs-use-symbol-ver.patch b/0082-multipath-tools-make-sure-plugin-DSOs-use-symbol-ver.patch new file mode 100644 index 0000000..cc3a633 --- /dev/null +++ b/0082-multipath-tools-make-sure-plugin-DSOs-use-symbol-ver.patch @@ -0,0 +1,149 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 16 Dec 2020 23:14:59 +0100 +Subject: [PATCH] multipath-tools: make sure plugin DSOs use symbol versions + +By adding -Wl,-z,defs, we'll get warnings about unresolved symbols +at the linking stage. This way we make sure our plugins (checkers etc.) +will use versioned symbols from libmultipath, and incompatible plugins +can't be loaded any more. Doing this requires explicitly linking +the plugins with all libraries they use, in particular libmultipath. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + Makefile | 1 + + Makefile.inc | 2 +- + libmpathpersist/Makefile | 8 ++++---- + libmultipath/checkers/Makefile | 7 +++---- + libmultipath/foreign/Makefile | 4 +++- + libmultipath/prioritizers/Makefile | 7 +++---- + 6 files changed, 15 insertions(+), 14 deletions(-) + +diff --git a/Makefile b/Makefile +index f127ff91..bddb2bf7 100644 +--- a/Makefile ++++ b/Makefile +@@ -31,6 +31,7 @@ $(BUILDDIRS): + + libmultipath libdmmp: libmpathcmd + libmpathpersist libmpathvalid multipath multipathd: libmultipath ++libmultipath/prioritizers libmultipath/checkers libmultipath/foreign: libmultipath + mpathpersist multipathd: libmpathpersist + + libmultipath/checkers.install \ +diff --git a/Makefile.inc b/Makefile.inc +index 13587a9f..05429307 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -105,7 +105,7 @@ CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ + BIN_CFLAGS = -fPIE -DPIE + LIB_CFLAGS = -fPIC + SHARED_FLAGS = -shared +-LDFLAGS := $(LDFLAGS) -Wl,-z,relro -Wl,-z,now ++LDFLAGS := $(LDFLAGS) -Wl,-z,relro -Wl,-z,now -Wl,-z,defs + BIN_LDFLAGS = -pie + + # Check whether a function with name $1 has been declared in header file $2. +diff --git a/libmpathpersist/Makefile b/libmpathpersist/Makefile +index 456ce4cf..57103e58 100644 +--- a/libmpathpersist/Makefile ++++ b/libmpathpersist/Makefile +@@ -6,17 +6,17 @@ LIBS = $(DEVLIB).$(SONAME) + VERSION_SCRIPT := libmpathpersist.version + + CFLAGS += $(LIB_CFLAGS) -I$(multipathdir) -I$(mpathpersistdir) -I$(mpathcmddir) ++LDFLAGS += -L$(multipathdir) -L$(mpathcmddir) + +-LIBDEPS += -lpthread -ldevmapper -ldl -L$(multipathdir) -lmultipath \ +- -L$(mpathcmddir) -lmpathcmd ++LIBDEPS += -lmultipath -lmpathcmd -ldevmapper -lpthread -ldl + + OBJS = mpath_persist.o mpath_updatepr.o mpath_pr_ioctl.o + + all: $(DEVLIB) man + + $(LIBS): $(OBJS) $(VERSION_SCRIPT) +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) $(LIBDEPS) -Wl,-soname=$@ \ +- -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) ++ $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ ++ -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) + + $(DEVLIB): $(LIBS) + $(LN) $(LIBS) $@ +diff --git a/libmultipath/checkers/Makefile b/libmultipath/checkers/Makefile +index 01c04510..8e0ed5e9 100644 +--- a/libmultipath/checkers/Makefile ++++ b/libmultipath/checkers/Makefile +@@ -4,6 +4,8 @@ + include ../../Makefile.inc + + CFLAGS += $(LIB_CFLAGS) -I.. ++LDFLAGS += -L.. -lmultipath ++LIBDEPS = -lmultipath -laio -lpthread -lrt + + # If you add or remove a checker also update multipath/multipath.conf.5 + LIBS= \ +@@ -17,11 +19,8 @@ LIBS= \ + + all: $(LIBS) + +-libcheckdirectio.so: directio.o +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ -laio +- + libcheck%.so: %.o +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ ++ $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) + + install: + $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(libdir) +diff --git a/libmultipath/foreign/Makefile b/libmultipath/foreign/Makefile +index fae58a0d..f447a1c4 100644 +--- a/libmultipath/foreign/Makefile ++++ b/libmultipath/foreign/Makefile +@@ -5,13 +5,15 @@ TOPDIR=../.. + include ../../Makefile.inc + + CFLAGS += $(LIB_CFLAGS) -I.. -I$(nvmedir) ++LDFLAGS += -L.. ++LIBDEPS = -lmultipath -ludev -lpthread -lrt + + LIBS = libforeign-nvme.so + + all: $(LIBS) + + libforeign-%.so: %.o +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ ++ $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) + + install: + $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(libdir) +diff --git a/libmultipath/prioritizers/Makefile b/libmultipath/prioritizers/Makefile +index fc6e0e0c..8d34ae32 100644 +--- a/libmultipath/prioritizers/Makefile ++++ b/libmultipath/prioritizers/Makefile +@@ -4,6 +4,8 @@ + include ../../Makefile.inc + + CFLAGS += $(LIB_CFLAGS) -I.. ++LDFLAGS += -L.. ++LIBDEPS = -lmultipath -lm -lpthread -lrt + + # If you add or remove a prioritizer also update multipath/multipath.conf.5 + LIBS = \ +@@ -28,11 +30,8 @@ endif + + all: $(LIBS) + +-libpriopath_latency.so: path_latency.o +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ -lm +- + libprio%.so: %.o +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ ++ $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) + + install: $(LIBS) + $(INSTALL_PROGRAM) -m 755 libprio*.so $(DESTDIR)$(libdir) +-- +2.17.2 + diff --git a/0083-libmultipath.version-add-missing-symbol.patch b/0083-libmultipath.version-add-missing-symbol.patch new file mode 100644 index 0000000..55e4396 --- /dev/null +++ b/0083-libmultipath.version-add-missing-symbol.patch @@ -0,0 +1,30 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 17 Dec 2020 01:30:30 +0100 +Subject: [PATCH] libmultipath.version: add missing symbol + +The weightedpath prioritizer uses get_next_string(). I'd overlooked +this before. This was found with the help of the previous patch. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/libmultipath.version | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version +index 751099dc..2228f4ec 100644 +--- a/libmultipath/libmultipath.version ++++ b/libmultipath/libmultipath.version +@@ -275,3 +275,8 @@ LIBMULTIPATH_4.3.0 { + global: + start_checker_thread; + } LIBMULTIPATH_4.2.0; ++ ++LIBMULTIPATH_4.4.0 { ++global: ++ get_next_string; ++} LIBMULTIPATH_4.3.0; +-- +2.17.2 + diff --git a/0084-libmpathvalid-use-default-_multipath_config-udev-and.patch b/0084-libmpathvalid-use-default-_multipath_config-udev-and.patch deleted file mode 100644 index 114d0f4..0000000 --- a/0084-libmpathvalid-use-default-_multipath_config-udev-and.patch +++ /dev/null @@ -1,180 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Sat, 26 Sep 2020 23:25:46 -0500 -Subject: [PATCH] libmpathvalid: use default *_multipath_config, udev, and - logsink - -Signed-off-by: Benjamin Marzinski ---- - libmpathvalid/libmpathvalid.version | 2 +- - libmpathvalid/mpath_valid.c | 73 ++++++++++++++++++++--------- - libmpathvalid/mpath_valid.h | 12 +++-- - 3 files changed, 61 insertions(+), 26 deletions(-) - -diff --git a/libmpathvalid/libmpathvalid.version b/libmpathvalid/libmpathvalid.version -index 4d8a8ba4..3bd0d3c5 100644 ---- a/libmpathvalid/libmpathvalid.version -+++ b/libmpathvalid/libmpathvalid.version -@@ -1,7 +1,7 @@ - MPATH_1.0 { - global: -- mpathvalid_conf; - mpathvalid_init; -+ mpathvalid_reload_config; - mpathvalid_exit; - mpathvalid_is_path; - mpathvalid_get_mode; -diff --git a/libmpathvalid/mpath_valid.c b/libmpathvalid/mpath_valid.c -index 6153e8b7..d839dbac 100644 ---- a/libmpathvalid/mpath_valid.c -+++ b/libmpathvalid/mpath_valid.c -@@ -15,9 +15,7 @@ - #include "mpath_cmd.h" - #include "valid.h" - #include "mpath_valid.h" -- --static struct config default_config = { .verbosity = -1 }; --struct config *mpathvalid_conf = &default_config; -+#include "debug.h" - - static unsigned int get_conf_mode(struct config *conf) - { -@@ -68,38 +66,70 @@ static int convert_result(int result) { - } - - int --mpathvalid_init(int verbosity) -+mpathvalid_init(int verbosity, int log_style) - { - unsigned int version[3]; - struct config *conf; - -- default_config.verbosity = verbosity; -- skip_libmp_dm_init(); -- conf = load_config(DEFAULT_CONFIGFILE); -- if (!conf) -+ logsink = log_style; -+ if (libmultipath_init()) - return -1; -+ conf = get_multipath_config(); - conf->verbosity = verbosity; -- if (dm_prereq(version)) -+ put_multipath_config(conf); -+ -+ skip_libmp_dm_init(); -+ if (init_config(DEFAULT_CONFIGFILE)) - goto fail; -- memcpy(conf->version, version, sizeof(version)); -+ if (dm_prereq(version)) -+ goto fail_config; - -- mpathvalid_conf = conf; -+ conf = get_multipath_config(); -+ conf->verbosity = verbosity; -+ memcpy(conf->version, version, sizeof(version)); -+ put_multipath_config(conf); - return 0; -+ -+fail_config: -+ uninit_config(); - fail: -- free_config(conf); -+ libmultipath_exit(); - return -1; - } - - int --mpathvalid_exit(void) -+mpathvalid_reload_config(void) - { -- struct config *conf = mpathvalid_conf; -+ int verbosity; -+ unsigned int version[3]; -+ struct config *conf; -+ -+ conf = get_multipath_config(); -+ memcpy(version, conf->version, sizeof(version)); -+ verbosity = conf->verbosity; -+ put_multipath_config(conf); - -- default_config.verbosity = -1; -- if (mpathvalid_conf == &default_config) -- return 0; -- mpathvalid_conf = &default_config; -- free_config(conf); -+ uninit_config(); -+ -+ conf = get_multipath_config(); -+ conf->verbosity = verbosity; -+ put_multipath_config(conf); -+ -+ if (init_config(DEFAULT_CONFIGFILE)) -+ return -1; -+ -+ conf = get_multipath_config(); -+ conf->verbosity = verbosity; -+ memcpy(conf->version, version, sizeof(version)); -+ put_multipath_config(conf); -+ return 0; -+} -+ -+int -+mpathvalid_exit(void) -+{ -+ uninit_config(); -+ libmultipath_exit(); - return 0; - } - -@@ -121,9 +151,10 @@ mpathvalid_is_path(const char *name, unsigned int mode, char **wwid, - - if (!name || mode >= MPATH_MAX_MODE) - return r; -- - if (nr_paths > 0 && !path_wwids) - return r; -+ if (!udev) -+ return r; - - pp = alloc_path(); - if (!pp) -@@ -136,7 +167,7 @@ mpathvalid_is_path(const char *name, unsigned int mode, char **wwid, - } - - conf = get_multipath_config(); -- if (!conf || conf == &default_config) -+ if (!conf) - goto out_wwid; - if (mode != MPATH_DEFAULT) - set_conf_mode(conf, mode); -diff --git a/libmpathvalid/mpath_valid.h b/libmpathvalid/mpath_valid.h -index 7fd8aa47..c83b8da5 100644 ---- a/libmpathvalid/mpath_valid.h -+++ b/libmpathvalid/mpath_valid.h -@@ -42,15 +42,19 @@ enum mpath_valid_result { - MPATH_IS_MAYBE_VALID, - }; - --struct config; --extern struct config *mpathvalid_conf; --int mpathvalid_init(int verbosity); -+enum mpath_valid_log_style { -+ MPATH_LOG_STDIO = -1, -+ MPATH_LOG_STDIO_TIMESTAMP, -+ MPATH_LOG_SYSLOG, -+}; -+ -+int mpathvalid_init(int verbosity, int log_style); -+int mpathvalid_reload_config(void); - int mpathvalid_exit(void); - unsigned int mpathvalid_get_mode(void); - int mpathvalid_is_path(const char *name, unsigned int mode, char **wwid, - const char **path_wwids, unsigned int nr_paths); - -- - #ifdef __cplusplus - } - #endif --- -2.17.2 - diff --git a/0084-multipath-tools-tests-unversioned-.so-for-valgrind-t.patch b/0084-multipath-tools-tests-unversioned-.so-for-valgrind-t.patch new file mode 100644 index 0000000..6be89d6 --- /dev/null +++ b/0084-multipath-tools-tests-unversioned-.so-for-valgrind-t.patch @@ -0,0 +1,30 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 18 Dec 2020 23:11:47 +0100 +Subject: [PATCH] multipath-tools tests: unversioned .so for valgrind tests + +We need to the same thing for valgrind tests as we did in +448752f ("libmultipath: create separate .so for unit tests"). + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + tests/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tests/Makefile b/tests/Makefile +index 54da774e..50673fae 100644 +--- a/tests/Makefile ++++ b/tests/Makefile +@@ -76,7 +76,7 @@ lib/libchecktur.so: + + %.vgr: %-test lib/libchecktur.so + @echo == running valgrind for $< == +- @LD_LIBRARY_PATH=$(multipathdir):$(mpathcmddir) \ ++ @LD_LIBRARY_PATH=.:$(mpathcmddir) \ + valgrind --leak-check=full --error-exitcode=128 ./$< >$@ 2>&1 + + OBJS = $(TESTS:%=%.o) $(HELPERS) +-- +2.17.2 + diff --git a/0085-Revert-libmultipath-add-ignore_udev_uid-option.patch b/0085-Revert-libmultipath-add-ignore_udev_uid-option.patch deleted file mode 100644 index 57ff199..0000000 --- a/0085-Revert-libmultipath-add-ignore_udev_uid-option.patch +++ /dev/null @@ -1,186 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Sat, 26 Sep 2020 23:26:32 -0500 -Subject: [PATCH] Revert "libmultipath: add ignore_udev_uid option" - -This reverts commit f1350bc5c4aa445804f3f4fc8968fb46d581336e. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/config.h | 1 - - libmultipath/dict.c | 4 ---- - libmultipath/discovery.c | 17 ++++++----------- - libmultipath/discovery.h | 8 +------- - libmultipath/uevent.c | 2 +- - multipath/multipath.conf.5 | 13 ------------- - multipathd/main.c | 7 +------ - 7 files changed, 9 insertions(+), 43 deletions(-) - -diff --git a/libmultipath/config.h b/libmultipath/config.h -index 089b2ac2..576f15d1 100644 ---- a/libmultipath/config.h -+++ b/libmultipath/config.h -@@ -192,7 +192,6 @@ struct config { - int find_multipaths_timeout; - int marginal_pathgroups; - int skip_delegate; -- int ignore_udev_uid; - unsigned int version[3]; - unsigned int sequence_nr; - -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index 9a0729bf..184d4b22 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -1406,9 +1406,6 @@ declare_hw_snprint(all_tg_pt, print_yes_no_undef) - declare_def_handler(marginal_pathgroups, set_yes_no) - declare_def_snprint(marginal_pathgroups, print_yes_no) - --declare_def_handler(ignore_udev_uid, set_yes_no) --declare_def_snprint(ignore_udev_uid, print_yes_no) -- - static int - def_uxsock_timeout_handler(struct config *conf, vector strvec) - { -@@ -1819,7 +1816,6 @@ init_keywords(vector keywords) - install_keyword("enable_foreign", &def_enable_foreign_handler, - &snprint_def_enable_foreign); - install_keyword("marginal_pathgroups", &def_marginal_pathgroups_handler, &snprint_def_marginal_pathgroups); -- install_keyword("ignore_udev_uid", &def_ignore_udev_uid_handler, &snprint_def_ignore_udev_uid); - __deprecated install_keyword("default_selector", &def_selector_handler, NULL); - __deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL); - __deprecated install_keyword("default_uid_attribute", &def_uid_attribute_handler, NULL); -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index f0e92227..002d3d18 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -2010,7 +2010,7 @@ static bool has_uid_fallback(struct path *pp) - - int - get_uid (struct path * pp, int path_state, struct udev_device *udev, -- int fallback) -+ int allow_fallback) - { - char *c; - const char *origin = "unknown"; -@@ -2043,9 +2043,7 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev, - } else - len = strlen(pp->wwid); - origin = "callout"; -- } else if (fallback == UID_FALLBACK_FORCE) -- len = uid_fallback(pp, path_state, &origin); -- else { -+ } else { - bool udev_available = udev && pp->uid_attribute - && *pp->uid_attribute; - -@@ -2058,9 +2056,8 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev, - else - origin = "udev"; - } -- if ((!udev_available || -- (len <= 0 && fallback == UID_FALLBACK_ALLOW)) && -- has_uid_fallback(pp)) { -+ if ((!udev_available || (len <= 0 && allow_fallback)) -+ && has_uid_fallback(pp)) { - used_fallback = 1; - len = uid_fallback(pp, path_state, &origin); - } -@@ -2200,10 +2197,8 @@ int pathinfo(struct path *pp, struct config *conf, int mask) - } - - if ((mask & DI_WWID) && !strlen(pp->wwid)) { -- int fallback = conf->ignore_udev_uid? UID_FALLBACK_FORCE : -- (pp->retriggers >= conf->retrigger_tries)? -- UID_FALLBACK_ALLOW : UID_FALLBACK_NONE; -- get_uid(pp, path_state, pp->udev, fallback); -+ get_uid(pp, path_state, pp->udev, -+ (pp->retriggers >= conf->retrigger_tries)); - if (!strlen(pp->wwid)) { - if (pp->bus == SYSFS_BUS_UNDEF) - return PATHINFO_SKIPPED; -diff --git a/libmultipath/discovery.h b/libmultipath/discovery.h -index ca8542d6..6444887d 100644 ---- a/libmultipath/discovery.h -+++ b/libmultipath/discovery.h -@@ -54,14 +54,8 @@ ssize_t sysfs_get_inquiry(struct udev_device *udev, - unsigned char *buff, size_t len); - int sysfs_get_asymmetric_access_state(struct path *pp, - char *buff, int buflen); -- --enum { -- UID_FALLBACK_NONE, -- UID_FALLBACK_ALLOW, -- UID_FALLBACK_FORCE, --}; - int get_uid(struct path * pp, int path_state, struct udev_device *udev, -- int fallback); -+ int allow_fallback); - - /* - * discovery bitmask -diff --git a/libmultipath/uevent.c b/libmultipath/uevent.c -index d67129d1..e0d13b11 100644 ---- a/libmultipath/uevent.c -+++ b/libmultipath/uevent.c -@@ -179,7 +179,7 @@ uevent_need_merge(void) - bool need_merge = false; - - conf = get_multipath_config(); -- if (!conf->ignore_udev_uid && VECTOR_SIZE(&conf->uid_attrs) > 0) -+ if (VECTOR_SIZE(&conf->uid_attrs) > 0) - need_merge = true; - put_multipath_config(conf); - -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 175ca095..42a192f6 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -286,19 +286,6 @@ The default is: \fB\fR - . - . - .TP --.B ignore_udev_uid --Setting this option to yes will force multipath to ignore the the uid_attrs --and uid_attribute settings, and generate the WWID by the \fIsysfs\fR --method. This will cause devices that cannot get their WWID from the standard --locations for their device type to not get a WWID; see \fBWWID generation\fR --below. --.RS --.TP --The default is: \fBno\fR --.RE --. --. --.TP - .B prio - The name of the path priority routine. The specified routine - should return a numeric value specifying the relative priority -diff --git a/multipathd/main.c b/multipathd/main.c -index 6a4b8b83..94926b57 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -1223,7 +1223,6 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) - if (pp) { - struct multipath *mpp = pp->mpp; - char wwid[WWID_SIZE]; -- int fallback; - - if (pp->initialized == INIT_REQUESTED_UDEV) { - needs_reinit = 1; -@@ -1235,11 +1234,7 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) - goto out; - - strcpy(wwid, pp->wwid); -- conf = get_multipath_config(); -- fallback = conf->ignore_udev_uid? UID_FALLBACK_FORCE: -- UID_FALLBACK_NONE; -- put_multipath_config(conf); -- rc = get_uid(pp, pp->state, uev->udev, fallback); -+ rc = get_uid(pp, pp->state, uev->udev, 0); - - if (rc != 0) - strcpy(pp->wwid, wwid); --- -2.17.2 - diff --git a/0085-multipath-tools-unit-tests-fix-memory-leaks-in-mpath.patch b/0085-multipath-tools-unit-tests-fix-memory-leaks-in-mpath.patch new file mode 100644 index 0000000..3a3bbbf --- /dev/null +++ b/0085-multipath-tools-unit-tests-fix-memory-leaks-in-mpath.patch @@ -0,0 +1,53 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 18 Dec 2020 23:17:48 +0100 +Subject: [PATCH] multipath-tools unit tests: fix memory leaks in mpathvalid + tests + +They break "make valgrind-test". + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + tests/mpathvalid.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/tests/mpathvalid.c b/tests/mpathvalid.c +index 5ffabb9d..cfe4bae1 100644 +--- a/tests/mpathvalid.c ++++ b/tests/mpathvalid.c +@@ -381,6 +381,7 @@ static void test_mpathvalid_is_path_good2(void **state) + assert_int_equal(mpathvalid_is_path(test_dev, MPATH_DEFAULT, &wwid, + wwids, 4), MPATH_IS_VALID); + assert_string_equal(wwid, TEST_WWID); ++ free(wwid); + } + + static void test_mpathvalid_is_path_good3(void **state) +@@ -395,6 +396,7 @@ static void test_mpathvalid_is_path_good3(void **state) + assert_int_equal(mpathvalid_is_path(test_dev, MPATH_SMART, &wwid, + wwids, 4), MPATH_IS_VALID); + assert_string_equal(wwid, TEST_WWID); ++ free(wwid); + } + + /* mabybe valid with no matching paths */ +@@ -410,6 +412,7 @@ static void test_mpathvalid_is_path_good4(void **state) + assert_int_equal(mpathvalid_is_path(test_dev, MPATH_DEFAULT, &wwid, + wwids, 4), MPATH_IS_MAYBE_VALID); + assert_string_equal(wwid, TEST_WWID); ++ free(wwid); + } + + /* maybe valid with matching paths */ +@@ -425,6 +428,7 @@ static void test_mpathvalid_is_path_good5(void **state) + assert_int_equal(mpathvalid_is_path(test_dev, MPATH_DEFAULT, &wwid, + wwids, 4), MPATH_IS_VALID); + assert_string_equal(wwid, TEST_WWID); ++ free(wwid); + } + + #define setup_test(name) \ +-- +2.17.2 + diff --git a/0086-mpathpersist-Fix-Register-and-Ignore-with-0x00-SARK.patch b/0086-mpathpersist-Fix-Register-and-Ignore-with-0x00-SARK.patch new file mode 100644 index 0000000..3e152fc --- /dev/null +++ b/0086-mpathpersist-Fix-Register-and-Ignore-with-0x00-SARK.patch @@ -0,0 +1,34 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Fri, 18 Dec 2020 17:06:37 -0600 +Subject: [PATCH] mpathpersist: Fix Register and Ignore with 0x00 SARK + +When the Register and Ignore command is run with sg_persist, if a 0x00 +Service Action Reservation Key is given or the --param-sark option is +not used at all, sg_persist will clear the registration. mpathpersist +will fail with an error. This patch fixes mpathpersist to work like +sg_persist in this case. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmpathpersist/mpath_persist.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c +index 79322e86..41789c46 100644 +--- a/libmpathpersist/mpath_persist.c ++++ b/libmpathpersist/mpath_persist.c +@@ -304,7 +304,8 @@ int __mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, + } + + if (memcmp(paramp->key, &mpp->reservation_key, 8) && +- memcmp(paramp->sa_key, &mpp->reservation_key, 8)) { ++ memcmp(paramp->sa_key, &mpp->reservation_key, 8) && ++ (prkey || rq_servact != MPATH_PROUT_REG_IGN_SA)) { + condlog(0, "%s: configured reservation key doesn't match: 0x%" PRIx64, alias, get_be64(mpp->reservation_key)); + ret = MPATH_PR_SYNTAX_ERROR; + goto out1; +-- +2.17.2 + diff --git a/0087-libmultipath-orphan_paths-avoid-BUG-message.patch b/0087-libmultipath-orphan_paths-avoid-BUG-message.patch deleted file mode 100644 index 3dcc3a4..0000000 --- a/0087-libmultipath-orphan_paths-avoid-BUG-message.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 11 Aug 2020 21:08:27 +0200 -Subject: [PATCH] libmultipath: orphan_paths(): avoid BUG message - -Since c44d769, we print a BUG message when we orphan a path that -holds the mpp->hwe pointer. But if this called via orphan_paths(), -this is expected and we shouldn't warn. - -Fixes: c44d769 ("libmultipath: warn if freeing path that holds mpp->hwe") - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/structs_vec.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c -index ede14297..d70bb6ad 100644 ---- a/libmultipath/structs_vec.c -+++ b/libmultipath/structs_vec.c -@@ -114,6 +114,8 @@ void orphan_paths(vector pathvec, struct multipath *mpp, const char *reason) - int i; - struct path * pp; - -+ /* Avoid BUG message from orphan_path() */ -+ mpp->hwe = NULL; - vector_foreach_slot (pathvec, pp, i) { - if (pp->mpp == mpp) { - orphan_path(pp, reason); --- -2.17.2 - diff --git a/0087-mpathpersist-update-prkeys-file-on-changing-registra.patch b/0087-mpathpersist-update-prkeys-file-on-changing-registra.patch new file mode 100644 index 0000000..79bee15 --- /dev/null +++ b/0087-mpathpersist-update-prkeys-file-on-changing-registra.patch @@ -0,0 +1,39 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Fri, 18 Dec 2020 17:06:38 -0600 +Subject: [PATCH] mpathpersist: update prkeys file on changing registrations + +When the "reservation_key" option is set to "file" and Register command +is run with both the current Reservation Key and a new Service Action +Reservation Key, mpathpersist will change the registration, but will not +update the prkeys file. This means that future paths that come online +will not be able to register, since multipathd is still using the old +reservation key. Fix this. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmpathpersist/mpath_persist.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c +index 41789c46..08077936 100644 +--- a/libmpathpersist/mpath_persist.c ++++ b/libmpathpersist/mpath_persist.c +@@ -290,9 +290,10 @@ int __mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, + + memcpy(&prkey, paramp->sa_key, 8); + if (mpp->prkey_source == PRKEY_SOURCE_FILE && prkey && +- ((!get_be64(mpp->reservation_key) && +- rq_servact == MPATH_PROUT_REG_SA) || +- rq_servact == MPATH_PROUT_REG_IGN_SA)) { ++ (rq_servact == MPATH_PROUT_REG_IGN_SA || ++ (rq_servact == MPATH_PROUT_REG_SA && ++ (!get_be64(mpp->reservation_key) || ++ memcmp(paramp->key, &mpp->reservation_key, 8) == 0)))) { + memcpy(&mpp->reservation_key, paramp->sa_key, 8); + if (update_prkey_flags(alias, get_be64(mpp->reservation_key), + paramp->sa_flags)) { +-- +2.17.2 + diff --git a/0088-libmultipath-warn-about-missing-braces-at-end-of-mul.patch b/0088-libmultipath-warn-about-missing-braces-at-end-of-mul.patch new file mode 100644 index 0000000..bbb9f13 --- /dev/null +++ b/0088-libmultipath-warn-about-missing-braces-at-end-of-mul.patch @@ -0,0 +1,42 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Fri, 18 Dec 2020 17:06:39 -0600 +Subject: [PATCH] libmultipath: warn about missing braces at end of + multipath.conf + +Multipath doesn't warn when multipath.conf is missing closing braces at +the end of the file. This has confused people about the correct config +file syntax, so add a warning. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/parser.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/parser.c b/libmultipath/parser.c +index 163ffbc9..c70243c3 100644 +--- a/libmultipath/parser.c ++++ b/libmultipath/parser.c +@@ -537,7 +537,7 @@ process_stream(struct config *conf, FILE *stream, vector keywords, + if (!strcmp(str, EOB)) { + if (kw_level > 0) { + free_strvec(strvec); +- break; ++ goto out; + } + condlog(0, "unmatched '%s' at line %d of %s", + EOB, line_nr, file); +@@ -576,7 +576,8 @@ process_stream(struct config *conf, FILE *stream, vector keywords, + + free_strvec(strvec); + } +- ++ if (kw_level == 1) ++ condlog(1, "missing '%s' at end of %s", EOB, file); + out: + FREE(buf); + free_uniques(uniques); +-- +2.17.2 + diff --git a/0089-libmultipath-ignore-multipaths-sections-without-wwid.patch b/0089-libmultipath-ignore-multipaths-sections-without-wwid.patch new file mode 100644 index 0000000..25aa7ea --- /dev/null +++ b/0089-libmultipath-ignore-multipaths-sections-without-wwid.patch @@ -0,0 +1,37 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Fri, 18 Dec 2020 17:06:40 -0600 +Subject: [PATCH] libmultipath: ignore multipaths sections without wwid option + +"multipathd show config local" was crashing in find_mp_by_wwid() if +the multipath configuration included a multipaths section that did +not set a wwid option. There is no reason to keep a mpentry that +didn't set its wwid. Remove it in merge_mptable(). + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/config.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/libmultipath/config.c b/libmultipath/config.c +index 9f3cb38d..a643703e 100644 +--- a/libmultipath/config.c ++++ b/libmultipath/config.c +@@ -509,6 +509,13 @@ void merge_mptable(vector mptable) + int i, j; + + vector_foreach_slot(mptable, mp1, i) { ++ /* drop invalid multipath configs */ ++ if (!mp1->wwid) { ++ condlog(0, "multipaths config section missing wwid"); ++ vector_del_slot(mptable, i--); ++ free_mpe(mp1); ++ continue; ++ } + j = i + 1; + vector_foreach_slot_after(mptable, mp2, j) { + if (strcmp(mp1->wwid, mp2->wwid)) +-- +2.17.2 + diff --git a/0090-libmultipath-fix-format-warning-with-clang.patch b/0090-libmultipath-fix-format-warning-with-clang.patch new file mode 100644 index 0000000..931e81c --- /dev/null +++ b/0090-libmultipath-fix-format-warning-with-clang.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 18 Dec 2020 23:34:35 +0100 +Subject: [PATCH] libmultipath: fix format warning with clang + +Reported-by: Xose Vazquez Perez +Tested-by: Xose Vazquez Perez +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/log.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/libmultipath/log.c b/libmultipath/log.c +index 6498c88c..10fa32cd 100644 +--- a/libmultipath/log.c ++++ b/libmultipath/log.c +@@ -125,6 +125,7 @@ void log_reset (char *program_name) + pthread_cleanup_pop(1); + } + ++__attribute__((format(printf, 2, 0))) + static int _log_enqueue(int prio, const char * fmt, va_list ap) + { + int len, fwd; +-- +2.17.2 + diff --git a/0091-libmultipath-check-for-null-wwid-before-strcmp.patch b/0091-libmultipath-check-for-null-wwid-before-strcmp.patch new file mode 100644 index 0000000..1f6894d --- /dev/null +++ b/0091-libmultipath-check-for-null-wwid-before-strcmp.patch @@ -0,0 +1,34 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 4 Jan 2021 21:59:54 -0600 +Subject: [PATCH] libmultipath: check for null wwid before strcmp + +Commit 749aabd0 (libmultipath: ignore multipaths sections without wwid +option) removed all mpentries with a NULL wwid, but didn't stop strcmp() +from being run on them in merge_mptable(). The result of strcmp() with +a NULL parameter is undefined, so fix that. + +Signed-off-by: Benjamin Marzinski + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/config.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmultipath/config.c b/libmultipath/config.c +index a643703e..be310159 100644 +--- a/libmultipath/config.c ++++ b/libmultipath/config.c +@@ -518,7 +518,7 @@ void merge_mptable(vector mptable) + } + j = i + 1; + vector_foreach_slot_after(mptable, mp2, j) { +- if (strcmp(mp1->wwid, mp2->wwid)) ++ if (!mp2->wwid || strcmp(mp1->wwid, mp2->wwid)) + continue; + condlog(1, "%s: duplicate multipath config section for %s", + __func__, mp1->wwid); +-- +2.17.2 + diff --git a/0092-multipath.conf.5-Improve-checker_timeout-description.patch b/0092-multipath.conf.5-Improve-checker_timeout-description.patch new file mode 100644 index 0000000..120c637 --- /dev/null +++ b/0092-multipath.conf.5-Improve-checker_timeout-description.patch @@ -0,0 +1,65 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 4 Jan 2021 21:59:55 -0600 +Subject: [PATCH] multipath.conf.5: Improve checker_timeout description + +I was asked to explain how checker_timeout works for checkers like +directio, that don't issue scsi commands with an explicit timeout. +Also, undeprecate the directio checker. + +Signed-off-by: Benjamin Marzinski + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + multipath/multipath.conf.5 | 20 ++++++++++++-------- + 1 file changed, 12 insertions(+), 8 deletions(-) + +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 +index ea66a01e..8ef3a747 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5 +@@ -472,8 +472,12 @@ The default is: \fB\fR + . + .TP + .B path_checker +-The default method used to determine the paths state. Possible values +-are: ++The default method used to determine the path's state. The synchronous ++checkers (all except \fItur\fR and \fIdirectio\fR) will cause multipathd to ++pause most activity, waiting up to \fIchecker_timeout\fR seconds for the path ++to respond. The asynchronous checkers (\fItur\fR and \fIdirectio\fR) will not ++pause multipathd. Instead, multipathd will check for a response once per ++second, until \fIchecker_timeout\fR seconds have elapsed. Possible values are: + .RS + .TP 12 + .I readsector0 +@@ -499,10 +503,8 @@ Check the path state for LSI/Engenio/NetApp RDAC class as NetApp SANtricity E/EF + Series, and OEM arrays from IBM DELL SGI STK and SUN. + .TP + .I directio +-(Deprecated) Read the first sector with direct I/O. If you have a large number +-of paths, or many AIO users on a system, you may need to use sysctl to +-increase fs.aio-max-nr. This checker is being deprecated, it could cause +-spurious path failures under high load. Please use \fItur\fR instead. ++Read the first sector with direct I/O. This checker could cause spurious path ++failures under high load. Increasing \fIchecker_timeout\fR can help with this. + .TP + .I cciss_tur + (Hardware-dependent) +@@ -639,8 +641,10 @@ The default is: \fBno\fR + . + .TP + .B checker_timeout +-Specify the timeout to use for path checkers and prioritizers that issue SCSI +-commands with an explicit timeout, in seconds. ++Specify the timeout to use for path checkers and prioritizers, in seconds. ++Only prioritizers that issue scsi commands use checker_timeout. If a path ++does not respond to the checker command after \fIchecker_timeout\fR ++seconds have elapsed, it is considered down. + .RS + .TP + The default is: in \fB/sys/block/sd/device/timeout\fR +-- +2.17.2 + diff --git a/0093-multipathd-fix-path-checkint-not-changed-when-path-s.patch b/0093-multipathd-fix-path-checkint-not-changed-when-path-s.patch new file mode 100644 index 0000000..868fa18 --- /dev/null +++ b/0093-multipathd-fix-path-checkint-not-changed-when-path-s.patch @@ -0,0 +1,36 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Chongyun Wu +Date: Wed, 6 Jan 2021 09:39:12 +0800 +Subject: [PATCH] multipathd: fix path checkint not changed when path state + changed from delay to failed + +Check_path: when path state change back to failed from delay state, +should change this path's check interval time to the shortest delay +to faster path state check. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Chongyun Wu +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 4417860b..7612430a 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -2161,6 +2161,11 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) + (pp->state == PATH_DELAYED)) { + /* If path state become failed again cancel path delay state */ + pp->state = newstate; ++ /* ++ * path state bad again should change the check interval time ++ * to the shortest delay ++ */ ++ pp->checkint = checkint; + return 1; + } + if (!pp->mpp) { +-- +2.17.2 + diff --git a/0094-libmultipath-select_action-skip-is_mpp_known_to_udev.patch b/0094-libmultipath-select_action-skip-is_mpp_known_to_udev.patch new file mode 100644 index 0000000..e37e4da --- /dev/null +++ b/0094-libmultipath-select_action-skip-is_mpp_known_to_udev.patch @@ -0,0 +1,51 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 8 Jan 2021 17:22:09 +0100 +Subject: [PATCH] libmultipath: select_action(): skip is_mpp_known_to_udev() + test + +This test is now superseded by the check introduced in +0d66e03 ("libmultipath: force map reload if udev incomplete"). + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/configure.c | 15 --------------- + 1 file changed, 15 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index d9fd9cb8..999f3106 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -635,15 +635,6 @@ trigger_paths_udev_change(struct multipath *mpp, bool is_mpath) + mpp->needs_paths_uevent = 0; + } + +-static int +-is_mpp_known_to_udev(const struct multipath *mpp) +-{ +- struct udev_device *udd = get_udev_for_mpp(mpp); +- int ret = (udd != NULL); +- udev_device_unref(udd); +- return ret; +-} +- + static int + sysfs_set_max_sectors_kb(struct multipath *mpp, int is_reload) + { +@@ -865,12 +856,6 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, + mpp->alias); + return; + } +- if (!is_mpp_known_to_udev(cmpp)) { +- mpp->action = ACT_RELOAD; +- condlog(3, "%s: set ACT_RELOAD (udev device not initialized)", +- mpp->alias); +- return; +- } + mpp->action = ACT_NOTHING; + condlog(3, "%s: set ACT_NOTHING (map unchanged)", + mpp->alias); +-- +2.17.2 + diff --git a/0095-libmultipath-coalesce_paths-stop-triggering-spurious.patch b/0095-libmultipath-coalesce_paths-stop-triggering-spurious.patch new file mode 100644 index 0000000..033525b --- /dev/null +++ b/0095-libmultipath-coalesce_paths-stop-triggering-spurious.patch @@ -0,0 +1,65 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 8 Jan 2021 17:36:40 +0100 +Subject: [PATCH] libmultipath: coalesce_paths(): stop triggering spurious + uevents + +Since 0d66e03 ("libmultipath: force map reload if udev incomplete"), we +force-reload maps that we find incompletely initialized by udev. If +select_action returns ACT_NOTHING nonetheless, the map must be initialized +in udev, and thus and "add" uevent must have been seen already. Triggering +this event once more is unlikely to fix anything for real. + +Reverts: b516118 ("libmultipath: coalesce_paths: trigger uevent if nothing done") + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/configure.c | 24 ------------------------ + 1 file changed, 24 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index 999f3106..3263bb01 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -527,18 +527,6 @@ get_udev_for_mpp(const struct multipath *mpp) + return udd; + } + +-static void +-trigger_udev_change(const struct multipath *mpp) +-{ +- static const char change[] = "change"; +- struct udev_device *udd = get_udev_for_mpp(mpp); +- if (!udd) +- return; +- condlog(3, "triggering %s uevent for %s", change, mpp->alias); +- sysfs_attr_set_value(udd, "uevent", change, sizeof(change)-1); +- udev_device_unref(udd); +-} +- + static void trigger_partitions_udev_change(struct udev_device *dev, + const char *action, int len) + { +@@ -1297,18 +1285,6 @@ int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid, + continue; + } + +- if (r == DOMAP_EXIST && mpp->action == ACT_NOTHING && +- force_reload == FORCE_RELOAD_WEAK) +- /* +- * First time we're called, and no changes applied. +- * domap() was a noop. But we can't be sure that +- * udev has already finished setting up this device +- * (udev in initrd may have been shut down while +- * processing this device or its children). +- * Trigger a change event, just in case. +- */ +- trigger_udev_change(find_mp_by_wwid(curmp, mpp->wwid)); +- + conf = get_multipath_config(); + allow_queueing = conf->allow_queueing; + put_multipath_config(conf); +-- +2.17.2 + diff --git a/0096-Revert-multipathd-uev_trigger-handle-incomplete-ADD-.patch b/0096-Revert-multipathd-uev_trigger-handle-incomplete-ADD-.patch new file mode 100644 index 0000000..79912f0 --- /dev/null +++ b/0096-Revert-multipathd-uev_trigger-handle-incomplete-ADD-.patch @@ -0,0 +1,61 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 8 Jan 2021 17:27:10 +0100 +Subject: [PATCH] Revert "multipathd: uev_trigger(): handle incomplete ADD + events" + +cb10d38 ("multipathd: uev_trigger(): handle incomplete ADD events") was an +attempt to fix issues with incompletely initialized multipath maps observed +in various scenarious. However, that patch was wrong. Spurious "change" events +as this patch would generate have no effect, because they are ignored by +the device-mapper udev rules. The correct fix for the problem we were +facing is 0d66e03 ("libmultipath: force map reload if udev incomplete"), +which forces a full map reload. + +Reverts: cb10d38 ("multipathd: uev_trigger(): handle incomplete ADD events") + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 25 ------------------------- + 1 file changed, 25 deletions(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 7612430a..92c45d44 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -1499,31 +1499,6 @@ uev_trigger (struct uevent * uev, void * trigger_data) + uev_pathfail_check(uev, vecs); + } else if (!strncmp(uev->action, "remove", 6)) { + r = uev_remove_map(uev, vecs); +- } else if (!strncmp(uev->action, "add", 3)) { +- const char *ev_name; +- char *dm_name; +- int major = -1, minor = -1; +- +- /* +- * If DM_NAME is not set for a valid map, trigger a +- * change event. This can happen during coldplug +- * if udev was killed between handling the 'add' and +- * 'change' events before. +- */ +- ev_name = uevent_get_dm_name(uev); +- if (!ev_name) { +- major = uevent_get_major(uev); +- minor = uevent_get_minor(uev); +- dm_name = dm_mapname(major, minor); +- if (dm_name && *dm_name) { +- condlog(2, "%s: received incomplete 'add' uevent, triggering change", +- dm_name); +- udev_device_set_sysattr_value(uev->udev, +- "uevent", +- "change"); +- free(dm_name); +- } +- } + } + goto out; + } +-- +2.17.2 + diff --git a/0097-libmultipath-make-find_err_path_by_dev-static.patch b/0097-libmultipath-make-find_err_path_by_dev-static.patch new file mode 100644 index 0000000..a19afc4 --- /dev/null +++ b/0097-libmultipath-make-find_err_path_by_dev-static.patch @@ -0,0 +1,27 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 14 Jan 2021 20:20:22 -0600 +Subject: [PATCH] libmultipath: make find_err_path_by_dev() static + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/io_err_stat.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmultipath/io_err_stat.c b/libmultipath/io_err_stat.c +index 5363049d..2e48ee81 100644 +--- a/libmultipath/io_err_stat.c ++++ b/libmultipath/io_err_stat.c +@@ -88,7 +88,7 @@ static void rcu_unregister(__attribute__((unused)) void *param) + rcu_unregister_thread(); + } + +-struct io_err_stat_path *find_err_path_by_dev(vector pathvec, char *dev) ++static struct io_err_stat_path *find_err_path_by_dev(vector pathvec, char *dev) + { + int i; + struct io_err_stat_path *pp; +-- +2.17.2 + diff --git a/0098-multipathd-avoid-io_err_stat-crash-during-shutdown.patch b/0098-multipathd-avoid-io_err_stat-crash-during-shutdown.patch new file mode 100644 index 0000000..4c21465 --- /dev/null +++ b/0098-multipathd-avoid-io_err_stat-crash-during-shutdown.patch @@ -0,0 +1,257 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 14 Jan 2021 20:20:23 -0600 +Subject: [PATCH] multipathd: avoid io_err_stat crash during shutdown + +The checker thread is reponsible for enqueueing paths for the +io_err_stat thread to check. During shutdown, the io_err_stat thread is +shut down and cleaned up before the checker thread. There is no code +to make sure that the checker thread isn't accessing the io_err_stat +pathvec or its mutex while they are being freed, which can lead to +memory corruption crashes. + +To solve this, get rid of the io_err_stat_pathvec structure, and +statically define the mutex. This means that the mutex is always valid +to access, and the io_err_stat pathvec can only be accessed while +holding it. If the io_err_stat thread has already been cleaned up +when the checker tries to access the pathvec, it will be NULL, and the +checker will simply fail to enqueue the path. + +This change also fixes a bug in free_io_err_pathvec(), which previously +only attempted to free the pathvec if it was not set, instead of when it +was set. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/io_err_stat.c | 111 ++++++++++++++----------------------- + 1 file changed, 43 insertions(+), 68 deletions(-) + +diff --git a/libmultipath/io_err_stat.c b/libmultipath/io_err_stat.c +index 2e48ee81..feb66469 100644 +--- a/libmultipath/io_err_stat.c ++++ b/libmultipath/io_err_stat.c +@@ -46,12 +46,6 @@ + #define io_err_stat_log(prio, fmt, args...) \ + condlog(prio, "io error statistic: " fmt, ##args) + +- +-struct io_err_stat_pathvec { +- pthread_mutex_t mutex; +- vector pathvec; +-}; +- + struct dio_ctx { + struct timespec io_starttime; + unsigned int blksize; +@@ -75,9 +69,10 @@ static pthread_t io_err_stat_thr; + + static pthread_mutex_t io_err_thread_lock = PTHREAD_MUTEX_INITIALIZER; + static pthread_cond_t io_err_thread_cond = PTHREAD_COND_INITIALIZER; ++static pthread_mutex_t io_err_pathvec_lock = PTHREAD_MUTEX_INITIALIZER; + static int io_err_thread_running = 0; + +-static struct io_err_stat_pathvec *paths; ++static vector io_err_pathvec; + struct vectors *vecs; + io_context_t ioctx; + +@@ -207,46 +202,23 @@ static void free_io_err_stat_path(struct io_err_stat_path *p) + FREE(p); + } + +-static struct io_err_stat_pathvec *alloc_pathvec(void) +-{ +- struct io_err_stat_pathvec *p; +- int r; +- +- p = (struct io_err_stat_pathvec *)MALLOC(sizeof(*p)); +- if (!p) +- return NULL; +- p->pathvec = vector_alloc(); +- if (!p->pathvec) +- goto out_free_struct_pathvec; +- r = pthread_mutex_init(&p->mutex, NULL); +- if (r) +- goto out_free_member_pathvec; +- +- return p; +- +-out_free_member_pathvec: +- vector_free(p->pathvec); +-out_free_struct_pathvec: +- FREE(p); +- return NULL; +-} +- +-static void free_io_err_pathvec(struct io_err_stat_pathvec *p) ++static void free_io_err_pathvec(void) + { + struct io_err_stat_path *path; + int i; + +- if (!p) +- return; +- pthread_mutex_destroy(&p->mutex); +- if (!p->pathvec) { +- vector_foreach_slot(p->pathvec, path, i) { +- destroy_directio_ctx(path); +- free_io_err_stat_path(path); +- } +- vector_free(p->pathvec); ++ pthread_mutex_lock(&io_err_pathvec_lock); ++ pthread_cleanup_push(cleanup_mutex, &io_err_pathvec_lock); ++ if (!io_err_pathvec) ++ goto out; ++ vector_foreach_slot(io_err_pathvec, path, i) { ++ destroy_directio_ctx(path); ++ free_io_err_stat_path(path); + } +- FREE(p); ++ vector_free(io_err_pathvec); ++ io_err_pathvec = NULL; ++out: ++ pthread_cleanup_pop(1); + } + + /* +@@ -258,13 +230,13 @@ static int enqueue_io_err_stat_by_path(struct path *path) + { + struct io_err_stat_path *p; + +- pthread_mutex_lock(&paths->mutex); +- p = find_err_path_by_dev(paths->pathvec, path->dev); ++ pthread_mutex_lock(&io_err_pathvec_lock); ++ p = find_err_path_by_dev(io_err_pathvec, path->dev); + if (p) { +- pthread_mutex_unlock(&paths->mutex); ++ pthread_mutex_unlock(&io_err_pathvec_lock); + return 0; + } +- pthread_mutex_unlock(&paths->mutex); ++ pthread_mutex_unlock(&io_err_pathvec_lock); + + p = alloc_io_err_stat_path(); + if (!p) +@@ -276,18 +248,18 @@ static int enqueue_io_err_stat_by_path(struct path *path) + + if (setup_directio_ctx(p)) + goto free_ioerr_path; +- pthread_mutex_lock(&paths->mutex); +- if (!vector_alloc_slot(paths->pathvec)) ++ pthread_mutex_lock(&io_err_pathvec_lock); ++ if (!vector_alloc_slot(io_err_pathvec)) + goto unlock_destroy; +- vector_set_slot(paths->pathvec, p); +- pthread_mutex_unlock(&paths->mutex); ++ vector_set_slot(io_err_pathvec, p); ++ pthread_mutex_unlock(&io_err_pathvec_lock); + + io_err_stat_log(2, "%s: enqueue path %s to check", + path->mpp->alias, path->dev); + return 0; + + unlock_destroy: +- pthread_mutex_unlock(&paths->mutex); ++ pthread_mutex_unlock(&io_err_pathvec_lock); + destroy_directio_ctx(p); + free_ioerr_path: + free_io_err_stat_path(p); +@@ -412,9 +384,9 @@ static int delete_io_err_stat_by_addr(struct io_err_stat_path *p) + { + int i; + +- i = find_slot(paths->pathvec, p); ++ i = find_slot(io_err_pathvec, p); + if (i != -1) +- vector_del_slot(paths->pathvec, i); ++ vector_del_slot(io_err_pathvec, i); + + destroy_directio_ctx(p); + free_io_err_stat_path(p); +@@ -585,7 +557,7 @@ static void poll_async_io_timeout(void) + + if (clock_gettime(CLOCK_MONOTONIC, &curr_time) != 0) + return; +- vector_foreach_slot(paths->pathvec, pp, i) { ++ vector_foreach_slot(io_err_pathvec, pp, i) { + for (j = 0; j < CONCUR_NR_EVENT; j++) { + rc = try_to_cancel_timeout_io(pp->dio_ctx_array + j, + &curr_time, pp->devname); +@@ -631,7 +603,7 @@ static void handle_async_io_done_event(struct io_event *io_evt) + int rc = PATH_UNCHECKED; + int i, j; + +- vector_foreach_slot(paths->pathvec, pp, i) { ++ vector_foreach_slot(io_err_pathvec, pp, i) { + for (j = 0; j < CONCUR_NR_EVENT; j++) { + ct = pp->dio_ctx_array + j; + if (&ct->io == io_evt->obj) { +@@ -665,19 +637,14 @@ static void service_paths(void) + struct io_err_stat_path *pp; + int i; + +- pthread_mutex_lock(&paths->mutex); +- vector_foreach_slot(paths->pathvec, pp, i) { ++ pthread_mutex_lock(&io_err_pathvec_lock); ++ vector_foreach_slot(io_err_pathvec, pp, i) { + send_batch_async_ios(pp); + process_async_ios_event(TIMEOUT_NO_IO_NSEC, pp->devname); + poll_async_io_timeout(); + poll_io_err_stat(vecs, pp); + } +- pthread_mutex_unlock(&paths->mutex); +-} +- +-static void cleanup_unlock(void *arg) +-{ +- pthread_mutex_unlock((pthread_mutex_t*) arg); ++ pthread_mutex_unlock(&io_err_pathvec_lock); + } + + static void cleanup_exited(__attribute__((unused)) void *arg) +@@ -736,13 +703,18 @@ int start_io_err_stat_thread(void *data) + io_err_stat_log(4, "io_setup failed"); + return 1; + } +- paths = alloc_pathvec(); +- if (!paths) ++ ++ pthread_mutex_lock(&io_err_pathvec_lock); ++ io_err_pathvec = vector_alloc(); ++ if (!io_err_pathvec) { ++ pthread_mutex_unlock(&io_err_pathvec_lock); + goto destroy_ctx; ++ } ++ pthread_mutex_unlock(&io_err_pathvec_lock); + + setup_thread_attr(&io_err_stat_attr, 32 * 1024, 0); + pthread_mutex_lock(&io_err_thread_lock); +- pthread_cleanup_push(cleanup_unlock, &io_err_thread_lock); ++ pthread_cleanup_push(cleanup_mutex, &io_err_thread_lock); + + ret = pthread_create(&io_err_stat_thr, &io_err_stat_attr, + io_err_stat_loop, data); +@@ -763,7 +735,10 @@ int start_io_err_stat_thread(void *data) + return 0; + + out_free: +- free_io_err_pathvec(paths); ++ pthread_mutex_lock(&io_err_pathvec_lock); ++ vector_free(io_err_pathvec); ++ io_err_pathvec = NULL; ++ pthread_mutex_unlock(&io_err_pathvec_lock); + destroy_ctx: + io_destroy(ioctx); + io_err_stat_log(0, "failed to start io_error statistic thread"); +@@ -779,6 +754,6 @@ void stop_io_err_stat_thread(void) + pthread_cancel(io_err_stat_thr); + + pthread_join(io_err_stat_thr, NULL); +- free_io_err_pathvec(paths); ++ free_io_err_pathvec(); + io_destroy(ioctx); + } +-- +2.17.2 + diff --git a/0099-multipathd-avoid-io_err_stat-ABBA-deadlock.patch b/0099-multipathd-avoid-io_err_stat-ABBA-deadlock.patch new file mode 100644 index 0000000..30584f6 --- /dev/null +++ b/0099-multipathd-avoid-io_err_stat-ABBA-deadlock.patch @@ -0,0 +1,146 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 14 Jan 2021 20:20:24 -0600 +Subject: [PATCH] multipathd: avoid io_err_stat ABBA deadlock + +When the checker thread enqueues paths for the io_err_stat thread to +check, it calls enqueue_io_err_stat_by_path() with the vecs lock held. +start_io_err_stat_thread() is also called with the vecs lock held. +These two functions both lock io_err_pathvec_lock. When the io_err_stat +thread updates the paths in vecs->pathvec in poll_io_err_stat(), it has +the io_err_pathvec_lock held, and then locks the vecs lock. This can +cause an ABBA deadlock. + +To solve this, service_paths() no longer updates the paths in +vecs->pathvec with the io_err_pathvec_lock held. It does this by moving +the io_err_stat_path from io_err_pathvec to a local vector when it needs +to update the path. After releasing the io_err_pathvec_lock, it goes +through this temporary vector, updates the paths with the vecs lock +held, and then frees everything. + +This change fixes a bug in service_paths() where elements were being +deleted from io_err_pathvec, without the index being decremented, +causing the loop to skip elements. Also, service_paths() could be +cancelled while holding the io_err_pathvec_lock, so it should have a +cleanup handler. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/io_err_stat.c | 56 ++++++++++++++++++++++---------------- + 1 file changed, 32 insertions(+), 24 deletions(-) + +diff --git a/libmultipath/io_err_stat.c b/libmultipath/io_err_stat.c +index feb66469..775e7259 100644 +--- a/libmultipath/io_err_stat.c ++++ b/libmultipath/io_err_stat.c +@@ -380,20 +380,6 @@ recover: + return 0; + } + +-static int delete_io_err_stat_by_addr(struct io_err_stat_path *p) +-{ +- int i; +- +- i = find_slot(io_err_pathvec, p); +- if (i != -1) +- vector_del_slot(io_err_pathvec, i); +- +- destroy_directio_ctx(p); +- free_io_err_stat_path(p); +- +- return 0; +-} +- + static void account_async_io_state(struct io_err_stat_path *pp, int rc) + { + switch (rc) { +@@ -410,17 +396,26 @@ static void account_async_io_state(struct io_err_stat_path *pp, int rc) + } + } + +-static int poll_io_err_stat(struct vectors *vecs, struct io_err_stat_path *pp) ++static int io_err_stat_time_up(struct io_err_stat_path *pp) + { + struct timespec currtime, difftime; +- struct path *path; +- double err_rate; + + if (clock_gettime(CLOCK_MONOTONIC, &currtime) != 0) +- return 1; ++ return 0; + timespecsub(&currtime, &pp->start_time, &difftime); + if (difftime.tv_sec < pp->total_time) + return 0; ++ return 1; ++} ++ ++static void end_io_err_stat(struct io_err_stat_path *pp) ++{ ++ struct timespec currtime; ++ struct path *path; ++ double err_rate; ++ ++ if (clock_gettime(CLOCK_MONOTONIC, &currtime) != 0) ++ currtime = pp->start_time; + + io_err_stat_log(4, "%s: check end", pp->devname); + +@@ -459,10 +454,6 @@ static int poll_io_err_stat(struct vectors *vecs, struct io_err_stat_path *pp) + pp->devname); + } + lock_cleanup_pop(vecs->lock); +- +- delete_io_err_stat_by_addr(pp); +- +- return 0; + } + + static int send_each_async_io(struct dio_ctx *ct, int fd, char *dev) +@@ -622,6 +613,7 @@ static void process_async_ios_event(int timeout_nsecs, char *dev) + struct timespec timeout = { .tv_nsec = timeout_nsecs }; + + errno = 0; ++ pthread_testcancel(); + n = io_getevents(ioctx, 1L, CONCUR_NR_EVENT, events, &timeout); + if (n < 0) { + io_err_stat_log(3, "%s: async io events returned %d (errno=%s)", +@@ -634,17 +626,33 @@ static void process_async_ios_event(int timeout_nsecs, char *dev) + + static void service_paths(void) + { ++ struct _vector _pathvec = {0}; ++ /* avoid gcc warnings that &_pathvec will never be NULL in vector ops */ ++ struct _vector * const tmp_pathvec = &_pathvec; + struct io_err_stat_path *pp; + int i; + + pthread_mutex_lock(&io_err_pathvec_lock); ++ pthread_cleanup_push(cleanup_mutex, &io_err_pathvec_lock); + vector_foreach_slot(io_err_pathvec, pp, i) { + send_batch_async_ios(pp); + process_async_ios_event(TIMEOUT_NO_IO_NSEC, pp->devname); + poll_async_io_timeout(); +- poll_io_err_stat(vecs, pp); ++ if (io_err_stat_time_up(pp)) { ++ if (!vector_alloc_slot(tmp_pathvec)) ++ continue; ++ vector_del_slot(io_err_pathvec, i--); ++ vector_set_slot(tmp_pathvec, pp); ++ } + } +- pthread_mutex_unlock(&io_err_pathvec_lock); ++ pthread_cleanup_pop(1); ++ vector_foreach_slot_backwards(tmp_pathvec, pp, i) { ++ end_io_err_stat(pp); ++ vector_del_slot(tmp_pathvec, i); ++ destroy_directio_ctx(pp); ++ free_io_err_stat_path(pp); ++ } ++ vector_reset(tmp_pathvec); + } + + static void cleanup_exited(__attribute__((unused)) void *arg) +-- +2.17.2 + diff --git a/0100-multipathd-use-get_monotonic_time-in-io_err_stat-cod.patch b/0100-multipathd-use-get_monotonic_time-in-io_err_stat-cod.patch new file mode 100644 index 0000000..89d9f73 --- /dev/null +++ b/0100-multipathd-use-get_monotonic_time-in-io_err_stat-cod.patch @@ -0,0 +1,111 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 14 Jan 2021 20:20:25 -0600 +Subject: [PATCH] multipathd: use get_monotonic_time() in io_err_stat code + +Instead of calling clock_gettime(), and dealing with failure +conditions, just call get_monotonic_time(). + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/io_err_stat.c | 34 +++++++++++----------------------- + 1 file changed, 11 insertions(+), 23 deletions(-) + +diff --git a/libmultipath/io_err_stat.c b/libmultipath/io_err_stat.c +index 775e7259..92871f40 100644 +--- a/libmultipath/io_err_stat.c ++++ b/libmultipath/io_err_stat.c +@@ -295,8 +295,7 @@ int io_err_stat_handle_pathfail(struct path *path) + * the repeated count threshold and time frame, we assume a path + * which fails at least twice within 60 seconds is flaky. + */ +- if (clock_gettime(CLOCK_MONOTONIC, &curr_time) != 0) +- return 1; ++ get_monotonic_time(&curr_time); + if (path->io_err_pathfail_cnt == 0) { + path->io_err_pathfail_cnt++; + path->io_err_pathfail_starttime = curr_time.tv_sec; +@@ -352,9 +351,9 @@ int need_io_err_check(struct path *pp) + } + if (pp->io_err_pathfail_cnt != PATH_IO_ERR_WAITING_TO_CHECK) + return 1; +- if (clock_gettime(CLOCK_MONOTONIC, &curr_time) != 0 || +- (curr_time.tv_sec - pp->io_err_dis_reinstate_time) > +- pp->mpp->marginal_path_err_recheck_gap_time) { ++ get_monotonic_time(&curr_time); ++ if ((curr_time.tv_sec - pp->io_err_dis_reinstate_time) > ++ pp->mpp->marginal_path_err_recheck_gap_time) { + io_err_stat_log(4, "%s: reschedule checking after %d seconds", + pp->dev, + pp->mpp->marginal_path_err_recheck_gap_time); +@@ -400,8 +399,7 @@ static int io_err_stat_time_up(struct io_err_stat_path *pp) + { + struct timespec currtime, difftime; + +- if (clock_gettime(CLOCK_MONOTONIC, &currtime) != 0) +- return 0; ++ get_monotonic_time(&currtime); + timespecsub(&currtime, &pp->start_time, &difftime); + if (difftime.tv_sec < pp->total_time) + return 0; +@@ -414,8 +412,7 @@ static void end_io_err_stat(struct io_err_stat_path *pp) + struct path *path; + double err_rate; + +- if (clock_gettime(CLOCK_MONOTONIC, &currtime) != 0) +- currtime = pp->start_time; ++ get_monotonic_time(&currtime); + + io_err_stat_log(4, "%s: check end", pp->devname); + +@@ -464,11 +461,7 @@ static int send_each_async_io(struct dio_ctx *ct, int fd, char *dev) + ct->io_starttime.tv_sec == 0) { + struct iocb *ios[1] = { &ct->io }; + +- if (clock_gettime(CLOCK_MONOTONIC, &ct->io_starttime) != 0) { +- ct->io_starttime.tv_sec = 0; +- ct->io_starttime.tv_nsec = 0; +- return rc; +- } ++ get_monotonic_time(&ct->io_starttime); + io_prep_pread(&ct->io, fd, ct->buf, ct->blksize, 0); + if (io_submit(ioctx, 1, ios) != 1) { + io_err_stat_log(5, "%s: io_submit error %i", +@@ -487,8 +480,7 @@ static void send_batch_async_ios(struct io_err_stat_path *pp) + struct dio_ctx *ct; + struct timespec currtime, difftime; + +- if (clock_gettime(CLOCK_MONOTONIC, &currtime) != 0) +- return; ++ get_monotonic_time(&currtime); + /* + * Give a free time for all IO to complete or timeout + */ +@@ -503,11 +495,8 @@ static void send_batch_async_ios(struct io_err_stat_path *pp) + if (!send_each_async_io(ct, pp->fd, pp->devname)) + pp->io_nr++; + } +- if (pp->start_time.tv_sec == 0 && pp->start_time.tv_nsec == 0 && +- clock_gettime(CLOCK_MONOTONIC, &pp->start_time)) { +- pp->start_time.tv_sec = 0; +- pp->start_time.tv_nsec = 0; +- } ++ if (pp->start_time.tv_sec == 0 && pp->start_time.tv_nsec == 0) ++ get_monotonic_time(&pp->start_time); + } + + static int try_to_cancel_timeout_io(struct dio_ctx *ct, struct timespec *t, +@@ -546,8 +535,7 @@ static void poll_async_io_timeout(void) + int rc = PATH_UNCHECKED; + int i, j; + +- if (clock_gettime(CLOCK_MONOTONIC, &curr_time) != 0) +- return; ++ get_monotonic_time(&curr_time); + vector_foreach_slot(io_err_pathvec, pp, i) { + for (j = 0; j < CONCUR_NR_EVENT; j++) { + rc = try_to_cancel_timeout_io(pp->dio_ctx_array + j, +-- +2.17.2 + diff --git a/0101-multipathd-combine-free_io_err_stat_path-and-destroy.patch b/0101-multipathd-combine-free_io_err_stat_path-and-destroy.patch new file mode 100644 index 0000000..90fd516 --- /dev/null +++ b/0101-multipathd-combine-free_io_err_stat_path-and-destroy.patch @@ -0,0 +1,101 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 14 Jan 2021 20:20:26 -0600 +Subject: [PATCH] multipathd: combine free_io_err_stat_path and + destroy_directio_ctx + +destroy_directio_ctx() is only called from free_io_err_stat_path(), and +free_io_err_stat_path() is very short, so combine them. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/io_err_stat.c | 24 ++++++++++-------------- + 1 file changed, 10 insertions(+), 14 deletions(-) + +diff --git a/libmultipath/io_err_stat.c b/libmultipath/io_err_stat.c +index 92871f40..bf78a236 100644 +--- a/libmultipath/io_err_stat.c ++++ b/libmultipath/io_err_stat.c +@@ -161,12 +161,15 @@ fail_close: + return 1; + } + +-static void destroy_directio_ctx(struct io_err_stat_path *p) ++static void free_io_err_stat_path(struct io_err_stat_path *p) + { + int i; + +- if (!p || !p->dio_ctx_array) ++ if (!p) + return; ++ if (!p->dio_ctx_array) ++ goto free_path; ++ + cancel_inflight_io(p); + + for (i = 0; i < CONCUR_NR_EVENT; i++) +@@ -175,6 +178,8 @@ static void destroy_directio_ctx(struct io_err_stat_path *p) + + if (p->fd > 0) + close(p->fd); ++free_path: ++ FREE(p); + } + + static struct io_err_stat_path *alloc_io_err_stat_path(void) +@@ -197,11 +202,6 @@ static struct io_err_stat_path *alloc_io_err_stat_path(void) + return p; + } + +-static void free_io_err_stat_path(struct io_err_stat_path *p) +-{ +- FREE(p); +-} +- + static void free_io_err_pathvec(void) + { + struct io_err_stat_path *path; +@@ -211,10 +211,8 @@ static void free_io_err_pathvec(void) + pthread_cleanup_push(cleanup_mutex, &io_err_pathvec_lock); + if (!io_err_pathvec) + goto out; +- vector_foreach_slot(io_err_pathvec, path, i) { +- destroy_directio_ctx(path); ++ vector_foreach_slot(io_err_pathvec, path, i) + free_io_err_stat_path(path); +- } + vector_free(io_err_pathvec); + io_err_pathvec = NULL; + out: +@@ -250,7 +248,7 @@ static int enqueue_io_err_stat_by_path(struct path *path) + goto free_ioerr_path; + pthread_mutex_lock(&io_err_pathvec_lock); + if (!vector_alloc_slot(io_err_pathvec)) +- goto unlock_destroy; ++ goto unlock_pathvec; + vector_set_slot(io_err_pathvec, p); + pthread_mutex_unlock(&io_err_pathvec_lock); + +@@ -258,9 +256,8 @@ static int enqueue_io_err_stat_by_path(struct path *path) + path->mpp->alias, path->dev); + return 0; + +-unlock_destroy: ++unlock_pathvec: + pthread_mutex_unlock(&io_err_pathvec_lock); +- destroy_directio_ctx(p); + free_ioerr_path: + free_io_err_stat_path(p); + +@@ -637,7 +634,6 @@ static void service_paths(void) + vector_foreach_slot_backwards(tmp_pathvec, pp, i) { + end_io_err_stat(pp); + vector_del_slot(tmp_pathvec, i); +- destroy_directio_ctx(pp); + free_io_err_stat_path(pp); + } + vector_reset(tmp_pathvec); +-- +2.17.2 + diff --git a/0102-multipathd-cleanup-logging-for-marginal-paths.patch b/0102-multipathd-cleanup-logging-for-marginal-paths.patch new file mode 100644 index 0000000..79ad137 --- /dev/null +++ b/0102-multipathd-cleanup-logging-for-marginal-paths.patch @@ -0,0 +1,123 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 18 Jan 2021 22:46:04 -0600 +Subject: [PATCH] multipathd: cleanup logging for marginal paths + +io_err_stat logged at level 2 whenever it enqueued a path to check, +which could happen multiple times while a path was marginal. On the +other hand if marginal_pathgroups wasn't set, multipathd didn't log when +paths were set to marginal. Now io_err_stat only logs at level 2 when +something unexpected happens, but multipathd will always log when a +path switches its marginal state. + +This patch also fixes an issue where paths in the delayed state could +get set to the pending state if they could not be checked in time. +Aside from going against the idea the paths should not be set to pending +if they already have a valid state, this caused multipathd to log a +message whenever the path state switched to from delayed to pending and +then back. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/io_err_stat.c | 7 +++---- + multipathd/main.c | 25 ++++++++++++++----------- + 2 files changed, 17 insertions(+), 15 deletions(-) + +diff --git a/libmultipath/io_err_stat.c b/libmultipath/io_err_stat.c +index bf78a236..abdd0b4f 100644 +--- a/libmultipath/io_err_stat.c ++++ b/libmultipath/io_err_stat.c +@@ -252,7 +252,7 @@ static int enqueue_io_err_stat_by_path(struct path *path) + vector_set_slot(io_err_pathvec, p); + pthread_mutex_unlock(&io_err_pathvec_lock); + +- io_err_stat_log(2, "%s: enqueue path %s to check", ++ io_err_stat_log(3, "%s: enqueue path %s to check", + path->mpp->alias, path->dev); + return 0; + +@@ -343,7 +343,7 @@ int need_io_err_check(struct path *pp) + if (uatomic_read(&io_err_thread_running) == 0) + return 0; + if (count_active_paths(pp->mpp) <= 0) { +- io_err_stat_log(2, "%s: recover path early", pp->dev); ++ io_err_stat_log(2, "%s: no paths. recovering early", pp->dev); + goto recover; + } + if (pp->io_err_pathfail_cnt != PATH_IO_ERR_WAITING_TO_CHECK) +@@ -361,8 +361,7 @@ int need_io_err_check(struct path *pp) + * Or else, return 1 to set path state to PATH_SHAKY + */ + if (r == 1) { +- io_err_stat_log(3, "%s: enqueue fails, to recover", +- pp->dev); ++ io_err_stat_log(2, "%s: enqueue failed. recovering early", pp->dev); + goto recover; + } else + pp->io_err_pathfail_cnt = PATH_IO_ERR_IN_CHECKING; +diff --git a/multipathd/main.c b/multipathd/main.c +index 92c45d44..99a89a69 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -2132,8 +2132,8 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) + pathinfo(pp, conf, 0); + pthread_cleanup_pop(1); + return 1; +- } else if ((newstate != PATH_UP && newstate != PATH_GHOST) && +- (pp->state == PATH_DELAYED)) { ++ } else if ((newstate != PATH_UP && newstate != PATH_GHOST && ++ newstate != PATH_PENDING) && (pp->state == PATH_DELAYED)) { + /* If path state become failed again cancel path delay state */ + pp->state = newstate; + /* +@@ -2200,8 +2200,9 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) + if ((newstate == PATH_UP || newstate == PATH_GHOST) && + (san_path_check_enabled(pp->mpp) || + marginal_path_check_enabled(pp->mpp))) { +- int was_marginal = pp->marginal; + if (should_skip_path(pp)) { ++ if (!pp->marginal && pp->state != PATH_DELAYED) ++ condlog(2, "%s: path is now marginal", pp->dev); + if (!marginal_pathgroups) { + if (marginal_path_check_enabled(pp->mpp)) + /* to reschedule as soon as possible, +@@ -2211,13 +2212,18 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) + pp->state = PATH_DELAYED; + return 1; + } +- if (!was_marginal) { ++ if (!pp->marginal) { + pp->marginal = 1; + marginal_changed = 1; + } +- } else if (marginal_pathgroups && was_marginal) { +- pp->marginal = 0; +- marginal_changed = 1; ++ } else { ++ if (pp->marginal || pp->state == PATH_DELAYED) ++ condlog(2, "%s: path is no longer marginal", ++ pp->dev); ++ if (marginal_pathgroups && pp->marginal) { ++ pp->marginal = 0; ++ marginal_changed = 1; ++ } + } + } + +@@ -2343,11 +2349,8 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) + */ + condlog(4, "path prio refresh"); + +- if (marginal_changed) { +- condlog(2, "%s: path is %s marginal", pp->dev, +- (pp->marginal)? "now" : "no longer"); ++ if (marginal_changed) + reload_and_sync_map(pp->mpp, vecs, 1); +- } + else if (update_prio(pp, new_path_up) && + (pp->mpp->pgpolicyfn == (pgpolicyfn *)group_by_prio) && + pp->mpp->pgfailback == -FAILBACK_IMMEDIATE) { +-- +2.17.2 + diff --git a/0059-RH-fixup-udev-rules-for-redhat.patch b/0103-RH-fixup-udev-rules-for-redhat.patch similarity index 98% rename from 0059-RH-fixup-udev-rules-for-redhat.patch rename to 0103-RH-fixup-udev-rules-for-redhat.patch index b1f5beb..d5bbd5b 100644 --- a/0059-RH-fixup-udev-rules-for-redhat.patch +++ b/0103-RH-fixup-udev-rules-for-redhat.patch @@ -15,7 +15,7 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 8ea3352d..873fb62f 100644 +index 05429307..24e943d5 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -53,7 +53,7 @@ endif diff --git a/0060-RH-Remove-the-property-blacklist-exception-builtin.patch b/0104-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 78% rename from 0060-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0104-RH-Remove-the-property-blacklist-exception-builtin.patch index f760f87..9c44867 100644 --- a/0060-RH-Remove-the-property-blacklist-exception-builtin.patch +++ b/0104-RH-Remove-the-property-blacklist-exception-builtin.patch @@ -13,29 +13,26 @@ it. Signed-off-by: Benjamin Marzinski --- - libmultipath/blacklist.c | 9 ++------- + libmultipath/blacklist.c | 6 ++---- multipath/multipath.conf.5 | 11 ++++++----- - tests/blacklist.c | 6 ++---- - 3 files changed, 10 insertions(+), 16 deletions(-) + tests/blacklist.c | 7 ++----- + 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c -index db58ccca..0c58aa32 100644 +index 6c6a5979..785f5ee9 100644 --- a/libmultipath/blacklist.c +++ b/libmultipath/blacklist.c -@@ -187,12 +187,6 @@ setup_default_blist (struct config * conf) - if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT)) +@@ -201,9 +201,6 @@ setup_default_blist (struct config * conf) + if (store_ble(conf->blist_devnode, "!^(sd[a-z]|dasd[a-z]|nvme[0-9])", ORIGIN_DEFAULT)) return 1; -- str = STRDUP("(SCSI_IDENT_|ID_WWN)"); -- if (!str) -- return 1; -- if (store_ble(conf->elist_property, str, ORIGIN_DEFAULT)) +- if (store_ble(conf->elist_property, "(SCSI_IDENT_|ID_WWN)", ORIGIN_DEFAULT)) - return 1; - vector_foreach_slot (conf->hwtable, hwe, i) { if (hwe->bl_product) { if (find_blacklist_device(conf->blist_device, -@@ -394,7 +388,8 @@ filter_property(struct config *conf, struct udev_device *udev, int lvl, +@@ -407,7 +404,8 @@ filter_property(const struct config *conf, struct udev_device *udev, *uid_attribute != '\0'; bool uid_attr_seen = false; @@ -46,10 +43,10 @@ index db58ccca..0c58aa32 100644 udev_device_get_properties_list_entry(udev)) { diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 5adaced6..42a192f6 100644 +index 8ef3a747..1e95a854 100644 --- a/multipath/multipath.conf.5 +++ b/multipath/multipath.conf.5 -@@ -1296,9 +1296,14 @@ keywords. Both are regular expressions. For a full description of these keywords +@@ -1333,9 +1333,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, @@ -65,7 +62,7 @@ index 5adaced6..42a192f6 100644 . .RS .PP -@@ -1309,10 +1314,6 @@ Blacklisting by missing properties is only applied to devices which do have the +@@ -1346,10 +1351,6 @@ Blacklisting by missing properties is only applied to devices which do have the property specified by \fIuid_attribute\fR (e.g. \fIID_SERIAL\fR) set. Previously, it was applied to every device, possibly causing devices to be blacklisted because of temporary I/O error conditions. @@ -77,19 +74,21 @@ index 5adaced6..42a192f6 100644 .TP .B protocol diff --git a/tests/blacklist.c b/tests/blacklist.c -index d5c40898..d20e97af 100644 +index 0b42e255..4d595eda 100644 --- a/tests/blacklist.c +++ b/tests/blacklist.c -@@ -380,7 +380,7 @@ static void test_property_missing(void **state) +@@ -375,9 +375,8 @@ static void test_property_missing(void **state) + { + static struct udev_device udev = { "sdb", { "ID_FOO", "ID_BAZ", "ID_BAR", "ID_SERIAL", NULL } }; conf.blist_property = blist_property_wwn; - expect_condlog(3, "sdb: blacklisted, udev property missing\n"); +- expect_condlog(3, "sdb: blacklisted, udev property missing\n"); assert_int_equal(filter_property(&conf, &udev, 3, "ID_SERIAL"), - MATCH_PROPERTY_BLIST_MISSING); + MATCH_NOTHING); assert_int_equal(filter_property(&conf, &udev, 3, "ID_BLAH"), MATCH_NOTHING); assert_int_equal(filter_property(&conf, &udev, 3, ""), -@@ -472,9 +472,7 @@ static void test_filter_path_missing1(void **state) +@@ -469,9 +468,7 @@ static void test_filter_path_missing1(void **state) conf.blist_device = blist_device_foo_bar; conf.blist_protocol = blist_protocol_fcp; conf.blist_wwid = blist_wwid_xyzzy; diff --git a/0061-RH-don-t-start-without-a-config-file.patch b/0105-RH-don-t-start-without-a-config-file.patch similarity index 85% rename from 0061-RH-don-t-start-without-a-config-file.patch rename to 0105-RH-don-t-start-without-a-config-file.patch index 4712300..2f8d791 100644 --- a/0061-RH-don-t-start-without-a-config-file.patch +++ b/0105-RH-don-t-start-without-a-config-file.patch @@ -12,26 +12,18 @@ simple way to disable multipath. Simply removing or renaming Signed-off-by: Benjamin Marzinski --- - libmultipath/config.c | 15 +++++++++++++++ + libmultipath/config.c | 13 +++++++++++++ libmultipath/config.h | 1 + multipath/multipath.rules | 1 + multipathd/multipathd.8 | 2 ++ multipathd/multipathd.service | 1 + - 5 files changed, 20 insertions(+) + 5 files changed, 18 insertions(+) diff --git a/libmultipath/config.c b/libmultipath/config.c -index 658bec8b..1c02e230 100644 +index be310159..8d291491 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c -@@ -26,6 +26,7 @@ - #include "devmapper.h" - #include "mpath_cmd.h" - #include "propsel.h" -+#include "version.h" - - static int - hwe_strmatch (const struct hwentry *hwe1, const struct hwentry *hwe2) -@@ -778,6 +779,20 @@ load_config (char * file) +@@ -893,6 +893,19 @@ int _init_config (const char *file, struct config *conf) goto out; } factorize_hwtable(conf->hwtable, builtin_hwtable_size, file); @@ -44,8 +36,7 @@ index 658bec8b..1c02e230 100644 + goto out; + } + } -+ if (store_ble(conf->blist_devnode, strdup(".*"), -+ ORIGIN_NO_CONFIG)) { ++ if (store_ble(conf->blist_devnode, ".*", ORIGIN_NO_CONFIG)) { + condlog(0, "cannot store default no-config blacklist\n"); + goto out; + } @@ -53,7 +44,7 @@ index 658bec8b..1c02e230 100644 conf->processed_main_config = 1; diff --git a/libmultipath/config.h b/libmultipath/config.h -index 92c61a0d..160867cd 100644 +index 9ce37f16..7f8d9cd0 100644 --- a/libmultipath/config.h +++ b/libmultipath/config.h @@ -9,6 +9,7 @@ @@ -62,8 +53,8 @@ index 92c61a0d..160867cd 100644 #define ORIGIN_CONFIG 1 +#define ORIGIN_NO_CONFIG 2 - /* - * In kernel, fast_io_fail == 0 means immediate failure on rport delete. + enum devtypes { + DEV_NONE, diff --git a/multipath/multipath.rules b/multipath/multipath.rules index 9df11a95..0486bf70 100644 --- a/multipath/multipath.rules diff --git a/0067-RH-Fix-nvme-compilation-warning.patch b/0106-RH-Fix-nvme-function-missing-argument.patch similarity index 82% rename from 0067-RH-Fix-nvme-compilation-warning.patch rename to 0106-RH-Fix-nvme-function-missing-argument.patch index fc6ccd7..b5c63c0 100644 --- a/0067-RH-Fix-nvme-compilation-warning.patch +++ b/0106-RH-Fix-nvme-function-missing-argument.patch @@ -1,7 +1,10 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Fri, 25 Jan 2019 14:54:56 -0600 -Subject: [PATCH] RH: Fix nvme compilation warning +Subject: [PATCH] RH: Fix nvme function missing argument + +A future patch will change the compilation options to error when +function declarations have unspecified arguments. Signed-off-by: Benjamin Marzinski --- diff --git a/0062-RH-use-rpm-optflags-if-present.patch b/0107-RH-use-rpm-optflags-if-present.patch similarity index 92% rename from 0062-RH-use-rpm-optflags-if-present.patch rename to 0107-RH-use-rpm-optflags-if-present.patch index d6c97c1..f765f47 100644 --- a/0062-RH-use-rpm-optflags-if-present.patch +++ b/0107-RH-use-rpm-optflags-if-present.patch @@ -13,10 +13,10 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 873fb62f..479523bc 100644 +index 24e943d5..e978d306 100644 --- a/Makefile.inc +++ b/Makefile.inc -@@ -89,15 +89,27 @@ TEST_CC_OPTION = $(shell \ +@@ -90,15 +90,27 @@ TEST_CC_OPTION = $(shell \ echo "$(2)"; \ fi) @@ -46,10 +46,10 @@ index 873fb62f..479523bc 100644 -CPPFLAGS := -Wp,-D_FORTIFY_SOURCE=2 + $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) \ + -Wstrict-prototypes - CFLAGS := $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ + CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ -DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" \ -MMD -MP -@@ -135,4 +147,4 @@ check_file = $(shell \ +@@ -136,4 +148,4 @@ check_file = $(shell \ %.o: %.c @echo building $@ because of $? diff --git a/0063-RH-add-mpathconf.patch b/0108-RH-add-mpathconf.patch similarity index 94% rename from 0063-RH-add-mpathconf.patch rename to 0108-RH-add-mpathconf.patch index 6480711..503fef2 100644 --- a/0063-RH-add-mpathconf.patch +++ b/0108-RH-add-mpathconf.patch @@ -14,17 +14,17 @@ Signed-off-by: Benjamin Marzinski --- libmultipath/config.c | 2 + multipath/Makefile | 5 + - multipath/mpathconf | 565 ++++++++++++++++++++++++++++++++++++++++++ + multipath/mpathconf | 555 ++++++++++++++++++++++++++++++++++++++++++ multipath/mpathconf.8 | 135 ++++++++++ - 4 files changed, 707 insertions(+) + 4 files changed, 697 insertions(+) create mode 100644 multipath/mpathconf create mode 100644 multipath/mpathconf.8 diff --git a/libmultipath/config.c b/libmultipath/config.c -index 1c02e230..a253a936 100644 +index 8d291491..bbdd1617 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c -@@ -781,6 +781,8 @@ load_config (char * file) +@@ -895,6 +895,8 @@ int _init_config (const char *file, struct config *conf) factorize_hwtable(conf->hwtable, builtin_hwtable_size, file); } else { condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices."); @@ -69,10 +69,10 @@ index b9bbb3cf..e720c7f6 100644 $(RM) core *.o $(EXEC) *.gz diff --git a/multipath/mpathconf b/multipath/mpathconf new file mode 100644 -index 00000000..f0d09cbb +index 00000000..f34003c9 --- /dev/null +++ b/multipath/mpathconf -@@ -0,0 +1,565 @@ +@@ -0,0 +1,555 @@ +#!/bin/bash +# +# Copyright (C) 2010 Red Hat, Inc. All rights reserved. @@ -107,6 +107,11 @@ index 00000000..f0d09cbb +defaults { + user_friendly_names yes + find_multipaths yes ++ enable_foreign \"^$\" ++} ++ ++blacklist_exceptions { ++ property \"(SCSI_IDENT_|ID_WWN)\" +}" + +CONFIGFILE="/etc/multipath.conf" @@ -125,7 +130,7 @@ index 00000000..f0d09cbb + echo "Only allow certain wwids (instead of enable): --allow " + echo "Set user_friendly_names (Default y): --user_friendly_names " + echo "Set find_multipaths (Default y): --find_multipaths " -+ echo "Set default property blacklist (Default n): --property_blacklist " ++ echo "Set default property blacklist (Default y): --property_blacklist " + echo "Set enable_foreign to show foreign devices (Default n): --enable_foreign " + echo "Load the dm-multipath modules on enable (Default y): --with_module " + echo "start/stop/reload multipathd (Default n): --with_multipathd " @@ -283,13 +288,12 @@ index 00000000..f0d09cbb + +function validate_args +{ -+ if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$PROPERTY" -o -n "$MODULE" -o -n "$FOREIGN" ]; then ++ if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$PROPERTY" -o -n "$MODULE" ]; then + echo "ignoring extra parameters on disable" + FRIENDLY="" + FIND="" + PROPERTY="" + MODULE="" -+ FOREIGN="" + fi + if [ -n "$FRIENDLY" ] && [ "$FRIENDLY" != "y" -a "$FRIENDLY" != "n" ]; then + echo "--user_friendly_names must be either 'y' or 'n'" @@ -307,7 +311,7 @@ index 00000000..f0d09cbb + echo "--enable_foreign must be either 'y' or 'n'" + exit 1 + fi -+ if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" -a -z "$PROPERTY" -a -z "$FOREIGN" ]; then ++ if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" -a -z "$PROPERTY" ]; then + SHOW_STATUS=1 + fi + if [ -n "$MODULE" ] && [ "$MODULE" != "y" -a "$MODULE" != "n" ]; then @@ -412,12 +416,8 @@ index 00000000..f0d09cbb + HAVE_FOREIGN=0 + elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]]*\"\^\$\"" ; then + HAVE_FOREIGN=1 -+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]]*\"NONE\"" ; then -+ HAVE_FOREIGN=1 -+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]] \"\.\?\*\"" ; then -+ HAVE_FOREIGN=2 + elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign" ; then -+ HAVE_FOREIGN=3 ++ HAVE_FOREIGN=2 + fi +fi + @@ -451,11 +451,9 @@ index 00000000..f0d09cbb + echo "default property blacklist is enabled" + fi + if [ -z "$HAVE_FOREIGN" -o "$HAVE_FOREIGN" = 0 ]; then -+ echo "enable_foreign is not set (no foreign multipath devices will be shown)" ++ echo "enable_foreign is not set (all foreign multipath devices will be shown)" + elif [ "$HAVE_FOREIGN" = 1 ]; then + echo "enable_foreign is set (no foreign multipath devices will be shown)" -+ elif [ "$HAVE_FOREIGN" = 2 ]; then -+ echo "enable_foreign is set (all foreign multipath devices will be shown)" + else + echo "enable_foreign is set (foreign multipath devices may not be shown)" + fi @@ -572,15 +570,7 @@ index 00000000..f0d09cbb + CHANGED_CONFIG=1 + fi +elif [ "$PROPERTY" = "y" ]; then -+ if [ -z "$HAVE_PROPERTY" -a -z "$HAVE_EXCEPTIONS" ]; then -+ cat >> $TMPFILE << _EOF_ -+ -+blacklist_exceptions { -+ property "(SCSI_IDENT_|ID_WWN)" -+} -+_EOF_ -+ CHANGED_CONFIG=1 -+ elif [ -z "$HAVE_PROPERTY" ]; then ++ if [ -z "$HAVE_PROPERTY" ]; then + sed -i '/^blacklist_exceptions[[:space:]]*{/ a\ + property "(SCSI_IDENT_|ID_WWN)" +' $TMPFILE @@ -592,18 +582,18 @@ index 00000000..f0d09cbb +fi + +if [ "$FOREIGN" = "y" ]; then -+ if [ -z "$HAVE_FOREIGN" ]; then -+ sed -i '/^defaults[[:space:]]*{/ a\ -+ enable_foreign ".*" -+' $TMPFILE -+ CHANGED_CONFIG=1 -+ elif [ "$HAVE_FOREIGN" = 0 -o "$HAVE_FOREIGN" = 1 -o "$HAVE_FOREIGN" = 3 ]; then -+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*#\?[[:space:]]*enable_foreign.*$/ enable_foreign ".*"/' $TMPFILE ++ if [ "$HAVE_FOREIGN" = 1 -o "$HAVE_FOREIGN" = 2 ]; then ++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*enable_foreign/# enable_foreign/' $TMPFILE + CHANGED_CONFIG=1 + fi +elif [ "$FOREIGN" = "n" ]; then -+ if [ "$HAVE_FOREIGN" = 2 -o "$HAVE_FOREIGN" = 3 ]; then -+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*enable_foreign/# enable_foreign/' $TMPFILE ++ if [ -z "$HAVE_FOREIGN" ]; then ++ sed -i '/^defaults[[:space:]]*{/ a\ ++ enable_foreign "^$" ++' $TMPFILE ++ CHANGED_CONFIG=1 ++ elif [ "$HAVE_FOREIGN" = 0 -o "$HAVE_FOREIGN" = 2 ]; then ++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*#\?[[:space:]]*enable_foreign.*$/ enable_foreign "^$"/' $TMPFILE + CHANGED_CONFIG=1 + fi +fi diff --git a/0064-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0109-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 78% rename from 0064-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0109-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch index 0b95ee6..cdce408 100644 --- a/0064-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +++ b/0109-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch @@ -14,23 +14,38 @@ multipathd.service Signed-off-by: Benjamin Marzinski --- - libmultipath/wwids.c | 44 +++++++++++++++++++++++++++++++++++ - libmultipath/wwids.h | 1 + - multipath/main.c | 10 ++++++-- - multipath/multipath.8 | 7 +++++- + multipath/main.c | 54 +++++++++++++++++++++++++++++++++-- + multipath/multipath.8 | 7 ++++- multipathd/multipathd.service | 1 + - 5 files changed, 60 insertions(+), 3 deletions(-) + 3 files changed, 59 insertions(+), 3 deletions(-) -diff --git a/libmultipath/wwids.c b/libmultipath/wwids.c -index 61d9c39e..c7a16636 100644 ---- a/libmultipath/wwids.c -+++ b/libmultipath/wwids.c -@@ -451,3 +451,47 @@ int unmark_failed_wwid(const char *wwid) - print_failed_wwid_result("unmark_failed", wwid, r); - return r; +diff --git a/multipath/main.c b/multipath/main.c +index 9ac42869..beaac3ca 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -122,7 +122,7 @@ usage (char * progname) + fprintf (stderr, " %s [-v level] [-R retries] -F\n", progname); + fprintf (stderr, " %s [-v level] [-l|-ll] [device]\n", progname); + fprintf (stderr, " %s [-v level] [-a|-w] device\n", progname); +- fprintf (stderr, " %s [-v level] -W\n", progname); ++ fprintf (stderr, " %s [-v level] [-A|-W]\n", progname); + fprintf (stderr, " %s [-v level] [-i] [-c|-C] device\n", progname); + fprintf (stderr, " %s [-v level] [-i] [-u|-U]\n", progname); + fprintf (stderr, " %s [-h|-t|-T]\n", progname); +@@ -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" ++ " -A add devices from kernel command line mpath.wwids\n" ++ " parameters to wwids file\n" + " -c check if a device should be a path in a multipath device\n" + " -C check if a multipath device has usable paths\n" + " -q allow queue_if_no_path when multipathd is not running\n" +@@ -452,6 +454,50 @@ static void cleanup_vecs(void) + free_pathvec(vecs.pathvec, FREE_PATHS); } -+ -+int remember_cmdline_wwid(void) + ++static int remember_cmdline_wwid(void) +{ + FILE *f = NULL; + char buf[LINE_MAX], *next, *ptr; @@ -73,42 +88,12 @@ index 61d9c39e..c7a16636 100644 + } + return ret; +} -diff --git a/libmultipath/wwids.h b/libmultipath/wwids.h -index 0c6ee54d..e32a0b0e 100644 ---- a/libmultipath/wwids.h -+++ b/libmultipath/wwids.h -@@ -17,6 +17,7 @@ int remember_wwid(char *wwid); - int check_wwids_file(char *wwid, int write_wwid); - int remove_wwid(char *wwid); - int replace_wwids(vector mp); -+int remember_cmdline_wwid(void); - - enum { - WWID_IS_NOT_FAILED = 0, -diff --git a/multipath/main.c b/multipath/main.c -index 3da692dc..ce48a932 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -135,7 +135,7 @@ usage (char * progname) - fprintf (stderr, " %s [-v level] [-R retries] -F\n", progname); - fprintf (stderr, " %s [-v level] [-l|-ll] [device]\n", progname); - fprintf (stderr, " %s [-v level] [-a|-w] device\n", progname); -- fprintf (stderr, " %s [-v level] -W\n", progname); -+ fprintf (stderr, " %s [-v level] [-A|-W]\n", progname); - fprintf (stderr, " %s [-v level] [-i] [-c|-C] device\n", progname); - fprintf (stderr, " %s [-v level] [-i] [-u|-U]\n", progname); - fprintf (stderr, " %s [-h|-t|-T]\n", progname); -@@ -149,6 +149,8 @@ usage (char * progname) - " -f flush a multipath device map\n" - " -F flush all multipath device maps\n" - " -a add a device wwid to the wwids file\n" -+ " -A add devices from kernel command line mpath.wwids\n" -+ " parameters to wwids file\n" - " -c check if a device should be a path in a multipath device\n" - " -C check if a multipath device has usable paths\n" - " -q allow queue_if_no_path when multipathd is not running\n" -@@ -896,7 +898,7 @@ main (int argc, char *argv[]) - multipath_conf = conf; ++ + static int + configure (struct config *conf, enum mpath_cmds cmd, + enum devtypes dev_type, char *devpath) +@@ -825,7 +871,7 @@ main (int argc, char *argv[]) + conf = get_multipath_config(); conf->retrigger_tries = 0; conf->force_sync = 1; - while ((arg = getopt(argc, argv, ":adDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { @@ -116,7 +101,7 @@ index 3da692dc..ce48a932 100644 switch(arg) { case 1: printf("optarg : %s\n",optarg); break; -@@ -973,6 +975,10 @@ main (int argc, char *argv[]) +@@ -902,6 +948,10 @@ main (int argc, char *argv[]) case 'T': cmd = CMD_DUMP_CONFIG; break; diff --git a/0066-RH-reset-default-find_mutipaths-value-to-off.patch b/0110-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 95% rename from 0066-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0110-RH-reset-default-find_mutipaths-value-to-off.patch index 2dfb52e..304db61 100644 --- a/0066-RH-reset-default-find_mutipaths-value-to-off.patch +++ b/0110-RH-reset-default-find_mutipaths-value-to-off.patch @@ -12,10 +12,10 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h -index 01a501bd..984d8dd8 100644 +index 947ba467..518d0b16 100644 --- a/libmultipath/defaults.h +++ b/libmultipath/defaults.h -@@ -22,7 +22,7 @@ +@@ -23,7 +23,7 @@ #define DEFAULT_NO_PATH_RETRY NO_PATH_RETRY_UNDEF #define DEFAULT_VERBOSITY 2 #define DEFAULT_REASSIGN_MAPS 0 diff --git a/0068-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0111-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 100% rename from 0068-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0111-RH-attempt-to-get-ANA-info-via-sysfs-first.patch diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 053e0d3..89e05ac 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,102 +1,126 @@ Name: device-mapper-multipath -Version: 0.8.4 -Release: 7%{?dist} +Version: 0.8.5 +Release: 1%{?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.8.4;sf=tgz" -o multipath-tools-0.8.4.tgz +# curl -L https://github.com/opensvc/multipath-tools/archive/0.8.5.tar.gz -o multipath-tools-0.8.5.tgz Source0: multipath-tools-0.8.4.tgz Source1: multipath.conf -Patch0001: 0001-libmpathpersist-limit-PRIN-allocation-length-to-8192.patch -Patch0002: 0002-libmpathpersist-format_transportids-avoid-PROUT-over.patch -Patch0003: 0003-libmpathpersist-mpath_format_readfullstatus-use-real.patch -Patch0004: 0004-libmultipath-assign-variable-to-make-gcc-happy.patch -Patch0005: 0005-libmutipath-don-t-close-fd-on-dm_lib_release.patch -Patch0006: 0006-libmultipath-allow-force-reload-with-no-active-paths.patch -Patch0007: 0007-kpartx.rules-honor-DM_UDEV_DISABLE_OTHER_RULES_FLAG.patch -Patch0008: 0008-kpartx.rules-check-for-skip_kpartx-on-synthetic-ueve.patch -Patch0009: 0009-libmpathpersist-depend-on-libmultipath.patch -Patch0010: 0010-multipath-tools-Makefile-more-dependency-fixes-for-p.patch -Patch0011: 0011-multipath-tools-Makefile.inc-separate-out-OPTFLAGS.patch -Patch0012: 0012-multipath-tools-Makefile.inc-allow-user-settings-for.patch -Patch0013: 0013-multipath-tools-Makefile.inc-set-Wno-error-clobbered.patch -Patch0014: 0014-libmultipath-discovery.c-use-z-qualifier-for-size_t.patch -Patch0015: 0015-libmultipath-eliminate-more-signed-unsigned-comparis.patch -Patch0016: 0016-libmultipath-set_uint-fix-parsing-for-32bit.patch -Patch0017: 0017-multipath-tools-tests-Makefile-add-lmpathcmd-to-LIBD.patch -Patch0018: 0018-multipath-tools-tests-Makefile-Fix-OBJDEPS-for-hwtab.patch -Patch0019: 0019-multipath-tools-tests-test-lib.c-drop-__wrap_is_clai.patch -Patch0020: 0020-multipath-tools-tests-directio-fix-Wmaybe-uninitaliz.patch -Patch0021: 0021-libmultipath-move-libsg-into-libmultipath.patch -Patch0022: 0022-multipath-tools-Makefile-add-install-dependency.patch -Patch0023: 0023-libmultipath-make-libmp_dm_init-optional.patch -Patch0024: 0024-libmultipath-make-sysfs_is_multipathed-able-to-retur.patch -Patch0025: 0025-multipath-centralize-validation-code.patch -Patch0026: 0026-Unit-tests-for-is_path_valid.patch -Patch0027: 0027-libmultipath-simplify-failed-wwid-code.patch -Patch0028: 0028-libmultipath-use-atomic-linkat-in-mark_failed_wwid.patch -Patch0029: 0029-fix-boolean-value-with-json-c-0.14.patch -Patch0030: 0030-libmultipath-fix-condlog-NULL-argument-in-uevent_get.patch -Patch0031: 0031-libmultipath-set-enable_foreign-to-NONE-by-default.patch -Patch0032: 0032-multipath-add-e-option-to-enable-foreign-libraries.patch -Patch0033: 0033-libmultipath-remove-_blacklist_exceptions-functions.patch -Patch0034: 0034-libmultipath-fix-parser-issue-with-comments-in-strin.patch -Patch0035: 0035-libmultipath-invert-regexes-that-start-with-exclamat.patch -Patch0036: 0036-multipath-Fix-compiler-warnings-when-built-without-s.patch -Patch0037: 0037-libmultipath-fix-sysfs-dev_loss_tmo-parsing.patch -Patch0038: 0038-kpartx-read-devices-with-direct-IO.patch -Patch0039: 0039-kpartx-handle-alternate-bsd-disklabel-location.patch -Patch0040: 0040-libmultipath-fix-checker-detection-for-nvme-devices.patch -Patch0041: 0041-libmultipath-make-dm_get_map-status-return-codes-sym.patch -Patch0042: 0042-multipathd-fix-check_path-errors-with-removed-map.patch -Patch0043: 0043-libmultipath-make-dm_flush_maps-only-return-0-on-suc.patch -Patch0044: 0044-multipathd-add-del-maps-multipathd-command.patch -Patch0045: 0045-multipath-make-flushing-maps-work-like-other-command.patch -Patch0046: 0046-multipath-delegate-flushing-maps-to-multipathd.patch -Patch0047: 0047-multipath-add-option-to-skip-multipathd-delegation.patch -Patch0048: 0048-libmultipath-add-device-to-hwtable.c.patch -Patch0049: 0049-master-libmultipath-fix-use-after-free-when-iscsi-lo.patch -Patch0050: 0050-libmultipath-warn-if-freeing-path-that-holds-mpp-hwe.patch -Patch0051: 0051-libmultipath-warn-about-NULL-value-of-mpp-hwe.patch -Patch0052: 0052-libmultipath-fix-mpp-hwe-handling-in-sync_paths.patch -Patch0053: 0053-Makefile.inc-trim-extra-information-from-systemd-ver.patch -Patch0054: 0054-kpartx-fix-Wsign-compare-error.patch -Patch0055: 0055-libmultipath-remove-code-duplication-in-path-countin.patch -Patch0056: 0056-libmultipath-count-pending-paths-as-active-on-loads.patch -Patch0057: 0057-libmultipath-deal-with-flushing-no-maps.patch -Patch0058: 0058-multipath-deal-with-delegation-failures-correctly.patch -Patch0059: 0059-RH-fixup-udev-rules-for-redhat.patch -Patch0060: 0060-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0061: 0061-RH-don-t-start-without-a-config-file.patch -Patch0062: 0062-RH-use-rpm-optflags-if-present.patch -Patch0063: 0063-RH-add-mpathconf.patch -Patch0064: 0064-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0065: 0065-RH-warn-on-invalid-regex-instead-of-failing.patch -Patch0066: 0066-RH-reset-default-find_mutipaths-value-to-off.patch -Patch0067: 0067-RH-Fix-nvme-compilation-warning.patch -Patch0068: 0068-RH-attempt-to-get-ANA-info-via-sysfs-first.patch -Patch0069: 0069-RH-work-around-gcc-10-format-truncation-issue.patch -Patch0070: 0070-multipath-add-libmpathvalid-library.patch -Patch0071: 0071-libmultipath-add-uid-failback-for-dasd-devices.patch -Patch0072: 0072-libmultipath-add-ignore_udev_uid-option.patch -Patch0073: 0073-libmultipath-util-constify-function-arguments.patch -Patch0074: 0074-libmultipath-constify-file-argument-in-config-parser.patch -Patch0075: 0075-libmultipath-provide-defaults-for-get-put-_multipath.patch -Patch0076: 0076-libmpathpersist-allow-using-libmultipath-get-put-_mu.patch -Patch0077: 0077-multipath-use-get_put-_multipath_config-from-libmult.patch -Patch0078: 0078-mpathpersist-use-get-put-_multipath_config-from-libm.patch -Patch0079: 0079-libmultipath-add-udev-and-logsink-symbols.patch -Patch0080: 0080-multipath-remove-logsink-and-udev.patch -Patch0081: 0081-libmpathpersist-call-libmultipath_-init-exit.patch -Patch0082: 0082-mpathpersist-remove-logsink-and-udev.patch -Patch0083: 0083-multipathd-remove-logsink-and-udev.patch -Patch0084: 0084-libmpathvalid-use-default-_multipath_config-udev-and.patch -Patch0085: 0085-Revert-libmultipath-add-ignore_udev_uid-option.patch -Patch0086: 0086-libmultipath-change-log-level-for-null-uid_attribute.patch -Patch0087: 0087-libmultipath-orphan_paths-avoid-BUG-message.patch +Patch0001: 0001-Change-the-multipath.conf-manpage-uxsock_timeout-def.patch +Patch0002: 0002-libmultipath-find_mpe-don-t-match-with-empty-WWID.patch +Patch0003: 0003-libmultipath-copy-mpp-hwe-from-pp-hwe.patch +Patch0004: 0004-libmultipath-dm_map_present_by_uuid-fix-dm_task_crea.patch +Patch0005: 0005-libdmmp-tests-fix-compilation.patch +Patch0006: 0006-libmultipath-prio-constify-some-function-parameters.patch +Patch0007: 0007-libmultipath-checkers-prio-allow-non-lazy-.so-loadin.patch +Patch0008: 0008-multipath-tools-Makefiles-separate-rules-for-.so-and.patch +Patch0009: 0009-libmultipath-create-separate-.so-for-unit-tests.patch +Patch0010: 0010-libmultipath-add-linker-version-script.patch +Patch0011: 0011-libmpathpersist-add-linker-version-script.patch +Patch0012: 0012-libmpathcmd-add-linker-version-script.patch +Patch0013: 0013-libmpathpersist-initialize-mpp-hwe-in-get_mpvec.patch +Patch0014: 0014-multipathd-allow-shutdown-during-configure.patch +Patch0015: 0015-multipathd-avoid-sending-READY-1-to-systemd-on-early.patch +Patch0016: 0016-multipathd-send-STOPPING-1-to-systemd-on-shutdown.patch +Patch0017: 0017-multipathd-send-RELOADING-1-to-systemd-on-DAEMON_CON.patch +Patch0018: 0018-multipathd-use-volatile-qualifier-for-running_state.patch +Patch0019: 0019-multipathd-generalize-and-fix-wait_for_state_change_.patch +Patch0020: 0020-multipathd-set_config_state-avoid-code-duplication.patch +Patch0021: 0021-multipathd-cancel-threads-early-during-shutdown.patch +Patch0022: 0022-multipath-tools-don-t-call-dm_lib_release-any-more.patch +Patch0023: 0023-libmultipath-devmapper-refactor-libdm-version-determ.patch +Patch0024: 0024-libmultipath-protect-racy-libdevmapper-calls-with-a-.patch +Patch0025: 0025-libmultipath-constify-file-argument-in-config-parser.patch +Patch0026: 0026-libmultipath-provide-defaults-for-get-put-_multipath.patch +Patch0027: 0027-libmpathpersist-allow-using-libmultipath-get-put-_mu.patch +Patch0028: 0028-multipath-use-get_put-_multipath_config-from-libmult.patch +Patch0029: 0029-mpathpersist-use-get-put-_multipath_config-from-libm.patch +Patch0030: 0030-libmultipath-add-udev-and-logsink-symbols.patch +Patch0031: 0031-multipath-remove-logsink-and-udev.patch +Patch0032: 0032-libmpathpersist-call-libmultipath_-init-exit.patch +Patch0033: 0033-mpathpersist-remove-logsink-and-udev.patch +Patch0034: 0034-multipathd-remove-logsink-and-udev.patch +Patch0035: 0035-multipath-tools-add-Vexata-by-StorCentric-VX-arrays.patch +Patch0036: 0036-multipath-tools-Violin-and-Nexsan-were-bought-by-Sto.patch +Patch0037: 0037-libmultipath-fix-memory-leaks-in-coalesce_paths.patch +Patch0038: 0038-multipath-tools-replace-hidden-tab-by-space-in-hwtab.patch +Patch0039: 0039-multipathd-uxlsnr-avoid-deadlock-on-exit.patch +Patch0040: 0040-multipathd-Fix-liburcu-memory-leak.patch +Patch0041: 0041-multipathd-move-handling-of-io_err_stat_attr-into-li.patch +Patch0042: 0042-multipathd-move-vecs-desctruction-into-cleanup-funct.patch +Patch0043: 0043-multipathd-make-some-globals-static.patch +Patch0044: 0044-multipathd-move-threads-destruction-into-separate-fu.patch +Patch0045: 0045-multipathd-move-conf-destruction-into-separate-funct.patch +Patch0046: 0046-multipathd-move-pid-destruction-into-separate-functi.patch +Patch0047: 0047-multipathd-close-pidfile-on-exit.patch +Patch0048: 0048-multipathd-add-helper-for-systemd-notification-at-ex.patch +Patch0049: 0049-multipathd-child-call-cleanups-in-failure-case-too.patch +Patch0050: 0050-multipathd-unwatch_all_dmevents-check-if-waiter-is-i.patch +Patch0051: 0051-multipathd-print-error-message-if-config-can-t-be-lo.patch +Patch0052: 0052-libmultipath-add-libmp_dm_exit.patch +Patch0053: 0053-multipathd-fixup-libdm-deinitialization.patch +Patch0054: 0054-libmultipath-log_thread_stop-check-if-logarea-is-ini.patch +Patch0055: 0055-multipathd-add-cleanup_child-exit-handler.patch +Patch0056: 0056-libmultipath-fix-log_thread-startup-and-teardown.patch +Patch0057: 0057-multipathd-move-cleanup_-prio-checkers-foreign-to-li.patch +Patch0058: 0058-multipath-use-atexit-for-cleanup-handlers.patch +Patch0059: 0059-mpathpersist-use-atexit-for-cleanup-handlers.patch +Patch0060: 0060-multipath-fix-leak-in-check_path_valid.patch +Patch0061: 0061-multipath-tools-mpath-tools.supp-file-with-valgrind-.patch +Patch0062: 0062-libmultipath-use-libmp_verbosity-to-track-verbosity.patch +Patch0063: 0063-libmultipath-introduce-symbolic-values-for-logsink.patch +Patch0064: 0064-libmultipath-simplify-dlog.patch +Patch0065: 0065-multipathd-common-code-for-k-and-command-args.patch +Patch0066: 0066-multipathd-sanitize-uxsock_listen.patch +Patch0067: 0067-libmultipath-fix-race-between-log_safe-and-log_threa.patch +Patch0068: 0068-multipath-add-libmpathvalid-library.patch +Patch0069: 0069-multipath-tools-tests-and-unit-tests-for-libmpathval.patch +Patch0070: 0070-libmultipath-add-uid-failback-for-dasd-devices.patch +Patch0071: 0071-libmultipath-change-log-level-for-null-uid_attribute.patch +Patch0072: 0072-libmultipath-move-fast_io_fail-defines-to-structs.h.patch +Patch0073: 0073-libmultipath-add-eh_deadline-multipath.conf-paramete.patch +Patch0074: 0074-multipathd-remove-redundant-vector_free-int-configur.patch +Patch0075: 0075-libmultipath-factor-out-code-to-get-vpd-page-data.patch +Patch0076: 0076-libmultipath-limit-reading-0xc9-vpd-page.patch +Patch0077: 0077-libmultipath-move-logq_lock-handling-to-log.c.patch +Patch0078: 0078-libmultipath-protect-logarea-with-logq_lock.patch +Patch0079: 0079-libmultipath-prevent-DSO-unloading-with-astray-check.patch +Patch0080: 0080-libmultipath-force-map-reload-if-udev-incomplete.patch +Patch0081: 0081-multipath-tools-avoid-access-to-etc-localtime.patch +Patch0082: 0082-multipath-tools-make-sure-plugin-DSOs-use-symbol-ver.patch +Patch0083: 0083-libmultipath.version-add-missing-symbol.patch +Patch0084: 0084-multipath-tools-tests-unversioned-.so-for-valgrind-t.patch +Patch0085: 0085-multipath-tools-unit-tests-fix-memory-leaks-in-mpath.patch +Patch0086: 0086-mpathpersist-Fix-Register-and-Ignore-with-0x00-SARK.patch +Patch0087: 0087-mpathpersist-update-prkeys-file-on-changing-registra.patch +Patch0088: 0088-libmultipath-warn-about-missing-braces-at-end-of-mul.patch +Patch0089: 0089-libmultipath-ignore-multipaths-sections-without-wwid.patch +Patch0090: 0090-libmultipath-fix-format-warning-with-clang.patch +Patch0091: 0091-libmultipath-check-for-null-wwid-before-strcmp.patch +Patch0092: 0092-multipath.conf.5-Improve-checker_timeout-description.patch +Patch0093: 0093-multipathd-fix-path-checkint-not-changed-when-path-s.patch +Patch0094: 0094-libmultipath-select_action-skip-is_mpp_known_to_udev.patch +Patch0095: 0095-libmultipath-coalesce_paths-stop-triggering-spurious.patch +Patch0096: 0096-Revert-multipathd-uev_trigger-handle-incomplete-ADD-.patch +Patch0097: 0097-libmultipath-make-find_err_path_by_dev-static.patch +Patch0098: 0098-multipathd-avoid-io_err_stat-crash-during-shutdown.patch +Patch0099: 0099-multipathd-avoid-io_err_stat-ABBA-deadlock.patch +Patch0100: 0100-multipathd-use-get_monotonic_time-in-io_err_stat-cod.patch +Patch0101: 0101-multipathd-combine-free_io_err_stat_path-and-destroy.patch +Patch0102: 0102-multipathd-cleanup-logging-for-marginal-paths.patch +Patch0103: 0103-RH-fixup-udev-rules-for-redhat.patch +Patch0104: 0104-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0105: 0105-RH-don-t-start-without-a-config-file.patch +Patch0106: 0106-RH-Fix-nvme-function-missing-argument.patch +Patch0107: 0107-RH-use-rpm-optflags-if-present.patch +Patch0108: 0108-RH-add-mpathconf.patch +Patch0109: 0109-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0110: 0110-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0111: 0111-RH-attempt-to-get-ANA-info-via-sysfs-first.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -180,7 +204,7 @@ This package contains the files needed to develop applications that use device-mapper-multipath's libdmmp C API library %prep -%autosetup -n multipath-tools-0.8.4 -p1 +%autosetup -n multipath-tools-0.8.5 -p1 cp %{SOURCE1} . %build @@ -294,6 +318,15 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Tue Jan 19 2021 Benjamin Marzinski - 0.8.5-1 +- Update Source to upstream version 0.8.5 plus post tag commits + * Patches 0001-0102 are from + https://github.com/openSUSE/multipath-tools/tree/queue and are + already queued for upstream. +- Rename files + * Previous patches 0059-0068 are now patches 0103-0111 + + * Sun Sep 27 2020 Benjamin Marzinski - 0.8.4-7 - Add 0073-libmultipath-util-constify-function-arguments.patch - Add 0074-libmultipath-constify-file-argument-in-config-parser.patch diff --git a/sources b/sources index 1e028ad..cf508e4 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (multipath-tools-0.8.4.tgz) = 130308e61d6dce31085fc2763219f4df0f3ad9153e0e6e7a5a1c3c948a2305cff9413699025c28f9b81dd24d2a9263f9fa825253060e44232c3bb6600cd1f07f +SHA512 (multipath-tools-0.8.5.tgz) = 3b65f89621203304cdc0d074124627132f0a600c347f2eec03372463737493e3a7da38813d375c1f7d6fe2e55a7d4f7494574f74412534832f217954ba34c293 SHA512 (multipath.conf) = 71953dce5a68adcf60a942305f5a66023e6f4c4baf53b1bfdb4edf65ed5b8e03db804363c36d1dcfd85591f4766f52b515269904c53b84d7b076da0b80b09942 From 26a2cd7a3e189bf91263d17bc8a8c449cc043fb0 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Tue, 19 Jan 2021 23:02:49 -0600 Subject: [PATCH 12/67] device-mapper-multipath-0.8.5-2 Fix build issues --- device-mapper-multipath.spec | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 89e05ac..bf64277 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.8.5 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -8,7 +8,7 @@ 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 -L https://github.com/opensvc/multipath-tools/archive/0.8.5.tar.gz -o multipath-tools-0.8.5.tgz -Source0: multipath-tools-0.8.4.tgz +Source0: multipath-tools-0.8.5.tgz Source1: multipath.conf Patch0001: 0001-Change-the-multipath.conf-manpage-uxsock_timeout-def.patch Patch0002: 0002-libmultipath-find_mpe-don-t-match-with-empty-WWID.patch @@ -262,14 +262,14 @@ fi %{_mandir}/man8/mpathpersist.8.gz %config /usr/lib/udev/rules.d/62-multipath.rules %config /usr/lib/udev/rules.d/11-dm-mpath.rules -%doc README +%doc README.md %doc README.alua %doc multipath.conf %dir /etc/multipath %files libs %license LICENSES/GPL-2.0 LICENSES/LGPL-2.0 -%doc README +%doc README.md %{_libdir}/libmultipath.so %{_libdir}/libmultipath.so.* %{_libdir}/libmpathpersist.so.* @@ -281,7 +281,7 @@ fi %ldconfig_scriptlets libs %files devel -%doc README +%doc README.md %{_libdir}/libmpathpersist.so %{_libdir}/libmpathcmd.so %{_libdir}/libmpathvalid.so @@ -293,7 +293,7 @@ fi %files -n kpartx %license LICENSES/GPL-2.0 -%doc README +%doc README.md %{_sbindir}/kpartx /usr/lib/udev/kpartx_id %{_mandir}/man8/kpartx.8.gz @@ -303,13 +303,13 @@ fi %files -n libdmmp %license LICENSES/GPL-3.0 -%doc README +%doc README.md %{_libdir}/libdmmp.so.* %ldconfig_scriptlets -n libdmmp %files -n libdmmp-devel -%doc README +%doc README.md %{_libdir}/libdmmp.so %dir %{_includedir}/libdmmp %{_includedir}/libdmmp/* @@ -318,6 +318,9 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Tue Jan 19 2021 Benjamin Marzinski - 0.8.5-2 +- Fix build issues + * Tue Jan 19 2021 Benjamin Marzinski - 0.8.5-1 - Update Source to upstream version 0.8.5 plus post tag commits * Patches 0001-0102 are from From 13dea6f50cfb70eabfb5a86566fc326e130570cc Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Tue, 26 Jan 2021 03:17:43 +0000 Subject: [PATCH 13/67] - Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- device-mapper-multipath.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index bf64277..3969445 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.8.5 -Release: 2%{?dist} +Release: 3%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -318,6 +318,9 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Tue Jan 26 2021 Fedora Release Engineering - 0.8.5-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + * Tue Jan 19 2021 Benjamin Marzinski - 0.8.5-2 - Fix build issues From 9fdf79cddf3be4e872b8d515e240dd533ea8dd34 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 11 Feb 2021 13:53:51 -0600 Subject: [PATCH 14/67] device-mapper-multipath-0.8.5-4 Update Source to upstream version 0.8.5 plus post tag commits * Patches 0001-0121 are from https://github.com/openSUSE/multipath-tools/tree/queue and are already queued for upstream * Patches 0122&0123 have been posted for upstream inclusion Rename files * Previous patches 0103-0111 are now patches 0124-0132 --- ...-NULL-dereference-in-find_path_by_de.patch | 46 +++ ...print_devices-avoid-NULL-dereference.patch | 38 +++ ...fix-thread-safety-of-default-functio.patch | 274 +++++++++++++++++ 0106-Added-github-action-for-building.patch | 37 +++ ...use-zram-device-as-test-block-device.patch | 40 +++ ...workflow-use-explicit-Ubuntu-version.patch | 26 ++ 0109-github-workflow-add-valgrind-tests.patch | 36 +++ 0110-github-workflow-run-apt-get-update.patch | 28 ++ ...flow-add-tests-with-gcc-10-and-clang.patch | 90 ++++++ ...-Fix-multipathd-stopping-on-shutdown.patch | 38 +++ ...-3rd-digit-as-transport_id-for-expan.patch | 45 +++ ...fs_set_nexus_loss_tmo-support-SAS-ex.patch | 57 ++++ ...pathd-add-code-to-initalize-unwinder.patch | 134 +++++++++ ...ck-if-adopt_path-really-added-curren.patch | 57 ++++ ...d_path-fail-if-add_map_with_path-fai.patch | 31 ++ ...ck-return-value-of-udev_device_get_d.patch | 31 ++ ...filter_property-after-sysfs_pathinfo.patch | 281 ++++++++++++++++++ ...hinfo-call-filter_property-only-with.patch | 88 ++++++ ...h-w-allow-removing-blacklisted-paths.patch | 39 +++ ...h-fix-use-after-free-in-uev_add_path.patch | 53 ++++ ...loop-device-after-listing-partitions.patch | 61 ++++ ... 0124-RH-fixup-udev-rules-for-redhat.patch | 0 ...property-blacklist-exception-builtin.patch | 0 ...RH-don-t-start-without-a-config-file.patch | 4 +- ...H-Fix-nvme-function-missing-argument.patch | 0 ... 0128-RH-use-rpm-optflags-if-present.patch | 0 ...hconf.patch => 0129-RH-add-mpathconf.patch | 56 ++-- ...om-kernel-cmdline-mpath.wwids-with-A.patch | 2 +- ...-default-find_mutipaths-value-to-off.patch | 0 ...empt-to-get-ANA-info-via-sysfs-first.patch | 0 device-mapper-multipath.spec | 50 +++- 31 files changed, 1601 insertions(+), 41 deletions(-) create mode 100644 0103-libmultipath-fix-NULL-dereference-in-find_path_by_de.patch create mode 100644 0104-libmultipath-snprint_devices-avoid-NULL-dereference.patch create mode 100644 0105-libmpathpersist-fix-thread-safety-of-default-functio.patch create mode 100644 0106-Added-github-action-for-building.patch create mode 100644 0107-github-workflow-use-zram-device-as-test-block-device.patch create mode 100644 0108-github-workflow-use-explicit-Ubuntu-version.patch create mode 100644 0109-github-workflow-add-valgrind-tests.patch create mode 100644 0110-github-workflow-run-apt-get-update.patch create mode 100644 0111-github-workflow-add-tests-with-gcc-10-and-clang.patch create mode 100644 0112-multipathd-Fix-multipathd-stopping-on-shutdown.patch create mode 100644 0113-libmultipath-use-3rd-digit-as-transport_id-for-expan.patch create mode 100644 0114-libmultipath-sysfs_set_nexus_loss_tmo-support-SAS-ex.patch create mode 100644 0115-multipathd-add-code-to-initalize-unwinder.patch create mode 100644 0116-libmultipath-check-if-adopt_path-really-added-curren.patch create mode 100644 0117-multipathd-ev_add_path-fail-if-add_map_with_path-fai.patch create mode 100644 0118-libmultipath-check-return-value-of-udev_device_get_d.patch create mode 100644 0119-pathinfo-call-filter_property-after-sysfs_pathinfo.patch create mode 100644 0120-libmultipath-pathinfo-call-filter_property-only-with.patch create mode 100644 0121-multipath-w-allow-removing-blacklisted-paths.patch create mode 100644 0122-libmultipath-fix-use-after-free-in-uev_add_path.patch create mode 100644 0123-kpartx-free-loop-device-after-listing-partitions.patch rename 0103-RH-fixup-udev-rules-for-redhat.patch => 0124-RH-fixup-udev-rules-for-redhat.patch (100%) rename 0104-RH-Remove-the-property-blacklist-exception-builtin.patch => 0125-RH-Remove-the-property-blacklist-exception-builtin.patch (100%) rename 0105-RH-don-t-start-without-a-config-file.patch => 0126-RH-don-t-start-without-a-config-file.patch (97%) rename 0106-RH-Fix-nvme-function-missing-argument.patch => 0127-RH-Fix-nvme-function-missing-argument.patch (100%) rename 0107-RH-use-rpm-optflags-if-present.patch => 0128-RH-use-rpm-optflags-if-present.patch (100%) rename 0108-RH-add-mpathconf.patch => 0129-RH-add-mpathconf.patch (93%) rename 0109-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch => 0130-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch (99%) rename 0110-RH-reset-default-find_mutipaths-value-to-off.patch => 0131-RH-reset-default-find_mutipaths-value-to-off.patch (100%) rename 0111-RH-attempt-to-get-ANA-info-via-sysfs-first.patch => 0132-RH-attempt-to-get-ANA-info-via-sysfs-first.patch (100%) diff --git a/0103-libmultipath-fix-NULL-dereference-in-find_path_by_de.patch b/0103-libmultipath-fix-NULL-dereference-in-find_path_by_de.patch new file mode 100644 index 0000000..4dd4051 --- /dev/null +++ b/0103-libmultipath-fix-NULL-dereference-in-find_path_by_de.patch @@ -0,0 +1,46 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: lixiaokeng +Date: Sat, 23 Jan 2021 16:19:28 +0800 +Subject: [PATCH] libmultipath: fix NULL dereference in find_path_by_dev + +When I test the 0.8.5 code with iscsi login/out, multipathd command +and multipath command concurrently, there is a multipathd coredump. +The stack is shown: + +uxlsnrloop + ->cli_list_devices + ->show_devices + ->snprint_devices + ->find_path_by_dev + +The reason is that devname is NULL in snprint_devices, then it will +be dereference. Here we check dev in find_path_by_dev. + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/structs.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/structs.c b/libmultipath/structs.c +index 464596fc..a3f27fd6 100644 +--- a/libmultipath/structs.c ++++ b/libmultipath/structs.c +@@ -453,12 +453,12 @@ find_mp_by_str (const struct _vector *mpvec, const char * str) + } + + struct path * +-find_path_by_dev (const struct _vector *pathvec, const char * dev) ++find_path_by_dev (const struct _vector *pathvec, const char *dev) + { + int i; + struct path * pp; + +- if (!pathvec) ++ if (!pathvec || !dev) + return NULL; + + vector_foreach_slot (pathvec, pp, i) +-- +2.17.2 + diff --git a/0104-libmultipath-snprint_devices-avoid-NULL-dereference.patch b/0104-libmultipath-snprint_devices-avoid-NULL-dereference.patch new file mode 100644 index 0000000..04ff739 --- /dev/null +++ b/0104-libmultipath-snprint_devices-avoid-NULL-dereference.patch @@ -0,0 +1,38 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 25 Jan 2021 16:12:10 +0100 +Subject: [PATCH] libmultipath: snprint_devices(): avoid NULL dereference + +All libudev functions may return NULL. Watch out for it. + +Fixes: d041258 ("libmultipath: snprint_devices(): use udev_enumerate" +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/print.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/libmultipath/print.c b/libmultipath/print.c +index 19de2c7c..8151e11e 100644 +--- a/libmultipath/print.c ++++ b/libmultipath/print.c +@@ -2055,8 +2055,16 @@ int snprint_devices(struct config *conf, char *buff, size_t len, + struct udev_device *u_dev; + + path = udev_list_entry_get_name(item); ++ if (!path) ++ continue; + u_dev = udev_device_new_from_syspath(udev, path); ++ if (!u_dev) ++ continue; + devname = udev_device_get_sysname(u_dev); ++ if (!devname) { ++ udev_device_unref(u_dev); ++ continue; ++ } + + fwd += snprintf(buff + fwd, len - fwd, " %s", devname); + if (fwd >= len) +-- +2.17.2 + diff --git a/0105-libmpathpersist-fix-thread-safety-of-default-functio.patch b/0105-libmpathpersist-fix-thread-safety-of-default-functio.patch new file mode 100644 index 0000000..dad9963 --- /dev/null +++ b/0105-libmpathpersist-fix-thread-safety-of-default-functio.patch @@ -0,0 +1,274 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 25 Jan 2021 23:31:04 -0600 +Subject: [PATCH] libmpathpersist: fix thread safety of default functions + +commit a839e39e ("libmpathpersist: factor out initialization and +teardown") made mpath_presistent_reserve_{in,out} use share variables +for curmp and pathvec. There are users of this library that call these +functions in a multi-threaded process, and this change causes their +application to crash. config and udev are also shared variables, but +libmpathpersist doesn't write to the config in +mpath_presistent_reserve_{in,out}, and looking into the libudev code, I +don't see any place where libmpathpersist uses the udev object in a way +that isn't thread-safe. + +This patch makes mpath_presistent_reserve_{in,out} go back to using +local variables for curmp and pathvec, so that multiple threads won't +be operating on these variables at the same time. + +Fixes: a839e39e ("libmpathpersist: factor out initialization and teardown") +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmpathpersist/mpath_persist.c | 116 +++++++++++++++++++++----------- + libmpathpersist/mpath_persist.h | 24 +++++-- + 2 files changed, 94 insertions(+), 46 deletions(-) + +diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c +index 08077936..5c95af20 100644 +--- a/libmpathpersist/mpath_persist.c ++++ b/libmpathpersist/mpath_persist.c +@@ -133,69 +133,57 @@ mpath_prin_activepath (struct multipath *mpp, int rq_servact, + return ret; + } + +-int mpath_persistent_reserve_in (int fd, int rq_servact, +- struct prin_resp *resp, int noisy, int verbose) +-{ +- int ret = mpath_persistent_reserve_init_vecs(verbose); +- +- if (ret != MPATH_PR_SUCCESS) +- return ret; +- ret = __mpath_persistent_reserve_in(fd, rq_servact, resp, noisy); +- mpath_persistent_reserve_free_vecs(); +- return ret; +-} +- +-int mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, +- unsigned int rq_type, struct prout_param_descriptor *paramp, int noisy, int verbose) +-{ +- int ret = mpath_persistent_reserve_init_vecs(verbose); +- +- if (ret != MPATH_PR_SUCCESS) +- return ret; +- ret = __mpath_persistent_reserve_out(fd, rq_servact, rq_scope, rq_type, +- paramp, noisy); +- mpath_persistent_reserve_free_vecs(); +- return ret; +-} +- + static vector curmp; + static vector pathvec; + +-void mpath_persistent_reserve_free_vecs(void) ++static void __mpath_persistent_reserve_free_vecs(vector curmp, vector pathvec) + { + free_multipathvec(curmp, KEEP_PATHS); + free_pathvec(pathvec, FREE_PATHS); ++} ++ ++void mpath_persistent_reserve_free_vecs(void) ++{ ++ __mpath_persistent_reserve_free_vecs(curmp, pathvec); + curmp = pathvec = NULL; + } + +-int mpath_persistent_reserve_init_vecs(int verbose) ++static int __mpath_persistent_reserve_init_vecs(vector *curmp_p, ++ vector *pathvec_p, int verbose) + { + libmp_verbosity = verbose; + +- if (curmp) ++ if (*curmp_p) + return MPATH_PR_SUCCESS; + /* + * allocate core vectors to store paths and multipaths + */ +- curmp = vector_alloc (); +- pathvec = vector_alloc (); ++ *curmp_p = vector_alloc (); ++ *pathvec_p = vector_alloc (); + +- if (!curmp || !pathvec){ ++ if (!*curmp_p || !*pathvec_p){ + condlog (0, "vector allocation failed."); + goto err; + } + +- if (dm_get_maps(curmp)) ++ if (dm_get_maps(*curmp_p)) + goto err; + + return MPATH_PR_SUCCESS; + + err: +- mpath_persistent_reserve_free_vecs(); ++ __mpath_persistent_reserve_free_vecs(*curmp_p, *pathvec_p); ++ *curmp_p = *pathvec_p = NULL; + return MPATH_PR_DMMP_ERROR; + } + +-static int mpath_get_map(int fd, char **palias, struct multipath **pmpp) ++int mpath_persistent_reserve_init_vecs(int verbose) ++{ ++ return __mpath_persistent_reserve_init_vecs(&curmp, &pathvec, verbose); ++} ++ ++static int mpath_get_map(vector curmp, vector pathvec, int fd, char **palias, ++ struct multipath **pmpp) + { + int ret = MPATH_PR_DMMP_ERROR; + struct stat info; +@@ -255,13 +243,13 @@ out: + return ret; + } + +-int __mpath_persistent_reserve_in (int fd, int rq_servact, +- struct prin_resp *resp, int noisy) ++static int do_mpath_persistent_reserve_in (vector curmp, vector pathvec, ++ int fd, int rq_servact, struct prin_resp *resp, int noisy) + { + struct multipath *mpp; + int ret; + +- ret = mpath_get_map(fd, NULL, &mpp); ++ ret = mpath_get_map(curmp, pathvec, fd, NULL, &mpp); + if (ret != MPATH_PR_SUCCESS) + return ret; + +@@ -270,8 +258,17 @@ int __mpath_persistent_reserve_in (int fd, int rq_servact, + return ret; + } + +-int __mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, +- unsigned int rq_type, struct prout_param_descriptor *paramp, int noisy) ++ ++int __mpath_persistent_reserve_in (int fd, int rq_servact, ++ struct prin_resp *resp, int noisy) ++{ ++ return do_mpath_persistent_reserve_in(curmp, pathvec, fd, rq_servact, ++ resp, noisy); ++} ++ ++static int do_mpath_persistent_reserve_out(vector curmp, vector pathvec, int fd, ++ int rq_servact, int rq_scope, unsigned int rq_type, ++ struct prout_param_descriptor *paramp, int noisy) + { + struct multipath *mpp; + char *alias; +@@ -279,7 +276,7 @@ int __mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, + uint64_t prkey; + struct config *conf; + +- ret = mpath_get_map(fd, &alias, &mpp); ++ ret = mpath_get_map(curmp, pathvec, fd, &alias, &mpp); + if (ret != MPATH_PR_SUCCESS) + return ret; + +@@ -349,6 +346,45 @@ out1: + return ret; + } + ++ ++int __mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, ++ unsigned int rq_type, struct prout_param_descriptor *paramp, int noisy) ++{ ++ return do_mpath_persistent_reserve_out(curmp, pathvec, fd, rq_servact, ++ rq_scope, rq_type, paramp, ++ noisy); ++} ++ ++int mpath_persistent_reserve_in (int fd, int rq_servact, ++ struct prin_resp *resp, int noisy, int verbose) ++{ ++ vector curmp = NULL, pathvec; ++ int ret = __mpath_persistent_reserve_init_vecs(&curmp, &pathvec, ++ verbose); ++ ++ if (ret != MPATH_PR_SUCCESS) ++ return ret; ++ ret = do_mpath_persistent_reserve_in(curmp, pathvec, fd, rq_servact, ++ resp, noisy); ++ __mpath_persistent_reserve_free_vecs(curmp, pathvec); ++ return ret; ++} ++ ++int mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, ++ unsigned int rq_type, struct prout_param_descriptor *paramp, int noisy, int verbose) ++{ ++ vector curmp = NULL, pathvec; ++ int ret = __mpath_persistent_reserve_init_vecs(&curmp, &pathvec, ++ verbose); ++ ++ if (ret != MPATH_PR_SUCCESS) ++ return ret; ++ ret = do_mpath_persistent_reserve_out(curmp, pathvec, fd, rq_servact, ++ rq_scope, rq_type, paramp, noisy); ++ __mpath_persistent_reserve_free_vecs(curmp, pathvec); ++ return ret; ++} ++ + int + get_mpvec (vector curmp, vector pathvec, char * refwwid) + { +diff --git a/libmpathpersist/mpath_persist.h b/libmpathpersist/mpath_persist.h +index 5435eae4..9e9c0a82 100644 +--- a/libmpathpersist/mpath_persist.h ++++ b/libmpathpersist/mpath_persist.h +@@ -246,9 +246,13 @@ extern int mpath_persistent_reserve_in (int fd, int rq_servact, struct prin_resp + + /* + * DESCRIPTION : +- * This function is like mpath_persistent_reserve_in(), except that it doesn't call +- * mpath_persistent_reserve_init_vecs() and mpath_persistent_reserve_free_vecs() +- * before and after the actual PR call. ++ * This function is like mpath_persistent_reserve_in(), except that it ++ * requires mpath_persistent_reserve_init_vecs() to be called before the ++ * PR call to set up internal variables. These must later be cleanup up ++ * by calling mpath_persistent_reserve_free_vecs(). ++ * ++ * RESTRICTIONS: ++ * This function uses static internal variables, and is not thread-safe. + */ + extern int __mpath_persistent_reserve_in(int fd, int rq_servact, + struct prin_resp *resp, int noisy); +@@ -280,9 +284,13 @@ extern int mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, + int verbose); + /* + * DESCRIPTION : +- * This function is like mpath_persistent_reserve_out(), except that it doesn't call +- * mpath_persistent_reserve_init_vecs() and mpath_persistent_reserve_free_vecs() +- * before and after the actual PR call. ++ * This function is like mpath_persistent_reserve_out(), except that it ++ * requires mpath_persistent_reserve_init_vecs() to be called before the ++ * PR call to set up internal variables. These must later be cleanup up ++ * by calling mpath_persistent_reserve_free_vecs(). ++ * ++ * RESTRICTIONS: ++ * This function uses static internal variables, and is not thread-safe. + */ + extern int __mpath_persistent_reserve_out( int fd, int rq_servact, int rq_scope, + unsigned int rq_type, struct prout_param_descriptor *paramp, +@@ -296,6 +304,7 @@ extern int __mpath_persistent_reserve_out( int fd, int rq_servact, int rq_scope, + * @verbose: Set verbosity level. Input argument. value:0 to 3. 0->disabled, 3->Max verbose + * + * RESTRICTIONS: ++ * This function uses static internal variables, and is not thread-safe. + * + * RETURNS: MPATH_PR_SUCCESS if successful else returns any of the status specified + * above in RETURN_STATUS. +@@ -306,6 +315,9 @@ int mpath_persistent_reserve_init_vecs(int verbose); + * DESCRIPTION : + * This function frees data structures allocated by + * mpath_persistent_reserve_init_vecs(). ++ * ++ * RESTRICTIONS: ++ * This function uses static internal variables, and is not thread-safe. + */ + void mpath_persistent_reserve_free_vecs(void); + +-- +2.17.2 + diff --git a/0106-Added-github-action-for-building.patch b/0106-Added-github-action-for-building.patch new file mode 100644 index 0000000..8a8a7d0 --- /dev/null +++ b/0106-Added-github-action-for-building.patch @@ -0,0 +1,37 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 18 Dec 2020 21:38:43 +0100 +Subject: [PATCH] Added github action for building + +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/build-and-unittest.yaml | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + create mode 100644 .github/workflows/build-and-unittest.yaml + +diff --git a/.github/workflows/build-and-unittest.yaml b/.github/workflows/build-and-unittest.yaml +new file mode 100644 +index 00000000..2b13c65c +--- /dev/null ++++ b/.github/workflows/build-and-unittest.yaml +@@ -0,0 +1,17 @@ ++name: basic-build-and-ci ++on: [push] ++jobs: ++ build: ++ runs-on: ubuntu-latest ++ steps: ++ - uses: actions/checkout@v2 ++ - name: dependencies ++ run: > ++ sudo apt-get install --yes gcc ++ make perl-base pkg-config ++ libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev ++ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev ++ - name: build ++ run: make -O -j$(grep -c ^processor /proc/cpuinfo) ++ - name: test ++ run: make -O -j$(grep -c ^processor /proc/cpuinfo) test +-- +2.17.2 + diff --git a/0107-github-workflow-use-zram-device-as-test-block-device.patch b/0107-github-workflow-use-zram-device-as-test-block-device.patch new file mode 100644 index 0000000..5b25c29 --- /dev/null +++ b/0107-github-workflow-use-zram-device-as-test-block-device.patch @@ -0,0 +1,40 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 18 Dec 2020 22:18:20 +0100 +Subject: [PATCH] github workflow: use zram device as test block device + +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/build-and-unittest.yaml | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/.github/workflows/build-and-unittest.yaml b/.github/workflows/build-and-unittest.yaml +index 2b13c65c..ef55b8c1 100644 +--- a/.github/workflows/build-and-unittest.yaml ++++ b/.github/workflows/build-and-unittest.yaml +@@ -5,6 +5,14 @@ jobs: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 ++ - name: mpath ++ run: sudo modprobe dm_multipath ++ - name: zram ++ run: sudo modprobe zram num_devices=0 ++ - name: zram-device ++ run: echo ZRAM=$(sudo cat /sys/class/zram-control/hot_add) >> $GITHUB_ENV ++ - name: set-zram-size ++ run: echo 1G | sudo tee /sys/block/zram$ZRAM/disksize + - name: dependencies + run: > + sudo apt-get install --yes gcc +@@ -15,3 +23,7 @@ jobs: + run: make -O -j$(grep -c ^processor /proc/cpuinfo) + - name: test + run: make -O -j$(grep -c ^processor /proc/cpuinfo) test ++ - name: clean-nonroot-artifacts ++ run: rm -f tests/dmevents.out tests/directio.out ++ - name: root-test ++ run: sudo make DIO_TEST_DEV=/dev/zram$ZRAM test +-- +2.17.2 + diff --git a/0108-github-workflow-use-explicit-Ubuntu-version.patch b/0108-github-workflow-use-explicit-Ubuntu-version.patch new file mode 100644 index 0000000..ff565d6 --- /dev/null +++ b/0108-github-workflow-use-explicit-Ubuntu-version.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 18 Dec 2020 22:54:24 +0100 +Subject: [PATCH] github workflow: use explicit Ubuntu version + +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/build-and-unittest.yaml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/.github/workflows/build-and-unittest.yaml b/.github/workflows/build-and-unittest.yaml +index ef55b8c1..577a14ac 100644 +--- a/.github/workflows/build-and-unittest.yaml ++++ b/.github/workflows/build-and-unittest.yaml +@@ -2,7 +2,7 @@ name: basic-build-and-ci + on: [push] + jobs: + build: +- runs-on: ubuntu-latest ++ runs-on: ubuntu-18.04 + steps: + - uses: actions/checkout@v2 + - name: mpath +-- +2.17.2 + diff --git a/0109-github-workflow-add-valgrind-tests.patch b/0109-github-workflow-add-valgrind-tests.patch new file mode 100644 index 0000000..5c4e366 --- /dev/null +++ b/0109-github-workflow-add-valgrind-tests.patch @@ -0,0 +1,36 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 18 Dec 2020 23:21:16 +0100 +Subject: [PATCH] github workflow: add valgrind tests + +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/build-and-unittest.yaml | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/.github/workflows/build-and-unittest.yaml b/.github/workflows/build-and-unittest.yaml +index 577a14ac..929f63a6 100644 +--- a/.github/workflows/build-and-unittest.yaml ++++ b/.github/workflows/build-and-unittest.yaml +@@ -16,13 +16,17 @@ jobs: + - name: dependencies + run: > + sudo apt-get install --yes gcc +- make perl-base pkg-config ++ make perl-base pkg-config valgrind + libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev + libudev-dev libjson-c-dev liburcu-dev libcmocka-dev + - name: build + run: make -O -j$(grep -c ^processor /proc/cpuinfo) + - name: test + run: make -O -j$(grep -c ^processor /proc/cpuinfo) test ++ - name: valgrind-test ++ run: make -O -j$(grep -c ^processor /proc/cpuinfo) valgrind-test ++ - name: valgrind-results ++ run: cat tests/*.vgr + - name: clean-nonroot-artifacts + run: rm -f tests/dmevents.out tests/directio.out + - name: root-test +-- +2.17.2 + diff --git a/0110-github-workflow-run-apt-get-update.patch b/0110-github-workflow-run-apt-get-update.patch new file mode 100644 index 0000000..d27f1ca --- /dev/null +++ b/0110-github-workflow-run-apt-get-update.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 18 Dec 2020 23:26:16 +0100 +Subject: [PATCH] github workflow: run apt-get update + +E: Failed to fetch http://azure.archive.ubuntu.com/ubuntu/pool/main/g/glibc/libc6-dbg_2.27-3ubuntu1.3_amd64.deb 404 Not Found [IP: 52.252.75.106 80] +E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing? +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/build-and-unittest.yaml | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/.github/workflows/build-and-unittest.yaml b/.github/workflows/build-and-unittest.yaml +index 929f63a6..389578be 100644 +--- a/.github/workflows/build-and-unittest.yaml ++++ b/.github/workflows/build-and-unittest.yaml +@@ -13,6 +13,8 @@ jobs: + run: echo ZRAM=$(sudo cat /sys/class/zram-control/hot_add) >> $GITHUB_ENV + - name: set-zram-size + run: echo 1G | sudo tee /sys/block/zram$ZRAM/disksize ++ - name: update ++ run: sudo apt-get update + - name: dependencies + run: > + sudo apt-get install --yes gcc +-- +2.17.2 + diff --git a/0111-github-workflow-add-tests-with-gcc-10-and-clang.patch b/0111-github-workflow-add-tests-with-gcc-10-and-clang.patch new file mode 100644 index 0000000..e95b3f8 --- /dev/null +++ b/0111-github-workflow-add-tests-with-gcc-10-and-clang.patch @@ -0,0 +1,90 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 18 Dec 2020 23:44:11 +0100 +Subject: [PATCH] github workflow: add tests with gcc 10 and clang + +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/build-and-unittest.yaml | 62 ++++++++++++++++++++++- + 1 file changed, 61 insertions(+), 1 deletion(-) + +diff --git a/.github/workflows/build-and-unittest.yaml b/.github/workflows/build-and-unittest.yaml +index 389578be..4173576f 100644 +--- a/.github/workflows/build-and-unittest.yaml ++++ b/.github/workflows/build-and-unittest.yaml +@@ -1,7 +1,7 @@ + name: basic-build-and-ci + on: [push] + jobs: +- build: ++ bionic: + runs-on: ubuntu-18.04 + steps: + - uses: actions/checkout@v2 +@@ -33,3 +33,63 @@ jobs: + run: rm -f tests/dmevents.out tests/directio.out + - name: root-test + run: sudo make DIO_TEST_DEV=/dev/zram$ZRAM test ++ focal-gcc10: ++ runs-on: ubuntu-20.04 ++ steps: ++ - uses: actions/checkout@v2 ++ - name: mpath ++ run: sudo modprobe dm_multipath ++ - name: brd ++ run: sudo modprobe brd rd_nr=1 rd_size=65536 ++ - name: update ++ run: sudo apt-get update ++ - name: dependencies ++ run: > ++ sudo apt-get install --yes gcc-10 ++ make perl-base pkg-config valgrind ++ libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev ++ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev ++ - name: set CC ++ run: echo CC=gcc-10 >> $GITHUB_ENV ++ - name: build ++ run: make -O -j$(grep -c ^processor /proc/cpuinfo) ++ - name: test ++ run: make -O -j$(grep -c ^processor /proc/cpuinfo) test ++ - name: valgrind-test ++ run: make -O -j$(grep -c ^processor /proc/cpuinfo) valgrind-test ++ - name: valgrind-results ++ run: cat tests/*.vgr ++ - name: clean-nonroot-artifacts ++ run: rm -f tests/dmevents.out tests/directio.out ++ - name: root-test ++ run: sudo make DIO_TEST_DEV=/dev/ram0 test ++ focal-clang10: ++ runs-on: ubuntu-20.04 ++ steps: ++ - uses: actions/checkout@v2 ++ - name: mpath ++ run: sudo modprobe dm_multipath ++ - name: brd ++ run: sudo modprobe brd rd_nr=1 rd_size=65536 ++ - name: update ++ run: sudo apt-get update ++ - name: dependencies ++ run: > ++ sudo apt-get install --yes clang ++ make perl-base pkg-config valgrind ++ libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev ++ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev ++ - name: set CC ++ run: echo CC=clang >> $GITHUB_ENV ++ - name: build ++ run: make -O -j$(grep -c ^processor /proc/cpuinfo) ++ - name: test ++ run: make -O -j$(grep -c ^processor /proc/cpuinfo) test ++ - name: valgrind-test ++ run: make -O -j$(grep -c ^processor /proc/cpuinfo) valgrind-test ++ - name: valgrind-results ++ run: cat tests/*.vgr ++ - name: clean-nonroot-artifacts ++ run: rm -f tests/dmevents.out tests/directio.out ++ - name: root-test ++ run: sudo make DIO_TEST_DEV=/dev/ram0 test +-- +2.17.2 + diff --git a/0112-multipathd-Fix-multipathd-stopping-on-shutdown.patch b/0112-multipathd-Fix-multipathd-stopping-on-shutdown.patch new file mode 100644 index 0000000..49ea563 --- /dev/null +++ b/0112-multipathd-Fix-multipathd-stopping-on-shutdown.patch @@ -0,0 +1,38 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Fri, 18 Dec 2020 17:06:41 -0600 +Subject: [PATCH] multipathd: Fix multipathd stopping on shutdown + +According to man "systemd.special" + +"shutdown.target: ... Services that shall be terminated on system +shutdown shall add Conflicts= and Before= dependencies to this unit for +their service unit, which is implicitly done when +DefaultDependencies=yes is set (the default)." + +multipathd.service sets DefaultDependencies=no and includes the +Conflits= dependency, but not the Before= one. This can cause multipathd +to continue running past when it is supposed to during shutdown. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + multipathd/multipathd.service | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service +index ba24983e..7d547fa7 100644 +--- a/multipathd/multipathd.service ++++ b/multipathd/multipathd.service +@@ -2,7 +2,7 @@ + Description=Device-Mapper Multipath Device Controller + Wants=systemd-udev-trigger.service systemd-udev-settle.service + Before=iscsi.service iscsid.service lvm2-activation-early.service +-Before=local-fs-pre.target blk-availability.service ++Before=local-fs-pre.target blk-availability.service shutdown.target + After=multipathd.socket systemd-udev-trigger.service systemd-udev-settle.service + DefaultDependencies=no + Conflicts=shutdown.target +-- +2.17.2 + diff --git a/0113-libmultipath-use-3rd-digit-as-transport_id-for-expan.patch b/0113-libmultipath-use-3rd-digit-as-transport_id-for-expan.patch new file mode 100644 index 0000000..17d53ce --- /dev/null +++ b/0113-libmultipath-use-3rd-digit-as-transport_id-for-expan.patch @@ -0,0 +1,45 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 13 Nov 2020 22:34:41 +0100 +Subject: [PATCH] libmultipath: use 3rd digit as transport_id for expanders + +On SAS expanders, node id's have 3 digits. sysfs paths look like this: + +/sys/devices/pci0000:80/0000:80:02.0/0000:8b:00.0/0000:8c:09.0/0000:8f:00.0/host9/port-9:0/expander-9:0/port-9:0:13/expander-9:1/port-9:1:12/expander-9:2/port-9:2:4/end_device-9:2:4/target9:0:29/9:0:29:0/block/sdac + +In that case, we should use the last digit as transport id. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/discovery.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index e818585a..6d74cc07 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -358,10 +358,17 @@ sysfs_get_tgt_nodename(struct path *pp, char *node) + if (value) { + tgtdev = udev_device_get_parent(parent); + while (tgtdev) { ++ char c; ++ + tgtname = udev_device_get_sysname(tgtdev); +- if (tgtname && sscanf(tgtname, "end_device-%d:%d", +- &host, &tgtid) == 2) +- break; ++ if (tgtname) { ++ if (sscanf(tgtname, "end_device-%d:%d:%d%c", ++ &host, &channel, &tgtid, &c) == 3) ++ break; ++ if (sscanf(tgtname, "end_device-%d:%d%c", ++ &host, &tgtid, &c) == 2) ++ break; ++ } + tgtdev = udev_device_get_parent(tgtdev); + tgtid = -1; + } +-- +2.17.2 + diff --git a/0114-libmultipath-sysfs_set_nexus_loss_tmo-support-SAS-ex.patch b/0114-libmultipath-sysfs_set_nexus_loss_tmo-support-SAS-ex.patch new file mode 100644 index 0000000..3207d2d --- /dev/null +++ b/0114-libmultipath-sysfs_set_nexus_loss_tmo-support-SAS-ex.patch @@ -0,0 +1,57 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 13 Nov 2020 22:38:21 +0100 +Subject: [PATCH] libmultipath: sysfs_set_nexus_loss_tmo(): support SAS + expanders + +With SAS expanders, SAS node names have 3 digits. libmultipath +would fail to discover the sas_end_device matching a given SCSI +target in this case. Fix it. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/discovery.c | 24 +++++++++++++++++++----- + 1 file changed, 19 insertions(+), 5 deletions(-) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index 6d74cc07..921025d4 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -789,14 +789,28 @@ sysfs_set_session_tmo(struct multipath *mpp, struct path *pp) + static void + sysfs_set_nexus_loss_tmo(struct multipath *mpp, struct path *pp) + { +- struct udev_device *sas_dev = NULL; +- char end_dev_id[64]; ++ struct udev_device *parent, *sas_dev = NULL; ++ const char *end_dev_id = NULL; + char value[11]; ++ static const char ed_str[] = "end_device-"; + +- if (mpp->dev_loss == DEV_LOSS_TMO_UNSET) ++ if (!pp->udev || mpp->dev_loss == DEV_LOSS_TMO_UNSET) + return; +- sprintf(end_dev_id, "end_device-%d:%d", +- pp->sg_id.host_no, pp->sg_id.transport_id); ++ ++ for (parent = udev_device_get_parent(pp->udev); ++ parent; ++ parent = udev_device_get_parent(parent)) { ++ const char *ed = udev_device_get_sysname(parent); ++ ++ if (!strncmp(ed, ed_str, sizeof(ed_str) - 1)) { ++ end_dev_id = ed; ++ break; ++ } ++ } ++ if (!end_dev_id) { ++ condlog(1, "%s: No SAS end device", pp->dev); ++ return; ++ } + sas_dev = udev_device_new_from_subsystem_sysname(udev, + "sas_end_device", end_dev_id); + if (!sas_dev) { +-- +2.17.2 + diff --git a/0115-multipathd-add-code-to-initalize-unwinder.patch b/0115-multipathd-add-code-to-initalize-unwinder.patch new file mode 100644 index 0000000..e231733 --- /dev/null +++ b/0115-multipathd-add-code-to-initalize-unwinder.patch @@ -0,0 +1,134 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 17 Dec 2020 16:50:06 +0100 +Subject: [PATCH] multipathd: add code to initalize unwinder + +glibc's implementation of pthread_cancel() loads symbols from +libgcc_s.so using dlopen() when pthread_cancel() is called +for the first time. This happens even with LD_BIND_NOW=1. +This may imply the need for file system access when a thread is +cancelled, which in the case of multipath-tools might be in a +dangerous situation where multipathd must avoid blocking. + +Call load_unwinder() during startup to make sure the dynamic +linker has all necessary symbols resolved early on. + +This implementation simply creates a dummy thread and cancels +it. This way all necessary symbols for thread cancellation +will be loaded, no matter what the C library needs to implement +cancellation. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipathd/Makefile | 2 +- + multipathd/init_unwinder.c | 34 ++++++++++++++++++++++++++++++++++ + multipathd/init_unwinder.h | 21 +++++++++++++++++++++ + multipathd/main.c | 2 ++ + 4 files changed, 58 insertions(+), 1 deletion(-) + create mode 100644 multipathd/init_unwinder.c + create mode 100644 multipathd/init_unwinder.h + +diff --git a/multipathd/Makefile b/multipathd/Makefile +index 632b82b1..d053c1ed 100644 +--- a/multipathd/Makefile ++++ b/multipathd/Makefile +@@ -30,7 +30,7 @@ ifeq ($(ENABLE_DMEVENTS_POLL),0) + endif + + OBJS = main.o pidfile.o uxlsnr.o uxclnt.o cli.o cli_handlers.o waiter.o \ +- dmevents.o ++ dmevents.o init_unwinder.o + + EXEC = multipathd + +diff --git a/multipathd/init_unwinder.c b/multipathd/init_unwinder.c +new file mode 100644 +index 00000000..14467f3d +--- /dev/null ++++ b/multipathd/init_unwinder.c +@@ -0,0 +1,34 @@ ++#include ++#include ++#include "init_unwinder.h" ++ ++static pthread_mutex_t dummy_mtx = PTHREAD_MUTEX_INITIALIZER; ++static pthread_cond_t dummy_cond = PTHREAD_COND_INITIALIZER; ++ ++static void *dummy_thread(void *arg __attribute__((unused))) ++{ ++ pthread_mutex_lock(&dummy_mtx); ++ pthread_cond_broadcast(&dummy_cond); ++ pthread_mutex_unlock(&dummy_mtx); ++ pause(); ++ return NULL; ++} ++ ++int init_unwinder(void) ++{ ++ pthread_t dummy; ++ int rc; ++ ++ pthread_mutex_lock(&dummy_mtx); ++ ++ rc = pthread_create(&dummy, NULL, dummy_thread, NULL); ++ if (rc != 0) { ++ pthread_mutex_unlock(&dummy_mtx); ++ return rc; ++ } ++ ++ pthread_cond_wait(&dummy_cond, &dummy_mtx); ++ pthread_mutex_unlock(&dummy_mtx); ++ ++ return pthread_cancel(dummy); ++} +diff --git a/multipathd/init_unwinder.h b/multipathd/init_unwinder.h +new file mode 100644 +index 00000000..ada09f82 +--- /dev/null ++++ b/multipathd/init_unwinder.h +@@ -0,0 +1,21 @@ ++#ifndef _INIT_UNWINDER_H ++#define _INIT_UNWINDER_H 1 ++ ++/* ++ * init_unwinder(): make sure unwinder symbols are loaded ++ * ++ * libc's implementation of pthread_cancel() loads symbols from ++ * libgcc_s.so using dlopen() when pthread_cancel() is called ++ * for the first time. This happens even with LD_BIND_NOW=1. ++ * This may imply the need for file system access when a thread is ++ * cancelled, which in the case of multipath-tools might be in a ++ * dangerous situation where multipathd must avoid blocking. ++ * ++ * Call load_unwinder() during startup to make sure the dynamic ++ * linker has all necessary symbols resolved early on. ++ * ++ * Return: 0 if successful, an error number otherwise. ++ */ ++int init_unwinder(void); ++ ++#endif +diff --git a/multipathd/main.c b/multipathd/main.c +index 99a89a69..6f851ae8 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -83,6 +83,7 @@ + #include "wwids.h" + #include "foreign.h" + #include "../third-party/valgrind/drd.h" ++#include "init_unwinder.h" + + #define FILE_NAME_SIZE 256 + #define CMDSIZE 160 +@@ -3041,6 +3042,7 @@ child (__attribute__((unused)) void *param) + enum daemon_status state; + int exit_code = 1; + ++ init_unwinder(); + mlockall(MCL_CURRENT | MCL_FUTURE); + signal_init(); + mp_rcu_data = setup_rcu(); +-- +2.17.2 + diff --git a/0116-libmultipath-check-if-adopt_path-really-added-curren.patch b/0116-libmultipath-check-if-adopt_path-really-added-curren.patch new file mode 100644 index 0000000..b656c08 --- /dev/null +++ b/0116-libmultipath-check-if-adopt_path-really-added-curren.patch @@ -0,0 +1,57 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 2 Feb 2021 11:12:21 +0100 +Subject: [PATCH] libmultipath: check if adopt_path() really added current path + +The description of 2d32d6f ("libmultipath: adopt_paths(): don't bail out on +single path failure") said "we need to check after successful call to +adopt_paths() if that specific path had been actually added, and fail in the +caller otherwise". But the commit failed to actually implement this check. +Instead, it just checked if the path was member of the pathvec, which will +almost always be the case. + +Fix it by checking what actually needs to be checked, membership of the +path to be added in mpp->paths. + +Fixes: 2d32d6f ("libmultipath: adopt_paths(): don't bail out on single path failure") + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/structs_vec.c | 4 ++-- + multipathd/main.c | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c +index f7f45f11..47b1d03e 100644 +--- a/libmultipath/structs_vec.c ++++ b/libmultipath/structs_vec.c +@@ -707,8 +707,8 @@ struct multipath *add_map_with_path(struct vectors *vecs, struct path *pp, + goto out; + mpp->size = pp->size; + +- if (adopt_paths(vecs->pathvec, mpp) || +- find_slot(vecs->pathvec, pp) == -1) ++ if (adopt_paths(vecs->pathvec, mpp) || pp->mpp != mpp || ++ find_slot(mpp->paths, pp) == -1) + goto out; + + if (add_vec) { +diff --git a/multipathd/main.c b/multipathd/main.c +index 6f851ae8..43d77688 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -1008,8 +1008,8 @@ rescan: + if (mpp) { + condlog(4,"%s: adopting all paths for path %s", + mpp->alias, pp->dev); +- if (adopt_paths(vecs->pathvec, mpp) || +- find_slot(vecs->pathvec, pp) == -1) ++ if (adopt_paths(vecs->pathvec, mpp) || pp->mpp != mpp || ++ find_slot(mpp->paths, pp) == -1) + goto fail; /* leave path added to pathvec */ + + verify_paths(mpp); +-- +2.17.2 + diff --git a/0117-multipathd-ev_add_path-fail-if-add_map_with_path-fai.patch b/0117-multipathd-ev_add_path-fail-if-add_map_with_path-fai.patch new file mode 100644 index 0000000..f223728 --- /dev/null +++ b/0117-multipathd-ev_add_path-fail-if-add_map_with_path-fai.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 1 Feb 2021 13:10:46 +0100 +Subject: [PATCH] multipathd: ev_add_path: fail if add_map_with_path() fails + +If start_waiter was set before and the "rescan" label was used, +we may try to set up an empty/invalid map. +Always fail if add_map_with_path() isn't successful. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 43d77688..425492a9 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -1028,7 +1028,7 @@ rescan: + */ + start_waiter = 1; + } +- if (!start_waiter) ++ else + goto fail; /* leave path added to pathvec */ + } + +-- +2.17.2 + diff --git a/0118-libmultipath-check-return-value-of-udev_device_get_d.patch b/0118-libmultipath-check-return-value-of-udev_device_get_d.patch new file mode 100644 index 0000000..fe69708 --- /dev/null +++ b/0118-libmultipath-check-return-value-of-udev_device_get_d.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 2 Feb 2021 15:18:33 +0100 +Subject: [PATCH] libmultipath: check return value of udev_device_get_devnum() + +udev_device_get_devnum() may fail, in which case it returns +makedev(0, 0). + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/discovery.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index 921025d4..15cf6413 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -1659,6 +1659,9 @@ common_sysfs_pathinfo (struct path * pp) + return PATHINFO_FAILED; + } + devt = udev_device_get_devnum(pp->udev); ++ if (major(devt) == 0 && minor(devt) == 0) ++ return PATHINFO_FAILED; ++ + snprintf(pp->dev_t, BLK_DEV_SIZE, "%d:%d", major(devt), minor(devt)); + + condlog(4, "%s: dev_t = %s", pp->dev, pp->dev_t); +-- +2.17.2 + diff --git a/0119-pathinfo-call-filter_property-after-sysfs_pathinfo.patch b/0119-pathinfo-call-filter_property-after-sysfs_pathinfo.patch new file mode 100644 index 0000000..cf106c2 --- /dev/null +++ b/0119-pathinfo-call-filter_property-after-sysfs_pathinfo.patch @@ -0,0 +1,281 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 2 Feb 2021 17:07:37 +0100 +Subject: [PATCH] pathinfo: call filter_property() after sysfs_pathinfo() + +The of filter_property() depends on the value of pp->uid_attribute. +This may in turn depend on pp->hwe, which is initialized in +sysfs_pathinfo(). To obtain consistent results from pathinfo(), +make sure uid_attribute is correctly set before calling filter_property(). + +filter_property() is now called from pathinfo() with properly set +uid_attribute, thus we don't need to call it from is_path_valid() any more. + +Thes changes require modifications to the unit tests. The is_path_valid() +test now wouldn't need to test filter_property() any more, because +is_path_valid() calls filter_property() no more. But that doesn't feel +right. Instead, test_filter_property() is modified to test the behavior +with the filter_property() test called indirectly from pathinfo(). + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/discovery.c | 21 +++++++++- + libmultipath/valid.c | 4 -- + tests/Makefile | 2 +- + tests/test-lib.c | 5 ++- + tests/valid.c | 91 ++++++++++++++++++++++++++++++++++++---- + 5 files changed, 105 insertions(+), 18 deletions(-) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index 15cf6413..febcd0ae 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -2247,9 +2247,17 @@ int pathinfo(struct path *pp, struct config *conf, int mask) + condlog(4, "%s: hidden", pp->dev); + return PATHINFO_SKIPPED; + } +- if (is_claimed_by_foreign(pp->udev) || +- filter_property(conf, pp->udev, 4, pp->uid_attribute) > 0) ++ ++ if (is_claimed_by_foreign(pp->udev)) + return PATHINFO_SKIPPED; ++ ++ /* ++ * uid_attribute is required for filter_property below, ++ * and needs access to pp->hwe. ++ */ ++ if (!(mask & DI_SYSFS) && !pp->uid_attribute && ++ VECTOR_SIZE(pp->hwe) == 0) ++ mask |= DI_SYSFS; + } + + if (strlen(pp->dev) != 0 && filter_devnode(conf->blist_devnode, +@@ -2287,6 +2295,15 @@ int pathinfo(struct path *pp, struct config *conf, int mask) + } + } + ++ if (pp->udev) { ++ /* uid_attribute is required for filter_property() */ ++ if (!pp->uid_attribute) ++ select_getuid(conf, pp); ++ ++ if (filter_property(conf, pp->udev, 4, pp->uid_attribute) > 0) ++ return PATHINFO_SKIPPED; ++ } ++ + if (mask & DI_BLACKLIST && mask & DI_SYSFS) { + if (filter_device(conf->blist_device, conf->elist_device, + pp->vendor_id, pp->product_id, pp->dev) > 0 || +diff --git a/libmultipath/valid.c b/libmultipath/valid.c +index 456b1f6e..a6aa9215 100644 +--- a/libmultipath/valid.c ++++ b/libmultipath/valid.c +@@ -89,10 +89,6 @@ is_path_valid(const char *name, struct config *conf, struct path *pp, + if (pp->wwid[0] == '\0') + return PATH_IS_NOT_VALID; + +- if (pp->udev && pp->uid_attribute && +- filter_property(conf, pp->udev, 3, pp->uid_attribute) > 0) +- return PATH_IS_NOT_VALID; +- + r = is_failed_wwid(pp->wwid); + if (r != WWID_IS_NOT_FAILED) { + if (r == WWID_IS_FAILED) +diff --git a/tests/Makefile b/tests/Makefile +index 50673fae..11ca1be5 100644 +--- a/tests/Makefile ++++ b/tests/Makefile +@@ -54,7 +54,7 @@ vpd-test_OBJDEPS := ../libmultipath/discovery.o + vpd-test_LIBDEPS := -ludev -lpthread -ldl + alias-test_TESTDEPS := test-log.o + alias-test_LIBDEPS := -lpthread -ldl +-valid-test_OBJDEPS := ../libmultipath/valid.o ++valid-test_OBJDEPS := ../libmultipath/valid.o ../libmultipath/discovery.o + valid-test_LIBDEPS := -ludev -lpthread -ldl + devt-test_LIBDEPS := -ludev + mpathvalid-test_LIBDEPS := -ludev -lpthread -ldl +diff --git a/tests/test-lib.c b/tests/test-lib.c +index e7663f9a..960a7665 100644 +--- a/tests/test-lib.c ++++ b/tests/test-lib.c +@@ -257,6 +257,9 @@ void mock_pathinfo(int mask, const struct mocked_path *mp) + } else + will_return(__wrap_udev_device_get_sysattr_value, "0"); + ++ if (mask & DI_SYSFS) ++ mock_sysfs_pathinfo(mp); ++ + /* filter_property */ + will_return(__wrap_udev_device_get_sysname, mp->devnode); + if (mp->flags & BL_BY_PROPERTY) { +@@ -265,8 +268,6 @@ void mock_pathinfo(int mask, const struct mocked_path *mp) + } else + will_return(__wrap_udev_list_entry_get_name, + "SCSI_IDENT_LUN_NAA_EXT"); +- if (mask & DI_SYSFS) +- mock_sysfs_pathinfo(mp); + + if (mp->flags & BL_BY_DEVICE && + (mask & DI_BLACKLIST && mask & DI_SYSFS)) +diff --git a/tests/valid.c b/tests/valid.c +index 693c72c5..8ec803e8 100644 +--- a/tests/valid.c ++++ b/tests/valid.c +@@ -25,13 +25,18 @@ + #include + #include + #include ++#include ++ + #include "globals.c" + #include "util.h" + #include "discovery.h" + #include "wwids.h" + #include "blacklist.h" ++#include "foreign.h" + #include "valid.h" + ++#define PATHINFO_REAL 9999 ++ + int test_fd; + struct udev_device { + int unused; +@@ -78,12 +83,66 @@ struct udev_device *__wrap_udev_device_new_from_subsystem_sysname(struct udev *u + return NULL; + } + ++/* For the "hidden" check in pathinfo() */ ++const char *__wrap_udev_device_get_sysattr_value(struct udev_device *udev_device, ++ const char *sysattr) ++{ ++ check_expected(sysattr); ++ return mock_ptr_type(char *); ++} ++ ++/* For pathinfo() -> is_claimed_by_foreign() */ ++int __wrap_add_foreign(struct udev_device *udev_device) ++{ ++ return mock_type(int); ++} ++ ++/* called from pathinfo() */ ++int __wrap_filter_devnode(struct config *conf, const struct _vector *elist, ++ const char *vendor, const char * product, const char *dev) ++{ ++ return mock_type(int); ++} ++ ++/* called from pathinfo() */ ++int __wrap_filter_device(const struct _vector *blist, const struct _vector *elist, ++ const char *vendor, const char * product, const char *dev) ++{ ++ return mock_type(int); ++} ++ ++/* for common_sysfs_pathinfo() */ ++dev_t __wrap_udev_device_get_devnum(struct udev_device *ud) ++{ ++ return mock_type(dev_t); ++} ++ ++/* for common_sysfs_pathinfo() */ ++int __wrap_sysfs_get_size(struct path *pp, unsigned long long * size) ++{ ++ return mock_type(int); ++} ++ ++/* called in pathinfo() before filter_property() */ ++int __wrap_select_getuid(struct config *conf, struct path *pp) ++{ ++ pp->uid_attribute = mock_ptr_type(char *); ++ return 0; ++} ++ ++int __real_pathinfo(struct path *pp, struct config *conf, int mask); ++ + int __wrap_pathinfo(struct path *pp, struct config *conf, int mask) + { + int ret = mock_type(int); ++ + assert_string_equal(pp->dev, mock_ptr_type(char *)); + assert_int_equal(mask, DI_SYSFS | DI_WWID | DI_BLACKLIST); +- if (ret == PATHINFO_OK) { ++ if (ret == PATHINFO_REAL) { ++ /* for test_filter_property() */ ++ ret = __real_pathinfo(pp, conf, mask); ++ return ret; ++ } else if (ret == PATHINFO_OK) { + pp->uid_attribute = "ID_TEST"; + strlcpy(pp->wwid, mock_ptr_type(char *), WWID_SIZE); + } else +@@ -128,6 +187,7 @@ enum { + STAGE_IS_MULTIPATHED, + STAGE_CHECK_MULTIPATHD, + STAGE_GET_UDEV_DEVICE, ++ STAGE_PATHINFO_REAL, + STAGE_PATHINFO, + STAGE_FILTER_PROPERTY, + STAGE_IS_FAILED, +@@ -167,12 +227,25 @@ static void setup_passing(char *name, char *wwid, unsigned int check_multipathd, + name); + if (stage == STAGE_GET_UDEV_DEVICE) + return; ++ if (stage == STAGE_PATHINFO_REAL) { ++ /* special case for test_filter_property() */ ++ will_return(__wrap_pathinfo, PATHINFO_REAL); ++ will_return(__wrap_pathinfo, name); ++ expect_string(__wrap_udev_device_get_sysattr_value, ++ sysattr, "hidden"); ++ will_return(__wrap_udev_device_get_sysattr_value, NULL); ++ will_return(__wrap_add_foreign, FOREIGN_IGNORED); ++ will_return(__wrap_filter_devnode, MATCH_NOTHING); ++ will_return(__wrap_udev_device_get_devnum, makedev(259, 0)); ++ will_return(__wrap_sysfs_get_size, 0); ++ will_return(__wrap_select_getuid, "ID_TEST"); ++ return; ++ } + will_return(__wrap_pathinfo, PATHINFO_OK); + will_return(__wrap_pathinfo, name); + will_return(__wrap_pathinfo, wwid); + if (stage == STAGE_PATHINFO) + return; +- will_return(__wrap_filter_property, MATCH_PROPERTY_BLIST_EXCEPT); + if (stage == STAGE_FILTER_PROPERTY) + return; + will_return(__wrap_is_failed_wwid, WWID_IS_NOT_FAILED); +@@ -317,24 +390,24 @@ static void test_filter_property(void **state) + /* test blacklist property */ + memset(&pp, 0, sizeof(pp)); + conf.find_multipaths = FIND_MULTIPATHS_STRICT; +- setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_PATHINFO); ++ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_PATHINFO_REAL); + will_return(__wrap_filter_property, MATCH_PROPERTY_BLIST); + assert_int_equal(is_path_valid(name, &conf, &pp, false), + PATH_IS_NOT_VALID); + assert_ptr_equal(pp.udev, &test_udev); +- assert_string_equal(pp.wwid, wwid); ++ + /* test missing property */ + memset(&pp, 0, sizeof(pp)); +- setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_PATHINFO); ++ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_PATHINFO_REAL); + will_return(__wrap_filter_property, MATCH_PROPERTY_BLIST_MISSING); + assert_int_equal(is_path_valid(name, &conf, &pp, false), + PATH_IS_NOT_VALID); +- /* test MATCH_NOTHING fail on is_failed_wwid */ ++ ++ /* test MATCH_NOTHING fail on filter_device */ + memset(&pp, 0, sizeof(pp)); +- setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_PATHINFO); ++ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_PATHINFO_REAL); + will_return(__wrap_filter_property, MATCH_NOTHING); +- will_return(__wrap_is_failed_wwid, WWID_IS_FAILED); +- will_return(__wrap_is_failed_wwid, wwid); ++ will_return(__wrap_filter_device, MATCH_DEVICE_BLIST); + assert_int_equal(is_path_valid(name, &conf, &pp, false), + PATH_IS_NOT_VALID); + } +-- +2.17.2 + diff --git a/0120-libmultipath-pathinfo-call-filter_property-only-with.patch b/0120-libmultipath-pathinfo-call-filter_property-only-with.patch new file mode 100644 index 0000000..c4c8efc --- /dev/null +++ b/0120-libmultipath-pathinfo-call-filter_property-only-with.patch @@ -0,0 +1,88 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 2 Feb 2021 19:55:28 +0100 +Subject: [PATCH] libmultipath: pathinfo: call filter_property only with + DI_BLACKLIST + +With the previous change to call filter_property() after sysfs_pathinfo(), +it can't happen any more that filter_property() is called from pathinfo +with uid_attribute not set. This may cause pathinfo() to return failure +in some cases where it should actually proceed (e.g. when called from +"multipath -m" -> get_refwwid(). Therefore, don't call filter_property() +any more unless DI_BLACKLIST is set. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/discovery.c | 16 ++++++---------- + tests/test-lib.c | 17 +++++++++-------- + 2 files changed, 15 insertions(+), 18 deletions(-) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index febcd0ae..9be94cd1 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -2255,8 +2255,8 @@ int pathinfo(struct path *pp, struct config *conf, int mask) + * uid_attribute is required for filter_property below, + * and needs access to pp->hwe. + */ +- if (!(mask & DI_SYSFS) && !pp->uid_attribute && +- VECTOR_SIZE(pp->hwe) == 0) ++ if (!(mask & DI_SYSFS) && (mask & DI_BLACKLIST) && ++ !pp->uid_attribute && VECTOR_SIZE(pp->hwe) == 0) + mask |= DI_SYSFS; + } + +@@ -2295,17 +2295,13 @@ int pathinfo(struct path *pp, struct config *conf, int mask) + } + } + +- if (pp->udev) { ++ if (mask & DI_BLACKLIST && mask & DI_SYSFS) { + /* uid_attribute is required for filter_property() */ +- if (!pp->uid_attribute) ++ if (pp->udev && !pp->uid_attribute) + select_getuid(conf, pp); + +- if (filter_property(conf, pp->udev, 4, pp->uid_attribute) > 0) +- return PATHINFO_SKIPPED; +- } +- +- if (mask & DI_BLACKLIST && mask & DI_SYSFS) { +- if (filter_device(conf->blist_device, conf->elist_device, ++ if (filter_property(conf, pp->udev, 4, pp->uid_attribute) > 0 || ++ filter_device(conf->blist_device, conf->elist_device, + pp->vendor_id, pp->product_id, pp->dev) > 0 || + filter_protocol(conf->blist_protocol, conf->elist_protocol, + pp) > 0) +diff --git a/tests/test-lib.c b/tests/test-lib.c +index 960a7665..f5542ed0 100644 +--- a/tests/test-lib.c ++++ b/tests/test-lib.c +@@ -260,14 +260,15 @@ void mock_pathinfo(int mask, const struct mocked_path *mp) + if (mask & DI_SYSFS) + mock_sysfs_pathinfo(mp); + +- /* filter_property */ +- will_return(__wrap_udev_device_get_sysname, mp->devnode); +- if (mp->flags & BL_BY_PROPERTY) { +- will_return(__wrap_udev_list_entry_get_name, "BAZ"); +- return; +- } else +- will_return(__wrap_udev_list_entry_get_name, +- "SCSI_IDENT_LUN_NAA_EXT"); ++ if (mask & DI_BLACKLIST) { ++ will_return(__wrap_udev_device_get_sysname, mp->devnode); ++ if (mp->flags & BL_BY_PROPERTY) { ++ will_return(__wrap_udev_list_entry_get_name, "BAZ"); ++ return; ++ } else ++ will_return(__wrap_udev_list_entry_get_name, ++ "SCSI_IDENT_LUN_NAA_EXT"); ++ } + + if (mp->flags & BL_BY_DEVICE && + (mask & DI_BLACKLIST && mask & DI_SYSFS)) +-- +2.17.2 + diff --git a/0121-multipath-w-allow-removing-blacklisted-paths.patch b/0121-multipath-w-allow-removing-blacklisted-paths.patch new file mode 100644 index 0000000..db6fe52 --- /dev/null +++ b/0121-multipath-w-allow-removing-blacklisted-paths.patch @@ -0,0 +1,39 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 2 Feb 2021 21:54:37 +0100 +Subject: [PATCH] multipath -w: allow removing blacklisted paths + +multipath should allow removing WWIDs of paths even if they +are blacklisted. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/configure.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index 3263bb01..598efe05 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -1441,7 +1441,7 @@ static int _get_refwwid(enum mpath_cmds cmd, const char *dev, + return ret; + } + } +- if (pp->udev && pp->uid_attribute && ++ if (flags & DI_BLACKLIST && + filter_property(conf, pp->udev, 3, pp->uid_attribute) > 0) + return PATHINFO_SKIPPED; + refwwid = pp->wwid; +@@ -1466,7 +1466,7 @@ static int _get_refwwid(enum mpath_cmds cmd, const char *dev, + refwwid = dev; + } + +- if (refwwid && strlen(refwwid) && ++ if (flags & DI_BLACKLIST && refwwid && strlen(refwwid) && + filter_wwid(conf->blist_wwid, conf->elist_wwid, refwwid, + NULL) > 0) + return PATHINFO_SKIPPED; +-- +2.17.2 + diff --git a/0122-libmultipath-fix-use-after-free-in-uev_add_path.patch b/0122-libmultipath-fix-use-after-free-in-uev_add_path.patch new file mode 100644 index 0000000..6a5fcad --- /dev/null +++ b/0122-libmultipath-fix-use-after-free-in-uev_add_path.patch @@ -0,0 +1,53 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 1 Feb 2021 19:47:11 -0600 +Subject: [PATCH] libmultipath: fix use-after-free in uev_add_path + +if ev_remove_path() returns success the path has very likely been +deleted. However, if pathinfo() returned something besides PATHINFO_OK, +but ev_remove_path() succeeded, uev_add_path() was still accessing the +the path afterwards, which would likely cause a use-after-free error. +Insted, uev_add_path() should only continue to access the path if +ev_remove_path() didn't succeed. + +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 15 +++++++-------- + 1 file changed, 7 insertions(+), 8 deletions(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 425492a9..19679848 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -890,13 +890,7 @@ uev_add_path (struct uevent *uev, struct vectors * vecs, int need_do_map) + */ + pp->mpp = prev_mpp; + ret = ev_remove_path(pp, vecs, true); +- if (r == PATHINFO_OK && !ret) +- /* +- * Path successfully freed, move on to +- * "new path" code path below +- */ +- pp = NULL; +- else { ++ if (ret != 0) { + /* + * Failure in ev_remove_path will keep + * path in pathvec in INIT_REMOVED state +@@ -907,7 +901,12 @@ uev_add_path (struct uevent *uev, struct vectors * vecs, int need_do_map) + dm_fail_path(pp->mpp->alias, pp->dev_t); + condlog(1, "%s: failed to re-add path still mapped in %s", + pp->dev, pp->mpp->alias); +- } ++ } else if (r == PATHINFO_OK) ++ /* ++ * Path successfully freed, move on to ++ * "new path" code path below ++ */ ++ pp = NULL; + } else if (r == PATHINFO_SKIPPED) { + condlog(3, "%s: remove blacklisted path", + uev->kernel); +-- +2.17.2 + diff --git a/0123-kpartx-free-loop-device-after-listing-partitions.patch b/0123-kpartx-free-loop-device-after-listing-partitions.patch new file mode 100644 index 0000000..4db7cfd --- /dev/null +++ b/0123-kpartx-free-loop-device-after-listing-partitions.patch @@ -0,0 +1,61 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 9 Feb 2021 17:16:04 -0600 +Subject: [PATCH] kpartx: free loop device after listing partitions + +If "kpartx -l" is run on a file that doesn't already have a loop device +associated with it, it will create a loop device to run the command. +Starting with da59d15c6 ("Fix loopback file with kpartx -av"), it will +not free the loop device when exitting. This is because it checks if the +the file it stat()ed is a regular file, before freeing the loop device. +However, after da59d15c6, stat() is rerun on the loop device itself, so +the check fails. There is no need to check this, if loopcreated is +true, then the file will be a kpartx created loop device, and should be +freed. + +Also, keep kpartx from printing that the loop device has been removed +at normal verbosity. + +Fixes: da59d15c6 ("Fix loopback file with kpartx -av") +Signed-off-by: Benjamin Marzinski +--- + kpartx/kpartx.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/kpartx/kpartx.c b/kpartx/kpartx.c +index 6a7933fa..8ff116b8 100644 +--- a/kpartx/kpartx.c ++++ b/kpartx/kpartx.c +@@ -424,7 +424,7 @@ main(int argc, char **argv){ + fprintf(stderr, "can't del loop : %s\n", + loopdev); + r = 1; +- } else ++ } else if (verbose) + fprintf(stderr, "loop deleted : %s\n", loopdev); + } + goto end; +@@ -668,16 +668,17 @@ main(int argc, char **argv){ + if (n > 0) + break; + } +- if (what == LIST && loopcreated && S_ISREG (buf.st_mode)) { ++ if (what == LIST && loopcreated) { + if (fd != -1) + close(fd); + if (del_loop(device)) { + if (verbose) +- printf("can't del loop : %s\n", ++ fprintf(stderr, "can't del loop : %s\n", + device); + exit(1); + } +- printf("loop deleted : %s\n", device); ++ if (verbose) ++ fprintf(stderr, "loop deleted : %s\n", device); + } + + end: +-- +2.17.2 + diff --git a/0103-RH-fixup-udev-rules-for-redhat.patch b/0124-RH-fixup-udev-rules-for-redhat.patch similarity index 100% rename from 0103-RH-fixup-udev-rules-for-redhat.patch rename to 0124-RH-fixup-udev-rules-for-redhat.patch diff --git a/0104-RH-Remove-the-property-blacklist-exception-builtin.patch b/0125-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 100% rename from 0104-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0125-RH-Remove-the-property-blacklist-exception-builtin.patch diff --git a/0105-RH-don-t-start-without-a-config-file.patch b/0126-RH-don-t-start-without-a-config-file.patch similarity index 97% rename from 0105-RH-don-t-start-without-a-config-file.patch rename to 0126-RH-don-t-start-without-a-config-file.patch index 2f8d791..2931726 100644 --- a/0105-RH-don-t-start-without-a-config-file.patch +++ b/0126-RH-don-t-start-without-a-config-file.patch @@ -81,12 +81,12 @@ index 048a838d..8bd47a80 100644 . .\" ---------------------------------------------------------------------------- diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service -index ba24983e..17434cef 100644 +index 7d547fa7..af592057 100644 --- a/multipathd/multipathd.service +++ b/multipathd/multipathd.service @@ -4,6 +4,7 @@ Wants=systemd-udev-trigger.service systemd-udev-settle.service Before=iscsi.service iscsid.service lvm2-activation-early.service - Before=local-fs-pre.target blk-availability.service + Before=local-fs-pre.target blk-availability.service shutdown.target After=multipathd.socket systemd-udev-trigger.service systemd-udev-settle.service +ConditionPathExists=/etc/multipath.conf DefaultDependencies=no diff --git a/0106-RH-Fix-nvme-function-missing-argument.patch b/0127-RH-Fix-nvme-function-missing-argument.patch similarity index 100% rename from 0106-RH-Fix-nvme-function-missing-argument.patch rename to 0127-RH-Fix-nvme-function-missing-argument.patch diff --git a/0107-RH-use-rpm-optflags-if-present.patch b/0128-RH-use-rpm-optflags-if-present.patch similarity index 100% rename from 0107-RH-use-rpm-optflags-if-present.patch rename to 0128-RH-use-rpm-optflags-if-present.patch diff --git a/0108-RH-add-mpathconf.patch b/0129-RH-add-mpathconf.patch similarity index 93% rename from 0108-RH-add-mpathconf.patch rename to 0129-RH-add-mpathconf.patch index 503fef2..346251a 100644 --- a/0108-RH-add-mpathconf.patch +++ b/0129-RH-add-mpathconf.patch @@ -69,7 +69,7 @@ index b9bbb3cf..e720c7f6 100644 $(RM) core *.o $(EXEC) *.gz diff --git a/multipath/mpathconf b/multipath/mpathconf new file mode 100644 -index 00000000..f34003c9 +index 00000000..2f4f3eaf --- /dev/null +++ b/multipath/mpathconf @@ -0,0 +1,555 @@ @@ -129,7 +129,7 @@ index 00000000..f34003c9 + echo "Disable: --disable" + echo "Only allow certain wwids (instead of enable): --allow " + echo "Set user_friendly_names (Default y): --user_friendly_names " -+ echo "Set find_multipaths (Default y): --find_multipaths " ++ echo "Set find_multipaths (Default y): --find_multipaths " + echo "Set default property blacklist (Default y): --property_blacklist " + echo "Set enable_foreign to show foreign devices (Default n): --enable_foreign " + echo "Load the dm-multipath modules on enable (Default y): --with_module " @@ -299,8 +299,12 @@ index 00000000..f34003c9 + echo "--user_friendly_names must be either 'y' or 'n'" + exit 1 + fi -+ if [ -n "$FIND" ] && [ "$FIND" != "y" -a "$FIND" != "n" ]; then -+ echo "--find_multipaths must be either 'y' or 'n'" ++ if [ "$FIND" = "y" ]; then ++ FIND="yes" ++ elif [ "$FIND" = "n" ]; then ++ FIND="no" ++ elif [ -n "$FIND" ] && [ "$FIND" != "yes" -a "$FIND" != "no" -a "$FIND" != "strict" -a "$FIND" != "greedy" -a "$FIND" != "smart" ]; then ++ echo "--find_multipaths must be one of 'yes' 'no' 'strict' 'greedy' or 'smart'" + exit 1 + fi + if [ -n "$PROPERTY" ] && [ "$PROPERTY" != "y" -a "$PROPERTY" != "n" ]; then @@ -402,10 +406,11 @@ index 00000000..f34003c9 +fi + +if [ "$HAVE_DEFAULTS" = "1" ]; then -+ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*find_multipaths[[:space:]]*\(yes\|1\)" ; then -+ HAVE_FIND=1 -+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*find_multipaths[[:space:]]*\(no\|0\)" ; then -+ HAVE_FIND=0 ++ HAVE_FIND=`sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | sed -n 's/^[[:blank:]]*find_multipaths[[:blank:]]*\([^[:blank:]]*\).*$/\1/p' | sed -n 1p` ++ if [ "$HAVE_FIND" = "1" ]; then ++ HAVE_FIND="yes" ++ elif [ "$HAVE_FIND" = "0" ]; then ++ HAVE_FIND="no" + fi + if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]]*\(yes\|1\)" ; then + HAVE_FRIENDLY=1 @@ -435,10 +440,10 @@ index 00000000..f34003c9 + else + echo "multipath is disabled" + fi -+ if [ -z "$HAVE_FIND" -o "$HAVE_FIND" = 0 ]; then -+ echo "find_multipaths is disabled" ++ if [ -z "$HAVE_FIND" ]; then ++ echo "find_multipaths is no" + else -+ echo "find_multipaths is enabled" ++ echo "find_multipaths is $HAVE_FIND" + fi + if [ -z "$HAVE_FRIENDLY" -o "$HAVE_FRIENDLY" = 0 ]; then + echo "user_friendly_names is disabled" @@ -530,19 +535,14 @@ index 00000000..f34003c9 + fi +fi + -+if [ "$FIND" = "n" ]; then -+ if [ "$HAVE_FIND" = 1 ]; then -+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*find_multipaths[[:space:]]*\(yes\|1\)/ find_multipaths no/' $TMPFILE -+ CHANGED_CONFIG=1 -+ fi -+elif [ "$FIND" = "y" ]; then ++if [ -n "$FIND" ]; then + if [ -z "$HAVE_FIND" ]; then + sed -i '/^defaults[[:space:]]*{/ a\ -+ find_multipaths yes ++ find_multipaths '"$FIND"' +' $TMPFILE + CHANGED_CONFIG=1 -+ elif [ "$HAVE_FIND" = 0 ]; then -+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*find_multipaths[[:space:]]*\(no\|0\)/ find_multipaths yes/' $TMPFILE ++ elif [ "$FIND" != "$HAVE_FIND" ]; then ++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:blank:]]*find_multipaths[[:blank:]]*[^[:blank:]]*/ find_multipaths '"$FIND"'/' $TMPFILE + CHANGED_CONFIG=1 + fi +fi @@ -630,7 +630,7 @@ index 00000000..f34003c9 +fi diff --git a/multipath/mpathconf.8 b/multipath/mpathconf.8 new file mode 100644 -index 00000000..b82961d6 +index 00000000..83515eb4 --- /dev/null +++ b/multipath/mpathconf.8 @@ -0,0 +1,135 @@ @@ -674,9 +674,9 @@ index 00000000..b82961d6 +already exists, mpathconf will edit it. If it does not exist, mpathconf will +create a default file with +.B user_friendly_names -+and ++set and +.B find_multipaths -+set. To disable these, use the ++set to \fByes\fP. To disable these, use the +.B --user_friendly_names n +and +.B --find_multipaths n @@ -713,13 +713,13 @@ index 00000000..b82961d6 +defaults section. If set to \fBn\fP, this removes the line, if present. This +command can be used along with any other command. +.TP -+.B --find_multipaths\fP { \fBy\fP | \fBn\fP } -+If set to \fBy\fP, this adds the line -+.B find_multipaths yes ++.B --find_multipaths\fP { \fByes\fP | \fBno\fP | \fBstrict\fP | \fBgreedy\fP | \fBsmart\fP } ++If set to \fB\fP, this adds the line ++.B find_multipaths +to the +.B /etc/multipath.conf -+defaults section. If set to \fBn\fP, this removes the line, if present. This -+command can be used along with any other command. ++defaults section. This command can be used along with any other command. ++\fBy\fP and \fBn\fP can be used instead of \fByes\fP and \fBno\fP. +.TP +.B --property_blacklist \fP { \fBy\fP | \fBn\fP } +If set to \fBy\fP, this adds the line diff --git a/0109-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0130-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 99% rename from 0109-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0130-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch index cdce408..3f0a9ad 100644 --- a/0109-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +++ b/0130-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch @@ -138,7 +138,7 @@ index 5b29a5d9..0478f4e7 100644 Remove the WWID for the specified device from the WWIDs file. . diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service -index 17434cef..0fbcc46b 100644 +index af592057..bc8fa07a 100644 --- a/multipathd/multipathd.service +++ b/multipathd/multipathd.service @@ -15,6 +15,7 @@ Type=notify diff --git a/0110-RH-reset-default-find_mutipaths-value-to-off.patch b/0131-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 100% rename from 0110-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0131-RH-reset-default-find_mutipaths-value-to-off.patch diff --git a/0111-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0132-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 100% rename from 0111-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0132-RH-attempt-to-get-ANA-info-via-sysfs-first.patch diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 3969445..a304363 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.8.5 -Release: 3%{?dist} +Release: 4%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -112,15 +112,36 @@ Patch0099: 0099-multipathd-avoid-io_err_stat-ABBA-deadlock.patch Patch0100: 0100-multipathd-use-get_monotonic_time-in-io_err_stat-cod.patch Patch0101: 0101-multipathd-combine-free_io_err_stat_path-and-destroy.patch Patch0102: 0102-multipathd-cleanup-logging-for-marginal-paths.patch -Patch0103: 0103-RH-fixup-udev-rules-for-redhat.patch -Patch0104: 0104-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0105: 0105-RH-don-t-start-without-a-config-file.patch -Patch0106: 0106-RH-Fix-nvme-function-missing-argument.patch -Patch0107: 0107-RH-use-rpm-optflags-if-present.patch -Patch0108: 0108-RH-add-mpathconf.patch -Patch0109: 0109-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0110: 0110-RH-reset-default-find_mutipaths-value-to-off.patch -Patch0111: 0111-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0103: 0103-libmultipath-fix-NULL-dereference-in-find_path_by_de.patch +Patch0104: 0104-libmultipath-snprint_devices-avoid-NULL-dereference.patch +Patch0105: 0105-libmpathpersist-fix-thread-safety-of-default-functio.patch +Patch0106: 0106-Added-github-action-for-building.patch +Patch0107: 0107-github-workflow-use-zram-device-as-test-block-device.patch +Patch0108: 0108-github-workflow-use-explicit-Ubuntu-version.patch +Patch0109: 0109-github-workflow-add-valgrind-tests.patch +Patch0110: 0110-github-workflow-run-apt-get-update.patch +Patch0111: 0111-github-workflow-add-tests-with-gcc-10-and-clang.patch +Patch0112: 0112-multipathd-Fix-multipathd-stopping-on-shutdown.patch +Patch0113: 0113-libmultipath-use-3rd-digit-as-transport_id-for-expan.patch +Patch0114: 0114-libmultipath-sysfs_set_nexus_loss_tmo-support-SAS-ex.patch +Patch0115: 0115-multipathd-add-code-to-initalize-unwinder.patch +Patch0116: 0116-libmultipath-check-if-adopt_path-really-added-curren.patch +Patch0117: 0117-multipathd-ev_add_path-fail-if-add_map_with_path-fai.patch +Patch0118: 0118-libmultipath-check-return-value-of-udev_device_get_d.patch +Patch0119: 0119-pathinfo-call-filter_property-after-sysfs_pathinfo.patch +Patch0120: 0120-libmultipath-pathinfo-call-filter_property-only-with.patch +Patch0121: 0121-multipath-w-allow-removing-blacklisted-paths.patch +Patch0122: 0122-libmultipath-fix-use-after-free-in-uev_add_path.patch +Patch0123: 0123-kpartx-free-loop-device-after-listing-partitions.patch +Patch0124: 0124-RH-fixup-udev-rules-for-redhat.patch +Patch0125: 0125-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0126: 0126-RH-don-t-start-without-a-config-file.patch +Patch0127: 0127-RH-Fix-nvme-function-missing-argument.patch +Patch0128: 0128-RH-use-rpm-optflags-if-present.patch +Patch0129: 0129-RH-add-mpathconf.patch +Patch0130: 0130-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0131: 0131-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0132: 0132-RH-attempt-to-get-ANA-info-via-sysfs-first.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -318,6 +339,15 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Thu Feb 11 2021 Benjamin Marzinski - 0.8.5-4 +- Update Source to upstream version 0.8.5 plus post tag commits + * Patches 0001-0121 are from + https://github.com/openSUSE/multipath-tools/tree/queue and are + already queued for upstream + * Patches 0122&0123 have been posted for upstream inclusion +- Rename files + * Previous patches 0103-0111 are now patches 0124-0132 + * Tue Jan 26 2021 Fedora Release Engineering - 0.8.5-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild From 7812c0e3964ccc3aee5917575ad97c27fb0215d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 2 Mar 2021 16:13:59 +0100 Subject: [PATCH 15/67] Rebuilt for updated systemd-rpm-macros See https://pagure.io/fesco/issue/2583. --- device-mapper-multipath.spec | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index a304363..ec5a48f 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.8.5 -Release: 4%{?dist} +Release: 5%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -339,6 +339,10 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Tue Mar 02 2021 Zbigniew Jędrzejewski-Szmek - 0.8.5-5 +- Rebuilt for updated systemd-rpm-macros + See https://pagure.io/fesco/issue/2583. + * Thu Feb 11 2021 Benjamin Marzinski - 0.8.5-4 - Update Source to upstream version 0.8.5 plus post tag commits * Patches 0001-0121 are from From b05147c3568a82643147f8c3f245a34a11f25526 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Fri, 26 Mar 2021 13:33:56 -0500 Subject: [PATCH 16/67] device-mapper-multipath-0.8.5-6 Change patch format to remove Git version * Patches 0001-0122 only have the patch format modified Update to the head of the upstream staging branch plus redhat patches * Patches 0123-0134 & 1036-0142 are from the upstream staging branch * Patches 0143-1046 have been submitted upstream * Patch 0156 is a Red Hat only patch. Red Hat udev rules set ID_SERIAL from 60-persistent-storage.rules instead of 55-scsi-sg3_id.rules. Multipath's parse_vpd_pg83() function needs to match the ID_SERIAL value from udev. Rename files * Previous patches 0123-0132 are now patches 1035 & 0147-0155 --- ...path.conf-manpage-uxsock_timeout-def.patch | 3 - ...find_mpe-don-t-match-with-empty-WWID.patch | 3 - ...ibmultipath-copy-mpp-hwe-from-pp-hwe.patch | 3 - ...map_present_by_uuid-fix-dm_task_crea.patch | 3 - 0005-libdmmp-tests-fix-compilation.patch | 3 - ...io-constify-some-function-parameters.patch | 3 - ...ckers-prio-allow-non-lazy-.so-loadin.patch | 3 - ...Makefiles-separate-rules-for-.so-and.patch | 3 - ...h-create-separate-.so-for-unit-tests.patch | 3 - ...bmultipath-add-linker-version-script.patch | 3 - ...athpersist-add-linker-version-script.patch | 3 - ...ibmpathcmd-add-linker-version-script.patch | 3 - ...sist-initialize-mpp-hwe-in-get_mpvec.patch | 3 - ...athd-allow-shutdown-during-configure.patch | 3 - ...-sending-READY-1-to-systemd-on-early.patch | 3 - ...nd-STOPPING-1-to-systemd-on-shutdown.patch | 3 - ...RELOADING-1-to-systemd-on-DAEMON_CON.patch | 3 - ...volatile-qualifier-for-running_state.patch | 3 - ...alize-and-fix-wait_for_state_change_.patch | 3 - ..._config_state-avoid-code-duplication.patch | 3 - ...cancel-threads-early-during-shutdown.patch | 3 - ...s-don-t-call-dm_lib_release-any-more.patch | 3 - ...mapper-refactor-libdm-version-determ.patch | 3 - ...tect-racy-libdevmapper-calls-with-a-.patch | 3 - ...stify-file-argument-in-config-parser.patch | 3 - ...vide-defaults-for-get-put-_multipath.patch | 3 - ...allow-using-libmultipath-get-put-_mu.patch | 3 - ...t_put-_multipath_config-from-libmult.patch | 3 - ...-get-put-_multipath_config-from-libm.patch | 3 - ...ltipath-add-udev-and-logsink-symbols.patch | 3 - 0031-multipath-remove-logsink-and-udev.patch | 3 - ...persist-call-libmultipath_-init-exit.patch | 3 - ...mpathpersist-remove-logsink-and-udev.patch | 3 - 0034-multipathd-remove-logsink-and-udev.patch | 3 - ...-add-Vexata-by-StorCentric-VX-arrays.patch | 3 - ...Violin-and-Nexsan-were-bought-by-Sto.patch | 3 - ...h-fix-memory-leaks-in-coalesce_paths.patch | 3 - ...replace-hidden-tab-by-space-in-hwtab.patch | 3 - ...ipathd-uxlsnr-avoid-deadlock-on-exit.patch | 3 - 0040-multipathd-Fix-liburcu-memory-leak.patch | 3 - ...handling-of-io_err_stat_attr-into-li.patch | 3 - ...vecs-desctruction-into-cleanup-funct.patch | 3 - ...-multipathd-make-some-globals-static.patch | 3 - ...threads-destruction-into-separate-fu.patch | 3 - ...conf-destruction-into-separate-funct.patch | 3 - ...pid-destruction-into-separate-functi.patch | 3 - 0047-multipathd-close-pidfile-on-exit.patch | 3 - ...elper-for-systemd-notification-at-ex.patch | 3 - ...ld-call-cleanups-in-failure-case-too.patch | 3 - ...ch_all_dmevents-check-if-waiter-is-i.patch | 3 - ...-error-message-if-config-can-t-be-lo.patch | 3 - 0052-libmultipath-add-libmp_dm_exit.patch | 3 - ...tipathd-fixup-libdm-deinitialization.patch | 3 - ..._thread_stop-check-if-logarea-is-ini.patch | 3 - ...pathd-add-cleanup_child-exit-handler.patch | 3 - ...-fix-log_thread-startup-and-teardown.patch | 3 - ...cleanup_-prio-checkers-foreign-to-li.patch | 3 - ...path-use-atexit-for-cleanup-handlers.patch | 3 - ...sist-use-atexit-for-cleanup-handlers.patch | 3 - ...ltipath-fix-leak-in-check_path_valid.patch | 3 - ...mpath-tools.supp-file-with-valgrind-.patch | 3 - ...e-libmp_verbosity-to-track-verbosity.patch | 3 - ...ntroduce-symbolic-values-for-logsink.patch | 3 - 0064-libmultipath-simplify-dlog.patch | 3 - ...d-common-code-for-k-and-command-args.patch | 3 - 0066-multipathd-sanitize-uxsock_listen.patch | 3 - ...-race-between-log_safe-and-log_threa.patch | 3 - ...-multipath-add-libmpathvalid-library.patch | 3 - ...tests-and-unit-tests-for-libmpathval.patch | 3 - ...th-add-uid-failback-for-dasd-devices.patch | 3 - ...nge-log-level-for-null-uid_attribute.patch | 3 - ...ve-fast_io_fail-defines-to-structs.h.patch | 3 - ...-eh_deadline-multipath.conf-paramete.patch | 3 - ...e-redundant-vector_free-int-configur.patch | 3 - ...factor-out-code-to-get-vpd-page-data.patch | 3 - ...ultipath-limit-reading-0xc9-vpd-page.patch | 3 - ...ath-move-logq_lock-handling-to-log.c.patch | 3 - ...ipath-protect-logarea-with-logq_lock.patch | 3 - ...vent-DSO-unloading-with-astray-check.patch | 3 - ...-force-map-reload-if-udev-incomplete.patch | 3 - ...-tools-avoid-access-to-etc-localtime.patch | 3 - ...make-sure-plugin-DSOs-use-symbol-ver.patch | 3 - ...multipath.version-add-missing-symbol.patch | 3 - ...tests-unversioned-.so-for-valgrind-t.patch | 3 - ...unit-tests-fix-memory-leaks-in-mpath.patch | 3 - ...x-Register-and-Ignore-with-0x00-SARK.patch | 3 - ...ate-prkeys-file-on-changing-registra.patch | 3 - ...n-about-missing-braces-at-end-of-mul.patch | 3 - ...ore-multipaths-sections-without-wwid.patch | 3 - ...tipath-fix-format-warning-with-clang.patch | 3 - ...th-check-for-null-wwid-before-strcmp.patch | 3 - ...-Improve-checker_timeout-description.patch | 3 - ...ath-checkint-not-changed-when-path-s.patch | 3 - ...ect_action-skip-is_mpp_known_to_udev.patch | 3 - ...lesce_paths-stop-triggering-spurious.patch | 3 - ...d-uev_trigger-handle-incomplete-ADD-.patch | 3 - ...ath-make-find_err_path_by_dev-static.patch | 3 - ...id-io_err_stat-crash-during-shutdown.patch | 3 - ...athd-avoid-io_err_stat-ABBA-deadlock.patch | 3 - ...et_monotonic_time-in-io_err_stat-cod.patch | 3 - ...ne-free_io_err_stat_path-and-destroy.patch | 3 - ...d-cleanup-logging-for-marginal-paths.patch | 3 - ...-NULL-dereference-in-find_path_by_de.patch | 3 - ...print_devices-avoid-NULL-dereference.patch | 3 - ...fix-thread-safety-of-default-functio.patch | 3 - 0106-Added-github-action-for-building.patch | 3 - ...use-zram-device-as-test-block-device.patch | 3 - ...workflow-use-explicit-Ubuntu-version.patch | 3 - 0109-github-workflow-add-valgrind-tests.patch | 3 - 0110-github-workflow-run-apt-get-update.patch | 3 - ...flow-add-tests-with-gcc-10-and-clang.patch | 3 - ...-Fix-multipathd-stopping-on-shutdown.patch | 3 - ...-3rd-digit-as-transport_id-for-expan.patch | 3 - ...fs_set_nexus_loss_tmo-support-SAS-ex.patch | 3 - ...pathd-add-code-to-initalize-unwinder.patch | 3 - ...ck-if-adopt_path-really-added-curren.patch | 3 - ...d_path-fail-if-add_map_with_path-fai.patch | 3 - ...ck-return-value-of-udev_device_get_d.patch | 3 - ...filter_property-after-sysfs_pathinfo.patch | 3 - ...hinfo-call-filter_property-only-with.patch | 3 - ...h-w-allow-removing-blacklisted-paths.patch | 3 - ...h-fix-use-after-free-in-uev_add_path.patch | 6 +- ...tests-fix-stringop-overflow-build-er.patch | 52 ++ ...anup-code-to-strip-wwid-trailing-spa.patch | 44 ++ ...-cleanup-uid_attribute-checking-code.patch | 53 ++ ...echeck_wwid-option-to-verify-the-pat.patch | 453 +++++++++++++++ ...heck-if-user_friendly_name-is-in-use.patch | 231 ++++++++ ...ests-for-checking-if-alias-is-in-use.patch | 525 ++++++++++++++++++ ...add-DellEMC-PowerStore-to-hardware-t.patch | 40 ++ ...delete-a-space-in-multipath.conf.5-t.patch | 30 + ...tests-allow-control-of-test-verbosit.patch | 253 +++++++++ ...devt-test-avoid-failure-when-run-in-.patch | 63 +++ ...fix-compilation-errors-on-32-bit-mus.patch | 96 ++++ ...-compilation-error-with-gcc-10-on-i3.patch | 58 ++ ...loop-device-after-listing-partitions.patch | 6 +- ...ge-update_multipath_table-and-update.patch | 229 ++++++++ ...-mpath.rules-run-multipath-U-with-v1.patch | 41 ++ ...tests-check-if-sys-dev-block-is-non-.patch | 62 +++ ...thd-reduce-log-levels-in-cli_add_map.patch | 36 ++ ...fix-format-in-multipath.conf.5-to-be.patch | 30 + ...use-same-format-for-default-values-i.patch | 41 ++ ...d-fix-NULL-dereference-in-check_path.patch | 39 ++ ...id-infinite-loop-with-bad-vpd-page-8.patch | 28 + ...ath-fix-priorities-in-parse_vpd_pg83.patch | 46 ++ ...ve-getting-parent-udevice-in-rescan_.patch | 40 ++ ...-trigger-uevent-for-partitions-on-ww.patch | 26 + ... 0147-RH-fixup-udev-rules-for-redhat.patch | 3 - ...property-blacklist-exception-builtin.patch | 11 +- ...RH-don-t-start-without-a-config-file.patch | 9 +- ...H-Fix-nvme-function-missing-argument.patch | 3 - ... 0151-RH-use-rpm-optflags-if-present.patch | 3 - ...hconf.patch => 0152-RH-add-mpathconf.patch | 7 +- ...om-kernel-cmdline-mpath.wwids-with-A.patch | 11 +- ...-default-find_mutipaths-value-to-off.patch | 5 +- ...empt-to-get-ANA-info-via-sysfs-first.patch | 3 - ...-parse_vpd_pg83-match-scsi_id-output.patch | 51 ++ device-mapper-multipath.spec | 59 +- 157 files changed, 2633 insertions(+), 423 deletions(-) create mode 100644 0123-multipath-tools-tests-fix-stringop-overflow-build-er.patch create mode 100644 0124-libmultipath-cleanup-code-to-strip-wwid-trailing-spa.patch create mode 100644 0125-libmultipath-cleanup-uid_attribute-checking-code.patch create mode 100644 0126-multipathd-add-recheck_wwid-option-to-verify-the-pat.patch create mode 100644 0127-libmultipath-check-if-user_friendly_name-is-in-use.patch create mode 100644 0128-tests-add-tests-for-checking-if-alias-is-in-use.patch create mode 100644 0129-multipath-tools-add-DellEMC-PowerStore-to-hardware-t.patch create mode 100644 0130-multipath-tools-delete-a-space-in-multipath.conf.5-t.patch create mode 100644 0131-multipath-tools-tests-allow-control-of-test-verbosit.patch create mode 100644 0132-multipath-tools-devt-test-avoid-failure-when-run-in-.patch create mode 100644 0133-multipath-tools-fix-compilation-errors-on-32-bit-mus.patch create mode 100644 0134-libmultipath-fix-compilation-error-with-gcc-10-on-i3.patch rename 0123-kpartx-free-loop-device-after-listing-partitions.patch => 0135-kpartx-free-loop-device-after-listing-partitions.patch (95%) create mode 100644 0136-libmultipath-merge-update_multipath_table-and-update.patch create mode 100644 0137-11-dm-mpath.rules-run-multipath-U-with-v1.patch create mode 100644 0138-multipath-tools-tests-check-if-sys-dev-block-is-non-.patch create mode 100644 0139-multipathd-reduce-log-levels-in-cli_add_map.patch create mode 100644 0140-multipath-tools-fix-format-in-multipath.conf.5-to-be.patch create mode 100644 0141-multipath-tools-use-same-format-for-default-values-i.patch create mode 100644 0142-multipathd-fix-NULL-dereference-in-check_path.patch create mode 100644 0143-libmultipath-avoid-infinite-loop-with-bad-vpd-page-8.patch create mode 100644 0144-libmultipath-fix-priorities-in-parse_vpd_pg83.patch create mode 100644 0145-multipathd-improve-getting-parent-udevice-in-rescan_.patch create mode 100644 0146-multipathd-don-t-trigger-uevent-for-partitions-on-ww.patch rename 0124-RH-fixup-udev-rules-for-redhat.patch => 0147-RH-fixup-udev-rules-for-redhat.patch (99%) rename 0125-RH-Remove-the-property-blacklist-exception-builtin.patch => 0148-RH-Remove-the-property-blacklist-exception-builtin.patch (95%) rename 0126-RH-don-t-start-without-a-config-file.patch => 0149-RH-don-t-start-without-a-config-file.patch (96%) rename 0127-RH-Fix-nvme-function-missing-argument.patch => 0150-RH-Fix-nvme-function-missing-argument.patch (98%) rename 0128-RH-use-rpm-optflags-if-present.patch => 0151-RH-use-rpm-optflags-if-present.patch (99%) rename 0129-RH-add-mpathconf.patch => 0152-RH-add-mpathconf.patch (99%) rename 0130-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch => 0153-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch (96%) rename 0131-RH-reset-default-find_mutipaths-value-to-off.patch => 0154-RH-reset-default-find_mutipaths-value-to-off.patch (95%) rename 0132-RH-attempt-to-get-ANA-info-via-sysfs-first.patch => 0155-RH-attempt-to-get-ANA-info-via-sysfs-first.patch (99%) create mode 100644 0156-RH-make-parse_vpd_pg83-match-scsi_id-output.patch diff --git a/0001-Change-the-multipath.conf-manpage-uxsock_timeout-def.patch b/0001-Change-the-multipath.conf-manpage-uxsock_timeout-def.patch index 02b2e18..21428df 100644 --- a/0001-Change-the-multipath.conf-manpage-uxsock_timeout-def.patch +++ b/0001-Change-the-multipath.conf-manpage-uxsock_timeout-def.patch @@ -25,6 +25,3 @@ index d2101ed6..7242d39b 100644 .RE . . --- -2.17.2 - diff --git a/0002-libmultipath-find_mpe-don-t-match-with-empty-WWID.patch b/0002-libmultipath-find_mpe-don-t-match-with-empty-WWID.patch index 2d38590..6ceeac1 100644 --- a/0002-libmultipath-find_mpe-don-t-match-with-empty-WWID.patch +++ b/0002-libmultipath-find_mpe-don-t-match-with-empty-WWID.patch @@ -22,6 +22,3 @@ index b9bdbdbc..df0f8f45 100644 return NULL; vector_foreach_slot (mptable, mpe, i) --- -2.17.2 - diff --git a/0003-libmultipath-copy-mpp-hwe-from-pp-hwe.patch b/0003-libmultipath-copy-mpp-hwe-from-pp-hwe.patch index 63ff6a5..fa4da39 100644 --- a/0003-libmultipath-copy-mpp-hwe-from-pp-hwe.patch +++ b/0003-libmultipath-copy-mpp-hwe-from-pp-hwe.patch @@ -255,6 +255,3 @@ index a4abbb27..eedc6c10 100644 if (setup_map(mpp, params, PARAMS_SIZE, vecs)) { condlog(0, "%s: failed to setup map for" " removal of path %s", mpp->alias, pp->dev); --- -2.17.2 - diff --git a/0004-libmultipath-dm_map_present_by_uuid-fix-dm_task_crea.patch b/0004-libmultipath-dm_map_present_by_uuid-fix-dm_task_crea.patch index c3a0a18..f4177ec 100644 --- a/0004-libmultipath-dm_map_present_by_uuid-fix-dm_task_crea.patch +++ b/0004-libmultipath-dm_map_present_by_uuid-fix-dm_task_crea.patch @@ -26,6 +26,3 @@ index 7f093617..0bc1d16e 100644 goto out; dm_task_no_open_count(dmt); --- -2.17.2 - diff --git a/0005-libdmmp-tests-fix-compilation.patch b/0005-libdmmp-tests-fix-compilation.patch index d1d9955..ae341cf 100644 --- a/0005-libdmmp-tests-fix-compilation.patch +++ b/0005-libdmmp-tests-fix-compilation.patch @@ -38,6 +38,3 @@ index d944e1e3..a940b576 100644 { struct dmmp_context *ctx = NULL; struct dmmp_mpath **dmmp_mps = NULL; --- -2.17.2 - diff --git a/0006-libmultipath-prio-constify-some-function-parameters.patch b/0006-libmultipath-prio-constify-some-function-parameters.patch index 80771ea..94fbd17 100644 --- a/0006-libmultipath-prio-constify-some-function-parameters.patch +++ b/0006-libmultipath-prio-constify-some-function-parameters.patch @@ -48,6 +48,3 @@ index 599d1d88..26754f78 100644 int prio_getprio (struct prio *, struct path *, unsigned int); void prio_get (char *, struct prio *, char *, char *); void prio_put (struct prio *); --- -2.17.2 - diff --git a/0007-libmultipath-checkers-prio-allow-non-lazy-.so-loadin.patch b/0007-libmultipath-checkers-prio-allow-non-lazy-.so-loadin.patch index 90a2f25..bdea162 100644 --- a/0007-libmultipath-checkers-prio-allow-non-lazy-.so-loadin.patch +++ b/0007-libmultipath-checkers-prio-allow-non-lazy-.so-loadin.patch @@ -85,6 +85,3 @@ index 3a718ba5..c92bde7f 100644 return 0; } --- -2.17.2 - diff --git a/0008-multipath-tools-Makefiles-separate-rules-for-.so-and.patch b/0008-multipath-tools-Makefiles-separate-rules-for-.so-and.patch index edc3e66..81ee846 100644 --- a/0008-multipath-tools-Makefiles-separate-rules-for-.so-and.patch +++ b/0008-multipath-tools-Makefiles-separate-rules-for-.so-and.patch @@ -91,6 +91,3 @@ index 62ba16e8..40028556 100644 $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(libdir) --- -2.17.2 - diff --git a/0009-libmultipath-create-separate-.so-for-unit-tests.patch b/0009-libmultipath-create-separate-.so-for-unit-tests.patch index 38a01d7..a342425 100644 --- a/0009-libmultipath-create-separate-.so-for-unit-tests.patch +++ b/0009-libmultipath-create-separate-.so-for-unit-tests.patch @@ -82,6 +82,3 @@ index d26b3ce7..9658c9fd 100644 $(CC) $(CFLAGS) -o $@ $(LDFLAGS) $< $($@_TESTDEPS) $($@_OBJDEPS) \ $(LIBDEPS) $($@_LIBDEPS) \ $(shell cat $<.wrap) $(foreach dep,$($@_TESTDEPS),$(shell cat $(dep).wrap)) --- -2.17.2 - diff --git a/0010-libmultipath-add-linker-version-script.patch b/0010-libmultipath-add-linker-version-script.patch index ed6ad7f..afbb4f3 100644 --- a/0010-libmultipath-add-linker-version-script.patch +++ b/0010-libmultipath-add-linker-version-script.patch @@ -298,6 +298,3 @@ index 00000000..a6bf8218 +local: + *; +}; --- -2.17.2 - diff --git a/0011-libmpathpersist-add-linker-version-script.patch b/0011-libmpathpersist-add-linker-version-script.patch index 916c4f3..e43e068 100644 --- a/0011-libmpathpersist-add-linker-version-script.patch +++ b/0011-libmpathpersist-add-linker-version-script.patch @@ -76,6 +76,3 @@ index 00000000..dc648ce6 + +local: *; +}; --- -2.17.2 - diff --git a/0012-libmpathcmd-add-linker-version-script.patch b/0012-libmpathcmd-add-linker-version-script.patch index 454c3b7..15ab67b 100644 --- a/0012-libmpathcmd-add-linker-version-script.patch +++ b/0012-libmpathcmd-add-linker-version-script.patch @@ -69,6 +69,3 @@ index 00000000..f1006280 +local: + *; +}; --- -2.17.2 - diff --git a/0013-libmpathpersist-initialize-mpp-hwe-in-get_mpvec.patch b/0013-libmpathpersist-initialize-mpp-hwe-in-get_mpvec.patch index a04673d..73d5f55 100644 --- a/0013-libmpathpersist-initialize-mpp-hwe-in-get_mpvec.patch +++ b/0013-libmpathpersist-initialize-mpp-hwe-in-get_mpvec.patch @@ -33,6 +33,3 @@ index 1f9817ed..4b3f3e0d 100644 } return MPATH_PR_SUCCESS ; } --- -2.17.2 - diff --git a/0014-multipathd-allow-shutdown-during-configure.patch b/0014-multipathd-allow-shutdown-during-configure.patch index 2cbfecf..951cf53 100644 --- a/0014-multipathd-allow-shutdown-during-configure.patch +++ b/0014-multipathd-allow-shutdown-during-configure.patch @@ -135,6 +135,3 @@ index eedc6c10..fa53e963 100644 sync_maps_state(mpvec); vector_foreach_slot(mpvec, mpp, i){ if (remember_wwid(mpp->wwid) == 1) --- -2.17.2 - diff --git a/0015-multipathd-avoid-sending-READY-1-to-systemd-on-early.patch b/0015-multipathd-avoid-sending-READY-1-to-systemd-on-early.patch index c2d1475..d6a674b 100644 --- a/0015-multipathd-avoid-sending-READY-1-to-systemd-on-early.patch +++ b/0015-multipathd-avoid-sending-READY-1-to-systemd-on-early.patch @@ -62,6 +62,3 @@ index fa53e963..53a22a43 100644 } } --- -2.17.2 - diff --git a/0016-multipathd-send-STOPPING-1-to-systemd-on-shutdown.patch b/0016-multipathd-send-STOPPING-1-to-systemd-on-shutdown.patch index b38cf2f..fbcfc2d 100644 --- a/0016-multipathd-send-STOPPING-1-to-systemd-on-shutdown.patch +++ b/0016-multipathd-send-STOPPING-1-to-systemd-on-shutdown.patch @@ -26,6 +26,3 @@ index 53a22a43..c264351c 100644 sd_notify(0, "READY=1"); startup_done = true; } --- -2.17.2 - diff --git a/0017-multipathd-send-RELOADING-1-to-systemd-on-DAEMON_CON.patch b/0017-multipathd-send-RELOADING-1-to-systemd-on-DAEMON_CON.patch index 76894d0..8b2d70e 100644 --- a/0017-multipathd-send-RELOADING-1-to-systemd-on-DAEMON_CON.patch +++ b/0017-multipathd-send-RELOADING-1-to-systemd-on-DAEMON_CON.patch @@ -37,6 +37,3 @@ index c264351c..e3f2328d 100644 } #endif --- -2.17.2 - diff --git a/0018-multipathd-use-volatile-qualifier-for-running_state.patch b/0018-multipathd-use-volatile-qualifier-for-running_state.patch index 400298e..7d9e6d2 100644 --- a/0018-multipathd-use-volatile-qualifier-for-running_state.patch +++ b/0018-multipathd-use-volatile-qualifier-for-running_state.patch @@ -26,6 +26,3 @@ index e3f2328d..d081b3e9 100644 pid_t daemon_pid; pthread_mutex_t config_lock = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t config_cond; --- -2.17.2 - diff --git a/0019-multipathd-generalize-and-fix-wait_for_state_change_.patch b/0019-multipathd-generalize-and-fix-wait_for_state_change_.patch index 73f99ec..a08eacd 100644 --- a/0019-multipathd-generalize-and-fix-wait_for_state_change_.patch +++ b/0019-multipathd-generalize-and-fix-wait_for_state_change_.patch @@ -67,6 +67,3 @@ index d081b3e9..1fb0ee62 100644 pthread_cleanup_pop(1); return st; } --- -2.17.2 - diff --git a/0020-multipathd-set_config_state-avoid-code-duplication.patch b/0020-multipathd-set_config_state-avoid-code-duplication.patch index a5310f3..e4dbd04 100644 --- a/0020-multipathd-set_config_state-avoid-code-duplication.patch +++ b/0020-multipathd-set_config_state-avoid-code-duplication.patch @@ -50,6 +50,3 @@ index 1fb0ee62..39aea4ad 100644 } pthread_cleanup_pop(1); return rc; --- -2.17.2 - diff --git a/0021-multipathd-cancel-threads-early-during-shutdown.patch b/0021-multipathd-cancel-threads-early-during-shutdown.patch index cc51513..96f9b75 100644 --- a/0021-multipathd-cancel-threads-early-during-shutdown.patch +++ b/0021-multipathd-cancel-threads-early-during-shutdown.patch @@ -56,6 +56,3 @@ index 39aea4ad..d1f8cc1b 100644 pthread_join(check_thr, NULL); pthread_join(uevent_thr, NULL); pthread_join(uxlsnr_thr, NULL); --- -2.17.2 - diff --git a/0022-multipath-tools-don-t-call-dm_lib_release-any-more.patch b/0022-multipath-tools-don-t-call-dm_lib_release-any-more.patch index fe32b1a..447c884 100644 --- a/0022-multipath-tools-don-t-call-dm_lib_release-any-more.patch +++ b/0022-multipath-tools-don-t-call-dm_lib_release-any-more.patch @@ -160,6 +160,3 @@ index d1f8cc1b..5cc34357 100644 dm_lib_exit(); /* We're done here */ --- -2.17.2 - diff --git a/0023-libmultipath-devmapper-refactor-libdm-version-determ.patch b/0023-libmultipath-devmapper-refactor-libdm-version-determ.patch index b5e96b2..76a14eb 100644 --- a/0023-libmultipath-devmapper-refactor-libdm-version-determ.patch +++ b/0023-libmultipath-devmapper-refactor-libdm-version-determ.patch @@ -501,6 +501,3 @@ index b7c09cc2..e7663f9a 100644 select_minio(conf, mp); put_multipath_config(conf); --- -2.17.2 - diff --git a/0024-libmultipath-protect-racy-libdevmapper-calls-with-a-.patch b/0024-libmultipath-protect-racy-libdevmapper-calls-with-a-.patch index 026dd7c..f8dd1e3 100644 --- a/0024-libmultipath-protect-racy-libdevmapper-calls-with-a-.patch +++ b/0024-libmultipath-protect-racy-libdevmapper-calls-with-a-.patch @@ -432,6 +432,3 @@ index bee117ac..b7c5122b 100644 assert_ptr_equal((struct test_data *)dmt, &data); if (data.names) { --- -2.17.2 - diff --git a/0025-libmultipath-constify-file-argument-in-config-parser.patch b/0025-libmultipath-constify-file-argument-in-config-parser.patch index 9470cf4..4344b92 100644 --- a/0025-libmultipath-constify-file-argument-in-config-parser.patch +++ b/0025-libmultipath-constify-file-argument-in-config-parser.patch @@ -93,6 +93,3 @@ index 62906e98..06666ccf 100644 extern struct keyword * find_keyword(vector keywords, vector v, char * name); int snprint_keyword(char *buff, int len, char *fmt, struct keyword *kw, const void *data); --- -2.17.2 - diff --git a/0026-libmultipath-provide-defaults-for-get-put-_multipath.patch b/0026-libmultipath-provide-defaults-for-get-put-_multipath.patch index e3375f0..9a0af2a 100644 --- a/0026-libmultipath-provide-defaults-for-get-put-_multipath.patch +++ b/0026-libmultipath-provide-defaults-for-get-put-_multipath.patch @@ -199,6 +199,3 @@ index 97acdbb2..3e780fce 100644 + init_config; + uninit_config; +} LIBMULTIPATH_2.1.0; --- -2.17.2 - diff --git a/0027-libmpathpersist-allow-using-libmultipath-get-put-_mu.patch b/0027-libmpathpersist-allow-using-libmultipath-get-put-_mu.patch index def8896..13e8b10 100644 --- a/0027-libmpathpersist-allow-using-libmultipath-get-put-_mu.patch +++ b/0027-libmpathpersist-allow-using-libmultipath-get-put-_mu.patch @@ -151,6 +151,3 @@ index 7cf4faf9..91606efc 100644 /* * DESCRIPTION : --- -2.17.2 - diff --git a/0028-multipath-use-get_put-_multipath_config-from-libmult.patch b/0028-multipath-use-get_put-_multipath_config-from-libmult.patch index 762daea..6ccc2ea 100644 --- a/0028-multipath-use-get_put-_multipath_config-from-libmult.patch +++ b/0028-multipath-use-get_put-_multipath_config-from-libmult.patch @@ -62,6 +62,3 @@ index dc4974b9..4bbfce9a 100644 udev_unref(udev); if (dev) FREE(dev); --- -2.17.2 - diff --git a/0029-mpathpersist-use-get-put-_multipath_config-from-libm.patch b/0029-mpathpersist-use-get-put-_multipath_config-from-libm.patch index 6ab3c10..09c4ad8 100644 --- a/0029-mpathpersist-use-get-put-_multipath_config-from-libm.patch +++ b/0029-mpathpersist-use-get-put-_multipath_config-from-libm.patch @@ -50,6 +50,3 @@ index a6a3bcf6..278e48f7 100644 udev_unref(udev); return (ret >= 0) ? ret : MPATH_PR_OTHER; --- -2.17.2 - diff --git a/0030-libmultipath-add-udev-and-logsink-symbols.patch b/0030-libmultipath-add-udev-and-logsink-symbols.patch index 3bd9de0..d936a42 100644 --- a/0030-libmultipath-add-udev-and-logsink-symbols.patch +++ b/0030-libmultipath-add-udev-and-logsink-symbols.patch @@ -163,6 +163,3 @@ index 3e780fce..0c300c81 100644 + libmultipath_init; + libmultipath_exit; +} LIBMULTIPATH_2.2.0; --- -2.17.2 - diff --git a/0031-multipath-remove-logsink-and-udev.patch b/0031-multipath-remove-logsink-and-udev.patch index 7ba8272..4faf540 100644 --- a/0031-multipath-remove-logsink-and-udev.patch +++ b/0031-multipath-remove-logsink-and-udev.patch @@ -43,6 +43,3 @@ index 4bbfce9a..9ae46ed5 100644 if (dev) FREE(dev); #ifdef _DEBUG_ --- -2.17.2 - diff --git a/0032-libmpathpersist-call-libmultipath_-init-exit.patch b/0032-libmpathpersist-call-libmultipath_-init-exit.patch index 9c52f9f..9671dfd 100644 --- a/0032-libmpathpersist-call-libmultipath_-init-exit.patch +++ b/0032-libmpathpersist-call-libmultipath_-init-exit.patch @@ -91,6 +91,3 @@ index 91606efc..5435eae4 100644 * RESTRICTIONS: * * RETURNS: 0->Success, 1->Failed. --- -2.17.2 - diff --git a/0033-mpathpersist-remove-logsink-and-udev.patch b/0033-mpathpersist-remove-logsink-and-udev.patch index 501f32f..bf508c6 100644 --- a/0033-mpathpersist-remove-logsink-and-udev.patch +++ b/0033-mpathpersist-remove-logsink-and-udev.patch @@ -47,6 +47,3 @@ index 278e48f7..3c2e6576 100644 return (ret >= 0) ? ret : MPATH_PR_OTHER; } --- -2.17.2 - diff --git a/0034-multipathd-remove-logsink-and-udev.patch b/0034-multipathd-remove-logsink-and-udev.patch index 25e929a..f974fd5 100644 --- a/0034-multipathd-remove-logsink-and-udev.patch +++ b/0034-multipathd-remove-logsink-and-udev.patch @@ -52,6 +52,3 @@ index 00b66ba4..c5c374b7 100644 libmp_udev_set_sync_support(0); while ((arg = getopt(argc, argv, ":dsv:k::Bniw")) != EOF ) { --- -2.17.2 - diff --git a/0035-multipath-tools-add-Vexata-by-StorCentric-VX-arrays.patch b/0035-multipath-tools-add-Vexata-by-StorCentric-VX-arrays.patch index c8fa5bb..3c50b70 100644 --- a/0035-multipath-tools-add-Vexata-by-StorCentric-VX-arrays.patch +++ b/0035-multipath-tools-add-Vexata-by-StorCentric-VX-arrays.patch @@ -35,6 +35,3 @@ index cd65afcc..c1d6f7ae 100644 }, /* * Promise Technology --- -2.17.2 - diff --git a/0036-multipath-tools-Violin-and-Nexsan-were-bought-by-Sto.patch b/0036-multipath-tools-Violin-and-Nexsan-were-bought-by-Sto.patch index 006d74e..1ba6166 100644 --- a/0036-multipath-tools-Violin-and-Nexsan-were-bought-by-Sto.patch +++ b/0036-multipath-tools-Violin-and-Nexsan-were-bought-by-Sto.patch @@ -40,6 +40,3 @@ index c1d6f7ae..a54cc0a3 100644 { /* 3000 / 6000 Series */ .vendor = "VIOLIN", --- -2.17.2 - diff --git a/0037-libmultipath-fix-memory-leaks-in-coalesce_paths.patch b/0037-libmultipath-fix-memory-leaks-in-coalesce_paths.patch index 0f67ead..a40bf11 100644 --- a/0037-libmultipath-fix-memory-leaks-in-coalesce_paths.patch +++ b/0037-libmultipath-fix-memory-leaks-in-coalesce_paths.patch @@ -112,6 +112,3 @@ index 1c8aac08..d36f0d0d 100644 return ret; } --- -2.17.2 - diff --git a/0038-multipath-tools-replace-hidden-tab-by-space-in-hwtab.patch b/0038-multipath-tools-replace-hidden-tab-by-space-in-hwtab.patch index d51c502..f75dd91 100644 --- a/0038-multipath-tools-replace-hidden-tab-by-space-in-hwtab.patch +++ b/0038-multipath-tools-replace-hidden-tab-by-space-in-hwtab.patch @@ -26,6 +26,3 @@ index a54cc0a3..921aadc5 100644 .product = "^NetApp ONTAP Controller", .pgpolicy = MULTIBUS, .no_path_retry = NO_PATH_RETRY_QUEUE, --- -2.17.2 - diff --git a/0039-multipathd-uxlsnr-avoid-deadlock-on-exit.patch b/0039-multipathd-uxlsnr-avoid-deadlock-on-exit.patch index 6f4fc00..db589ac 100644 --- a/0039-multipathd-uxlsnr-avoid-deadlock-on-exit.patch +++ b/0039-multipathd-uxlsnr-avoid-deadlock-on-exit.patch @@ -100,6 +100,3 @@ index 1c5ce9d2..ce2b6800 100644 if (polls[i].revents & POLLIN) { struct timespec start_time; --- -2.17.2 - diff --git a/0040-multipathd-Fix-liburcu-memory-leak.patch b/0040-multipathd-Fix-liburcu-memory-leak.patch index 8f04a66..0416db3 100644 --- a/0040-multipathd-Fix-liburcu-memory-leak.patch +++ b/0040-multipathd-Fix-liburcu-memory-leak.patch @@ -93,6 +93,3 @@ index c5c374b7..ce14bb66 100644 setup_thread_attr(&misc_attr, 64 * 1024, 0); setup_thread_attr(&uevent_attr, DEFAULT_UEVENT_STACKSIZE * 1024, 0); --- -2.17.2 - diff --git a/0041-multipathd-move-handling-of-io_err_stat_attr-into-li.patch b/0041-multipathd-move-handling-of-io_err_stat_attr-into-li.patch index 329876d..8a0e23d 100644 --- a/0041-multipathd-move-handling-of-io_err_stat_attr-into-li.patch +++ b/0041-multipathd-move-handling-of-io_err_stat_attr-into-li.patch @@ -141,6 +141,3 @@ index ce14bb66..abc6a9f7 100644 #ifdef _DEBUG_ dbg_free_final(NULL); #endif --- -2.17.2 - diff --git a/0042-multipathd-move-vecs-desctruction-into-cleanup-funct.patch b/0042-multipathd-move-vecs-desctruction-into-cleanup-funct.patch index f65e6eb..1c0c3fd 100644 --- a/0042-multipathd-move-vecs-desctruction-into-cleanup-funct.patch +++ b/0042-multipathd-move-vecs-desctruction-into-cleanup-funct.patch @@ -120,6 +120,3 @@ index abc6a9f7..3da0d7cc 100644 cleanup_foreign(); cleanup_checkers(); cleanup_prio(); --- -2.17.2 - diff --git a/0043-multipathd-make-some-globals-static.patch b/0043-multipathd-make-some-globals-static.patch index 6ae5835..c7fb5ce 100644 --- a/0043-multipathd-make-some-globals-static.patch +++ b/0043-multipathd-make-some-globals-static.patch @@ -40,6 +40,3 @@ index 3da0d7cc..eb760a71 100644 static inline enum daemon_status get_running_state(void) { --- -2.17.2 - diff --git a/0044-multipathd-move-threads-destruction-into-separate-fu.patch b/0044-multipathd-move-threads-destruction-into-separate-fu.patch index 6c2251e..2e069ff 100644 --- a/0044-multipathd-move-threads-destruction-into-separate-fu.patch +++ b/0044-multipathd-move-threads-destruction-into-separate-fu.patch @@ -159,6 +159,3 @@ index eb760a71..9eb658d4 100644 #ifdef _DEBUG_ dbg_free_final(NULL); #endif --- -2.17.2 - diff --git a/0045-multipathd-move-conf-destruction-into-separate-funct.patch b/0045-multipathd-move-conf-destruction-into-separate-funct.patch index 97125dc..c6ea6b2 100644 --- a/0045-multipathd-move-conf-destruction-into-separate-funct.patch +++ b/0045-multipathd-move-conf-destruction-into-separate-funct.patch @@ -51,6 +51,3 @@ index 9eb658d4..07973e85 100644 #ifdef _DEBUG_ dbg_free_final(NULL); #endif --- -2.17.2 - diff --git a/0046-multipathd-move-pid-destruction-into-separate-functi.patch b/0046-multipathd-move-pid-destruction-into-separate-functi.patch index bbff859..70220dd 100644 --- a/0046-multipathd-move-pid-destruction-into-separate-functi.patch +++ b/0046-multipathd-move-pid-destruction-into-separate-functi.patch @@ -37,6 +37,3 @@ index 07973e85..fc1f8d7f 100644 condlog(2, "--------shut down-------"); if (logsink == 1) --- -2.17.2 - diff --git a/0047-multipathd-close-pidfile-on-exit.patch b/0047-multipathd-close-pidfile-on-exit.patch index 6c9c1b1..fa3a5e9 100644 --- a/0047-multipathd-close-pidfile-on-exit.patch +++ b/0047-multipathd-close-pidfile-on-exit.patch @@ -40,6 +40,3 @@ index fc1f8d7f..f6b80668 100644 struct config *conf; char *envp; enum daemon_status state; --- -2.17.2 - diff --git a/0048-multipathd-add-helper-for-systemd-notification-at-ex.patch b/0048-multipathd-add-helper-for-systemd-notification-at-ex.patch index bf3c462..8dfe28e 100644 --- a/0048-multipathd-add-helper-for-systemd-notification-at-ex.patch +++ b/0048-multipathd-add-helper-for-systemd-notification-at-ex.patch @@ -55,6 +55,3 @@ index f6b80668..07068e4a 100644 } static int --- -2.17.2 - diff --git a/0049-multipathd-child-call-cleanups-in-failure-case-too.patch b/0049-multipathd-child-call-cleanups-in-failure-case-too.patch index fba8169..85bd5f4 100644 --- a/0049-multipathd-child-call-cleanups-in-failure-case-too.patch +++ b/0049-multipathd-child-call-cleanups-in-failure-case-too.patch @@ -47,6 +47,3 @@ index 07068e4a..6b9e323e 100644 } static int --- -2.17.2 - diff --git a/0050-multipathd-unwatch_all_dmevents-check-if-waiter-is-i.patch b/0050-multipathd-unwatch_all_dmevents-check-if-waiter-is-i.patch index 279109c..2629bab 100644 --- a/0050-multipathd-unwatch_all_dmevents-check-if-waiter-is-i.patch +++ b/0050-multipathd-unwatch_all_dmevents-check-if-waiter-is-i.patch @@ -23,6 +23,3 @@ index b561cbfd..f52f5970 100644 pthread_mutex_lock(&waiter->events_lock); vector_foreach_slot(waiter->events, dev_evt, i) free(dev_evt); --- -2.17.2 - diff --git a/0051-multipathd-print-error-message-if-config-can-t-be-lo.patch b/0051-multipathd-print-error-message-if-config-can-t-be-lo.patch index 9cf6182..0d51d12 100644 --- a/0051-multipathd-print-error-message-if-config-can-t-be-lo.patch +++ b/0051-multipathd-print-error-message-if-config-can-t-be-lo.patch @@ -25,6 +25,3 @@ index 6b9e323e..7ab3eab8 100644 if (verbosity) conf->verbosity = verbosity; --- -2.17.2 - diff --git a/0052-libmultipath-add-libmp_dm_exit.patch b/0052-libmultipath-add-libmp_dm_exit.patch index db24711..86baccd 100644 --- a/0052-libmultipath-add-libmp_dm_exit.patch +++ b/0052-libmultipath-add-libmp_dm_exit.patch @@ -87,6 +87,3 @@ index fa6b3c53..e29b4d41 100644 void libmp_udev_set_sync_support(int on); struct dm_task *libmp_dm_task_create(int task); int dm_simplecmd_flush (int, const char *, uint16_t); --- -2.17.2 - diff --git a/0053-multipathd-fixup-libdm-deinitialization.patch b/0053-multipathd-fixup-libdm-deinitialization.patch index b57a8cd..b12d925 100644 --- a/0053-multipathd-fixup-libdm-deinitialization.patch +++ b/0053-multipathd-fixup-libdm-deinitialization.patch @@ -35,6 +35,3 @@ index 7ab3eab8..4c4e2eab 100644 libmultipath_init(); if (atexit(libmultipath_exit)) condlog(3, "failed to register exit handler for libmultipath"); --- -2.17.2 - diff --git a/0054-libmultipath-log_thread_stop-check-if-logarea-is-ini.patch b/0054-libmultipath-log_thread_stop-check-if-logarea-is-ini.patch index 004016c..32a6fc8 100644 --- a/0054-libmultipath-log_thread_stop-check-if-logarea-is-ini.patch +++ b/0054-libmultipath-log_thread_stop-check-if-logarea-is-ini.patch @@ -24,6 +24,3 @@ index 15baef88..0c327ffc 100644 logdbg(stderr,"enter log_thread_stop\n"); pthread_mutex_lock(&logev_lock); --- -2.17.2 - diff --git a/0055-multipathd-add-cleanup_child-exit-handler.patch b/0055-multipathd-add-cleanup_child-exit-handler.patch index 8455a96..a031baa 100644 --- a/0055-multipathd-add-cleanup_child-exit-handler.patch +++ b/0055-multipathd-add-cleanup_child-exit-handler.patch @@ -90,6 +90,3 @@ index 4c4e2eab..50cc3356 100644 return sd_notify_exit(exit_code); } --- -2.17.2 - diff --git a/0056-libmultipath-fix-log_thread-startup-and-teardown.patch b/0056-libmultipath-fix-log_thread-startup-and-teardown.patch index 106f19a..0804551 100644 --- a/0056-libmultipath-fix-log_thread-startup-and-teardown.patch +++ b/0056-libmultipath-fix-log_thread-startup-and-teardown.patch @@ -143,6 +143,3 @@ index 0c327ffc..3a2566ae 100644 pthread_mutex_destroy(&logq_lock); pthread_mutex_destroy(&logev_lock); --- -2.17.2 - diff --git a/0057-multipathd-move-cleanup_-prio-checkers-foreign-to-li.patch b/0057-multipathd-move-cleanup_-prio-checkers-foreign-to-li.patch index 017034e..891b54f 100644 --- a/0057-multipathd-move-cleanup_-prio-checkers-foreign-to-li.patch +++ b/0057-multipathd-move-cleanup_-prio-checkers-foreign-to-li.patch @@ -88,6 +88,3 @@ index 50cc3356..4de0978e 100644 if (poll_dmevents) cleanup_dmevent_waiter(); --- -2.17.2 - diff --git a/0058-multipath-use-atexit-for-cleanup-handlers.patch b/0058-multipath-use-atexit-for-cleanup-handlers.patch index 444a39d..b07cf95 100644 --- a/0058-multipath-use-atexit-for-cleanup-handlers.patch +++ b/0058-multipath-use-atexit-for-cleanup-handlers.patch @@ -105,6 +105,3 @@ index 9ae46ed5..1949a1cd 100644 #ifdef _DEBUG_ dbg_free_final(NULL); #endif --- -2.17.2 - diff --git a/0059-mpathpersist-use-atexit-for-cleanup-handlers.patch b/0059-mpathpersist-use-atexit-for-cleanup-handlers.patch index 7494b34..0c88e70 100644 --- a/0059-mpathpersist-use-atexit-for-cleanup-handlers.patch +++ b/0059-mpathpersist-use-atexit-for-cleanup-handlers.patch @@ -27,6 +27,3 @@ index 3c2e6576..14245cc3 100644 return (ret >= 0) ? ret : MPATH_PR_OTHER; } --- -2.17.2 - diff --git a/0060-multipath-fix-leak-in-check_path_valid.patch b/0060-multipath-fix-leak-in-check_path_valid.patch index c96f4cb..5c82a35 100644 --- a/0060-multipath-fix-leak-in-check_path_valid.patch +++ b/0060-multipath-fix-leak-in-check_path_valid.patch @@ -90,6 +90,3 @@ index 1949a1cd..043d8fa7 100644 } static int --- -2.17.2 - diff --git a/0061-multipath-tools-mpath-tools.supp-file-with-valgrind-.patch b/0061-multipath-tools-mpath-tools.supp-file-with-valgrind-.patch index 4228be6..7eb6471 100644 --- a/0061-multipath-tools-mpath-tools.supp-file-with-valgrind-.patch +++ b/0061-multipath-tools-mpath-tools.supp-file-with-valgrind-.patch @@ -57,6 +57,3 @@ index 00000000..0537fd56 + ... + fun:_dl_init +} --- -2.17.2 - diff --git a/0062-libmultipath-use-libmp_verbosity-to-track-verbosity.patch b/0062-libmultipath-use-libmp_verbosity-to-track-verbosity.patch index 042929d..400656e 100644 --- a/0062-libmultipath-use-libmp_verbosity-to-track-verbosity.patch +++ b/0062-libmultipath-use-libmp_verbosity-to-track-verbosity.patch @@ -436,6 +436,3 @@ index 84a3ba2f..0b42e255 100644 return 0; } --- -2.17.2 - diff --git a/0063-libmultipath-introduce-symbolic-values-for-logsink.patch b/0063-libmultipath-introduce-symbolic-values-for-logsink.patch index 24cf615..936bb6f 100644 --- a/0063-libmultipath-introduce-symbolic-values-for-logsink.patch +++ b/0063-libmultipath-introduce-symbolic-values-for-logsink.patch @@ -180,6 +180,3 @@ index 57f832b7..4dd0873b 100644 struct config *get_multipath_config(void) { --- -2.17.2 - diff --git a/0064-libmultipath-simplify-dlog.patch b/0064-libmultipath-simplify-dlog.patch index af47833..67985a1 100644 --- a/0064-libmultipath-simplify-dlog.patch +++ b/0064-libmultipath-simplify-dlog.patch @@ -147,6 +147,3 @@ index 2c878c63..6d22cd23 100644 void expect_condlog(int prio, char *string); #endif --- -2.17.2 - diff --git a/0065-multipathd-common-code-for-k-and-command-args.patch b/0065-multipathd-common-code-for-k-and-command-args.patch index 1fc5a75..d31afd7 100644 --- a/0065-multipathd-common-code-for-k-and-command-args.patch +++ b/0065-multipathd-common-code-for-k-and-command-args.patch @@ -82,6 +82,3 @@ index 867f0f84..b6a5f5b7 100644 err = uxclnt(s, uxsock_timeout + 100); free_config(conf); return err; --- -2.17.2 - diff --git a/0066-multipathd-sanitize-uxsock_listen.patch b/0066-multipathd-sanitize-uxsock_listen.patch index d7efc72..bffb94c 100644 --- a/0066-multipathd-sanitize-uxsock_listen.patch +++ b/0066-multipathd-sanitize-uxsock_listen.patch @@ -152,6 +152,3 @@ index ce2b6800..cd462b6d 100644 if (polls[i].revents & POLLIN) { struct timespec start_time; --- -2.17.2 - diff --git a/0067-libmultipath-fix-race-between-log_safe-and-log_threa.patch b/0067-libmultipath-fix-race-between-log_safe-and-log_threa.patch index 29f5ce7..cc6e5d3 100644 --- a/0067-libmultipath-fix-race-between-log_safe-and-log_threa.patch +++ b/0067-libmultipath-fix-race-between-log_safe-and-log_threa.patch @@ -102,6 +102,3 @@ index 3a2566ae..0d48c52c 100644 + flush_logqueue(); log_close(); } --- -2.17.2 - diff --git a/0068-multipath-add-libmpathvalid-library.patch b/0068-multipath-add-libmpathvalid-library.patch index 24ba4ac..2a19329 100644 --- a/0068-multipath-add-libmpathvalid-library.patch +++ b/0068-multipath-add-libmpathvalid-library.patch @@ -500,6 +500,3 @@ index 67a7379f..2e3583f5 100644 + dm_prereq; + skip_libmp_dm_init; +} LIBMULTIPATH_4.1.0; --- -2.17.2 - diff --git a/0069-multipath-tools-tests-and-unit-tests-for-libmpathval.patch b/0069-multipath-tools-tests-and-unit-tests-for-libmpathval.patch index cd24d4e..e8a56a3 100644 --- a/0069-multipath-tools-tests-and-unit-tests-for-libmpathval.patch +++ b/0069-multipath-tools-tests-and-unit-tests-for-libmpathval.patch @@ -527,6 +527,3 @@ index 00000000..5ffabb9d + r += test_mpathvalid(); + return r; +} --- -2.17.2 - diff --git a/0070-libmultipath-add-uid-failback-for-dasd-devices.patch b/0070-libmultipath-add-uid-failback-for-dasd-devices.patch index c052217..9a26734 100644 --- a/0070-libmultipath-add-uid-failback-for-dasd-devices.patch +++ b/0070-libmultipath-add-uid-failback-for-dasd-devices.patch @@ -85,6 +85,3 @@ index e7084664..877e8f2b 100644 !strcmp(pp->uid_attribute, "")))); } --- -2.17.2 - diff --git a/0071-libmultipath-change-log-level-for-null-uid_attribute.patch b/0071-libmultipath-change-log-level-for-null-uid_attribute.patch index 3fa6b93..de48c1b 100644 --- a/0071-libmultipath-change-log-level-for-null-uid_attribute.patch +++ b/0071-libmultipath-change-log-level-for-null-uid_attribute.patch @@ -40,6 +40,3 @@ index 877e8f2b..c74f13bf 100644 len = uid_fallback(pp, path_state, &origin); } } --- -2.17.2 - diff --git a/0072-libmultipath-move-fast_io_fail-defines-to-structs.h.patch b/0072-libmultipath-move-fast_io_fail-defines-to-structs.h.patch index 8346fa2..557763c 100644 --- a/0072-libmultipath-move-fast_io_fail-defines-to-structs.h.patch +++ b/0072-libmultipath-move-fast_io_fail-defines-to-structs.h.patch @@ -155,6 +155,3 @@ index 4ce30551..cfa7b649 100644 struct vpd_vendor_page { int pg; const char *name; --- -2.17.2 - diff --git a/0073-libmultipath-add-eh_deadline-multipath.conf-paramete.patch b/0073-libmultipath-add-eh_deadline-multipath.conf-paramete.patch index f5b1d8a..96b8d5c 100644 --- a/0073-libmultipath-add-eh_deadline-multipath.conf-paramete.patch +++ b/0073-libmultipath-add-eh_deadline-multipath.conf-paramete.patch @@ -333,6 +333,3 @@ index 7242d39b..ea66a01e 100644 .B bindings_file The full pathname of the binding file to be used when the user_friendly_names option is set. --- -2.17.2 - diff --git a/0074-multipathd-remove-redundant-vector_free-int-configur.patch b/0074-multipathd-remove-redundant-vector_free-int-configur.patch index c9947f5..5d1fd0a 100644 --- a/0074-multipathd-remove-redundant-vector_free-int-configur.patch +++ b/0074-multipathd-remove-redundant-vector_free-int-configur.patch @@ -32,6 +32,3 @@ index b6a5f5b7..2eab4854 100644 vecs->mpvec = mpvec; /* --- -2.17.2 - diff --git a/0075-libmultipath-factor-out-code-to-get-vpd-page-data.patch b/0075-libmultipath-factor-out-code-to-get-vpd-page-data.patch index fe2ea50..1d7b142 100644 --- a/0075-libmultipath-factor-out-code-to-get-vpd-page-data.patch +++ b/0075-libmultipath-factor-out-code-to-get-vpd-page-data.patch @@ -61,6 +61,3 @@ index add7bb97..f901e9ff 100644 if (pg == 0x80) len = parse_vpd_pg80(buff, str, maxlen); else if (pg == 0x83) --- -2.17.2 - diff --git a/0076-libmultipath-limit-reading-0xc9-vpd-page.patch b/0076-libmultipath-limit-reading-0xc9-vpd-page.patch index 6208fe5..f5483b2 100644 --- a/0076-libmultipath-limit-reading-0xc9-vpd-page.patch +++ b/0076-libmultipath-limit-reading-0xc9-vpd-page.patch @@ -86,6 +86,3 @@ index fa4ac5d9..f771a830 100644 return 0; len = get_vpd_sgio(pp->fd, 0xC9, 0, buff, 44); if (len <= 0) --- -2.17.2 - diff --git a/0077-libmultipath-move-logq_lock-handling-to-log.c.patch b/0077-libmultipath-move-logq_lock-handling-to-log.c.patch index ae9385f..b2799a8 100644 --- a/0077-libmultipath-move-logq_lock-handling-to-log.c.patch +++ b/0077-libmultipath-move-logq_lock-handling-to-log.c.patch @@ -136,6 +136,3 @@ index 0d48c52c..65992101 100644 } void log_thread_stop (void) --- -2.17.2 - diff --git a/0078-libmultipath-protect-logarea-with-logq_lock.patch b/0078-libmultipath-protect-logarea-with-logq_lock.patch index e27aa64..d59a9b8 100644 --- a/0078-libmultipath-protect-logarea-with-logq_lock.patch +++ b/0078-libmultipath-protect-logarea-with-logq_lock.patch @@ -105,6 +105,3 @@ index d2448f6a..fa224e4d 100644 -void free_logarea (void); #endif /* LOG_H */ --- -2.17.2 - diff --git a/0079-libmultipath-prevent-DSO-unloading-with-astray-check.patch b/0079-libmultipath-prevent-DSO-unloading-with-astray-check.patch index 31fd8b4..8a81d79 100644 --- a/0079-libmultipath-prevent-DSO-unloading-with-astray-check.patch +++ b/0079-libmultipath-prevent-DSO-unloading-with-astray-check.patch @@ -279,6 +279,3 @@ index 2e3583f5..751099dc 100644 +global: + start_checker_thread; +} LIBMULTIPATH_4.2.0; --- -2.17.2 - diff --git a/0080-libmultipath-force-map-reload-if-udev-incomplete.patch b/0080-libmultipath-force-map-reload-if-udev-incomplete.patch index 913c438..4de3108 100644 --- a/0080-libmultipath-force-map-reload-if-udev-incomplete.patch +++ b/0080-libmultipath-force-map-reload-if-udev-incomplete.patch @@ -146,6 +146,3 @@ index c076be72..d9fd9cb8 100644 return; } if (cmpp->nextpg != mpp->bestpg) { --- -2.17.2 - diff --git a/0081-multipath-tools-avoid-access-to-etc-localtime.patch b/0081-multipath-tools-avoid-access-to-etc-localtime.patch index 1e67613..1286fa5 100644 --- a/0081-multipath-tools-avoid-access-to-etc-localtime.patch +++ b/0081-multipath-tools-avoid-access-to-etc-localtime.patch @@ -107,6 +107,3 @@ index 2eab4854..4417860b 100644 if (bindings_read_only) conf->bindings_read_only = bindings_read_only; check_alias_settings(conf); --- -2.17.2 - diff --git a/0082-multipath-tools-make-sure-plugin-DSOs-use-symbol-ver.patch b/0082-multipath-tools-make-sure-plugin-DSOs-use-symbol-ver.patch index cc3a633..1dcc7f0 100644 --- a/0082-multipath-tools-make-sure-plugin-DSOs-use-symbol-ver.patch +++ b/0082-multipath-tools-make-sure-plugin-DSOs-use-symbol-ver.patch @@ -144,6 +144,3 @@ index fc6e0e0c..8d34ae32 100644 install: $(LIBS) $(INSTALL_PROGRAM) -m 755 libprio*.so $(DESTDIR)$(libdir) --- -2.17.2 - diff --git a/0083-libmultipath.version-add-missing-symbol.patch b/0083-libmultipath.version-add-missing-symbol.patch index 55e4396..11edbd0 100644 --- a/0083-libmultipath.version-add-missing-symbol.patch +++ b/0083-libmultipath.version-add-missing-symbol.patch @@ -25,6 +25,3 @@ index 751099dc..2228f4ec 100644 +global: + get_next_string; +} LIBMULTIPATH_4.3.0; --- -2.17.2 - diff --git a/0084-multipath-tools-tests-unversioned-.so-for-valgrind-t.patch b/0084-multipath-tools-tests-unversioned-.so-for-valgrind-t.patch index 6be89d6..fa83da7 100644 --- a/0084-multipath-tools-tests-unversioned-.so-for-valgrind-t.patch +++ b/0084-multipath-tools-tests-unversioned-.so-for-valgrind-t.patch @@ -25,6 +25,3 @@ index 54da774e..50673fae 100644 valgrind --leak-check=full --error-exitcode=128 ./$< >$@ 2>&1 OBJS = $(TESTS:%=%.o) $(HELPERS) --- -2.17.2 - diff --git a/0085-multipath-tools-unit-tests-fix-memory-leaks-in-mpath.patch b/0085-multipath-tools-unit-tests-fix-memory-leaks-in-mpath.patch index 3a3bbbf..cfbf24c 100644 --- a/0085-multipath-tools-unit-tests-fix-memory-leaks-in-mpath.patch +++ b/0085-multipath-tools-unit-tests-fix-memory-leaks-in-mpath.patch @@ -48,6 +48,3 @@ index 5ffabb9d..cfe4bae1 100644 } #define setup_test(name) \ --- -2.17.2 - diff --git a/0086-mpathpersist-Fix-Register-and-Ignore-with-0x00-SARK.patch b/0086-mpathpersist-Fix-Register-and-Ignore-with-0x00-SARK.patch index 3e152fc..323176f 100644 --- a/0086-mpathpersist-Fix-Register-and-Ignore-with-0x00-SARK.patch +++ b/0086-mpathpersist-Fix-Register-and-Ignore-with-0x00-SARK.patch @@ -29,6 +29,3 @@ index 79322e86..41789c46 100644 condlog(0, "%s: configured reservation key doesn't match: 0x%" PRIx64, alias, get_be64(mpp->reservation_key)); ret = MPATH_PR_SYNTAX_ERROR; goto out1; --- -2.17.2 - diff --git a/0087-mpathpersist-update-prkeys-file-on-changing-registra.patch b/0087-mpathpersist-update-prkeys-file-on-changing-registra.patch index 79bee15..f555825 100644 --- a/0087-mpathpersist-update-prkeys-file-on-changing-registra.patch +++ b/0087-mpathpersist-update-prkeys-file-on-changing-registra.patch @@ -34,6 +34,3 @@ index 41789c46..08077936 100644 memcpy(&mpp->reservation_key, paramp->sa_key, 8); if (update_prkey_flags(alias, get_be64(mpp->reservation_key), paramp->sa_flags)) { --- -2.17.2 - diff --git a/0088-libmultipath-warn-about-missing-braces-at-end-of-mul.patch b/0088-libmultipath-warn-about-missing-braces-at-end-of-mul.patch index bbb9f13..4534b41 100644 --- a/0088-libmultipath-warn-about-missing-braces-at-end-of-mul.patch +++ b/0088-libmultipath-warn-about-missing-braces-at-end-of-mul.patch @@ -37,6 +37,3 @@ index 163ffbc9..c70243c3 100644 out: FREE(buf); free_uniques(uniques); --- -2.17.2 - diff --git a/0089-libmultipath-ignore-multipaths-sections-without-wwid.patch b/0089-libmultipath-ignore-multipaths-sections-without-wwid.patch index 25aa7ea..f49f461 100644 --- a/0089-libmultipath-ignore-multipaths-sections-without-wwid.patch +++ b/0089-libmultipath-ignore-multipaths-sections-without-wwid.patch @@ -32,6 +32,3 @@ index 9f3cb38d..a643703e 100644 j = i + 1; vector_foreach_slot_after(mptable, mp2, j) { if (strcmp(mp1->wwid, mp2->wwid)) --- -2.17.2 - diff --git a/0090-libmultipath-fix-format-warning-with-clang.patch b/0090-libmultipath-fix-format-warning-with-clang.patch index 931e81c..24bbe92 100644 --- a/0090-libmultipath-fix-format-warning-with-clang.patch +++ b/0090-libmultipath-fix-format-warning-with-clang.patch @@ -23,6 +23,3 @@ index 6498c88c..10fa32cd 100644 static int _log_enqueue(int prio, const char * fmt, va_list ap) { int len, fwd; --- -2.17.2 - diff --git a/0091-libmultipath-check-for-null-wwid-before-strcmp.patch b/0091-libmultipath-check-for-null-wwid-before-strcmp.patch index 1f6894d..3162352 100644 --- a/0091-libmultipath-check-for-null-wwid-before-strcmp.patch +++ b/0091-libmultipath-check-for-null-wwid-before-strcmp.patch @@ -29,6 +29,3 @@ index a643703e..be310159 100644 continue; condlog(1, "%s: duplicate multipath config section for %s", __func__, mp1->wwid); --- -2.17.2 - diff --git a/0092-multipath.conf.5-Improve-checker_timeout-description.patch b/0092-multipath.conf.5-Improve-checker_timeout-description.patch index 120c637..09f108c 100644 --- a/0092-multipath.conf.5-Improve-checker_timeout-description.patch +++ b/0092-multipath.conf.5-Improve-checker_timeout-description.patch @@ -60,6 +60,3 @@ index ea66a01e..8ef3a747 100644 .RS .TP The default is: in \fB/sys/block/sd/device/timeout\fR --- -2.17.2 - diff --git a/0093-multipathd-fix-path-checkint-not-changed-when-path-s.patch b/0093-multipathd-fix-path-checkint-not-changed-when-path-s.patch index 868fa18..0fa29be 100644 --- a/0093-multipathd-fix-path-checkint-not-changed-when-path-s.patch +++ b/0093-multipathd-fix-path-checkint-not-changed-when-path-s.patch @@ -31,6 +31,3 @@ index 4417860b..7612430a 100644 return 1; } if (!pp->mpp) { --- -2.17.2 - diff --git a/0094-libmultipath-select_action-skip-is_mpp_known_to_udev.patch b/0094-libmultipath-select_action-skip-is_mpp_known_to_udev.patch index e37e4da..b129afa 100644 --- a/0094-libmultipath-select_action-skip-is_mpp_known_to_udev.patch +++ b/0094-libmultipath-select_action-skip-is_mpp_known_to_udev.patch @@ -46,6 +46,3 @@ index d9fd9cb8..999f3106 100644 mpp->action = ACT_NOTHING; condlog(3, "%s: set ACT_NOTHING (map unchanged)", mpp->alias); --- -2.17.2 - diff --git a/0095-libmultipath-coalesce_paths-stop-triggering-spurious.patch b/0095-libmultipath-coalesce_paths-stop-triggering-spurious.patch index 033525b..0f8e520 100644 --- a/0095-libmultipath-coalesce_paths-stop-triggering-spurious.patch +++ b/0095-libmultipath-coalesce_paths-stop-triggering-spurious.patch @@ -60,6 +60,3 @@ index 999f3106..3263bb01 100644 conf = get_multipath_config(); allow_queueing = conf->allow_queueing; put_multipath_config(conf); --- -2.17.2 - diff --git a/0096-Revert-multipathd-uev_trigger-handle-incomplete-ADD-.patch b/0096-Revert-multipathd-uev_trigger-handle-incomplete-ADD-.patch index 79912f0..49cf1b0 100644 --- a/0096-Revert-multipathd-uev_trigger-handle-incomplete-ADD-.patch +++ b/0096-Revert-multipathd-uev_trigger-handle-incomplete-ADD-.patch @@ -56,6 +56,3 @@ index 7612430a..92c45d44 100644 } goto out; } --- -2.17.2 - diff --git a/0097-libmultipath-make-find_err_path_by_dev-static.patch b/0097-libmultipath-make-find_err_path_by_dev-static.patch index a19afc4..19f0a01 100644 --- a/0097-libmultipath-make-find_err_path_by_dev-static.patch +++ b/0097-libmultipath-make-find_err_path_by_dev-static.patch @@ -22,6 +22,3 @@ index 5363049d..2e48ee81 100644 { int i; struct io_err_stat_path *pp; --- -2.17.2 - diff --git a/0098-multipathd-avoid-io_err_stat-crash-during-shutdown.patch b/0098-multipathd-avoid-io_err_stat-crash-during-shutdown.patch index 4c21465..2cab5a8 100644 --- a/0098-multipathd-avoid-io_err_stat-crash-during-shutdown.patch +++ b/0098-multipathd-avoid-io_err_stat-crash-during-shutdown.patch @@ -252,6 +252,3 @@ index 2e48ee81..feb66469 100644 + free_io_err_pathvec(); io_destroy(ioctx); } --- -2.17.2 - diff --git a/0099-multipathd-avoid-io_err_stat-ABBA-deadlock.patch b/0099-multipathd-avoid-io_err_stat-ABBA-deadlock.patch index 30584f6..e6bf72d 100644 --- a/0099-multipathd-avoid-io_err_stat-ABBA-deadlock.patch +++ b/0099-multipathd-avoid-io_err_stat-ABBA-deadlock.patch @@ -141,6 +141,3 @@ index feb66469..775e7259 100644 } static void cleanup_exited(__attribute__((unused)) void *arg) --- -2.17.2 - diff --git a/0100-multipathd-use-get_monotonic_time-in-io_err_stat-cod.patch b/0100-multipathd-use-get_monotonic_time-in-io_err_stat-cod.patch index 89d9f73..a5ef865 100644 --- a/0100-multipathd-use-get_monotonic_time-in-io_err_stat-cod.patch +++ b/0100-multipathd-use-get_monotonic_time-in-io_err_stat-cod.patch @@ -106,6 +106,3 @@ index 775e7259..92871f40 100644 vector_foreach_slot(io_err_pathvec, pp, i) { for (j = 0; j < CONCUR_NR_EVENT; j++) { rc = try_to_cancel_timeout_io(pp->dio_ctx_array + j, --- -2.17.2 - diff --git a/0101-multipathd-combine-free_io_err_stat_path-and-destroy.patch b/0101-multipathd-combine-free_io_err_stat_path-and-destroy.patch index 90fd516..d6d015e 100644 --- a/0101-multipathd-combine-free_io_err_stat_path-and-destroy.patch +++ b/0101-multipathd-combine-free_io_err_stat_path-and-destroy.patch @@ -96,6 +96,3 @@ index 92871f40..bf78a236 100644 free_io_err_stat_path(pp); } vector_reset(tmp_pathvec); --- -2.17.2 - diff --git a/0102-multipathd-cleanup-logging-for-marginal-paths.patch b/0102-multipathd-cleanup-logging-for-marginal-paths.patch index 79ad137..a88c07b 100644 --- a/0102-multipathd-cleanup-logging-for-marginal-paths.patch +++ b/0102-multipathd-cleanup-logging-for-marginal-paths.patch @@ -118,6 +118,3 @@ index 92c45d44..99a89a69 100644 else if (update_prio(pp, new_path_up) && (pp->mpp->pgpolicyfn == (pgpolicyfn *)group_by_prio) && pp->mpp->pgfailback == -FAILBACK_IMMEDIATE) { --- -2.17.2 - diff --git a/0103-libmultipath-fix-NULL-dereference-in-find_path_by_de.patch b/0103-libmultipath-fix-NULL-dereference-in-find_path_by_de.patch index 4dd4051..e115e58 100644 --- a/0103-libmultipath-fix-NULL-dereference-in-find_path_by_de.patch +++ b/0103-libmultipath-fix-NULL-dereference-in-find_path_by_de.patch @@ -41,6 +41,3 @@ index 464596fc..a3f27fd6 100644 return NULL; vector_foreach_slot (pathvec, pp, i) --- -2.17.2 - diff --git a/0104-libmultipath-snprint_devices-avoid-NULL-dereference.patch b/0104-libmultipath-snprint_devices-avoid-NULL-dereference.patch index 04ff739..4ddae1c 100644 --- a/0104-libmultipath-snprint_devices-avoid-NULL-dereference.patch +++ b/0104-libmultipath-snprint_devices-avoid-NULL-dereference.patch @@ -33,6 +33,3 @@ index 19de2c7c..8151e11e 100644 fwd += snprintf(buff + fwd, len - fwd, " %s", devname); if (fwd >= len) --- -2.17.2 - diff --git a/0105-libmpathpersist-fix-thread-safety-of-default-functio.patch b/0105-libmpathpersist-fix-thread-safety-of-default-functio.patch index dad9963..e21e27c 100644 --- a/0105-libmpathpersist-fix-thread-safety-of-default-functio.patch +++ b/0105-libmpathpersist-fix-thread-safety-of-default-functio.patch @@ -269,6 +269,3 @@ index 5435eae4..9e9c0a82 100644 */ void mpath_persistent_reserve_free_vecs(void); --- -2.17.2 - diff --git a/0106-Added-github-action-for-building.patch b/0106-Added-github-action-for-building.patch index 8a8a7d0..9622788 100644 --- a/0106-Added-github-action-for-building.patch +++ b/0106-Added-github-action-for-building.patch @@ -32,6 +32,3 @@ index 00000000..2b13c65c + run: make -O -j$(grep -c ^processor /proc/cpuinfo) + - name: test + run: make -O -j$(grep -c ^processor /proc/cpuinfo) test --- -2.17.2 - diff --git a/0107-github-workflow-use-zram-device-as-test-block-device.patch b/0107-github-workflow-use-zram-device-as-test-block-device.patch index 5b25c29..4a2d179 100644 --- a/0107-github-workflow-use-zram-device-as-test-block-device.patch +++ b/0107-github-workflow-use-zram-device-as-test-block-device.patch @@ -35,6 +35,3 @@ index 2b13c65c..ef55b8c1 100644 + run: rm -f tests/dmevents.out tests/directio.out + - name: root-test + run: sudo make DIO_TEST_DEV=/dev/zram$ZRAM test --- -2.17.2 - diff --git a/0108-github-workflow-use-explicit-Ubuntu-version.patch b/0108-github-workflow-use-explicit-Ubuntu-version.patch index ff565d6..f9b2336 100644 --- a/0108-github-workflow-use-explicit-Ubuntu-version.patch +++ b/0108-github-workflow-use-explicit-Ubuntu-version.patch @@ -21,6 +21,3 @@ index ef55b8c1..577a14ac 100644 steps: - uses: actions/checkout@v2 - name: mpath --- -2.17.2 - diff --git a/0109-github-workflow-add-valgrind-tests.patch b/0109-github-workflow-add-valgrind-tests.patch index 5c4e366..fc5f15c 100644 --- a/0109-github-workflow-add-valgrind-tests.patch +++ b/0109-github-workflow-add-valgrind-tests.patch @@ -31,6 +31,3 @@ index 577a14ac..929f63a6 100644 - name: clean-nonroot-artifacts run: rm -f tests/dmevents.out tests/directio.out - name: root-test --- -2.17.2 - diff --git a/0110-github-workflow-run-apt-get-update.patch b/0110-github-workflow-run-apt-get-update.patch index d27f1ca..f257ffc 100644 --- a/0110-github-workflow-run-apt-get-update.patch +++ b/0110-github-workflow-run-apt-get-update.patch @@ -23,6 +23,3 @@ index 929f63a6..389578be 100644 - name: dependencies run: > sudo apt-get install --yes gcc --- -2.17.2 - diff --git a/0111-github-workflow-add-tests-with-gcc-10-and-clang.patch b/0111-github-workflow-add-tests-with-gcc-10-and-clang.patch index e95b3f8..a328464 100644 --- a/0111-github-workflow-add-tests-with-gcc-10-and-clang.patch +++ b/0111-github-workflow-add-tests-with-gcc-10-and-clang.patch @@ -85,6 +85,3 @@ index 389578be..4173576f 100644 + run: rm -f tests/dmevents.out tests/directio.out + - name: root-test + run: sudo make DIO_TEST_DEV=/dev/ram0 test --- -2.17.2 - diff --git a/0112-multipathd-Fix-multipathd-stopping-on-shutdown.patch b/0112-multipathd-Fix-multipathd-stopping-on-shutdown.patch index 49ea563..d18b363 100644 --- a/0112-multipathd-Fix-multipathd-stopping-on-shutdown.patch +++ b/0112-multipathd-Fix-multipathd-stopping-on-shutdown.patch @@ -33,6 +33,3 @@ index ba24983e..7d547fa7 100644 After=multipathd.socket systemd-udev-trigger.service systemd-udev-settle.service DefaultDependencies=no Conflicts=shutdown.target --- -2.17.2 - diff --git a/0113-libmultipath-use-3rd-digit-as-transport_id-for-expan.patch b/0113-libmultipath-use-3rd-digit-as-transport_id-for-expan.patch index 17d53ce..a83d7bd 100644 --- a/0113-libmultipath-use-3rd-digit-as-transport_id-for-expan.patch +++ b/0113-libmultipath-use-3rd-digit-as-transport_id-for-expan.patch @@ -40,6 +40,3 @@ index e818585a..6d74cc07 100644 tgtdev = udev_device_get_parent(tgtdev); tgtid = -1; } --- -2.17.2 - diff --git a/0114-libmultipath-sysfs_set_nexus_loss_tmo-support-SAS-ex.patch b/0114-libmultipath-sysfs_set_nexus_loss_tmo-support-SAS-ex.patch index 3207d2d..1eccb08 100644 --- a/0114-libmultipath-sysfs_set_nexus_loss_tmo-support-SAS-ex.patch +++ b/0114-libmultipath-sysfs_set_nexus_loss_tmo-support-SAS-ex.patch @@ -52,6 +52,3 @@ index 6d74cc07..921025d4 100644 sas_dev = udev_device_new_from_subsystem_sysname(udev, "sas_end_device", end_dev_id); if (!sas_dev) { --- -2.17.2 - diff --git a/0115-multipathd-add-code-to-initalize-unwinder.patch b/0115-multipathd-add-code-to-initalize-unwinder.patch index e231733..b2ccb84 100644 --- a/0115-multipathd-add-code-to-initalize-unwinder.patch +++ b/0115-multipathd-add-code-to-initalize-unwinder.patch @@ -129,6 +129,3 @@ index 99a89a69..6f851ae8 100644 mlockall(MCL_CURRENT | MCL_FUTURE); signal_init(); mp_rcu_data = setup_rcu(); --- -2.17.2 - diff --git a/0116-libmultipath-check-if-adopt_path-really-added-curren.patch b/0116-libmultipath-check-if-adopt_path-really-added-curren.patch index b656c08..195e9ed 100644 --- a/0116-libmultipath-check-if-adopt_path-really-added-curren.patch +++ b/0116-libmultipath-check-if-adopt_path-really-added-curren.patch @@ -52,6 +52,3 @@ index 6f851ae8..43d77688 100644 goto fail; /* leave path added to pathvec */ verify_paths(mpp); --- -2.17.2 - diff --git a/0117-multipathd-ev_add_path-fail-if-add_map_with_path-fai.patch b/0117-multipathd-ev_add_path-fail-if-add_map_with_path-fai.patch index f223728..1bff1e5 100644 --- a/0117-multipathd-ev_add_path-fail-if-add_map_with_path-fai.patch +++ b/0117-multipathd-ev_add_path-fail-if-add_map_with_path-fai.patch @@ -26,6 +26,3 @@ index 43d77688..425492a9 100644 goto fail; /* leave path added to pathvec */ } --- -2.17.2 - diff --git a/0118-libmultipath-check-return-value-of-udev_device_get_d.patch b/0118-libmultipath-check-return-value-of-udev_device_get_d.patch index fe69708..711e00f 100644 --- a/0118-libmultipath-check-return-value-of-udev_device_get_d.patch +++ b/0118-libmultipath-check-return-value-of-udev_device_get_d.patch @@ -26,6 +26,3 @@ index 921025d4..15cf6413 100644 snprintf(pp->dev_t, BLK_DEV_SIZE, "%d:%d", major(devt), minor(devt)); condlog(4, "%s: dev_t = %s", pp->dev, pp->dev_t); --- -2.17.2 - diff --git a/0119-pathinfo-call-filter_property-after-sysfs_pathinfo.patch b/0119-pathinfo-call-filter_property-after-sysfs_pathinfo.patch index cf106c2..660ba85 100644 --- a/0119-pathinfo-call-filter_property-after-sysfs_pathinfo.patch +++ b/0119-pathinfo-call-filter_property-after-sysfs_pathinfo.patch @@ -276,6 +276,3 @@ index 693c72c5..8ec803e8 100644 assert_int_equal(is_path_valid(name, &conf, &pp, false), PATH_IS_NOT_VALID); } --- -2.17.2 - diff --git a/0120-libmultipath-pathinfo-call-filter_property-only-with.patch b/0120-libmultipath-pathinfo-call-filter_property-only-with.patch index c4c8efc..62c930b 100644 --- a/0120-libmultipath-pathinfo-call-filter_property-only-with.patch +++ b/0120-libmultipath-pathinfo-call-filter_property-only-with.patch @@ -83,6 +83,3 @@ index 960a7665..f5542ed0 100644 if (mp->flags & BL_BY_DEVICE && (mask & DI_BLACKLIST && mask & DI_SYSFS)) --- -2.17.2 - diff --git a/0121-multipath-w-allow-removing-blacklisted-paths.patch b/0121-multipath-w-allow-removing-blacklisted-paths.patch index db6fe52..6b3e4f7 100644 --- a/0121-multipath-w-allow-removing-blacklisted-paths.patch +++ b/0121-multipath-w-allow-removing-blacklisted-paths.patch @@ -34,6 +34,3 @@ index 3263bb01..598efe05 100644 filter_wwid(conf->blist_wwid, conf->elist_wwid, refwwid, NULL) > 0) return PATHINFO_SKIPPED; --- -2.17.2 - diff --git a/0122-libmultipath-fix-use-after-free-in-uev_add_path.patch b/0122-libmultipath-fix-use-after-free-in-uev_add_path.patch index 6a5fcad..921a0cc 100644 --- a/0122-libmultipath-fix-use-after-free-in-uev_add_path.patch +++ b/0122-libmultipath-fix-use-after-free-in-uev_add_path.patch @@ -1,6 +1,6 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski -Date: Mon, 1 Feb 2021 19:47:11 -0600 +Date: Mon, 8 Feb 2021 23:19:26 -0600 Subject: [PATCH] libmultipath: fix use-after-free in uev_add_path if ev_remove_path() returns success the path has very likely been @@ -11,6 +11,7 @@ Insted, uev_add_path() should only continue to access the path if ev_remove_path() didn't succeed. Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck --- multipathd/main.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) @@ -48,6 +49,3 @@ index 425492a9..19679848 100644 } else if (r == PATHINFO_SKIPPED) { condlog(3, "%s: remove blacklisted path", uev->kernel); --- -2.17.2 - diff --git a/0123-multipath-tools-tests-fix-stringop-overflow-build-er.patch b/0123-multipath-tools-tests-fix-stringop-overflow-build-er.patch new file mode 100644 index 0000000..bb199f5 --- /dev/null +++ b/0123-multipath-tools-tests-fix-stringop-overflow-build-er.patch @@ -0,0 +1,52 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 10 Feb 2021 13:15:17 +0100 +Subject: [PATCH] multipath-tools tests: fix stringop-overflow build errors + with gcc 11 + +gcc-11 throws an error compiling alias.c and dmevents.c: + +In file included from ../libmultipath/checkers.h:4, + from ../libmultipath/prio.h:7, + from ../libmultipath/structs.h:8, + from dmevents.c:29: +../multipathd/dmevents.c: In function 'dmevent_loop': +../multipathd/dmevents.c:357:17: error: '__sigsetjmp' accessing 200 bytes in a region of size 72 [-Werror=stringop-overflow=] + 357 | pthread_cleanup_push(cleanup_lock, &waiter->vecs->lock); + | ^~~~~~~~~~~~~~~~~~~~ +../multipathd/dmevents.c:357:17: note: referencing argument 1 of type 'struct __jmp_buf_tag *' +/usr/include/pthread.h:734:12: note: in a call to function '__sigsetjmp' + 734 | extern int __sigsetjmp (struct __jmp_buf_tag *__env, int __savemask) __THROWNL; + | ^~~~~~~~~~~ + +The reason seems to be a mismatch between the __sigsetjmp() prototype +in and . The error is encountered iUntil this is fixed in the toolchain, +work around it by including before . + +Signed-off-by: Benjamin Marzinski +--- + tests/alias.c | 1 + + tests/dmevents.c | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/tests/alias.c b/tests/alias.c +index 0311faa6..5e0bfea3 100644 +--- a/tests/alias.c ++++ b/tests/alias.c +@@ -1,3 +1,4 @@ ++#include + #include + #include + #include +diff --git a/tests/dmevents.c b/tests/dmevents.c +index b7c5122b..29eaa6db 100644 +--- a/tests/dmevents.c ++++ b/tests/dmevents.c +@@ -16,6 +16,7 @@ + * + */ + ++#include + #include + #include + #include diff --git a/0124-libmultipath-cleanup-code-to-strip-wwid-trailing-spa.patch b/0124-libmultipath-cleanup-code-to-strip-wwid-trailing-spa.patch new file mode 100644 index 0000000..0d4a25e --- /dev/null +++ b/0124-libmultipath-cleanup-code-to-strip-wwid-trailing-spa.patch @@ -0,0 +1,44 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 24 Feb 2021 00:33:20 -0600 +Subject: [PATCH] libmultipath: cleanup code to strip wwid trailing spaces + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/discovery.c | 11 ++++------- + 1 file changed, 4 insertions(+), 7 deletions(-) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index 9be94cd1..3a06f319 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -2152,11 +2152,11 @@ int + get_uid (struct path * pp, int path_state, struct udev_device *udev, + int allow_fallback) + { +- char *c; + const char *origin = "unknown"; + ssize_t len = 0; + struct config *conf; + int used_fallback = 0; ++ size_t i; + + if (!pp->uid_attribute && !pp->getuid) { + conf = get_multipath_config(); +@@ -2210,12 +2210,9 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev, + return 1; + } else { + /* Strip any trailing blanks */ +- c = strchr(pp->wwid, '\0'); +- c--; +- while (c && c >= pp->wwid && *c == ' ') { +- *c = '\0'; +- c--; +- } ++ for (i = strlen(pp->wwid); i > 0 && pp->wwid[i-1] == ' '; i--); ++ /* no-op */ ++ pp->wwid[i] = '\0'; + } + condlog((used_fallback)? 1 : 3, "%s: uid = %s (%s)", pp->dev, + *pp->wwid == '\0' ? "" : pp->wwid, origin); diff --git a/0125-libmultipath-cleanup-uid_attribute-checking-code.patch b/0125-libmultipath-cleanup-uid_attribute-checking-code.patch new file mode 100644 index 0000000..56e473d --- /dev/null +++ b/0125-libmultipath-cleanup-uid_attribute-checking-code.patch @@ -0,0 +1,53 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 24 Feb 2021 00:33:21 -0600 +Subject: [PATCH] libmultipath: cleanup uid_attribute checking code + +In get_uid(), if pp->getuid is NULL, multipath will check the +pp->uid_attribute to get the wwid. If pp->uid_attribute is NULL, +nothing will happen in that block of code, because both udev_available +and has_uid_fallback() are false if pp->uid_attribute is NULL. So +instead of multiple checks if pp->uid_attribute is NULL, just check once +for the code block. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/discovery.c | 17 ++++++++--------- + 1 file changed, 8 insertions(+), 9 deletions(-) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index 3a06f319..40727fa3 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -2183,22 +2183,21 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev, + } else + len = strlen(pp->wwid); + origin = "callout"; +- } else { +- bool valid_uid_attr = pp->uid_attribute +- && *pp->uid_attribute; +- bool empty_uid_attr = pp->uid_attribute +- && !*pp->uid_attribute; +- bool udev_available = udev && valid_uid_attr; ++ } else if (pp->uid_attribute) { ++ /* if the uid_attribute is an empty string skip udev checking */ ++ bool check_uid_attr = udev && *pp->uid_attribute; + +- if (udev_available) { ++ if (check_uid_attr) { + len = get_udev_uid(pp, pp->uid_attribute, udev); + origin = "udev"; + if (len == 0) + condlog(1, "%s: empty udev uid", pp->dev); + } +- if ((!udev_available || (len <= 0 && allow_fallback)) ++ if ((!check_uid_attr || (len <= 0 && allow_fallback)) + && has_uid_fallback(pp)) { +- if (!udev || !empty_uid_attr) ++ /* if udev wasn't set or we failed in get_udev_uid() ++ * log at a higher priority */ ++ if (!udev || check_uid_attr) + used_fallback = 1; + len = uid_fallback(pp, path_state, &origin); + } diff --git a/0126-multipathd-add-recheck_wwid-option-to-verify-the-pat.patch b/0126-multipathd-add-recheck_wwid-option-to-verify-the-pat.patch new file mode 100644 index 0000000..27bc16c --- /dev/null +++ b/0126-multipathd-add-recheck_wwid-option-to-verify-the-pat.patch @@ -0,0 +1,453 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 24 Feb 2021 00:33:22 -0600 +Subject: [PATCH] multipathd: add recheck_wwid option to verify the path wwid + +There are cases where the wwid of a path changes due to LUN remapping +without triggering uevent for the changed path. Multipathd has no method +for trying to catch these cases, and corruption has resulted because of +it. + +In order to have a better chance at catching these cases, multipath now +has a recheck_wwid option. If this is set to "yes", when a failed path +has become active again, multipathd will recheck its wwid. If multipathd +notices that a path's wwid has changed, it will remove and re-add the +path, just like the existing wwid checking code for change events does. +In cases where the no uevent occurs, both the udev database entry and +sysfs will have the old wwid, so the only way to get a current wwid is +to ask the device directly. Currently multipath only has code to +directly get the wwid for scsi devices, so this option only effects scsi +devices, and they must be configured to be able to use the uid_fallback +methods. To make sure both the sysfs and udev database values are +updated, multipathd triggers a both a rescan of the device and a udev +add event. + +Co-developed-by: Chongyun Wu +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck Reviewed-by: Martin Wilck +--- + libmultipath/config.c | 2 + + libmultipath/config.h | 2 + + libmultipath/configure.c | 4 +- + libmultipath/configure.h | 2 + + libmultipath/defaults.h | 1 + + libmultipath/dict.c | 11 +++++ + libmultipath/discovery.c | 7 ++- + libmultipath/discovery.h | 1 + + libmultipath/libmultipath.version | 6 +++ + libmultipath/propsel.c | 21 +++++++++ + libmultipath/propsel.h | 1 + + libmultipath/structs.h | 7 +++ + multipath/multipath.conf.5 | 14 ++++++ + multipathd/cli_handlers.c | 9 ++++ + multipathd/main.c | 78 +++++++++++++++++++++++++++++++ + multipathd/main.h | 2 + + 16 files changed, 164 insertions(+), 4 deletions(-) + +diff --git a/libmultipath/config.c b/libmultipath/config.c +index be310159..30046a17 100644 +--- a/libmultipath/config.c ++++ b/libmultipath/config.c +@@ -436,6 +436,7 @@ merge_hwe (struct hwentry * dst, struct hwentry * src) + merge_num(max_sectors_kb); + merge_num(ghost_delay); + merge_num(all_tg_pt); ++ merge_num(recheck_wwid); + merge_num(vpd_vendor_id); + merge_num(san_path_err_threshold); + merge_num(san_path_err_forget_rate); +@@ -867,6 +868,7 @@ int _init_config (const char *file, struct config *conf) + conf->remove_retries = 0; + conf->ghost_delay = DEFAULT_GHOST_DELAY; + conf->all_tg_pt = DEFAULT_ALL_TG_PT; ++ conf->recheck_wwid = DEFAULT_RECHECK_WWID; + /* + * preload default hwtable + */ +diff --git a/libmultipath/config.h b/libmultipath/config.h +index 9ce37f16..933fe0d1 100644 +--- a/libmultipath/config.h ++++ b/libmultipath/config.h +@@ -83,6 +83,7 @@ struct hwentry { + int ghost_delay; + int all_tg_pt; + int vpd_vendor_id; ++ int recheck_wwid; + char * bl_product; + }; + +@@ -187,6 +188,7 @@ struct config { + int marginal_pathgroups; + int skip_delegate; + unsigned int sequence_nr; ++ int recheck_wwid; + + char * multipath_dir; + char * selector; +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index 598efe05..6ca1f4bb 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -527,8 +527,8 @@ get_udev_for_mpp(const struct multipath *mpp) + return udd; + } + +-static void trigger_partitions_udev_change(struct udev_device *dev, +- const char *action, int len) ++void trigger_partitions_udev_change(struct udev_device *dev, ++ const char *action, int len) + { + struct udev_enumerate *part_enum; + struct udev_list_entry *item; +diff --git a/libmultipath/configure.h b/libmultipath/configure.h +index 6b23ccbb..70cf77a3 100644 +--- a/libmultipath/configure.h ++++ b/libmultipath/configure.h +@@ -58,3 +58,5 @@ int get_refwwid (enum mpath_cmds cmd, const char *dev, enum devtypes dev_type, + vector pathvec, char **wwid); + struct udev_device *get_udev_device(const char *dev, enum devtypes dev_type); + void trigger_paths_udev_change(struct multipath *mpp, bool is_mpath); ++void trigger_partitions_udev_change(struct udev_device *dev, const char *action, ++ int len); +diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h +index 947ba467..c27946c7 100644 +--- a/libmultipath/defaults.h ++++ b/libmultipath/defaults.h +@@ -53,6 +53,7 @@ + #define DEFAULT_FIND_MULTIPATHS_TIMEOUT -10 + #define DEFAULT_UNKNOWN_FIND_MULTIPATHS_TIMEOUT 1 + #define DEFAULT_ALL_TG_PT ALL_TG_PT_OFF ++#define DEFAULT_RECHECK_WWID RECHECK_WWID_OFF + /* Enable no foreign libraries by default */ + #define DEFAULT_ENABLE_FOREIGN "NONE" + +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index bab96146..dd08abf5 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -1401,6 +1401,14 @@ declare_hw_snprint(all_tg_pt, print_yes_no_undef) + declare_def_handler(marginal_pathgroups, set_yes_no) + declare_def_snprint(marginal_pathgroups, print_yes_no) + ++declare_def_handler(recheck_wwid, set_yes_no_undef) ++declare_def_snprint_defint(recheck_wwid, print_yes_no_undef, DEFAULT_RECHECK_WWID) ++declare_ovr_handler(recheck_wwid, set_yes_no_undef) ++declare_ovr_snprint(recheck_wwid, print_yes_no_undef) ++declare_hw_handler(recheck_wwid, set_yes_no_undef) ++declare_hw_snprint(recheck_wwid, print_yes_no_undef) ++ ++ + static int + def_uxsock_timeout_handler(struct config *conf, vector strvec) + { +@@ -1819,6 +1827,7 @@ init_keywords(vector keywords) + install_keyword("enable_foreign", &def_enable_foreign_handler, + &snprint_def_enable_foreign); + install_keyword("marginal_pathgroups", &def_marginal_pathgroups_handler, &snprint_def_marginal_pathgroups); ++ install_keyword("recheck_wwid", &def_recheck_wwid_handler, &snprint_def_recheck_wwid); + __deprecated install_keyword("default_selector", &def_selector_handler, NULL); + __deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL); + __deprecated install_keyword("default_uid_attribute", &def_uid_attribute_handler, NULL); +@@ -1908,6 +1917,7 @@ init_keywords(vector keywords) + 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_keyword("vpd_vendor", &hw_vpd_vendor_handler, &snprint_hw_vpd_vendor); ++ install_keyword("recheck_wwid", &hw_recheck_wwid_handler, &snprint_hw_recheck_wwid); + install_sublevel_end(); + + install_keyword_root("overrides", &overrides_handler); +@@ -1949,6 +1959,7 @@ init_keywords(vector keywords) + 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("recheck_wwid", &ovr_recheck_wwid_handler, &snprint_ovr_recheck_wwid); + + install_keyword_root("multipaths", &multipaths_handler); + install_keyword_multi("multipath", &multipath_handler, NULL); +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index 40727fa3..f216a724 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -2127,7 +2127,7 @@ static ssize_t uid_fallback(struct path *pp, int path_state, + return len; + } + +-static bool has_uid_fallback(struct path *pp) ++bool has_uid_fallback(struct path *pp) + { + /* + * Falling back to direct WWID determination is dangerous +@@ -2162,6 +2162,7 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev, + conf = get_multipath_config(); + pthread_cleanup_push(put_multipath_config, conf); + select_getuid(conf, pp); ++ select_recheck_wwid(conf, pp); + pthread_cleanup_pop(1); + } + +@@ -2293,8 +2294,10 @@ int pathinfo(struct path *pp, struct config *conf, int mask) + + if (mask & DI_BLACKLIST && mask & DI_SYSFS) { + /* uid_attribute is required for filter_property() */ +- if (pp->udev && !pp->uid_attribute) ++ if (pp->udev && !pp->uid_attribute) { + select_getuid(conf, pp); ++ select_recheck_wwid(conf, pp); ++ } + + if (filter_property(conf, pp->udev, 4, pp->uid_attribute) > 0 || + filter_device(conf->blist_device, conf->elist_device, +diff --git a/libmultipath/discovery.h b/libmultipath/discovery.h +index d3193daf..a5446b4d 100644 +--- a/libmultipath/discovery.h ++++ b/libmultipath/discovery.h +@@ -54,6 +54,7 @@ ssize_t sysfs_get_inquiry(struct udev_device *udev, + unsigned char *buff, size_t len); + int sysfs_get_asymmetric_access_state(struct path *pp, + char *buff, int buflen); ++bool has_uid_fallback(struct path *pp); + int get_uid(struct path * pp, int path_state, struct udev_device *udev, + int allow_fallback); + bool is_vpd_page_supported(int fd, int pg); +diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version +index 2228f4ec..e9b4608f 100644 +--- a/libmultipath/libmultipath.version ++++ b/libmultipath/libmultipath.version +@@ -280,3 +280,9 @@ LIBMULTIPATH_4.4.0 { + global: + get_next_string; + } LIBMULTIPATH_4.3.0; ++ ++LIBMULITIPATH_4.5.0 { ++global: ++ get_vpd_sgio; ++ trigger_partitions_udev_change; ++} LIBMULTIPATH_4.4.0; +diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c +index f771a830..b7b33791 100644 +--- a/libmultipath/propsel.c ++++ b/libmultipath/propsel.c +@@ -581,6 +581,27 @@ out: + return 0; + } + ++/* must be called after select_getuid */ ++int select_recheck_wwid(struct config *conf, struct path * pp) ++{ ++ const char *origin; ++ ++ pp_set_ovr(recheck_wwid); ++ pp_set_hwe(recheck_wwid); ++ pp_set_conf(recheck_wwid); ++ pp_set_default(recheck_wwid, DEFAULT_RECHECK_WWID); ++out: ++ if (pp->recheck_wwid == RECHECK_WWID_ON && ++ (pp->bus != SYSFS_BUS_SCSI || pp->getuid != NULL || ++ !has_uid_fallback(pp))) { ++ pp->recheck_wwid = RECHECK_WWID_OFF; ++ origin = "(setting: unsupported by device type/config)"; ++ } ++ condlog(3, "%s: recheck_wwid = %i %s", pp->dev, pp->recheck_wwid, ++ origin); ++ return 0; ++} ++ + void + detect_prio(struct config *conf, struct path * pp) + { +diff --git a/libmultipath/propsel.h b/libmultipath/propsel.h +index a68bacf0..72a7e33c 100644 +--- a/libmultipath/propsel.h ++++ b/libmultipath/propsel.h +@@ -7,6 +7,7 @@ int select_features (struct config *conf, struct multipath * mp); + int select_hwhandler (struct config *conf, struct multipath * mp); + int select_checker(struct config *conf, struct path *pp); + int select_getuid (struct config *conf, struct path * pp); ++int select_recheck_wwid(struct config *conf, struct path * pp); + int select_prio (struct config *conf, struct path * pp); + int select_find_multipaths_timeout(struct config *conf, struct path *pp); + int select_no_path_retry(struct config *conf, struct multipath *mp); +diff --git a/libmultipath/structs.h b/libmultipath/structs.h +index d6ff6762..c8447e56 100644 +--- a/libmultipath/structs.h ++++ b/libmultipath/structs.h +@@ -242,6 +242,12 @@ enum eh_deadline_states { + EH_DEADLINE_ZERO = UOZ_ZERO, + }; + ++enum recheck_wwid_states { ++ RECHECK_WWID_UNDEF = YNU_UNDEF, ++ RECHECK_WWID_OFF = YNU_NO, ++ RECHECK_WWID_ON = YNU_YES, ++}; ++ + struct vpd_vendor_page { + int pg; + const char *name; +@@ -316,6 +322,7 @@ struct path { + int find_multipaths_timeout; + int marginal; + int vpd_vendor_id; ++ int recheck_wwid; + /* configlet pointers */ + vector hwe; + struct gen_path generic_path; +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 +index 8ef3a747..37030765 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5 +@@ -1273,6 +1273,20 @@ The default is: \fB\(dqNONE\(dq\fR + .RE + . + . ++.TP ++.B recheck_wwid ++If set to \fIyes\fR, when a failed path is restored, its wwid is rechecked. If ++the wwid has changed, the path is removed from the current multipath device, ++and re-added as a new path. Multipathd will also recheck a path's wwid if it is ++manually re-added. This option only works for SCSI devices that are configured ++to use the default uid_attribute, \fIID_SERIAL\fR, or sysfs for getting their ++wwid. ++.RS ++.TP ++The default is \fBno\fR ++.RE ++. ++. + + . + .\" ---------------------------------------------------------------------------- +diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c +index 54635738..7f3e61f6 100644 +--- a/multipathd/cli_handlers.c ++++ b/multipathd/cli_handlers.c +@@ -715,6 +715,15 @@ cli_add_path (void * v, char ** reply, int * len, void * data) + pp = find_path_by_dev(vecs->pathvec, param); + if (pp && pp->initialized != INIT_REMOVED) { + condlog(2, "%s: path already in pathvec", param); ++ ++ if (pp->recheck_wwid == RECHECK_WWID_ON && ++ check_path_wwid_change(pp)) { ++ condlog(0, "%s: wwid changed. Removing device", ++ pp->dev); ++ handle_path_wwid_change(pp, vecs); ++ return 1; ++ } ++ + if (pp->mpp) + return 0; + } else if (pp) { +diff --git a/multipathd/main.c b/multipathd/main.c +index 19679848..637a53bf 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -823,6 +823,73 @@ ev_remove_map (char * devname, char * alias, int minor, struct vectors * vecs) + return flush_map(mpp, vecs, 0); + } + ++static void ++rescan_path(struct udev_device *parent) ++{ ++ while(parent) { ++ const char *subsys = udev_device_get_subsystem(parent); ++ if (subsys && !strncmp(subsys, "scsi", 4)) ++ break; ++ parent = udev_device_get_parent(parent); ++ } ++ if (parent) ++ sysfs_attr_set_value(parent, "rescan", "1", strlen("1")); ++} ++ ++void ++handle_path_wwid_change(struct path *pp, struct vectors *vecs) ++{ ++ struct udev_device *udd; ++ ++ if (!pp || !pp->udev) ++ return; ++ ++ udd = udev_device_ref(pp->udev); ++ if (ev_remove_path(pp, vecs, 1) != 0 && pp->mpp) { ++ pp->dmstate = PSTATE_FAILED; ++ dm_fail_path(pp->mpp->alias, pp->dev_t); ++ } ++ rescan_path(udd); ++ sysfs_attr_set_value(udd, "uevent", "add", strlen("add")); ++ trigger_partitions_udev_change(udd, "add", strlen("add")); ++ udev_device_unref(udd); ++} ++ ++bool ++check_path_wwid_change(struct path *pp) ++{ ++ char wwid[WWID_SIZE]; ++ int len = 0; ++ size_t i; ++ ++ if (!strlen(pp->wwid)) ++ return false; ++ ++ /* Get the real fresh device wwid by sgio. sysfs still has old ++ * data, so only get_vpd_sgio will work to get the new wwid */ ++ len = get_vpd_sgio(pp->fd, 0x83, 0, wwid, WWID_SIZE); ++ ++ if (len <= 0) { ++ condlog(2, "%s: failed to check wwid by sgio: len = %d", ++ pp->dev, len); ++ return false; ++ } ++ ++ /*Strip any trailing blanks */ ++ for (i = strlen(pp->wwid); i > 0 && pp->wwid[i-1] == ' '; i--); ++ /* no-op */ ++ pp->wwid[i] = '\0'; ++ condlog(4, "%s: Got wwid %s by sgio", pp->dev, wwid); ++ ++ if (strncmp(wwid, pp->wwid, WWID_SIZE)) { ++ condlog(0, "%s: wwid '%s' doesn't match wwid '%s' from device", ++ pp->dev, pp->wwid, wwid); ++ return true; ++ } ++ ++ return false; ++} ++ + static int + uev_add_path (struct uevent *uev, struct vectors * vecs, int need_do_map) + { +@@ -1296,6 +1363,7 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) + condlog(0, "%s: path wwid changed from '%s' to '%s'", + uev->kernel, wwid, pp->wwid); + ev_remove_path(pp, vecs, 1); ++ rescan_path(uev->udev); + needs_reinit = 1; + goto out; + } else { +@@ -2197,6 +2265,16 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) + return 0; + set_no_path_retry(pp->mpp); + ++ if (pp->recheck_wwid == RECHECK_WWID_ON && ++ (newstate == PATH_UP || newstate == PATH_GHOST) && ++ ((pp->state != PATH_UP && pp->state != PATH_GHOST) || ++ pp->dmstate == PSTATE_FAILED) && ++ check_path_wwid_change(pp)) { ++ condlog(0, "%s: path wwid change detected. Removing", pp->dev); ++ handle_path_wwid_change(pp, vecs); ++ return 0; ++ } ++ + if ((newstate == PATH_UP || newstate == PATH_GHOST) && + (san_path_check_enabled(pp->mpp) || + marginal_path_check_enabled(pp->mpp))) { +diff --git a/multipathd/main.h b/multipathd/main.h +index 5abbe97b..ddd953f9 100644 +--- a/multipathd/main.h ++++ b/multipathd/main.h +@@ -50,4 +50,6 @@ int update_multipath (struct vectors *vecs, char *mapname, int reset); + int reload_and_sync_map(struct multipath *mpp, struct vectors *vecs, + int refresh); + ++void handle_path_wwid_change(struct path *pp, struct vectors *vecs); ++bool check_path_wwid_change(struct path *pp); + #endif /* MAIN_H */ diff --git a/0127-libmultipath-check-if-user_friendly_name-is-in-use.patch b/0127-libmultipath-check-if-user_friendly_name-is-in-use.patch new file mode 100644 index 0000000..770dc90 --- /dev/null +++ b/0127-libmultipath-check-if-user_friendly_name-is-in-use.patch @@ -0,0 +1,231 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 10 Mar 2021 15:15:14 -0600 +Subject: [PATCH] libmultipath: check if user_friendly_name is in use + +If there are multipath devices that have user_friendly_names but do not +have their bindings in the bindings_file, get_user_friendly_alias() can +currently give out those names again. This can result in an incorrect +entry in the bindings file, and a device that gets created with a WWID +alias instead of a user_friendly_name. This situation can happen after +the pivot root, if a multipath device is created in the initramfs. If +this device doesn't have a binding in the regular filesystem +bindings_file and a new multipath device is created before it can add +its binding, the new device can steal that user_friendly_name during +multipathd's initial configure. + +To solve this, get_user_friendly_alias() now calls lookup_binding() with +a new paramter, telling it to check if the id it found is already in use +by a diffent device. If so, lookup_binding() will continue to check open +ids, until it finds one that it not currently in use by a dm device. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/alias.c | 48 +++++++++++++++++++++++++++++++++++++++++--- + tests/alias.c | 22 ++++++++++---------- + 2 files changed, 56 insertions(+), 14 deletions(-) + +diff --git a/libmultipath/alias.c b/libmultipath/alias.c +index a7ba485a..02bc9d65 100644 +--- a/libmultipath/alias.c ++++ b/libmultipath/alias.c +@@ -21,6 +21,7 @@ + #include "config.h" + #include "util.h" + #include "errno.h" ++#include "devmapper.h" + + + /* +@@ -119,6 +120,28 @@ scan_devname(const char *alias, const char *prefix) + return n; + } + ++static int ++id_already_taken(int id, const char *prefix, const char *map_wwid) ++{ ++ char alias[LINE_MAX]; ++ ++ if (format_devname(alias, id, LINE_MAX, prefix) < 0) ++ return 0; ++ ++ if (dm_map_present(alias)) { ++ char wwid[WWID_SIZE]; ++ ++ /* If both the name and the wwid match, then it's fine.*/ ++ if (dm_get_uuid(alias, wwid, sizeof(wwid)) == 0 && ++ strncmp(map_wwid, wwid, sizeof(wwid)) == 0) ++ return 0; ++ condlog(3, "%s: alias '%s' already taken, but not in bindings file. reselecting alias", map_wwid, alias); ++ return 1; ++ } ++ return 0; ++} ++ ++ + /* + * Returns: 0 if matching entry in WWIDs file found + * -1 if an error occurs +@@ -128,7 +151,7 @@ scan_devname(const char *alias, const char *prefix) + */ + static int + lookup_binding(FILE *f, const char *map_wwid, char **map_alias, +- const char *prefix) ++ const char *prefix, int check_if_taken) + { + char buf[LINE_MAX]; + unsigned int line_nr = 0; +@@ -183,12 +206,31 @@ lookup_binding(FILE *f, const char *map_wwid, char **map_alias, + return 0; + } + } ++ if (!prefix && check_if_taken) ++ id = -1; + if (id >= smallest_bigger_id) { + if (biggest_id < INT_MAX) + id = biggest_id + 1; + else + id = -1; + } ++ if (id > 0 && check_if_taken) { ++ while(id_already_taken(id, prefix, map_wwid)) { ++ if (id == INT_MAX) { ++ id = -1; ++ break; ++ } ++ id++; ++ if (id == smallest_bigger_id) { ++ if (biggest_id == INT_MAX) { ++ id = -1; ++ break; ++ } ++ if (biggest_id >= smallest_bigger_id) ++ id = biggest_id + 1; ++ } ++ } ++ } + if (id < 0) { + condlog(0, "no more available user_friendly_names"); + return -1; +@@ -331,7 +373,7 @@ use_existing_alias (const char *wwid, const char *file, const char *alias_old, + goto out; + } + +- id = lookup_binding(f, wwid, &alias, NULL); ++ id = lookup_binding(f, wwid, &alias, NULL, 0); + if (alias) { + condlog(3, "Use existing binding [%s] for WWID [%s]", + alias, wwid); +@@ -388,7 +430,7 @@ get_user_friendly_alias(const char *wwid, const char *file, const char *prefix, + return NULL; + } + +- id = lookup_binding(f, wwid, &alias, prefix); ++ id = lookup_binding(f, wwid, &alias, prefix, 1); + if (id < 0) { + fclose(f); + return NULL; +diff --git a/tests/alias.c b/tests/alias.c +index 5e0bfea3..344aba73 100644 +--- a/tests/alias.c ++++ b/tests/alias.c +@@ -357,7 +357,7 @@ static void lb_empty(void **state) + + will_return(__wrap_fgets, NULL); + expect_condlog(3, "No matching wwid [WWID0] in bindings file.\n"); +- rc = lookup_binding(NULL, "WWID0", &alias, NULL); ++ rc = lookup_binding(NULL, "WWID0", &alias, NULL, 0); + assert_int_equal(rc, 1); + assert_ptr_equal(alias, NULL); + } +@@ -370,7 +370,7 @@ static void lb_match_a(void **state) + will_return(__wrap_fgets, "MPATHa WWID0\n"); + expect_condlog(3, "Found matching wwid [WWID0] in bindings file." + " Setting alias to MPATHa\n"); +- rc = lookup_binding(NULL, "WWID0", &alias, "MPATH"); ++ rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 0); + assert_int_equal(rc, 0); + assert_ptr_not_equal(alias, NULL); + assert_string_equal(alias, "MPATHa"); +@@ -385,7 +385,7 @@ static void lb_nomatch_a(void **state) + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, NULL); + expect_condlog(3, "No matching wwid [WWID1] in bindings file.\n"); +- rc = lookup_binding(NULL, "WWID1", &alias, "MPATH"); ++ rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 0); + assert_int_equal(rc, 2); + assert_ptr_equal(alias, NULL); + } +@@ -399,7 +399,7 @@ static void lb_match_c(void **state) + will_return(__wrap_fgets, "MPATHc WWID1\n"); + expect_condlog(3, "Found matching wwid [WWID1] in bindings file." + " Setting alias to MPATHc\n"); +- rc = lookup_binding(NULL, "WWID1", &alias, "MPATH"); ++ rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 0); + assert_int_equal(rc, 0); + assert_ptr_not_equal(alias, NULL); + assert_string_equal(alias, "MPATHc"); +@@ -415,7 +415,7 @@ static void lb_nomatch_a_c(void **state) + will_return(__wrap_fgets, "MPATHc WWID1\n"); + will_return(__wrap_fgets, NULL); + expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); +- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH"); ++ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); + assert_int_equal(rc, 2); + assert_ptr_equal(alias, NULL); + } +@@ -429,7 +429,7 @@ static void lb_nomatch_c_a(void **state) + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, NULL); + expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); +- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH"); ++ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); + assert_int_equal(rc, 2); + assert_ptr_equal(alias, NULL); + } +@@ -444,7 +444,7 @@ static void lb_nomatch_a_b(void **state) + will_return(__wrap_fgets, "MPATHb WWID1\n"); + will_return(__wrap_fgets, NULL); + expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); +- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH"); ++ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); + assert_int_equal(rc, 3); + assert_ptr_equal(alias, NULL); + } +@@ -460,7 +460,7 @@ static void lb_nomatch_a_b_bad(void **state) + will_return(__wrap_fgets, NULL); + expect_condlog(3, "Ignoring malformed line 3 in bindings file\n"); + expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); +- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH"); ++ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); + assert_int_equal(rc, 3); + assert_ptr_equal(alias, NULL); + } +@@ -475,7 +475,7 @@ static void lb_nomatch_b_a(void **state) + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, NULL); + expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); +- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH"); ++ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); + assert_int_equal(rc, 27); + assert_ptr_equal(alias, NULL); + } +@@ -491,7 +491,7 @@ static void lb_nomatch_int_max(void **state) + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, NULL); + expect_condlog(0, "no more available user_friendly_names\n"); +- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH"); ++ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); + assert_int_equal(rc, -1); + assert_ptr_equal(alias, NULL); + } +@@ -506,7 +506,7 @@ static void lb_nomatch_int_max_m1(void **state) + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, NULL); + expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); +- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH"); ++ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); + assert_int_equal(rc, INT_MAX); + assert_ptr_equal(alias, NULL); + } diff --git a/0128-tests-add-tests-for-checking-if-alias-is-in-use.patch b/0128-tests-add-tests-for-checking-if-alias-is-in-use.patch new file mode 100644 index 0000000..9849282 --- /dev/null +++ b/0128-tests-add-tests-for-checking-if-alias-is-in-use.patch @@ -0,0 +1,525 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 10 Mar 2021 15:15:15 -0600 +Subject: [PATCH] tests: add tests for checking if alias is in use + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + tests/alias.c | 409 +++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 405 insertions(+), 4 deletions(-) + +diff --git a/tests/alias.c b/tests/alias.c +index 344aba73..ebe1209e 100644 +--- a/tests/alias.c ++++ b/tests/alias.c +@@ -62,6 +62,25 @@ int __wrap_ftruncate(int fd, off_t length) + return __set_errno(mock_type(int)); + } + ++int __wrap_dm_map_present(const char * str) ++{ ++ check_expected(str); ++ return mock_type(int); ++} ++ ++int __wrap_dm_get_uuid(const char *name, char *uuid, int uuid_len) ++{ ++ int ret; ++ ++ check_expected(name); ++ check_expected(uuid_len); ++ assert_non_null(uuid); ++ ret = mock_type(int); ++ if (ret == 0) ++ strcpy(uuid, mock_ptr_type(char *)); ++ return ret; ++} ++ + static void fd_mpatha(void **state) + { + char buf[32]; +@@ -350,6 +369,45 @@ static int test_scan_devname(void) + return cmocka_run_group_tests(tests, NULL, NULL); + } + ++static void mock_unused_alias(const char *alias) ++{ ++ expect_string(__wrap_dm_map_present, str, alias); ++ will_return(__wrap_dm_map_present, 0); ++} ++ ++static void mock_self_alias(const char *alias, const char *wwid) ++{ ++ expect_string(__wrap_dm_map_present, str, alias); ++ will_return(__wrap_dm_map_present, 1); ++ expect_string(__wrap_dm_get_uuid, name, alias); ++ expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); ++ will_return(__wrap_dm_get_uuid, 0); ++ will_return(__wrap_dm_get_uuid, wwid); ++} ++ ++#define USED_STR(alias_str, wwid_str) wwid_str ": alias '" alias_str "' already taken, but not in bindings file. reselecting alias\n" ++ ++static void mock_failed_alias(const char *alias, char *msg) ++{ ++ expect_string(__wrap_dm_map_present, str, alias); ++ will_return(__wrap_dm_map_present, 1); ++ expect_string(__wrap_dm_get_uuid, name, alias); ++ expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); ++ will_return(__wrap_dm_get_uuid, 1); ++ expect_condlog(3, msg); ++} ++ ++static void mock_used_alias(const char *alias, char *msg) ++{ ++ expect_string(__wrap_dm_map_present, str, alias); ++ will_return(__wrap_dm_map_present, 1); ++ expect_string(__wrap_dm_get_uuid, name, alias); ++ expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); ++ will_return(__wrap_dm_get_uuid, 0); ++ will_return(__wrap_dm_get_uuid, "WWID_USED"); ++ expect_condlog(3, msg); ++} ++ + static void lb_empty(void **state) + { + int rc; +@@ -362,6 +420,65 @@ static void lb_empty(void **state) + assert_ptr_equal(alias, NULL); + } + ++static void lb_empty_unused(void **state) ++{ ++ int rc; ++ char *alias; ++ ++ will_return(__wrap_fgets, NULL); ++ mock_unused_alias("MPATHa"); ++ expect_condlog(3, "No matching wwid [WWID0] in bindings file.\n"); ++ rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); ++ assert_int_equal(rc, 1); ++ assert_ptr_equal(alias, NULL); ++ free(alias); ++} ++ ++static void lb_empty_failed(void **state) ++{ ++ int rc; ++ char *alias; ++ ++ will_return(__wrap_fgets, NULL); ++ mock_failed_alias("MPATHa", USED_STR("MPATHa", "WWID0")); ++ mock_unused_alias("MPATHb"); ++ expect_condlog(3, "No matching wwid [WWID0] in bindings file.\n"); ++ rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); ++ assert_int_equal(rc, 2); ++ assert_ptr_equal(alias, NULL); ++ free(alias); ++} ++ ++static void lb_empty_1_used(void **state) ++{ ++ int rc; ++ char *alias; ++ ++ will_return(__wrap_fgets, NULL); ++ mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); ++ mock_unused_alias("MPATHb"); ++ expect_condlog(3, "No matching wwid [WWID0] in bindings file.\n"); ++ rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); ++ assert_int_equal(rc, 2); ++ assert_ptr_equal(alias, NULL); ++ free(alias); ++} ++ ++static void lb_empty_1_used_self(void **state) ++{ ++ int rc; ++ char *alias; ++ ++ will_return(__wrap_fgets, NULL); ++ mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); ++ mock_self_alias("MPATHb", "WWID0"); ++ expect_condlog(3, "No matching wwid [WWID0] in bindings file.\n"); ++ rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); ++ assert_int_equal(rc, 2); ++ assert_ptr_equal(alias, NULL); ++ free(alias); ++} ++ + static void lb_match_a(void **state) + { + int rc; +@@ -390,7 +507,52 @@ static void lb_nomatch_a(void **state) + assert_ptr_equal(alias, NULL); + } + +-static void lb_match_c(void **state) ++static void lb_nomatch_a_bad_check(void **state) ++{ ++ int rc; ++ char *alias; ++ ++ will_return(__wrap_fgets, "MPATHa WWID0\n"); ++ will_return(__wrap_fgets, NULL); ++ expect_condlog(0, "no more available user_friendly_names\n"); ++ rc = lookup_binding(NULL, "WWID1", &alias, NULL, 1); ++ assert_int_equal(rc, -1); ++ assert_ptr_equal(alias, NULL); ++} ++ ++static void lb_nomatch_a_unused(void **state) ++{ ++ int rc; ++ char *alias; ++ ++ will_return(__wrap_fgets, "MPATHa WWID0\n"); ++ will_return(__wrap_fgets, NULL); ++ mock_unused_alias("MPATHb"); ++ expect_condlog(3, "No matching wwid [WWID1] in bindings file.\n"); ++ rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1); ++ assert_int_equal(rc, 2); ++ assert_ptr_equal(alias, NULL); ++} ++ ++static void lb_nomatch_a_3_used_failed_self(void **state) ++{ ++ int rc; ++ char *alias; ++ ++ will_return(__wrap_fgets, "MPATHa WWID0\n"); ++ will_return(__wrap_fgets, NULL); ++ mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID1")); ++ mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID1")); ++ mock_used_alias("MPATHd", USED_STR("MPATHd", "WWID1")); ++ mock_failed_alias("MPATHe", USED_STR("MPATHe", "WWID1")); ++ mock_self_alias("MPATHf", "WWID1"); ++ expect_condlog(3, "No matching wwid [WWID1] in bindings file.\n"); ++ rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1); ++ assert_int_equal(rc, 6); ++ assert_ptr_equal(alias, NULL); ++} ++ ++static void do_lb_match_c(void **state, int check_if_taken) + { + int rc; + char *alias; +@@ -399,13 +561,23 @@ static void lb_match_c(void **state) + will_return(__wrap_fgets, "MPATHc WWID1\n"); + expect_condlog(3, "Found matching wwid [WWID1] in bindings file." + " Setting alias to MPATHc\n"); +- rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 0); ++ rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", check_if_taken); + assert_int_equal(rc, 0); + assert_ptr_not_equal(alias, NULL); + assert_string_equal(alias, "MPATHc"); + free(alias); + } + ++static void lb_match_c(void **state) ++{ ++ do_lb_match_c(state, 0); ++} ++ ++static void lb_match_c_check(void **state) ++{ ++ do_lb_match_c(state, 1); ++} ++ + static void lb_nomatch_a_c(void **state) + { + int rc; +@@ -420,6 +592,72 @@ static void lb_nomatch_a_c(void **state) + assert_ptr_equal(alias, NULL); + } + ++static void lb_nomatch_a_d_unused(void **state) ++{ ++ int rc; ++ char *alias; ++ ++ will_return(__wrap_fgets, "MPATHa WWID0\n"); ++ will_return(__wrap_fgets, "MPATHd WWID1\n"); ++ will_return(__wrap_fgets, NULL); ++ mock_unused_alias("MPATHb"); ++ expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); ++ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); ++ assert_int_equal(rc, 2); ++ assert_ptr_equal(alias, NULL); ++} ++ ++static void lb_nomatch_a_d_1_used(void **state) ++{ ++ int rc; ++ char *alias; ++ ++ will_return(__wrap_fgets, "MPATHa WWID0\n"); ++ will_return(__wrap_fgets, "MPATHd WWID1\n"); ++ will_return(__wrap_fgets, NULL); ++ mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2")); ++ mock_unused_alias("MPATHc"); ++ expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); ++ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); ++ assert_int_equal(rc, 3); ++ assert_ptr_equal(alias, NULL); ++} ++ ++static void lb_nomatch_a_d_2_used(void **state) ++{ ++ int rc; ++ char *alias; ++ ++ will_return(__wrap_fgets, "MPATHa WWID0\n"); ++ will_return(__wrap_fgets, "MPATHd WWID1\n"); ++ will_return(__wrap_fgets, NULL); ++ mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2")); ++ mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID2")); ++ mock_unused_alias("MPATHe"); ++ expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); ++ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); ++ assert_int_equal(rc, 5); ++ assert_ptr_equal(alias, NULL); ++} ++ ++static void lb_nomatch_a_d_3_used(void **state) ++{ ++ int rc; ++ char *alias; ++ ++ will_return(__wrap_fgets, "MPATHa WWID0\n"); ++ will_return(__wrap_fgets, "MPATHd WWID1\n"); ++ will_return(__wrap_fgets, NULL); ++ mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2")); ++ mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID2")); ++ mock_used_alias("MPATHe", USED_STR("MPATHe", "WWID2")); ++ mock_unused_alias("MPATHf"); ++ expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); ++ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); ++ assert_int_equal(rc, 6); ++ assert_ptr_equal(alias, NULL); ++} ++ + static void lb_nomatch_c_a(void **state) + { + int rc; +@@ -434,6 +672,39 @@ static void lb_nomatch_c_a(void **state) + assert_ptr_equal(alias, NULL); + } + ++static void lb_nomatch_d_a_unused(void **state) ++{ ++ int rc; ++ char *alias; ++ ++ will_return(__wrap_fgets, "MPATHc WWID1\n"); ++ will_return(__wrap_fgets, "MPATHa WWID0\n"); ++ will_return(__wrap_fgets, "MPATHd WWID0\n"); ++ will_return(__wrap_fgets, NULL); ++ mock_unused_alias("MPATHb"); ++ expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); ++ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); ++ assert_int_equal(rc, 2); ++ assert_ptr_equal(alias, NULL); ++} ++ ++static void lb_nomatch_d_a_1_used(void **state) ++{ ++ int rc; ++ char *alias; ++ ++ will_return(__wrap_fgets, "MPATHc WWID1\n"); ++ will_return(__wrap_fgets, "MPATHa WWID0\n"); ++ will_return(__wrap_fgets, "MPATHd WWID0\n"); ++ will_return(__wrap_fgets, NULL); ++ mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2")); ++ mock_unused_alias("MPATHe"); ++ expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); ++ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); ++ assert_int_equal(rc, 5); ++ assert_ptr_equal(alias, NULL); ++} ++ + static void lb_nomatch_a_b(void **state) + { + int rc; +@@ -465,6 +736,23 @@ static void lb_nomatch_a_b_bad(void **state) + assert_ptr_equal(alias, NULL); + } + ++static void lb_nomatch_a_b_bad_self(void **state) ++{ ++ int rc; ++ char *alias; ++ ++ will_return(__wrap_fgets, "MPATHa WWID0\n"); ++ will_return(__wrap_fgets, "MPATHz WWID26\n"); ++ will_return(__wrap_fgets, "MPATHb\n"); ++ will_return(__wrap_fgets, NULL); ++ expect_condlog(3, "Ignoring malformed line 3 in bindings file\n"); ++ mock_self_alias("MPATHc", "WWID2"); ++ expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); ++ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); ++ assert_int_equal(rc, 3); ++ assert_ptr_equal(alias, NULL); ++} ++ + static void lb_nomatch_b_a(void **state) + { + int rc; +@@ -480,8 +768,27 @@ static void lb_nomatch_b_a(void **state) + assert_ptr_equal(alias, NULL); + } + ++static void lb_nomatch_b_a_3_used(void **state) ++{ ++ int rc; ++ char *alias; ++ ++ will_return(__wrap_fgets, "MPATHb WWID1\n"); ++ will_return(__wrap_fgets, "MPATHz WWID26\n"); ++ will_return(__wrap_fgets, "MPATHa WWID0\n"); ++ will_return(__wrap_fgets, NULL); ++ mock_used_alias("MPATHaa", USED_STR("MPATHaa", "WWID2")); ++ mock_used_alias("MPATHab", USED_STR("MPATHab", "WWID2")); ++ mock_used_alias("MPATHac", USED_STR("MPATHac", "WWID2")); ++ mock_unused_alias("MPATHad"); ++ expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); ++ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); ++ assert_int_equal(rc, 30); ++ assert_ptr_equal(alias, NULL); ++} ++ + #ifdef MPATH_ID_INT_MAX +-static void lb_nomatch_int_max(void **state) ++static void do_lb_nomatch_int_max(void **state, int check_if_taken) + { + int rc; + char *alias; +@@ -491,7 +798,32 @@ static void lb_nomatch_int_max(void **state) + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, NULL); + expect_condlog(0, "no more available user_friendly_names\n"); +- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); ++ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", check_if_taken); ++ assert_int_equal(rc, -1); ++ assert_ptr_equal(alias, NULL); ++} ++ ++static void lb_nomatch_int_max(void **state) ++{ ++ do_lb_nomatch_int_max(state, 0); ++} ++ ++static void lb_nomatch_int_max_check(void **state) ++{ ++ do_lb_nomatch_int_max(state, 1); ++} ++ ++static void lb_nomatch_int_max_used(void **state) ++{ ++ int rc; ++ char *alias; ++ ++ will_return(__wrap_fgets, "MPATHb WWID1\n"); ++ will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n"); ++ will_return(__wrap_fgets, NULL); ++ mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID2")); ++ expect_condlog(0, "no more available user_friendly_names\n"); ++ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, -1); + assert_ptr_equal(alias, NULL); + } +@@ -510,23 +842,92 @@ static void lb_nomatch_int_max_m1(void **state) + assert_int_equal(rc, INT_MAX); + assert_ptr_equal(alias, NULL); + } ++ ++static void lb_nomatch_int_max_m1_used(void **state) ++{ ++ int rc; ++ char *alias; ++ ++ will_return(__wrap_fgets, "MPATHb WWID1\n"); ++ will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"); ++ will_return(__wrap_fgets, "MPATHa WWID0\n"); ++ will_return(__wrap_fgets, NULL); ++ mock_used_alias("MPATH" MPATH_ID_INT_MAX, USED_STR("MPATH" MPATH_ID_INT_MAX, "WWID2")); ++ expect_condlog(0, "no more available user_friendly_names\n"); ++ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); ++ assert_int_equal(rc, -1); ++ assert_ptr_equal(alias, NULL); ++} ++ ++static void lb_nomatch_int_max_m1_1_used(void **state) ++{ ++ int rc; ++ char *alias; ++ ++ will_return(__wrap_fgets, "MPATHb WWID1\n"); ++ will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"); ++ will_return(__wrap_fgets, NULL); ++ mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID2")); ++ mock_unused_alias("MPATH" MPATH_ID_INT_MAX); ++ expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); ++ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); ++ assert_int_equal(rc, INT_MAX); ++ assert_ptr_equal(alias, NULL); ++} ++ ++static void lb_nomatch_int_max_m1_2_used(void **state) ++{ ++ int rc; ++ char *alias; ++ ++ will_return(__wrap_fgets, "MPATHb WWID1\n"); ++ will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"); ++ will_return(__wrap_fgets, NULL); ++ mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID2")); ++ mock_used_alias("MPATH" MPATH_ID_INT_MAX, USED_STR("MPATH" MPATH_ID_INT_MAX, "WWID2")); ++ expect_condlog(0, "no more available user_friendly_names\n"); ++ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); ++ assert_int_equal(rc, -1); ++ assert_ptr_equal(alias, NULL); ++} + #endif + + static int test_lookup_binding(void) + { + const struct CMUnitTest tests[] = { + cmocka_unit_test(lb_empty), ++ cmocka_unit_test(lb_empty_unused), ++ cmocka_unit_test(lb_empty_failed), ++ cmocka_unit_test(lb_empty_1_used), ++ cmocka_unit_test(lb_empty_1_used_self), + cmocka_unit_test(lb_match_a), + cmocka_unit_test(lb_nomatch_a), ++ cmocka_unit_test(lb_nomatch_a_bad_check), ++ cmocka_unit_test(lb_nomatch_a_unused), ++ cmocka_unit_test(lb_nomatch_a_3_used_failed_self), + cmocka_unit_test(lb_match_c), ++ cmocka_unit_test(lb_match_c_check), + cmocka_unit_test(lb_nomatch_a_c), ++ cmocka_unit_test(lb_nomatch_a_d_unused), ++ cmocka_unit_test(lb_nomatch_a_d_1_used), ++ cmocka_unit_test(lb_nomatch_a_d_2_used), ++ cmocka_unit_test(lb_nomatch_a_d_3_used), + cmocka_unit_test(lb_nomatch_c_a), ++ cmocka_unit_test(lb_nomatch_d_a_unused), ++ cmocka_unit_test(lb_nomatch_d_a_1_used), + cmocka_unit_test(lb_nomatch_a_b), + cmocka_unit_test(lb_nomatch_a_b_bad), ++ cmocka_unit_test(lb_nomatch_a_b_bad_self), + cmocka_unit_test(lb_nomatch_b_a), ++ cmocka_unit_test(lb_nomatch_b_a_3_used), + #ifdef MPATH_ID_INT_MAX + cmocka_unit_test(lb_nomatch_int_max), ++ cmocka_unit_test(lb_nomatch_int_max_check), ++ cmocka_unit_test(lb_nomatch_int_max_used), + cmocka_unit_test(lb_nomatch_int_max_m1), ++ cmocka_unit_test(lb_nomatch_int_max_m1_used), ++ cmocka_unit_test(lb_nomatch_int_max_m1_1_used), ++ cmocka_unit_test(lb_nomatch_int_max_m1_2_used), + #endif + }; + diff --git a/0129-multipath-tools-add-DellEMC-PowerStore-to-hardware-t.patch b/0129-multipath-tools-add-DellEMC-PowerStore-to-hardware-t.patch new file mode 100644 index 0000000..596527f --- /dev/null +++ b/0129-multipath-tools-add-DellEMC-PowerStore-to-hardware-t.patch @@ -0,0 +1,40 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Sat, 6 Mar 2021 03:54:15 +0100 +Subject: [PATCH] multipath-tools: add DellEMC/PowerStore to hardware table + +Info from: https://www.delltechnologies.com/en-us/collaterals/unauth/technical-guides-support-information/products/storage-2/docu5128.pdf + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/hwtable.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index 921aadc5..58fa7387 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -388,6 +388,17 @@ static struct hwentry default_hw[] = { + .product = "^EMC PowerMax_", + .pgpolicy = MULTIBUS, + }, ++ { ++ /* PowerStore */ ++ .vendor = "DellEMC", ++ .product = "PowerStore", ++ .pgpolicy = GROUP_BY_PRIO, ++ .prio_name = PRIO_ALUA, ++ .hwhandler = "1 alua", ++ .pgfailback = -FAILBACK_IMMEDIATE, ++ .no_path_retry = 3, ++ .fast_io_fail = 15, ++ }, + /* + * Fujitsu + */ diff --git a/0130-multipath-tools-delete-a-space-in-multipath.conf.5-t.patch b/0130-multipath-tools-delete-a-space-in-multipath.conf.5-t.patch new file mode 100644 index 0000000..c8c8d1e --- /dev/null +++ b/0130-multipath-tools-delete-a-space-in-multipath.conf.5-t.patch @@ -0,0 +1,30 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Sat, 6 Mar 2021 16:39:59 +0100 +Subject: [PATCH] multipath-tools: delete a space in multipath.conf.5 to be + consistent + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + multipath/multipath.conf.5 | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 +index 37030765..73977b97 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5 +@@ -1095,7 +1095,7 @@ for the configured time, and is declared healthy, it will be returned to its + normal pathgroup. See "Shaky paths detection" below for more information. + .RS + .TP +-The default is: \fBno\fR ++The default is: \fBno\fR + .RE + . + . diff --git a/0131-multipath-tools-tests-allow-control-of-test-verbosit.patch b/0131-multipath-tools-tests-allow-control-of-test-verbosit.patch new file mode 100644 index 0000000..50da56b --- /dev/null +++ b/0131-multipath-tools-tests-allow-control-of-test-verbosit.patch @@ -0,0 +1,253 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 11 Feb 2021 22:52:39 +0100 +Subject: [PATCH] multipath-tools tests: allow control of test verbosity + +Use common code to control verbosity during unit tests runs. +The environment variable MPATHTEST_VERBOSITY is honored by most +tests, except those that need to parse the log messages or have +other special needs. + +Also, get rid of the now obsolete global variables logsink and +udev, as these are now defined in libmultipath. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + tests/README.md | 5 +++++ + tests/alias.c | 2 +- + tests/blacklist.c | 2 +- + tests/devt.c | 1 + + tests/directio.c | 2 +- + tests/dmevents.c | 1 + + tests/globals.c | 27 +++++++++++++++++++++------ + tests/hwtable.c | 2 ++ + tests/parser.c | 1 + + tests/pgpolicy.c | 1 + + tests/uevent.c | 1 + + tests/unaligned.c | 1 + + tests/util.c | 1 + + tests/valid.c | 2 ++ + tests/vpd.c | 1 + + 15 files changed, 41 insertions(+), 9 deletions(-) + +diff --git a/tests/README.md b/tests/README.md +index 6e7ad405..47c0f0b2 100644 +--- a/tests/README.md ++++ b/tests/README.md +@@ -13,6 +13,11 @@ If valgrind detects a bad memory access or leak, the test will fail. The + output of the test run, including valgrind output, is stored as + `.vgr`. + ++## Controlling verbosity for unit tests ++ ++Some test programs use the environment variable `MPATHTEST_VERBOSITY` to ++control the log level during test execution. ++ + ## Notes on individual tests + + ### Tests that require root permissions +diff --git a/tests/alias.c b/tests/alias.c +index ebe1209e..7e7c1878 100644 +--- a/tests/alias.c ++++ b/tests/alias.c +@@ -1137,7 +1137,7 @@ static int test_allocate_binding(void) + int main(void) + { + int ret = 0; +- libmp_verbosity = conf.verbosity; ++ init_test_verbosity(3); + + ret += test_format_devname(); + ret += test_scan_devname(); +diff --git a/tests/blacklist.c b/tests/blacklist.c +index 0b42e255..882aa3a1 100644 +--- a/tests/blacklist.c ++++ b/tests/blacklist.c +@@ -153,7 +153,7 @@ static int setup(void **state) + store_ble(blist_property_wwn_inv, "!ID_WWN", ORIGIN_CONFIG)) + return -1; + +- libmp_verbosity = conf.verbosity = 4; ++ init_test_verbosity(4); + return 0; + } + +diff --git a/tests/devt.c b/tests/devt.c +index fd4d74a3..2b728516 100644 +--- a/tests/devt.c ++++ b/tests/devt.c +@@ -187,6 +187,7 @@ int main(void) + { + int ret = 0; + ++ init_test_verbosity(-1); + ret += devt2devname_tests(); + return ret; + } +diff --git a/tests/directio.c b/tests/directio.c +index 98954099..9f7d3883 100644 +--- a/tests/directio.c ++++ b/tests/directio.c +@@ -770,7 +770,7 @@ int main(void) + { + int ret = 0; + +- conf.verbosity = 2; ++ init_test_verbosity(2); + ret += test_directio(); + return ret; + } +diff --git a/tests/dmevents.c b/tests/dmevents.c +index 29eaa6db..204cf1d9 100644 +--- a/tests/dmevents.c ++++ b/tests/dmevents.c +@@ -925,6 +925,7 @@ int main(void) + { + int ret = 0; + ++ init_test_verbosity(-1); + ret += test_dmevents(); + return ret; + } +diff --git a/tests/globals.c b/tests/globals.c +index fc0c07ad..36319ed3 100644 +--- a/tests/globals.c ++++ b/tests/globals.c +@@ -1,13 +1,12 @@ ++#include ++#include ++ ++#include "defaults.h" + #include "structs.h" + #include "config.h" + #include "debug.h" + +-/* Required globals */ +-struct udev *udev; +-int logsink = LOGSINK_STDERR_WITHOUT_TIME; +-struct config conf = { +- .verbosity = 4, +-}; ++struct config conf; + + struct config *get_multipath_config(void) + { +@@ -16,3 +15,19 @@ struct config *get_multipath_config(void) + + void put_multipath_config(void *arg) + {} ++ ++static __attribute__((unused)) void init_test_verbosity(int test_verbosity) ++{ ++ char *verb = getenv("MPATHTEST_VERBOSITY"); ++ ++ libmp_verbosity = test_verbosity >= 0 ? test_verbosity : ++ DEFAULT_VERBOSITY; ++ if (verb && *verb) { ++ char *c; ++ int vb; ++ ++ vb = strtoul(verb, &c, 10); ++ if (!*c && vb >= 0 && vb <= 5) ++ libmp_verbosity = vb; ++ } ++} +diff --git a/tests/hwtable.c b/tests/hwtable.c +index 4dd0873b..6f5766f7 100644 +--- a/tests/hwtable.c ++++ b/tests/hwtable.c +@@ -1778,6 +1778,8 @@ int main(void) + { + int ret = 0; + ++ /* We can't use init_test_verbosity in this test */ ++ libmp_verbosity = VERBOSITY; + ret += test_hwtable(); + return ret; + } +diff --git a/tests/parser.c b/tests/parser.c +index 5772391e..cf96d81f 100644 +--- a/tests/parser.c ++++ b/tests/parser.c +@@ -511,6 +511,7 @@ int main(void) + { + int ret = 0; + ++ init_test_verbosity(-1); + ret += test_config_parser(); + return ret; + } +diff --git a/tests/pgpolicy.c b/tests/pgpolicy.c +index 3f61b123..57ad3381 100644 +--- a/tests/pgpolicy.c ++++ b/tests/pgpolicy.c +@@ -1031,6 +1031,7 @@ int main(void) + { + int ret = 0; + ++ init_test_verbosity(-1); + ret += test_pgpolicies(); + return ret; + } +diff --git a/tests/uevent.c b/tests/uevent.c +index 9ffcd2df..648ff268 100644 +--- a/tests/uevent.c ++++ b/tests/uevent.c +@@ -322,6 +322,7 @@ int main(void) + { + int ret = 0; + ++ init_test_verbosity(-1); + ret += test_uevent_get_XXX(); + return ret; + } +diff --git a/tests/unaligned.c b/tests/unaligned.c +index 7ece1de8..e43b64d4 100644 +--- a/tests/unaligned.c ++++ b/tests/unaligned.c +@@ -91,6 +91,7 @@ int main(void) + { + int ret = 0; + ++ init_test_verbosity(-1); + ret += test_unaligned(); + return ret; + } +diff --git a/tests/util.c b/tests/util.c +index c3c49b60..9affb0e1 100644 +--- a/tests/util.c ++++ b/tests/util.c +@@ -946,6 +946,7 @@ int main(void) + { + int ret = 0; + ++ init_test_verbosity(-1); + ret += test_basenamecpy(); + ret += test_bitmasks(); + ret += test_strlcpy(); +diff --git a/tests/valid.c b/tests/valid.c +index 8ec803e8..e7393a1c 100644 +--- a/tests/valid.c ++++ b/tests/valid.c +@@ -554,6 +554,8 @@ int test_valid(void) + int main(void) + { + int ret = 0; ++ ++ init_test_verbosity(-1); + ret += test_valid(); + return ret; + } +diff --git a/tests/vpd.c b/tests/vpd.c +index e2ec65e9..8e730d37 100644 +--- a/tests/vpd.c ++++ b/tests/vpd.c +@@ -799,6 +799,7 @@ int main(void) + { + int ret = 0; + ++ init_test_verbosity(-1); + ret += test_vpd(); + return ret; + } diff --git a/0132-multipath-tools-devt-test-avoid-failure-when-run-in-.patch b/0132-multipath-tools-devt-test-avoid-failure-when-run-in-.patch new file mode 100644 index 0000000..35ea98d --- /dev/null +++ b/0132-multipath-tools-devt-test-avoid-failure-when-run-in-.patch @@ -0,0 +1,63 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 11 Feb 2021 22:54:58 +0100 +Subject: [PATCH] multipath-tools: devt test: avoid failure when run in + containers + +/sys/dev/block is usually unavailable containers, causing libudev +calls to fail. Skip the respective tests. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + tests/devt.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/tests/devt.c b/tests/devt.c +index 2b728516..02f2e8f3 100644 +--- a/tests/devt.c ++++ b/tests/devt.c +@@ -11,11 +11,25 @@ + #include + #include + #include ++#include ++#include ++#include + #include "util.h" + #include "debug.h" + + #include "globals.c" + ++static bool sys_dev_block_exists(void) ++{ ++ int fd; ++ bool rc; ++ ++ fd = open("/sys/dev/block", O_RDONLY|O_DIRECTORY); ++ rc = (fd != -1); ++ close(fd); ++ return rc; ++} ++ + static int get_one_devt(char *devt, size_t len) + { + struct udev_enumerate *enm; +@@ -71,6 +85,8 @@ static void test_devt2devname_devt_good(void **state) + { + char dummy[BLK_DEV_SIZE]; + ++ if (!sys_dev_block_exists()) ++ skip(); + assert_int_equal(devt2devname(dummy, sizeof(dummy), *state), 0); + } + +@@ -137,6 +153,8 @@ static void test_devt2devname_real(void **state) + struct udev_list_entry *first, *item; + unsigned int i = 0; + ++ if (!sys_dev_block_exists()) ++ skip(); + enm = udev_enumerate_new(udev); + assert_non_null(enm); + r = udev_enumerate_add_match_subsystem(enm, "block"); diff --git a/0133-multipath-tools-fix-compilation-errors-on-32-bit-mus.patch b/0133-multipath-tools-fix-compilation-errors-on-32-bit-mus.patch new file mode 100644 index 0000000..36a7607 --- /dev/null +++ b/0133-multipath-tools-fix-compilation-errors-on-32-bit-mus.patch @@ -0,0 +1,96 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 12 Feb 2021 00:38:44 +0100 +Subject: [PATCH] multipath-tools: fix compilation errors on 32-bit musl + +gcc on alpine Linux/i386 throws errors because the "tv_sec" element +of struct timespec is a time_t, which is a "long long" in that +environment. In general, time_t is signed. As we only use CLOCK_MONOTONIC, +which starts at boot time, a cast to long should be no problem, even +in 32bit environments. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/main.c | 2 +- + multipathd/main.c | 16 ++++++++-------- + multipathd/uxlsnr.c | 4 ++-- + 3 files changed, 11 insertions(+), 11 deletions(-) + +diff --git a/multipath/main.c b/multipath/main.c +index 9ac42869..3f97582b 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -417,7 +417,7 @@ static int print_cmd_valid(int k, const vector pathvec, + 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); ++ (long)until.tv_sec, until.tv_nsec/1000); + else if (wait == FIND_MULTIPATHS_WAIT_DONE) + printf("FIND_MULTIPATHS_WAIT_UNTIL=\"0\"\n"); + printf("DM_MULTIPATH_DEVICE_PATH=\"%d\"\n", +diff --git a/multipathd/main.c b/multipathd/main.c +index 637a53bf..e0797ccd 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -2486,8 +2486,8 @@ checkerloop (void *ap) + get_monotonic_time(&start_time); + if (start_time.tv_sec && last_time.tv_sec) { + timespecsub(&start_time, &last_time, &diff_time); +- condlog(4, "tick (%lu.%06lu secs)", +- diff_time.tv_sec, diff_time.tv_nsec / 1000); ++ condlog(4, "tick (%ld.%06lu secs)", ++ (long)diff_time.tv_sec, diff_time.tv_nsec / 1000); + last_time = start_time; + ticks = diff_time.tv_sec; + } else { +@@ -2548,18 +2548,18 @@ checkerloop (void *ap) + if (num_paths) { + unsigned int max_checkint; + +- condlog(4, "checked %d path%s in %lu.%06lu secs", ++ condlog(4, "checked %d path%s in %ld.%06lu secs", + num_paths, num_paths > 1 ? "s" : "", +- diff_time.tv_sec, ++ (long)diff_time.tv_sec, + diff_time.tv_nsec / 1000); + conf = get_multipath_config(); + max_checkint = conf->max_checkint; + put_multipath_config(conf); + if (diff_time.tv_sec > (time_t)max_checkint) + condlog(1, "path checkers took longer " +- "than %lu seconds, consider " ++ "than %ld seconds, consider " + "increasing max_polling_interval", +- diff_time.tv_sec); ++ (long)diff_time.tv_sec); + } + } + +@@ -2585,8 +2585,8 @@ checkerloop (void *ap) + } else + diff_time.tv_sec = 1; + +- condlog(3, "waiting for %lu.%06lu secs", +- diff_time.tv_sec, ++ condlog(3, "waiting for %ld.%06lu secs", ++ (long)diff_time.tv_sec, + diff_time.tv_nsec / 1000); + if (nanosleep(&diff_time, NULL) != 0) { + condlog(3, "nanosleep failed with error %d", +diff --git a/multipathd/uxlsnr.c b/multipathd/uxlsnr.c +index cd462b6d..dbee0d6f 100644 +--- a/multipathd/uxlsnr.c ++++ b/multipathd/uxlsnr.c +@@ -154,8 +154,8 @@ static void check_timeout(struct timespec start_time, char *inbuf, + diff_time.tv_nsec / (1000 * 1000); + if (msecs > timeout) + condlog(2, "cli cmd '%s' timeout reached " +- "after %lu.%06lu secs", inbuf, +- diff_time.tv_sec, diff_time.tv_nsec / 1000); ++ "after %ld.%06lu secs", inbuf, ++ (long)diff_time.tv_sec, diff_time.tv_nsec / 1000); + } + } + diff --git a/0134-libmultipath-fix-compilation-error-with-gcc-10-on-i3.patch b/0134-libmultipath-fix-compilation-error-with-gcc-10-on-i3.patch new file mode 100644 index 0000000..dff5288 --- /dev/null +++ b/0134-libmultipath-fix-compilation-error-with-gcc-10-on-i3.patch @@ -0,0 +1,58 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 12 Feb 2021 00:41:55 +0100 +Subject: [PATCH] libmultipath: fix compilation error with gcc 10 on i386 + +gcc complained about a possible negative value of "nr" in the +memcpy() call. I consider that a false positive, but it's easily +fixed. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/sysfs.c | 29 ++++++++++++++--------------- + 1 file changed, 14 insertions(+), 15 deletions(-) + +diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c +index 5390de62..7a2af1ea 100644 +--- a/libmultipath/sysfs.c ++++ b/libmultipath/sysfs.c +@@ -344,24 +344,23 @@ bool sysfs_is_multipathed(struct path *pp, bool set_wwid) + pthread_cleanup_push(close_fd, (void *)fd); + nr = read(fd, uuid, sizeof(uuid)); + if (nr > (int)UUID_PREFIX_LEN && +- !memcmp(uuid, UUID_PREFIX, UUID_PREFIX_LEN)) ++ !memcmp(uuid, UUID_PREFIX, UUID_PREFIX_LEN)) { + found = true; +- else if (nr < 0) { ++ if (set_wwid) { ++ nr -= UUID_PREFIX_LEN; ++ memcpy(pp->wwid, uuid + UUID_PREFIX_LEN, nr); ++ if (nr == WWID_SIZE) { ++ condlog(4, "%s: overflow while reading from %s", ++ __func__, pathbuf); ++ pp->wwid[0] = '\0'; ++ } else { ++ pp->wwid[nr] = '\0'; ++ strchop(pp->wwid); ++ } ++ } ++ } else if (nr < 0) + condlog(1, "%s: error reading from %s: %m", + __func__, pathbuf); +- } +- if (found && set_wwid) { +- nr -= UUID_PREFIX_LEN; +- memcpy(pp->wwid, uuid + UUID_PREFIX_LEN, nr); +- if (nr == WWID_SIZE) { +- condlog(4, "%s: overflow while reading from %s", +- __func__, pathbuf); +- pp->wwid[0] = '\0'; +- } else { +- pp->wwid[nr] = '\0'; +- strchop(pp->wwid); +- } +- } + + pthread_cleanup_pop(1); + } diff --git a/0123-kpartx-free-loop-device-after-listing-partitions.patch b/0135-kpartx-free-loop-device-after-listing-partitions.patch similarity index 95% rename from 0123-kpartx-free-loop-device-after-listing-partitions.patch rename to 0135-kpartx-free-loop-device-after-listing-partitions.patch index 4db7cfd..566bee4 100644 --- a/0123-kpartx-free-loop-device-after-listing-partitions.patch +++ b/0135-kpartx-free-loop-device-after-listing-partitions.patch @@ -1,6 +1,6 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski -Date: Tue, 9 Feb 2021 17:16:04 -0600 +Date: Wed, 24 Feb 2021 00:05:13 -0600 Subject: [PATCH] kpartx: free loop device after listing partitions If "kpartx -l" is run on a file that doesn't already have a loop device @@ -18,6 +18,7 @@ at normal verbosity. Fixes: da59d15c6 ("Fix loopback file with kpartx -av") Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck --- kpartx/kpartx.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) @@ -56,6 +57,3 @@ index 6a7933fa..8ff116b8 100644 } end: --- -2.17.2 - diff --git a/0136-libmultipath-merge-update_multipath_table-and-update.patch b/0136-libmultipath-merge-update_multipath_table-and-update.patch new file mode 100644 index 0000000..482f122 --- /dev/null +++ b/0136-libmultipath-merge-update_multipath_table-and-update.patch @@ -0,0 +1,229 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 17 Mar 2021 17:18:22 +0100 +Subject: [PATCH] libmultipath: merge update_multipath_table() and + update_multipath_status() + +Since 378cb66 ("multipath: use update_pathvec_from_dm()"), +we remove paths and even pathgroups from multipathd's data structures +in update_multipath_table() if these paths are found to be non-existent. +But update_multipath_status() is called afterwards, and it +uses the kernel's mapping of pathgroups and paths, which won't match +any more if any members had been removed. disassemble_status() returns +an error if the number of path groups doesn't match, causing the +entire structure setup to fail. And because disassemble_status() +doesn't check the dev_t against the corresponding values in multipathd's +data structures, it may assign wrong DM state to paths. + +Fix this by calling disassemble_status() before making any changes to +the data structure in update_pathvec_from_dm(). This can be easily +done, because every call to update_multipath_status() is preceded +by a call to update_multipath_table() anyway, and vice versa. So +we simply merge the two functions into one. This actually simplifies +the code for all callers. + +As we remove a symbol, the major library version must be bumped. + +Fixes: 378cb66 ("multipath: use update_pathvec_from_dm()") +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmpathpersist/mpath_persist.c | 1 - + libmultipath/libmultipath.version | 30 ++++++++---------------- + libmultipath/structs_vec.c | 38 ++++++++----------------------- + multipath/main.c | 6 ++--- + multipathd/main.c | 5 +--- + 5 files changed, 21 insertions(+), 59 deletions(-) + +diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c +index 5c95af20..190e9707 100644 +--- a/libmpathpersist/mpath_persist.c ++++ b/libmpathpersist/mpath_persist.c +@@ -408,7 +408,6 @@ get_mpvec (vector curmp, vector pathvec, char * refwwid) + continue; + + if (update_multipath_table(mpp, pathvec, DI_CHECKER) != DMP_OK || +- update_multipath_status(mpp) != DMP_OK || + update_mpp_paths(mpp, pathvec)) { + condlog(1, "error parsing map %s", mpp->wwid); + remove_map(mpp, pathvec, curmp, PURGE_VEC); +diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version +index e9b4608f..0cff3111 100644 +--- a/libmultipath/libmultipath.version ++++ b/libmultipath/libmultipath.version +@@ -31,7 +31,7 @@ + * The new version inherits the previous ones. + */ + +-LIBMULTIPATH_4.0.0 { ++LIBMULTIPATH_5.0.0 { + global: + /* symbols referenced by multipath and multipathd */ + add_foreign; +@@ -198,7 +198,6 @@ global: + uevent_is_mpath; + uevent_listen; + update_mpp_paths; +- update_multipath_status; + update_multipath_strings; + update_multipath_table; + update_pathvec_from_dm; +@@ -256,33 +255,22 @@ global: + libmultipath_init; + libmultipath_exit; + +-local: +- *; +-}; +- +-LIBMULTIPATH_4.1.0 { +-global: ++ /* added in 4.1.0 */ + libmp_verbosity; +-} LIBMULTIPATH_4.0.0; + +-LIBMULTIPATH_4.2.0 { +-global: ++ /* added in 4.2.0 */ + dm_prereq; + skip_libmp_dm_init; +-} LIBMULTIPATH_4.1.0; + +-LIBMULTIPATH_4.3.0 { +-global: ++ /* added in 4.3.0 */ + start_checker_thread; +-} LIBMULTIPATH_4.2.0; + +-LIBMULTIPATH_4.4.0 { +-global: ++ /* added in 4.4.0 */ + get_next_string; +-} LIBMULTIPATH_4.3.0; + +-LIBMULITIPATH_4.5.0 { +-global: ++ /* added in 4.5.0 */ + get_vpd_sgio; + trigger_partitions_udev_change; +-} LIBMULTIPATH_4.4.0; ++local: ++ *; ++}; +diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c +index 47b1d03e..d242c06b 100644 +--- a/libmultipath/structs_vec.c ++++ b/libmultipath/structs_vec.c +@@ -423,44 +423,27 @@ update_multipath_table (struct multipath *mpp, vector pathvec, int flags) + + r = dm_get_map(mpp->alias, &mpp->size, params); + if (r != DMP_OK) { +- condlog(3, "%s: %s", mpp->alias, (r == DMP_ERR)? "error getting table" : "map not present"); ++ condlog(2, "%s: %s", mpp->alias, (r == DMP_ERR)? "error getting table" : "map not present"); + return r; + } + + if (disassemble_map(pathvec, params, mpp)) { +- condlog(3, "%s: cannot disassemble map", mpp->alias); ++ condlog(2, "%s: cannot disassemble map", mpp->alias); + return DMP_ERR; + } + ++ *params = '\0'; ++ if (dm_get_status(mpp->alias, params) != DMP_OK) ++ condlog(2, "%s: %s", mpp->alias, (r == DMP_ERR)? "error getting status" : "map not present"); ++ else if (disassemble_status(params, mpp)) ++ condlog(2, "%s: cannot disassemble status", mpp->alias); ++ + /* FIXME: we should deal with the return value here */ + update_pathvec_from_dm(pathvec, mpp, flags); + + return DMP_OK; + } + +-int +-update_multipath_status (struct multipath *mpp) +-{ +- int r = DMP_ERR; +- char status[PARAMS_SIZE] = {0}; +- +- if (!mpp) +- return r; +- +- r = dm_get_status(mpp->alias, status); +- if (r != DMP_OK) { +- condlog(3, "%s: %s", mpp->alias, (r == DMP_ERR)? "error getting status" : "map not present"); +- return r; +- } +- +- if (disassemble_status(status, mpp)) { +- condlog(3, "%s: cannot disassemble status", mpp->alias); +- return DMP_ERR; +- } +- +- return DMP_OK; +-} +- + static struct path *find_devt_in_pathgroups(const struct multipath *mpp, + const char *dev_t) + { +@@ -538,11 +521,8 @@ update_multipath_strings(struct multipath *mpp, vector pathvec) + r = update_multipath_table(mpp, pathvec, 0); + if (r != DMP_OK) + return r; +- sync_paths(mpp, pathvec); + +- r = update_multipath_status(mpp); +- if (r != DMP_OK) +- return r; ++ sync_paths(mpp, pathvec); + + vector_foreach_slot(mpp->pg, pgp, i) + if (pgp->paths) +diff --git a/multipath/main.c b/multipath/main.c +index 3f97582b..ef89c7cf 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -196,8 +196,7 @@ get_dm_mpvec (enum mpath_cmds cmd, vector curmp, vector pathvec, char * refwwid) + continue; + } + +- if (update_multipath_table(mpp, pathvec, flags) != DMP_OK || +- update_multipath_status(mpp) != DMP_OK) { ++ if (update_multipath_table(mpp, pathvec, flags) != DMP_OK) { + condlog(1, "error parsing map %s", mpp->wwid); + remove_map(mpp, pathvec, curmp, PURGE_VEC); + i--; +@@ -263,8 +262,7 @@ static int check_usable_paths(struct config *conf, + if (mpp == NULL) + goto free; + +- if (update_multipath_table(mpp, pathvec, 0) != DMP_OK || +- update_multipath_status(mpp) != DMP_OK) ++ if (update_multipath_table(mpp, pathvec, 0) != DMP_OK) + goto free; + + vector_foreach_slot (mpp->pg, pg, i) { +diff --git a/multipathd/main.c b/multipathd/main.c +index e0797ccd..154a4eef 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -559,8 +559,6 @@ add_map_without_path (struct vectors *vecs, const char *alias) + + if (update_multipath_table(mpp, vecs->pathvec, 0) != DMP_OK) + goto out; +- if (update_multipath_status(mpp) != DMP_OK) +- goto out; + + if (!vector_alloc_slot(vecs->mpvec)) + goto out; +@@ -1469,8 +1467,7 @@ map_discovery (struct vectors * vecs) + return 1; + + vector_foreach_slot (vecs->mpvec, mpp, i) +- if (update_multipath_table(mpp, vecs->pathvec, 0) != DMP_OK || +- update_multipath_status(mpp) != DMP_OK) { ++ if (update_multipath_table(mpp, vecs->pathvec, 0) != DMP_OK) { + remove_map(mpp, vecs->pathvec, vecs->mpvec, PURGE_VEC); + i--; + } diff --git a/0137-11-dm-mpath.rules-run-multipath-U-with-v1.patch b/0137-11-dm-mpath.rules-run-multipath-U-with-v1.patch new file mode 100644 index 0000000..eb50696 --- /dev/null +++ b/0137-11-dm-mpath.rules-run-multipath-U-with-v1.patch @@ -0,0 +1,41 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 17 Mar 2021 17:30:54 +0100 +Subject: [PATCH] 11-dm-mpath.rules: run "multipath -U" with -v1 + +In cases where some path devices are temporarily unavailable (e.g. failover), +high amounts of error messages such as these are seen: + +Feb 27 08:02:03 ictm1608s02h1 multipath[1420]: get_udev_device: failed to look up 65:224 with type 1 +Feb 27 08:02:03 ictm1608s02h1 multipath[1420]: 3600a098000aada210000f1625de51ed9: discarding non-existing path 65:224 + +This is because every invocation of "multipath -U" prints these messages +at the default log level (-v2). In the case of "multipath -U", these +messages aren't important, and in failover situations, "multipath -U" is +run pretty often, spamming the log with many similar messages. + +Generally reducing the log level of these messages would be wrong, +because they are important for multipathd's operation, to verify that +multipathd does the right thing when discovering a discrepancy between the dm +state and the devices present in the system. Therefore, just decrease the +verbosity with which we invoke "multipath -U" in the udev rules. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/11-dm-mpath.rules | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/multipath/11-dm-mpath.rules b/multipath/11-dm-mpath.rules +index cd522e8c..d191ae8d 100644 +--- a/multipath/11-dm-mpath.rules ++++ b/multipath/11-dm-mpath.rules +@@ -32,7 +32,7 @@ ACTION=="add", ENV{.MPATH_DEVICE_READY_OLD}=="1", GOTO="paths_ok" + + # Check the map state directly with multipath -U. + # This doesn't attempt I/O on the device. +-PROGRAM=="$env{MPATH_SBIN_PATH}/multipath -U %k", GOTO="paths_ok" ++PROGRAM=="$env{MPATH_SBIN_PATH}/multipath -U -v1 %k", GOTO="paths_ok" + ENV{MPATH_DEVICE_READY}="0", GOTO="mpath_action" + LABEL="paths_ok" + diff --git a/0138-multipath-tools-tests-check-if-sys-dev-block-is-non-.patch b/0138-multipath-tools-tests-check-if-sys-dev-block-is-non-.patch new file mode 100644 index 0000000..534ebba --- /dev/null +++ b/0138-multipath-tools-tests-check-if-sys-dev-block-is-non-.patch @@ -0,0 +1,62 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 18 Mar 2021 09:50:55 +0100 +Subject: [PATCH] multipath-tools tests: check if /sys/dev/block is non-empty + +Since f131e31 ("multipath-tools: devt test: avoid failure when run in +containers"), we check the existence of /sys/dev/block before running +the devt test. It turns out that on recent releases of podman (3.0.1), +this check is insufficient, because /sys/dev/block exists now in +containers, albeit empty. So we need to check for actual entries +in the directory. + +Fixes: f131e31 ("multipath-tools: devt test: avoid failure when run in containers") + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + tests/devt.c | 22 +++++++++++++++++----- + 1 file changed, 17 insertions(+), 5 deletions(-) + +diff --git a/tests/devt.c b/tests/devt.c +index 02f2e8f3..d971302c 100644 +--- a/tests/devt.c ++++ b/tests/devt.c +@@ -13,7 +13,9 @@ + #include + #include + #include ++#include + #include ++#include + #include "util.h" + #include "debug.h" + +@@ -21,12 +23,22 @@ + + static bool sys_dev_block_exists(void) + { +- int fd; +- bool rc; ++ DIR *dir; ++ bool rc = false; + +- fd = open("/sys/dev/block", O_RDONLY|O_DIRECTORY); +- rc = (fd != -1); +- close(fd); ++ dir = opendir("/sys/dev/block"); ++ if (dir != NULL) { ++ struct dirent *de; ++ ++ while((de = readdir(dir)) != NULL) { ++ if (strcmp(de->d_name, ".") && ++ strcmp(de->d_name, "..")) { ++ rc = true; ++ break; ++ } ++ } ++ } ++ closedir(dir); + return rc; + } + diff --git a/0139-multipathd-reduce-log-levels-in-cli_add_map.patch b/0139-multipathd-reduce-log-levels-in-cli_add_map.patch new file mode 100644 index 0000000..85823f0 --- /dev/null +++ b/0139-multipathd-reduce-log-levels-in-cli_add_map.patch @@ -0,0 +1,36 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 19 Mar 2021 09:50:46 +0100 +Subject: [PATCH] multipathd: reduce log levels in cli_add_map() + +Normally "add map" will be used to add a map which doesn't exist +yet. Thus not finding this map in the first place is not a problem +indicator and should be logged at level 3 only. + +Signed-off-by: Benjamin Marzinski +--- + multipathd/cli_handlers.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c +index 7f3e61f6..1de6ad8e 100644 +--- a/multipathd/cli_handlers.c ++++ b/multipathd/cli_handlers.c +@@ -852,14 +852,15 @@ cli_add_map (void * v, char ** reply, int * len, void * data) + } + do { + if (dm_get_major_minor(param, &major, &minor) < 0) +- condlog(2, "%s: not a device mapper table", param); ++ condlog(count ? 2 : 3, ++ "%s: not a device mapper table", param); + else { + sprintf(dev_path, "dm-%d", minor); + alias = dm_mapname(major, minor); + } + /*if there is no mapname found, we first create the device*/ + if (!alias && !count) { +- condlog(2, "%s: mapname not found for %d:%d", ++ condlog(3, "%s: mapname not found for %d:%d", + param, major, minor); + get_refwwid(CMD_NONE, param, DEV_DEVMAP, + vecs->pathvec, &refwwid); diff --git a/0140-multipath-tools-fix-format-in-multipath.conf.5-to-be.patch b/0140-multipath-tools-fix-format-in-multipath.conf.5-to-be.patch new file mode 100644 index 0000000..71c4413 --- /dev/null +++ b/0140-multipath-tools-fix-format-in-multipath.conf.5-to-be.patch @@ -0,0 +1,30 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Fri, 19 Mar 2021 17:18:56 +0100 +Subject: [PATCH] multipath-tools: fix format in multipath.conf.5 to be + consistent + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + multipath/multipath.conf.5 | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 +index 73977b97..2aa0f526 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5 +@@ -1283,7 +1283,7 @@ to use the default uid_attribute, \fIID_SERIAL\fR, or sysfs for getting their + wwid. + .RS + .TP +-The default is \fBno\fR ++The default is: \fBno\fR + .RE + . + . diff --git a/0141-multipath-tools-use-same-format-for-default-values-i.patch b/0141-multipath-tools-use-same-format-for-default-values-i.patch new file mode 100644 index 0000000..1fc374b --- /dev/null +++ b/0141-multipath-tools-use-same-format-for-default-values-i.patch @@ -0,0 +1,41 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Sat, 20 Mar 2021 03:13:07 +0100 +Subject: [PATCH] multipath-tools: use same format for default values in + multipath.conf.5 + +For max_sectors_kb, replace "device dependent" with its sysfs path. +And use as wildcard for device in paths. + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + multipath/multipath.conf.5 | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 +index 2aa0f526..064e4826 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5 +@@ -647,7 +647,7 @@ does not respond to the checker command after \fIchecker_timeout\fR + seconds have elapsed, it is considered down. + .RS + .TP +-The default is: in \fB/sys/block/sd/device/timeout\fR ++The default is: in \fB/sys/block//device/timeout\fR + .RE + . + . +@@ -1242,7 +1242,7 @@ Sets the max_sectors_kb device parameter on all path devices and the multipath + device to the specified value. + .RS + .TP +-The default is: \fB\fR ++The default is: in \fB/sys/block//queue/max_sectors_kb\fR + .RE + . + . diff --git a/0142-multipathd-fix-NULL-dereference-in-check_path.patch b/0142-multipathd-fix-NULL-dereference-in-check_path.patch new file mode 100644 index 0000000..3e7e86f --- /dev/null +++ b/0142-multipathd-fix-NULL-dereference-in-check_path.patch @@ -0,0 +1,39 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: lixiaokeng +Date: Tue, 23 Mar 2021 19:50:02 +0800 +Subject: [PATCH] multipathd fix NULL dereference in check_path + +When iscsi login/logout and multipath command are executed +concurrently, there is a coredump. + +The reason is: +check_path + ->update_multipath_strings + ->sync_paths + ->orphan_path //pp->mpp is set to NULL + ->update_multipath_status + ->dm_get_status //return DMP_NOT_FOUND + ->condlog //pp->mpp->alias, NULL dereference + +Here we don't dereference pp-> mpp if it is NULL. + +Signed-off-by: Lixiaokeng +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 154a4eef..1df69096 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -2250,7 +2250,7 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) + if (ret == DMP_NOT_FOUND) { + /* multipath device missing. Likely removed */ + condlog(1, "%s: multipath device '%s' not found", +- pp->dev, pp->mpp->alias); ++ pp->dev, pp->mpp ? pp->mpp->alias : ""); + return 0; + } else + condlog(1, "%s: Couldn't synchronize with kernel state", diff --git a/0143-libmultipath-avoid-infinite-loop-with-bad-vpd-page-8.patch b/0143-libmultipath-avoid-infinite-loop-with-bad-vpd-page-8.patch new file mode 100644 index 0000000..d4a4dd0 --- /dev/null +++ b/0143-libmultipath-avoid-infinite-loop-with-bad-vpd-page-8.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 24 Mar 2021 14:15:02 -0500 +Subject: [PATCH] libmultipath: avoid infinite loop with bad vpd page 83 + identifier + +If a device with a scsi name identifier has an unknown prefix, +parse_vpd_pg83() needs to advance to the next identifier, instead of +simply trying the same one again in an infinite loop. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/discovery.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index f216a724..5727f7a6 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -1157,7 +1157,7 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, + if (memcmp(d + 4, "eui.", 4) && + memcmp(d + 4, "naa.", 4) && + memcmp(d + 4, "iqn.", 4)) +- continue; ++ break; + if (prio < 4) { + prio = 4; + vpd = d; diff --git a/0144-libmultipath-fix-priorities-in-parse_vpd_pg83.patch b/0144-libmultipath-fix-priorities-in-parse_vpd_pg83.patch new file mode 100644 index 0000000..dbd28e9 --- /dev/null +++ b/0144-libmultipath-fix-priorities-in-parse_vpd_pg83.patch @@ -0,0 +1,46 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 24 Mar 2021 14:48:07 -0500 +Subject: [PATCH] libmultipath: fix priorities in parse_vpd_pg83 + +The priorities for the EUI-64 (0x02) and NAME (0x08) scsi identifiers in +parse_vpd_pg83() don't match their priorities in 55-scsi-sg3_id.rules. +Switch them so that they match. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/discovery.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index 5727f7a6..f8044141 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -1152,19 +1152,19 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, + vpd = d; + } + break; +- case 0x8: +- /* SCSI Name: Prio 4 */ +- if (memcmp(d + 4, "eui.", 4) && +- memcmp(d + 4, "naa.", 4) && +- memcmp(d + 4, "iqn.", 4)) +- break; ++ case 0x2: ++ /* EUI-64: Prio 4 */ + if (prio < 4) { + prio = 4; + vpd = d; + } + break; +- case 0x2: +- /* EUI-64: Prio 3 */ ++ case 0x8: ++ /* SCSI Name: Prio 3 */ ++ if (memcmp(d + 4, "eui.", 4) && ++ memcmp(d + 4, "naa.", 4) && ++ memcmp(d + 4, "iqn.", 4)) ++ break; + if (prio < 3) { + prio = 3; + vpd = d; diff --git a/0145-multipathd-improve-getting-parent-udevice-in-rescan_.patch b/0145-multipathd-improve-getting-parent-udevice-in-rescan_.patch new file mode 100644 index 0000000..a3ceeab --- /dev/null +++ b/0145-multipathd-improve-getting-parent-udevice-in-rescan_.patch @@ -0,0 +1,40 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 24 Mar 2021 21:48:15 -0500 +Subject: [PATCH] multipathd: improve getting parent udevice in rescan_path + +Instead of looping through parents and checking, just call +udev_device_get_parent_with_subsystem_devtype() to get the +right one. + +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 14 +++++--------- + 1 file changed, 5 insertions(+), 9 deletions(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 1df69096..bc747d0e 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -822,16 +822,12 @@ ev_remove_map (char * devname, char * alias, int minor, struct vectors * vecs) + } + + static void +-rescan_path(struct udev_device *parent) ++rescan_path(struct udev_device *ud) + { +- while(parent) { +- const char *subsys = udev_device_get_subsystem(parent); +- if (subsys && !strncmp(subsys, "scsi", 4)) +- break; +- parent = udev_device_get_parent(parent); +- } +- if (parent) +- sysfs_attr_set_value(parent, "rescan", "1", strlen("1")); ++ ud = udev_device_get_parent_with_subsystem_devtype(ud, "scsi", ++ "scsi_device"); ++ if (ud) ++ sysfs_attr_set_value(ud, "rescan", "1", strlen("1")); + } + + void diff --git a/0146-multipathd-don-t-trigger-uevent-for-partitions-on-ww.patch b/0146-multipathd-don-t-trigger-uevent-for-partitions-on-ww.patch new file mode 100644 index 0000000..160adc2 --- /dev/null +++ b/0146-multipathd-don-t-trigger-uevent-for-partitions-on-ww.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 24 Mar 2021 23:24:08 -0500 +Subject: [PATCH] multipathd: don't trigger uevent for partitions on wwid + change + +If the wwid changed, the device is no longer the same, so sending add +events to the devices partitions doesn't make any sense. + +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index bc747d0e..3579bad7 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -845,7 +845,6 @@ handle_path_wwid_change(struct path *pp, struct vectors *vecs) + } + rescan_path(udd); + sysfs_attr_set_value(udd, "uevent", "add", strlen("add")); +- trigger_partitions_udev_change(udd, "add", strlen("add")); + udev_device_unref(udd); + } + diff --git a/0124-RH-fixup-udev-rules-for-redhat.patch b/0147-RH-fixup-udev-rules-for-redhat.patch similarity index 99% rename from 0124-RH-fixup-udev-rules-for-redhat.patch rename to 0147-RH-fixup-udev-rules-for-redhat.patch index d5bbd5b..efb8857 100644 --- a/0124-RH-fixup-udev-rules-for-redhat.patch +++ b/0147-RH-fixup-udev-rules-for-redhat.patch @@ -61,6 +61,3 @@ index 0828a8f7..b9bbb3cf 100644 $(RM) $(DESTDIR)$(man8dir)/$(EXEC).8.gz $(RM) $(DESTDIR)$(man5dir)/$(EXEC).conf.5.gz --- -2.17.2 - diff --git a/0125-RH-Remove-the-property-blacklist-exception-builtin.patch b/0148-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 95% rename from 0125-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0148-RH-Remove-the-property-blacklist-exception-builtin.patch index 9c44867..dcb1491 100644 --- a/0125-RH-Remove-the-property-blacklist-exception-builtin.patch +++ b/0148-RH-Remove-the-property-blacklist-exception-builtin.patch @@ -43,10 +43,10 @@ index 6c6a5979..785f5ee9 100644 udev_device_get_properties_list_entry(udev)) { diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 8ef3a747..1e95a854 100644 +index 064e4826..0d2bce09 100644 --- a/multipath/multipath.conf.5 +++ b/multipath/multipath.conf.5 -@@ -1333,9 +1333,14 @@ keywords. Both are regular expressions. For a full description of these keywords +@@ -1347,9 +1347,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, @@ -62,7 +62,7 @@ index 8ef3a747..1e95a854 100644 . .RS .PP -@@ -1346,10 +1351,6 @@ Blacklisting by missing properties is only applied to devices which do have the +@@ -1360,10 +1365,6 @@ Blacklisting by missing properties is only applied to devices which do have the property specified by \fIuid_attribute\fR (e.g. \fIID_SERIAL\fR) set. Previously, it was applied to every device, possibly causing devices to be blacklisted because of temporary I/O error conditions. @@ -74,7 +74,7 @@ index 8ef3a747..1e95a854 100644 .TP .B protocol diff --git a/tests/blacklist.c b/tests/blacklist.c -index 0b42e255..4d595eda 100644 +index 882aa3a1..6a22b660 100644 --- a/tests/blacklist.c +++ b/tests/blacklist.c @@ -375,9 +375,8 @@ static void test_property_missing(void **state) @@ -99,6 +99,3 @@ index 0b42e255..4d595eda 100644 } /* This one matches the property whitelist, to test the other missing --- -2.17.2 - diff --git a/0126-RH-don-t-start-without-a-config-file.patch b/0149-RH-don-t-start-without-a-config-file.patch similarity index 96% rename from 0126-RH-don-t-start-without-a-config-file.patch rename to 0149-RH-don-t-start-without-a-config-file.patch index 2931726..1d5c693 100644 --- a/0126-RH-don-t-start-without-a-config-file.patch +++ b/0149-RH-don-t-start-without-a-config-file.patch @@ -20,10 +20,10 @@ Signed-off-by: Benjamin Marzinski 5 files changed, 18 insertions(+) diff --git a/libmultipath/config.c b/libmultipath/config.c -index be310159..8d291491 100644 +index 30046a17..5f35c3d3 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c -@@ -893,6 +893,19 @@ int _init_config (const char *file, struct config *conf) +@@ -895,6 +895,19 @@ int _init_config (const char *file, struct config *conf) goto out; } factorize_hwtable(conf->hwtable, builtin_hwtable_size, file); @@ -44,7 +44,7 @@ index be310159..8d291491 100644 conf->processed_main_config = 1; diff --git a/libmultipath/config.h b/libmultipath/config.h -index 9ce37f16..7f8d9cd0 100644 +index 933fe0d1..5f01c1fc 100644 --- a/libmultipath/config.h +++ b/libmultipath/config.h @@ -9,6 +9,7 @@ @@ -92,6 +92,3 @@ index 7d547fa7..af592057 100644 DefaultDependencies=no Conflicts=shutdown.target ConditionKernelCommandLine=!nompath --- -2.17.2 - diff --git a/0127-RH-Fix-nvme-function-missing-argument.patch b/0150-RH-Fix-nvme-function-missing-argument.patch similarity index 98% rename from 0127-RH-Fix-nvme-function-missing-argument.patch rename to 0150-RH-Fix-nvme-function-missing-argument.patch index b5c63c0..ced7159 100644 --- a/0127-RH-Fix-nvme-function-missing-argument.patch +++ b/0150-RH-Fix-nvme-function-missing-argument.patch @@ -24,6 +24,3 @@ index adb192b6..bfd10ef8 100644 void argconfig_append_usage(const char *str); void argconfig_print_help(const char *program_desc, const struct argconfig_commandline_options *options); --- -2.17.2 - diff --git a/0128-RH-use-rpm-optflags-if-present.patch b/0151-RH-use-rpm-optflags-if-present.patch similarity index 99% rename from 0128-RH-use-rpm-optflags-if-present.patch rename to 0151-RH-use-rpm-optflags-if-present.patch index f765f47..7b0334d 100644 --- a/0128-RH-use-rpm-optflags-if-present.patch +++ b/0151-RH-use-rpm-optflags-if-present.patch @@ -55,6 +55,3 @@ index 24e943d5..e978d306 100644 @echo building $@ because of $? - $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< + $(CC) $(CFLAGS) -c -o $@ $< --- -2.17.2 - diff --git a/0129-RH-add-mpathconf.patch b/0152-RH-add-mpathconf.patch similarity index 99% rename from 0129-RH-add-mpathconf.patch rename to 0152-RH-add-mpathconf.patch index 346251a..d262f55 100644 --- a/0129-RH-add-mpathconf.patch +++ b/0152-RH-add-mpathconf.patch @@ -21,10 +21,10 @@ Signed-off-by: Benjamin Marzinski create mode 100644 multipath/mpathconf.8 diff --git a/libmultipath/config.c b/libmultipath/config.c -index 8d291491..bbdd1617 100644 +index 5f35c3d3..cee3bbb7 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c -@@ -895,6 +895,8 @@ int _init_config (const char *file, struct config *conf) +@@ -897,6 +897,8 @@ int _init_config (const char *file, struct config *conf) factorize_hwtable(conf->hwtable, builtin_hwtable_size, file); } else { condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices."); @@ -769,6 +769,3 @@ index 00000000..83515eb4 +.BR service (8), +.SH AUTHOR +Benjamin Marzinski --- -2.17.2 - diff --git a/0130-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0153-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 96% rename from 0130-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0153-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch index 3f0a9ad..557669b 100644 --- a/0130-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +++ b/0153-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch @@ -20,7 +20,7 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/multipath/main.c b/multipath/main.c -index 9ac42869..beaac3ca 100644 +index ef89c7cf..f618550d 100644 --- a/multipath/main.c +++ b/multipath/main.c @@ -122,7 +122,7 @@ usage (char * progname) @@ -41,7 +41,7 @@ index 9ac42869..beaac3ca 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" -@@ -452,6 +454,50 @@ static void cleanup_vecs(void) +@@ -450,6 +452,50 @@ static void cleanup_vecs(void) free_pathvec(vecs.pathvec, FREE_PATHS); } @@ -92,7 +92,7 @@ index 9ac42869..beaac3ca 100644 static int configure (struct config *conf, enum mpath_cmds cmd, enum devtypes dev_type, char *devpath) -@@ -825,7 +871,7 @@ main (int argc, char *argv[]) +@@ -823,7 +869,7 @@ main (int argc, char *argv[]) conf = get_multipath_config(); conf->retrigger_tries = 0; conf->force_sync = 1; @@ -101,7 +101,7 @@ index 9ac42869..beaac3ca 100644 switch(arg) { case 1: printf("optarg : %s\n",optarg); break; -@@ -902,6 +948,10 @@ main (int argc, char *argv[]) +@@ -900,6 +946,10 @@ main (int argc, char *argv[]) case 'T': cmd = CMD_DUMP_CONFIG; break; @@ -149,6 +149,3 @@ index af592057..bc8fa07a 100644 ExecStart=/sbin/multipathd -d -s ExecReload=/sbin/multipathd reconfigure TasksMax=infinity --- -2.17.2 - diff --git a/0131-RH-reset-default-find_mutipaths-value-to-off.patch b/0154-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 95% rename from 0131-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0154-RH-reset-default-find_mutipaths-value-to-off.patch index 304db61..d5b5601 100644 --- a/0131-RH-reset-default-find_mutipaths-value-to-off.patch +++ b/0154-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 947ba467..518d0b16 100644 +index c27946c7..e0dd32ad 100644 --- a/libmultipath/defaults.h +++ b/libmultipath/defaults.h @@ -23,7 +23,7 @@ @@ -24,6 +24,3 @@ index 947ba467..518d0b16 100644 #define DEFAULT_FAST_IO_FAIL 5 #define DEFAULT_DEV_LOSS_TMO 600 #define DEFAULT_RETAIN_HWHANDLER RETAIN_HWHANDLER_ON --- -2.17.2 - diff --git a/0132-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0155-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 99% rename from 0132-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0155-RH-attempt-to-get-ANA-info-via-sysfs-first.patch index 14b3367..06233ff 100644 --- a/0132-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +++ b/0155-RH-attempt-to-get-ANA-info-via-sysfs-first.patch @@ -82,6 +82,3 @@ index b5c7873d..e139360c 100644 switch (rc) { case NVME_ANA_OPTIMIZED: --- -2.17.2 - diff --git a/0156-RH-make-parse_vpd_pg83-match-scsi_id-output.patch b/0156-RH-make-parse_vpd_pg83-match-scsi_id-output.patch new file mode 100644 index 0000000..0e30d1f --- /dev/null +++ b/0156-RH-make-parse_vpd_pg83-match-scsi_id-output.patch @@ -0,0 +1,51 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 25 Mar 2021 13:05:10 -0500 +Subject: [PATCH] RH: make parse_vpd_pg83 match scsi_id output + +Red Hat sets ID_SERIAL based on the result of scsi_id, instead of using +the result of sg_inq and 55-scsi-sg3_id.rules. Make parse_vpd_pg83 match +that. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/discovery.c | 18 ++---------------- + 1 file changed, 2 insertions(+), 16 deletions(-) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index f8044141..e6590d07 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -1135,12 +1135,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, + naa_prio = 7; + break; + case 2: +- /* IEEE Extended: Prio 6 */ +- naa_prio = 6; +- break; + case 3: +- /* IEEE Locally assigned: Prio 1 */ +- naa_prio = 1; ++ /* IEEE Extended or Locally assigned: Prio 6 */ ++ naa_prio = 6; + break; + default: + /* Default: no priority */ +@@ -1159,17 +1156,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, + vpd = d; + } + break; +- case 0x8: +- /* SCSI Name: Prio 3 */ +- if (memcmp(d + 4, "eui.", 4) && +- memcmp(d + 4, "naa.", 4) && +- memcmp(d + 4, "iqn.", 4)) +- break; +- if (prio < 3) { +- prio = 3; +- vpd = d; +- } +- break; + case 0x1: + /* T-10 Vendor ID: Prio 2 */ + if (prio < 2) { diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index ec5a48f..b8e18d7 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.8.5 -Release: 5%{?dist} +Release: 6%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -132,16 +132,40 @@ Patch0119: 0119-pathinfo-call-filter_property-after-sysfs_pathinfo.patch Patch0120: 0120-libmultipath-pathinfo-call-filter_property-only-with.patch Patch0121: 0121-multipath-w-allow-removing-blacklisted-paths.patch Patch0122: 0122-libmultipath-fix-use-after-free-in-uev_add_path.patch -Patch0123: 0123-kpartx-free-loop-device-after-listing-partitions.patch -Patch0124: 0124-RH-fixup-udev-rules-for-redhat.patch -Patch0125: 0125-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0126: 0126-RH-don-t-start-without-a-config-file.patch -Patch0127: 0127-RH-Fix-nvme-function-missing-argument.patch -Patch0128: 0128-RH-use-rpm-optflags-if-present.patch -Patch0129: 0129-RH-add-mpathconf.patch -Patch0130: 0130-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0131: 0131-RH-reset-default-find_mutipaths-value-to-off.patch -Patch0132: 0132-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0123: 0123-multipath-tools-tests-fix-stringop-overflow-build-er.patch +Patch0124: 0124-libmultipath-cleanup-code-to-strip-wwid-trailing-spa.patch +Patch0125: 0125-libmultipath-cleanup-uid_attribute-checking-code.patch +Patch0126: 0126-multipathd-add-recheck_wwid-option-to-verify-the-pat.patch +Patch0127: 0127-libmultipath-check-if-user_friendly_name-is-in-use.patch +Patch0128: 0128-tests-add-tests-for-checking-if-alias-is-in-use.patch +Patch0129: 0129-multipath-tools-add-DellEMC-PowerStore-to-hardware-t.patch +Patch0130: 0130-multipath-tools-delete-a-space-in-multipath.conf.5-t.patch +Patch0131: 0131-multipath-tools-tests-allow-control-of-test-verbosit.patch +Patch0132: 0132-multipath-tools-devt-test-avoid-failure-when-run-in-.patch +Patch0133: 0133-multipath-tools-fix-compilation-errors-on-32-bit-mus.patch +Patch0134: 0134-libmultipath-fix-compilation-error-with-gcc-10-on-i3.patch +Patch0135: 0135-kpartx-free-loop-device-after-listing-partitions.patch +Patch0136: 0136-libmultipath-merge-update_multipath_table-and-update.patch +Patch0137: 0137-11-dm-mpath.rules-run-multipath-U-with-v1.patch +Patch0138: 0138-multipath-tools-tests-check-if-sys-dev-block-is-non-.patch +Patch0139: 0139-multipathd-reduce-log-levels-in-cli_add_map.patch +Patch0140: 0140-multipath-tools-fix-format-in-multipath.conf.5-to-be.patch +Patch0141: 0141-multipath-tools-use-same-format-for-default-values-i.patch +Patch0142: 0142-multipathd-fix-NULL-dereference-in-check_path.patch +Patch0143: 0143-libmultipath-avoid-infinite-loop-with-bad-vpd-page-8.patch +Patch0144: 0144-libmultipath-fix-priorities-in-parse_vpd_pg83.patch +Patch0145: 0145-multipathd-improve-getting-parent-udevice-in-rescan_.patch +Patch0146: 0146-multipathd-don-t-trigger-uevent-for-partitions-on-ww.patch +Patch0147: 0147-RH-fixup-udev-rules-for-redhat.patch +Patch0148: 0148-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0149: 0149-RH-don-t-start-without-a-config-file.patch +Patch0150: 0150-RH-Fix-nvme-function-missing-argument.patch +Patch0151: 0151-RH-use-rpm-optflags-if-present.patch +Patch0152: 0152-RH-add-mpathconf.patch +Patch0153: 0153-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0154: 0154-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0155: 0155-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0156: 0156-RH-make-parse_vpd_pg83-match-scsi_id-output.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -339,6 +363,19 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Fri Mar 26 2021 Benjamin Marzinski - 0.8.5-6 +- Change patch format to remove Git version + * Patches 0001-0122 only have the patch format modified +- Update to the head of the upstream staging branch plus redhat patches + * Patches 0123-0134 & 1036-0142 are from the upstream staging branch + * Patches 0143-1046 have been submitted upstream + * Patch 0156 is a Red Hat only patch. Red Hat udev rules set ID_SERIAL + from 60-persistent-storage.rules instead of 55-scsi-sg3_id.rules. + Multipath's parse_vpd_pg83() function needs to match the ID_SERIAL + value from udev. +- Rename files + * Previous patches 0123-0132 are now patches 1035 & 0147-0155 + * Tue Mar 02 2021 Zbigniew Jędrzejewski-Szmek - 0.8.5-5 - Rebuilt for updated systemd-rpm-macros See https://pagure.io/fesco/issue/2583. From ac4e55e1c0e1f10b54215d0855f27b7056bdce74 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Mon, 5 Apr 2021 22:37:31 -0500 Subject: [PATCH 17/67] device-mapper-multipath-0.8.6-1 Update Source to upstream version 0.8.6 * Previous patches 0001-0146 are included in the commit Rename files * Previous patches 0147-0156 are now patches 0001-0010 sync tests with RHEL repository --- .gitignore | 1 + ...path.conf-manpage-uxsock_timeout-def.patch | 27 - ... 0001-RH-fixup-udev-rules-for-redhat.patch | 4 +- ...property-blacklist-exception-builtin.patch | 0 ...find_mpe-don-t-match-with-empty-WWID.patch | 24 - ...RH-don-t-start-without-a-config-file.patch | 0 ...ibmultipath-copy-mpp-hwe-from-pp-hwe.patch | 257 ------- ...H-Fix-nvme-function-missing-argument.patch | 0 ...map_present_by_uuid-fix-dm_task_crea.patch | 28 - ... 0005-RH-use-rpm-optflags-if-present.patch | 6 +- 0005-libdmmp-tests-fix-compilation.patch | 40 -- ...hconf.patch => 0006-RH-add-mpathconf.patch | 0 ...io-constify-some-function-parameters.patch | 50 -- ...om-kernel-cmdline-mpath.wwids-with-A.patch | 0 ...ckers-prio-allow-non-lazy-.so-loadin.patch | 87 --- ...-default-find_mutipaths-value-to-off.patch | 0 ...Makefiles-separate-rules-for-.so-and.patch | 93 --- ...empt-to-get-ANA-info-via-sysfs-first.patch | 0 ...h-create-separate-.so-for-unit-tests.patch | 84 --- ...-parse_vpd_pg83-match-scsi_id-output.patch | 2 +- ...bmultipath-add-linker-version-script.patch | 300 -------- ...athpersist-add-linker-version-script.patch | 78 -- ...ibmpathcmd-add-linker-version-script.patch | 71 -- ...sist-initialize-mpp-hwe-in-get_mpvec.patch | 35 - ...athd-allow-shutdown-during-configure.patch | 137 ---- ...-sending-READY-1-to-systemd-on-early.patch | 64 -- ...nd-STOPPING-1-to-systemd-on-shutdown.patch | 28 - ...RELOADING-1-to-systemd-on-DAEMON_CON.patch | 39 - ...volatile-qualifier-for-running_state.patch | 28 - ...alize-and-fix-wait_for_state_change_.patch | 69 -- ..._config_state-avoid-code-duplication.patch | 52 -- ...cancel-threads-early-during-shutdown.patch | 58 -- ...s-don-t-call-dm_lib_release-any-more.patch | 162 ----- ...mapper-refactor-libdm-version-determ.patch | 503 ------------- ...tect-racy-libdevmapper-calls-with-a-.patch | 434 ----------- ...stify-file-argument-in-config-parser.patch | 95 --- ...vide-defaults-for-get-put-_multipath.patch | 201 ------ ...allow-using-libmultipath-get-put-_mu.patch | 153 ---- ...t_put-_multipath_config-from-libmult.patch | 64 -- ...-get-put-_multipath_config-from-libm.patch | 52 -- ...ltipath-add-udev-and-logsink-symbols.patch | 165 ----- 0031-multipath-remove-logsink-and-udev.patch | 45 -- ...persist-call-libmultipath_-init-exit.patch | 93 --- ...mpathpersist-remove-logsink-and-udev.patch | 49 -- 0034-multipathd-remove-logsink-and-udev.patch | 54 -- ...-add-Vexata-by-StorCentric-VX-arrays.patch | 37 - ...Violin-and-Nexsan-were-bought-by-Sto.patch | 42 -- ...h-fix-memory-leaks-in-coalesce_paths.patch | 114 --- ...replace-hidden-tab-by-space-in-hwtab.patch | 28 - ...ipathd-uxlsnr-avoid-deadlock-on-exit.patch | 102 --- 0040-multipathd-Fix-liburcu-memory-leak.patch | 95 --- ...handling-of-io_err_stat_attr-into-li.patch | 143 ---- ...vecs-desctruction-into-cleanup-funct.patch | 122 ---- ...-multipathd-make-some-globals-static.patch | 42 -- ...threads-destruction-into-separate-fu.patch | 161 ----- ...conf-destruction-into-separate-funct.patch | 53 -- ...pid-destruction-into-separate-functi.patch | 39 - 0047-multipathd-close-pidfile-on-exit.patch | 42 -- ...elper-for-systemd-notification-at-ex.patch | 57 -- ...ld-call-cleanups-in-failure-case-too.patch | 49 -- ...ch_all_dmevents-check-if-waiter-is-i.patch | 25 - ...-error-message-if-config-can-t-be-lo.patch | 27 - 0052-libmultipath-add-libmp_dm_exit.patch | 89 --- ...tipathd-fixup-libdm-deinitialization.patch | 37 - ..._thread_stop-check-if-logarea-is-ini.patch | 26 - ...pathd-add-cleanup_child-exit-handler.patch | 92 --- ...-fix-log_thread-startup-and-teardown.patch | 145 ---- ...cleanup_-prio-checkers-foreign-to-li.patch | 90 --- ...path-use-atexit-for-cleanup-handlers.patch | 107 --- ...sist-use-atexit-for-cleanup-handlers.patch | 29 - ...ltipath-fix-leak-in-check_path_valid.patch | 92 --- ...mpath-tools.supp-file-with-valgrind-.patch | 59 -- ...e-libmp_verbosity-to-track-verbosity.patch | 438 ------------ ...ntroduce-symbolic-values-for-logsink.patch | 182 ----- 0064-libmultipath-simplify-dlog.patch | 149 ---- ...d-common-code-for-k-and-command-args.patch | 84 --- 0066-multipathd-sanitize-uxsock_listen.patch | 154 ---- ...-race-between-log_safe-and-log_threa.patch | 104 --- ...-multipath-add-libmpathvalid-library.patch | 502 ------------- ...tests-and-unit-tests-for-libmpathval.patch | 529 -------------- ...th-add-uid-failback-for-dasd-devices.patch | 87 --- ...nge-log-level-for-null-uid_attribute.patch | 42 -- ...ve-fast_io_fail-defines-to-structs.h.patch | 157 ---- ...-eh_deadline-multipath.conf-paramete.patch | 335 --------- ...e-redundant-vector_free-int-configur.patch | 34 - ...factor-out-code-to-get-vpd-page-data.patch | 63 -- ...ultipath-limit-reading-0xc9-vpd-page.patch | 88 --- ...ath-move-logq_lock-handling-to-log.c.patch | 138 ---- ...ipath-protect-logarea-with-logq_lock.patch | 107 --- ...vent-DSO-unloading-with-astray-check.patch | 281 -------- ...-force-map-reload-if-udev-incomplete.patch | 148 ---- ...-tools-avoid-access-to-etc-localtime.patch | 109 --- ...make-sure-plugin-DSOs-use-symbol-ver.patch | 146 ---- ...multipath.version-add-missing-symbol.patch | 27 - ...tests-unversioned-.so-for-valgrind-t.patch | 27 - ...unit-tests-fix-memory-leaks-in-mpath.patch | 50 -- ...x-Register-and-Ignore-with-0x00-SARK.patch | 31 - ...ate-prkeys-file-on-changing-registra.patch | 36 - ...n-about-missing-braces-at-end-of-mul.patch | 39 - ...ore-multipaths-sections-without-wwid.patch | 34 - ...tipath-fix-format-warning-with-clang.patch | 25 - ...th-check-for-null-wwid-before-strcmp.patch | 31 - ...-Improve-checker_timeout-description.patch | 62 -- ...ath-checkint-not-changed-when-path-s.patch | 33 - ...ect_action-skip-is_mpp_known_to_udev.patch | 48 -- ...lesce_paths-stop-triggering-spurious.patch | 62 -- ...d-uev_trigger-handle-incomplete-ADD-.patch | 58 -- ...ath-make-find_err_path_by_dev-static.patch | 24 - ...id-io_err_stat-crash-during-shutdown.patch | 254 ------- ...athd-avoid-io_err_stat-ABBA-deadlock.patch | 143 ---- ...et_monotonic_time-in-io_err_stat-cod.patch | 108 --- ...ne-free_io_err_stat_path-and-destroy.patch | 98 --- ...d-cleanup-logging-for-marginal-paths.patch | 120 ---- ...-NULL-dereference-in-find_path_by_de.patch | 43 -- ...print_devices-avoid-NULL-dereference.patch | 35 - ...fix-thread-safety-of-default-functio.patch | 271 ------- 0106-Added-github-action-for-building.patch | 34 - ...use-zram-device-as-test-block-device.patch | 37 - ...workflow-use-explicit-Ubuntu-version.patch | 23 - 0109-github-workflow-add-valgrind-tests.patch | 33 - 0110-github-workflow-run-apt-get-update.patch | 25 - ...flow-add-tests-with-gcc-10-and-clang.patch | 87 --- ...-Fix-multipathd-stopping-on-shutdown.patch | 35 - ...-3rd-digit-as-transport_id-for-expan.patch | 42 -- ...fs_set_nexus_loss_tmo-support-SAS-ex.patch | 54 -- ...pathd-add-code-to-initalize-unwinder.patch | 131 ---- ...ck-if-adopt_path-really-added-curren.patch | 54 -- ...d_path-fail-if-add_map_with_path-fai.patch | 28 - ...ck-return-value-of-udev_device_get_d.patch | 28 - ...filter_property-after-sysfs_pathinfo.patch | 278 -------- ...hinfo-call-filter_property-only-with.patch | 85 --- ...h-w-allow-removing-blacklisted-paths.patch | 36 - ...h-fix-use-after-free-in-uev_add_path.patch | 51 -- ...tests-fix-stringop-overflow-build-er.patch | 52 -- ...anup-code-to-strip-wwid-trailing-spa.patch | 44 -- ...-cleanup-uid_attribute-checking-code.patch | 53 -- ...echeck_wwid-option-to-verify-the-pat.patch | 453 ------------ ...heck-if-user_friendly_name-is-in-use.patch | 231 ------ ...ests-for-checking-if-alias-is-in-use.patch | 525 -------------- ...add-DellEMC-PowerStore-to-hardware-t.patch | 40 -- ...delete-a-space-in-multipath.conf.5-t.patch | 30 - ...tests-allow-control-of-test-verbosit.patch | 253 ------- ...devt-test-avoid-failure-when-run-in-.patch | 63 -- ...fix-compilation-errors-on-32-bit-mus.patch | 96 --- ...-compilation-error-with-gcc-10-on-i3.patch | 58 -- ...loop-device-after-listing-partitions.patch | 59 -- ...ge-update_multipath_table-and-update.patch | 229 ------ ...-mpath.rules-run-multipath-U-with-v1.patch | 41 -- ...tests-check-if-sys-dev-block-is-non-.patch | 62 -- ...thd-reduce-log-levels-in-cli_add_map.patch | 36 - ...fix-format-in-multipath.conf.5-to-be.patch | 30 - ...use-same-format-for-default-values-i.patch | 41 -- ...d-fix-NULL-dereference-in-check_path.patch | 39 - ...id-infinite-loop-with-bad-vpd-page-8.patch | 28 - ...ath-fix-priorities-in-parse_vpd_pg83.patch | 46 -- ...ve-getting-parent-udevice-in-rescan_.patch | 40 -- ...-trigger-uevent-for-partitions-on-ww.patch | 26 - device-mapper-multipath.spec | 183 +---- sources | 2 +- tests/alias_clash/LICENSE | 675 ++++++++++++++++++ tests/alias_clash/PURPOSE | 20 + tests/alias_clash/main.sh | 122 ++++ tests/find_multipaths/main.sh | 66 +- tests/include/mpath.sh | 3 +- tests/multipath_conf_syntax/main.sh | 189 +++-- tests/restate_module/main.sh | 1 + tests/tests.yml | 18 +- 167 files changed, 1012 insertions(+), 15115 deletions(-) delete mode 100644 0001-Change-the-multipath.conf-manpage-uxsock_timeout-def.patch rename 0147-RH-fixup-udev-rules-for-redhat.patch => 0001-RH-fixup-udev-rules-for-redhat.patch (97%) rename 0148-RH-Remove-the-property-blacklist-exception-builtin.patch => 0002-RH-Remove-the-property-blacklist-exception-builtin.patch (100%) delete mode 100644 0002-libmultipath-find_mpe-don-t-match-with-empty-WWID.patch rename 0149-RH-don-t-start-without-a-config-file.patch => 0003-RH-don-t-start-without-a-config-file.patch (100%) delete mode 100644 0003-libmultipath-copy-mpp-hwe-from-pp-hwe.patch rename 0150-RH-Fix-nvme-function-missing-argument.patch => 0004-RH-Fix-nvme-function-missing-argument.patch (100%) delete mode 100644 0004-libmultipath-dm_map_present_by_uuid-fix-dm_task_crea.patch rename 0151-RH-use-rpm-optflags-if-present.patch => 0005-RH-use-rpm-optflags-if-present.patch (94%) delete mode 100644 0005-libdmmp-tests-fix-compilation.patch rename 0152-RH-add-mpathconf.patch => 0006-RH-add-mpathconf.patch (100%) delete mode 100644 0006-libmultipath-prio-constify-some-function-parameters.patch rename 0153-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch => 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch (100%) delete mode 100644 0007-libmultipath-checkers-prio-allow-non-lazy-.so-loadin.patch rename 0154-RH-reset-default-find_mutipaths-value-to-off.patch => 0008-RH-reset-default-find_mutipaths-value-to-off.patch (100%) delete mode 100644 0008-multipath-tools-Makefiles-separate-rules-for-.so-and.patch rename 0155-RH-attempt-to-get-ANA-info-via-sysfs-first.patch => 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch (100%) delete mode 100644 0009-libmultipath-create-separate-.so-for-unit-tests.patch rename 0156-RH-make-parse_vpd_pg83-match-scsi_id-output.patch => 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch (97%) delete mode 100644 0010-libmultipath-add-linker-version-script.patch delete mode 100644 0011-libmpathpersist-add-linker-version-script.patch delete mode 100644 0012-libmpathcmd-add-linker-version-script.patch delete mode 100644 0013-libmpathpersist-initialize-mpp-hwe-in-get_mpvec.patch delete mode 100644 0014-multipathd-allow-shutdown-during-configure.patch delete mode 100644 0015-multipathd-avoid-sending-READY-1-to-systemd-on-early.patch delete mode 100644 0016-multipathd-send-STOPPING-1-to-systemd-on-shutdown.patch delete mode 100644 0017-multipathd-send-RELOADING-1-to-systemd-on-DAEMON_CON.patch delete mode 100644 0018-multipathd-use-volatile-qualifier-for-running_state.patch delete mode 100644 0019-multipathd-generalize-and-fix-wait_for_state_change_.patch delete mode 100644 0020-multipathd-set_config_state-avoid-code-duplication.patch delete mode 100644 0021-multipathd-cancel-threads-early-during-shutdown.patch delete mode 100644 0022-multipath-tools-don-t-call-dm_lib_release-any-more.patch delete mode 100644 0023-libmultipath-devmapper-refactor-libdm-version-determ.patch delete mode 100644 0024-libmultipath-protect-racy-libdevmapper-calls-with-a-.patch delete mode 100644 0025-libmultipath-constify-file-argument-in-config-parser.patch delete mode 100644 0026-libmultipath-provide-defaults-for-get-put-_multipath.patch delete mode 100644 0027-libmpathpersist-allow-using-libmultipath-get-put-_mu.patch delete mode 100644 0028-multipath-use-get_put-_multipath_config-from-libmult.patch delete mode 100644 0029-mpathpersist-use-get-put-_multipath_config-from-libm.patch delete mode 100644 0030-libmultipath-add-udev-and-logsink-symbols.patch delete mode 100644 0031-multipath-remove-logsink-and-udev.patch delete mode 100644 0032-libmpathpersist-call-libmultipath_-init-exit.patch delete mode 100644 0033-mpathpersist-remove-logsink-and-udev.patch delete mode 100644 0034-multipathd-remove-logsink-and-udev.patch delete mode 100644 0035-multipath-tools-add-Vexata-by-StorCentric-VX-arrays.patch delete mode 100644 0036-multipath-tools-Violin-and-Nexsan-were-bought-by-Sto.patch delete mode 100644 0037-libmultipath-fix-memory-leaks-in-coalesce_paths.patch delete mode 100644 0038-multipath-tools-replace-hidden-tab-by-space-in-hwtab.patch delete mode 100644 0039-multipathd-uxlsnr-avoid-deadlock-on-exit.patch delete mode 100644 0040-multipathd-Fix-liburcu-memory-leak.patch delete mode 100644 0041-multipathd-move-handling-of-io_err_stat_attr-into-li.patch delete mode 100644 0042-multipathd-move-vecs-desctruction-into-cleanup-funct.patch delete mode 100644 0043-multipathd-make-some-globals-static.patch delete mode 100644 0044-multipathd-move-threads-destruction-into-separate-fu.patch delete mode 100644 0045-multipathd-move-conf-destruction-into-separate-funct.patch delete mode 100644 0046-multipathd-move-pid-destruction-into-separate-functi.patch delete mode 100644 0047-multipathd-close-pidfile-on-exit.patch delete mode 100644 0048-multipathd-add-helper-for-systemd-notification-at-ex.patch delete mode 100644 0049-multipathd-child-call-cleanups-in-failure-case-too.patch delete mode 100644 0050-multipathd-unwatch_all_dmevents-check-if-waiter-is-i.patch delete mode 100644 0051-multipathd-print-error-message-if-config-can-t-be-lo.patch delete mode 100644 0052-libmultipath-add-libmp_dm_exit.patch delete mode 100644 0053-multipathd-fixup-libdm-deinitialization.patch delete mode 100644 0054-libmultipath-log_thread_stop-check-if-logarea-is-ini.patch delete mode 100644 0055-multipathd-add-cleanup_child-exit-handler.patch delete mode 100644 0056-libmultipath-fix-log_thread-startup-and-teardown.patch delete mode 100644 0057-multipathd-move-cleanup_-prio-checkers-foreign-to-li.patch delete mode 100644 0058-multipath-use-atexit-for-cleanup-handlers.patch delete mode 100644 0059-mpathpersist-use-atexit-for-cleanup-handlers.patch delete mode 100644 0060-multipath-fix-leak-in-check_path_valid.patch delete mode 100644 0061-multipath-tools-mpath-tools.supp-file-with-valgrind-.patch delete mode 100644 0062-libmultipath-use-libmp_verbosity-to-track-verbosity.patch delete mode 100644 0063-libmultipath-introduce-symbolic-values-for-logsink.patch delete mode 100644 0064-libmultipath-simplify-dlog.patch delete mode 100644 0065-multipathd-common-code-for-k-and-command-args.patch delete mode 100644 0066-multipathd-sanitize-uxsock_listen.patch delete mode 100644 0067-libmultipath-fix-race-between-log_safe-and-log_threa.patch delete mode 100644 0068-multipath-add-libmpathvalid-library.patch delete mode 100644 0069-multipath-tools-tests-and-unit-tests-for-libmpathval.patch delete mode 100644 0070-libmultipath-add-uid-failback-for-dasd-devices.patch delete mode 100644 0071-libmultipath-change-log-level-for-null-uid_attribute.patch delete mode 100644 0072-libmultipath-move-fast_io_fail-defines-to-structs.h.patch delete mode 100644 0073-libmultipath-add-eh_deadline-multipath.conf-paramete.patch delete mode 100644 0074-multipathd-remove-redundant-vector_free-int-configur.patch delete mode 100644 0075-libmultipath-factor-out-code-to-get-vpd-page-data.patch delete mode 100644 0076-libmultipath-limit-reading-0xc9-vpd-page.patch delete mode 100644 0077-libmultipath-move-logq_lock-handling-to-log.c.patch delete mode 100644 0078-libmultipath-protect-logarea-with-logq_lock.patch delete mode 100644 0079-libmultipath-prevent-DSO-unloading-with-astray-check.patch delete mode 100644 0080-libmultipath-force-map-reload-if-udev-incomplete.patch delete mode 100644 0081-multipath-tools-avoid-access-to-etc-localtime.patch delete mode 100644 0082-multipath-tools-make-sure-plugin-DSOs-use-symbol-ver.patch delete mode 100644 0083-libmultipath.version-add-missing-symbol.patch delete mode 100644 0084-multipath-tools-tests-unversioned-.so-for-valgrind-t.patch delete mode 100644 0085-multipath-tools-unit-tests-fix-memory-leaks-in-mpath.patch delete mode 100644 0086-mpathpersist-Fix-Register-and-Ignore-with-0x00-SARK.patch delete mode 100644 0087-mpathpersist-update-prkeys-file-on-changing-registra.patch delete mode 100644 0088-libmultipath-warn-about-missing-braces-at-end-of-mul.patch delete mode 100644 0089-libmultipath-ignore-multipaths-sections-without-wwid.patch delete mode 100644 0090-libmultipath-fix-format-warning-with-clang.patch delete mode 100644 0091-libmultipath-check-for-null-wwid-before-strcmp.patch delete mode 100644 0092-multipath.conf.5-Improve-checker_timeout-description.patch delete mode 100644 0093-multipathd-fix-path-checkint-not-changed-when-path-s.patch delete mode 100644 0094-libmultipath-select_action-skip-is_mpp_known_to_udev.patch delete mode 100644 0095-libmultipath-coalesce_paths-stop-triggering-spurious.patch delete mode 100644 0096-Revert-multipathd-uev_trigger-handle-incomplete-ADD-.patch delete mode 100644 0097-libmultipath-make-find_err_path_by_dev-static.patch delete mode 100644 0098-multipathd-avoid-io_err_stat-crash-during-shutdown.patch delete mode 100644 0099-multipathd-avoid-io_err_stat-ABBA-deadlock.patch delete mode 100644 0100-multipathd-use-get_monotonic_time-in-io_err_stat-cod.patch delete mode 100644 0101-multipathd-combine-free_io_err_stat_path-and-destroy.patch delete mode 100644 0102-multipathd-cleanup-logging-for-marginal-paths.patch delete mode 100644 0103-libmultipath-fix-NULL-dereference-in-find_path_by_de.patch delete mode 100644 0104-libmultipath-snprint_devices-avoid-NULL-dereference.patch delete mode 100644 0105-libmpathpersist-fix-thread-safety-of-default-functio.patch delete mode 100644 0106-Added-github-action-for-building.patch delete mode 100644 0107-github-workflow-use-zram-device-as-test-block-device.patch delete mode 100644 0108-github-workflow-use-explicit-Ubuntu-version.patch delete mode 100644 0109-github-workflow-add-valgrind-tests.patch delete mode 100644 0110-github-workflow-run-apt-get-update.patch delete mode 100644 0111-github-workflow-add-tests-with-gcc-10-and-clang.patch delete mode 100644 0112-multipathd-Fix-multipathd-stopping-on-shutdown.patch delete mode 100644 0113-libmultipath-use-3rd-digit-as-transport_id-for-expan.patch delete mode 100644 0114-libmultipath-sysfs_set_nexus_loss_tmo-support-SAS-ex.patch delete mode 100644 0115-multipathd-add-code-to-initalize-unwinder.patch delete mode 100644 0116-libmultipath-check-if-adopt_path-really-added-curren.patch delete mode 100644 0117-multipathd-ev_add_path-fail-if-add_map_with_path-fai.patch delete mode 100644 0118-libmultipath-check-return-value-of-udev_device_get_d.patch delete mode 100644 0119-pathinfo-call-filter_property-after-sysfs_pathinfo.patch delete mode 100644 0120-libmultipath-pathinfo-call-filter_property-only-with.patch delete mode 100644 0121-multipath-w-allow-removing-blacklisted-paths.patch delete mode 100644 0122-libmultipath-fix-use-after-free-in-uev_add_path.patch delete mode 100644 0123-multipath-tools-tests-fix-stringop-overflow-build-er.patch delete mode 100644 0124-libmultipath-cleanup-code-to-strip-wwid-trailing-spa.patch delete mode 100644 0125-libmultipath-cleanup-uid_attribute-checking-code.patch delete mode 100644 0126-multipathd-add-recheck_wwid-option-to-verify-the-pat.patch delete mode 100644 0127-libmultipath-check-if-user_friendly_name-is-in-use.patch delete mode 100644 0128-tests-add-tests-for-checking-if-alias-is-in-use.patch delete mode 100644 0129-multipath-tools-add-DellEMC-PowerStore-to-hardware-t.patch delete mode 100644 0130-multipath-tools-delete-a-space-in-multipath.conf.5-t.patch delete mode 100644 0131-multipath-tools-tests-allow-control-of-test-verbosit.patch delete mode 100644 0132-multipath-tools-devt-test-avoid-failure-when-run-in-.patch delete mode 100644 0133-multipath-tools-fix-compilation-errors-on-32-bit-mus.patch delete mode 100644 0134-libmultipath-fix-compilation-error-with-gcc-10-on-i3.patch delete mode 100644 0135-kpartx-free-loop-device-after-listing-partitions.patch delete mode 100644 0136-libmultipath-merge-update_multipath_table-and-update.patch delete mode 100644 0137-11-dm-mpath.rules-run-multipath-U-with-v1.patch delete mode 100644 0138-multipath-tools-tests-check-if-sys-dev-block-is-non-.patch delete mode 100644 0139-multipathd-reduce-log-levels-in-cli_add_map.patch delete mode 100644 0140-multipath-tools-fix-format-in-multipath.conf.5-to-be.patch delete mode 100644 0141-multipath-tools-use-same-format-for-default-values-i.patch delete mode 100644 0142-multipathd-fix-NULL-dereference-in-check_path.patch delete mode 100644 0143-libmultipath-avoid-infinite-loop-with-bad-vpd-page-8.patch delete mode 100644 0144-libmultipath-fix-priorities-in-parse_vpd_pg83.patch delete mode 100644 0145-multipathd-improve-getting-parent-udevice-in-rescan_.patch delete mode 100644 0146-multipathd-don-t-trigger-uevent-for-partitions-on-ww.patch create mode 100644 tests/alias_clash/LICENSE create mode 100644 tests/alias_clash/PURPOSE create mode 100755 tests/alias_clash/main.sh diff --git a/.gitignore b/.gitignore index befbabe..7ac9519 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ multipath-tools-091027.tar.gz /multipath-tools-0.8.2.tgz /multipath-tools-0.8.4.tgz /multipath-tools-0.8.5.tgz +/multipath-tools-0.8.6.tgz diff --git a/0001-Change-the-multipath.conf-manpage-uxsock_timeout-def.patch b/0001-Change-the-multipath.conf-manpage-uxsock_timeout-def.patch deleted file mode 100644 index 21428df..0000000 --- a/0001-Change-the-multipath.conf-manpage-uxsock_timeout-def.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Christophe Varoqui -Date: Mon, 14 Dec 2020 11:05:24 +0100 -Subject: [PATCH] Change the multipath.conf manpage uxsock_timeout default - value - -Fixes: 7db0c44 ("multipathd: Set CLI timeout correctly") - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - multipath/multipath.conf.5 | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index d2101ed6..7242d39b 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -1153,7 +1153,7 @@ In these cases it is recommended to increase the CLI timeout to avoid - those issues. - .RS - .TP --The default is: \fB1000\fR -+The default is: \fB4000\fR - .RE - . - . diff --git a/0147-RH-fixup-udev-rules-for-redhat.patch b/0001-RH-fixup-udev-rules-for-redhat.patch similarity index 97% rename from 0147-RH-fixup-udev-rules-for-redhat.patch rename to 0001-RH-fixup-udev-rules-for-redhat.patch index efb8857..e84f9e0 100644 --- a/0147-RH-fixup-udev-rules-for-redhat.patch +++ b/0001-RH-fixup-udev-rules-for-redhat.patch @@ -15,10 +15,10 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 05429307..24e943d5 100644 +index f1e23131..c593fd3b 100644 --- a/Makefile.inc +++ b/Makefile.inc -@@ -53,7 +53,7 @@ endif +@@ -55,7 +55,7 @@ endif prefix = exec_prefix = $(prefix) usr_prefix = $(prefix) diff --git a/0148-RH-Remove-the-property-blacklist-exception-builtin.patch b/0002-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 100% rename from 0148-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0002-RH-Remove-the-property-blacklist-exception-builtin.patch diff --git a/0002-libmultipath-find_mpe-don-t-match-with-empty-WWID.patch b/0002-libmultipath-find_mpe-don-t-match-with-empty-WWID.patch deleted file mode 100644 index 6ceeac1..0000000 --- a/0002-libmultipath-find_mpe-don-t-match-with-empty-WWID.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 16 Sep 2020 21:59:11 +0200 -Subject: [PATCH] libmultipath: find_mpe(): don't match with empty WWID - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/config.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/config.c b/libmultipath/config.c -index b9bdbdbc..df0f8f45 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -147,7 +147,7 @@ struct mpentry *find_mpe(vector mptable, char *wwid) - int i; - struct mpentry * mpe; - -- if (!wwid) -+ if (!wwid || !*wwid) - return NULL; - - vector_foreach_slot (mptable, mpe, i) diff --git a/0149-RH-don-t-start-without-a-config-file.patch b/0003-RH-don-t-start-without-a-config-file.patch similarity index 100% rename from 0149-RH-don-t-start-without-a-config-file.patch rename to 0003-RH-don-t-start-without-a-config-file.patch diff --git a/0003-libmultipath-copy-mpp-hwe-from-pp-hwe.patch b/0003-libmultipath-copy-mpp-hwe-from-pp-hwe.patch deleted file mode 100644 index fa4da39..0000000 --- a/0003-libmultipath-copy-mpp-hwe-from-pp-hwe.patch +++ /dev/null @@ -1,257 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 16 Sep 2020 22:22:36 +0200 -Subject: [PATCH] libmultipath: copy mpp->hwe from pp->hwe - -Since f0462f0 ("libmultipath: use vector for for pp->hwe and mp->hwe"), -we've been trying to fix issues caused by paths getting freed and mpp->hwe -dangling. This approach couldn't work because we need mpp->hwe to persist, -even if all paths are removed from the map. Before f0462f0, a simple -assignment worked, because the lifetime of the hwe wasn't bound to the -path. But now, we need to copy the vector. It turns out that we need to set -mpp->hwe only in two places, add_map_with_path() and setup_map(), and -that the code is simplified overall. - -Even now, it can happen that a map is added with add_map_without_paths(), -and has no paths. In that case, calling do_set_from_hwe() with a NULL -pointer is not a bug, so remove the message. - -Fixes: f0462f0 ("libmultipath: use vector for for pp->hwe and mp->hwe") -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 7 +++++ - libmultipath/propsel.c | 4 +-- - libmultipath/structs.c | 15 +++++++++++ - libmultipath/structs.h | 1 + - libmultipath/structs_vec.c | 54 ++++++++++++++++---------------------- - multipathd/main.c | 10 ------- - 6 files changed, 46 insertions(+), 45 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 6fb477fc..d7afc915 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -311,6 +311,13 @@ int setup_map(struct multipath *mpp, char *params, int params_size, - if (mpp->disable_queueing && VECTOR_SIZE(mpp->paths) != 0) - mpp->disable_queueing = 0; - -+ /* -+ * If this map was created with add_map_without_path(), -+ * mpp->hwe might not be set yet. -+ */ -+ if (!mpp->hwe) -+ extract_hwe_from_path(mpp); -+ - /* - * properties selectors - * -diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c -index 7e6e0d68..40201344 100644 ---- a/libmultipath/propsel.c -+++ b/libmultipath/propsel.c -@@ -65,9 +65,7 @@ do { \ - __do_set_from_vec(struct hwentry, var, (src)->hwe, dest) - - #define do_set_from_hwe(var, src, dest, msg) \ -- if (!src->hwe) { \ -- condlog(0, "BUG: do_set_from_hwe called with hwe == NULL"); \ -- } else if (__do_set_from_hwe(var, src, dest)) { \ -+ if (src->hwe && __do_set_from_hwe(var, src, dest)) { \ - origin = msg; \ - goto out; \ - } -diff --git a/libmultipath/structs.c b/libmultipath/structs.c -index 464596fc..2efad6f0 100644 ---- a/libmultipath/structs.c -+++ b/libmultipath/structs.c -@@ -234,6 +234,17 @@ alloc_multipath (void) - return mpp; - } - -+void *set_mpp_hwe(struct multipath *mpp, const struct path *pp) -+{ -+ if (!mpp || !pp || !pp->hwe) -+ return NULL; -+ if (mpp->hwe) -+ return mpp->hwe; -+ mpp->hwe = vector_convert(NULL, pp->hwe, -+ struct hwentry, identity); -+ return mpp->hwe; -+} -+ - void free_multipath_attributes(struct multipath *mpp) - { - if (!mpp) -@@ -290,6 +301,10 @@ free_multipath (struct multipath * mpp, enum free_path_mode free_paths) - - free_pathvec(mpp->paths, free_paths); - free_pgvec(mpp->pg, free_paths); -+ if (mpp->hwe) { -+ vector_free(mpp->hwe); -+ mpp->hwe = NULL; -+ } - FREE_PTR(mpp->mpcontext); - FREE(mpp); - } -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index 7de93d6c..4ce30551 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -422,6 +422,7 @@ struct host_group { - struct path * alloc_path (void); - struct pathgroup * alloc_pathgroup (void); - struct multipath * alloc_multipath (void); -+void *set_mpp_hwe(struct multipath *mpp, const struct path *pp); - void uninitialize_path(struct path *pp); - void free_path (struct path *); - void free_pathvec (vector vec, enum free_path_mode free_paths); -diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c -index 8895fa77..f7f45f11 100644 ---- a/libmultipath/structs_vec.c -+++ b/libmultipath/structs_vec.c -@@ -294,11 +294,6 @@ err: - void orphan_path(struct path *pp, const char *reason) - { - condlog(3, "%s: orphan path, %s", pp->dev, reason); -- if (pp->mpp && pp->hwe && pp->mpp->hwe == pp->hwe) { -- condlog(0, "BUG: orphaning path %s that holds hwe of %s", -- pp->dev, pp->mpp->alias); -- pp->mpp->hwe = NULL; -- } - pp->mpp = NULL; - uninitialize_path(pp); - } -@@ -308,8 +303,6 @@ void orphan_paths(vector pathvec, struct multipath *mpp, const char *reason) - int i; - struct path * pp; - -- /* Avoid BUG message from orphan_path() */ -- mpp->hwe = NULL; - vector_foreach_slot (pathvec, pp, i) { - if (pp->mpp == mpp) { - if (pp->initialized == INIT_REMOVED) { -@@ -397,24 +390,26 @@ extract_hwe_from_path(struct multipath * mpp) - if (mpp->hwe || !mpp->paths) - return; - -- condlog(3, "%s: searching paths for valid hwe", mpp->alias); -+ condlog(4, "%s: searching paths for valid hwe", mpp->alias); - /* doing this in two passes seems like paranoia to me */ - vector_foreach_slot(mpp->paths, pp, i) { -- if (pp->state != PATH_UP) -- continue; -- if (pp->hwe) { -- mpp->hwe = pp->hwe; -- return; -- } -+ if (pp->state == PATH_UP && -+ pp->initialized != INIT_REMOVED && pp->hwe) -+ goto done; - } - vector_foreach_slot(mpp->paths, pp, i) { -- if (pp->state == PATH_UP) -- continue; -- if (pp->hwe) { -- mpp->hwe = pp->hwe; -- return; -- } -+ if (pp->state != PATH_UP && -+ pp->initialized != INIT_REMOVED && pp->hwe) -+ goto done; - } -+done: -+ if (i < VECTOR_SIZE(mpp->paths)) -+ (void)set_mpp_hwe(mpp, pp); -+ -+ if (mpp->hwe) -+ condlog(3, "%s: got hwe from path %s", mpp->alias, pp->dev); -+ else -+ condlog(2, "%s: no hwe found", mpp->alias); - } - - int -@@ -514,8 +509,6 @@ void sync_paths(struct multipath *mpp, vector pathvec) - } - if (!found) { - condlog(3, "%s dropped path %s", mpp->alias, pp->dev); -- if (mpp->hwe == pp->hwe) -- mpp->hwe = NULL; - vector_del_slot(mpp->paths, i--); - orphan_path(pp, "path removed externally"); - } -@@ -524,8 +517,6 @@ void sync_paths(struct multipath *mpp, vector pathvec) - update_mpp_paths(mpp, pathvec); - vector_foreach_slot (mpp->paths, pp, i) - pp->mpp = mpp; -- if (mpp->hwe == NULL) -- extract_hwe_from_path(mpp); - } - - int -@@ -701,9 +692,15 @@ struct multipath *add_map_with_path(struct vectors *vecs, struct path *pp, - - conf = get_multipath_config(); - mpp->mpe = find_mpe(conf->mptable, pp->wwid); -- mpp->hwe = pp->hwe; - put_multipath_config(conf); - -+ /* -+ * We need to call this before select_alias(), -+ * because that accesses hwe properties. -+ */ -+ if (pp->hwe && !set_mpp_hwe(mpp, pp)) -+ goto out; -+ - strcpy(mpp->wwid, pp->wwid); - find_existing_alias(mpp, vecs); - if (select_alias(conf, mpp)) -@@ -754,12 +751,6 @@ int verify_paths(struct multipath *mpp) - vector_del_slot(mpp->paths, i); - i--; - -- /* Make sure mpp->hwe doesn't point to freed memory. -- * We call extract_hwe_from_path() below to restore -- * mpp->hwe -- */ -- if (mpp->hwe == pp->hwe) -- mpp->hwe = NULL; - /* - * Don't delete path from pathvec yet. We'll do this - * after the path has been removed from the map, in -@@ -771,7 +762,6 @@ int verify_paths(struct multipath *mpp) - mpp->alias, pp->dev, pp->dev_t); - } - } -- extract_hwe_from_path(mpp); - return count; - } - -diff --git a/multipathd/main.c b/multipathd/main.c -index a4abbb27..eedc6c10 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -1153,13 +1153,6 @@ ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map) - if (i != -1) - vector_del_slot(mpp->paths, i); - -- /* -- * Make sure mpp->hwe doesn't point to freed memory -- * We call extract_hwe_from_path() below to restore mpp->hwe -- */ -- if (mpp->hwe == pp->hwe) -- mpp->hwe = NULL; -- - /* - * remove the map IF removing the last path - */ -@@ -1191,9 +1184,6 @@ ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map) - */ - } - -- if (mpp->hwe == NULL) -- extract_hwe_from_path(mpp); -- - if (setup_map(mpp, params, PARAMS_SIZE, vecs)) { - condlog(0, "%s: failed to setup map for" - " removal of path %s", mpp->alias, pp->dev); diff --git a/0150-RH-Fix-nvme-function-missing-argument.patch b/0004-RH-Fix-nvme-function-missing-argument.patch similarity index 100% rename from 0150-RH-Fix-nvme-function-missing-argument.patch rename to 0004-RH-Fix-nvme-function-missing-argument.patch diff --git a/0004-libmultipath-dm_map_present_by_uuid-fix-dm_task_crea.patch b/0004-libmultipath-dm_map_present_by_uuid-fix-dm_task_crea.patch deleted file mode 100644 index f4177ec..0000000 --- a/0004-libmultipath-dm_map_present_by_uuid-fix-dm_task_crea.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 22 Sep 2020 14:24:41 +0200 -Subject: [PATCH] libmultipath: dm_map_present_by_uuid(): fix dm_task_create() - call - -libmultipath shouldn't call dm_task_create() directly any more. - -Fixes: 90535a3 ("multipath: centralize validation code") -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/devmapper.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index 7f093617..0bc1d16e 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -836,7 +836,7 @@ dm_map_present_by_uuid(const char *uuid) - if (safe_sprintf(prefixed_uuid, UUID_PREFIX "%s", uuid)) - goto out; - -- if (!(dmt = dm_task_create(DM_DEVICE_INFO))) -+ if (!(dmt = libmp_dm_task_create(DM_DEVICE_INFO))) - goto out; - - dm_task_no_open_count(dmt); diff --git a/0151-RH-use-rpm-optflags-if-present.patch b/0005-RH-use-rpm-optflags-if-present.patch similarity index 94% rename from 0151-RH-use-rpm-optflags-if-present.patch rename to 0005-RH-use-rpm-optflags-if-present.patch index 7b0334d..debec54 100644 --- a/0151-RH-use-rpm-optflags-if-present.patch +++ b/0005-RH-use-rpm-optflags-if-present.patch @@ -13,10 +13,10 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 24e943d5..e978d306 100644 +index c593fd3b..87fb39f2 100644 --- a/Makefile.inc +++ b/Makefile.inc -@@ -90,15 +90,27 @@ TEST_CC_OPTION = $(shell \ +@@ -92,15 +92,27 @@ TEST_CC_OPTION = $(shell \ echo "$(2)"; \ fi) @@ -49,7 +49,7 @@ index 24e943d5..e978d306 100644 CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ -DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" \ -MMD -MP -@@ -136,4 +148,4 @@ check_file = $(shell \ +@@ -138,4 +150,4 @@ check_file = $(shell \ %.o: %.c @echo building $@ because of $? diff --git a/0005-libdmmp-tests-fix-compilation.patch b/0005-libdmmp-tests-fix-compilation.patch deleted file mode 100644 index ae341cf..0000000 --- a/0005-libdmmp-tests-fix-compilation.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 22 Sep 2020 12:10:35 +0200 -Subject: [PATCH] libdmmp tests: fix compilation - -These tests don't compile with -Werror=unused-parameter. Fix it. -Reviewed-by: Benjamin Marzinski - -Signed-off-by: Benjamin Marzinski ---- - libdmmp/test/libdmmp_speed_test.c | 2 +- - libdmmp/test/libdmmp_test.c | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/libdmmp/test/libdmmp_speed_test.c b/libdmmp/test/libdmmp_speed_test.c -index 372cd390..d91ba50a 100644 ---- a/libdmmp/test/libdmmp_speed_test.c -+++ b/libdmmp/test/libdmmp_speed_test.c -@@ -27,7 +27,7 @@ - - #include - --int main(int argc, char *argv[]) -+int main(void) - { - struct dmmp_context *ctx = NULL; - struct dmmp_mpath **dmmp_mps = NULL; -diff --git a/libdmmp/test/libdmmp_test.c b/libdmmp/test/libdmmp_test.c -index d944e1e3..a940b576 100644 ---- a/libdmmp/test/libdmmp_test.c -+++ b/libdmmp/test/libdmmp_test.c -@@ -102,7 +102,7 @@ out: - return rc; - } - --int main(int argc, char *argv[]) -+int main(void) - { - struct dmmp_context *ctx = NULL; - struct dmmp_mpath **dmmp_mps = NULL; diff --git a/0152-RH-add-mpathconf.patch b/0006-RH-add-mpathconf.patch similarity index 100% rename from 0152-RH-add-mpathconf.patch rename to 0006-RH-add-mpathconf.patch diff --git a/0006-libmultipath-prio-constify-some-function-parameters.patch b/0006-libmultipath-prio-constify-some-function-parameters.patch deleted file mode 100644 index 94fbd17..0000000 --- a/0006-libmultipath-prio-constify-some-function-parameters.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 18 Sep 2020 23:57:22 +0200 -Subject: [PATCH] libmultipath: prio: constify some function parameters - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/prio.c | 4 ++-- - libmultipath/prio.h | 4 ++-- - 2 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/libmultipath/prio.c b/libmultipath/prio.c -index 194563c4..3a718ba5 100644 ---- a/libmultipath/prio.c -+++ b/libmultipath/prio.c -@@ -18,7 +18,7 @@ unsigned int get_prio_timeout(unsigned int timeout_ms, - return default_timeout; - } - --int init_prio (char *multipath_dir) -+int init_prio (const char *multipath_dir) - { - if (!add_prio(multipath_dir, DEFAULT_PRIO)) - return 1; -@@ -87,7 +87,7 @@ int prio_set_args (struct prio * p, const char * args) - return snprintf(p->args, PRIO_ARGS_LEN, "%s", args); - } - --struct prio * add_prio (char *multipath_dir, char * name) -+struct prio * add_prio (const char *multipath_dir, const char * name) - { - char libname[LIB_PRIO_NAMELEN]; - struct stat stbuf; -diff --git a/libmultipath/prio.h b/libmultipath/prio.h -index 599d1d88..26754f78 100644 ---- a/libmultipath/prio.h -+++ b/libmultipath/prio.h -@@ -55,9 +55,9 @@ struct prio { - - unsigned int get_prio_timeout(unsigned int checker_timeout, - unsigned int default_timeout); --int init_prio (char *); -+int init_prio (const char *); - void cleanup_prio (void); --struct prio * add_prio (char *, char *); -+struct prio * add_prio (const char *, const char *); - int prio_getprio (struct prio *, struct path *, unsigned int); - void prio_get (char *, struct prio *, char *, char *); - void prio_put (struct prio *); diff --git a/0153-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 100% rename from 0153-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch diff --git a/0007-libmultipath-checkers-prio-allow-non-lazy-.so-loadin.patch b/0007-libmultipath-checkers-prio-allow-non-lazy-.so-loadin.patch deleted file mode 100644 index bdea162..0000000 --- a/0007-libmultipath-checkers-prio-allow-non-lazy-.so-loadin.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 18 Sep 2020 23:58:15 +0200 -Subject: [PATCH] libmultipath: checkers/prio: allow non-lazy .so loading - -If compiled with -DLOAD_ALL_SHARED_LIBS, all known prioritizers -and checkers will be loaded immediately on startup. This is useful -for determining symbol usage (start executables with LD_BIND_NOW=1). - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/checkers.c | 17 +++++++++++++++++ - libmultipath/prio.c | 22 ++++++++++++++++++++++ - 2 files changed, 39 insertions(+) - -diff --git a/libmultipath/checkers.c b/libmultipath/checkers.c -index f7ddd536..18b1f5eb 100644 ---- a/libmultipath/checkers.c -+++ b/libmultipath/checkers.c -@@ -7,6 +7,7 @@ - #include "debug.h" - #include "checkers.h" - #include "vector.h" -+#include "util.h" - - struct checker_class { - struct list_head node; -@@ -375,7 +376,23 @@ void checker_get(const char *multipath_dir, struct checker *dst, - - int init_checkers(const char *multipath_dir) - { -+#ifdef LOAD_ALL_SHARED_LIBS -+ static const char *const all_checkers[] = { -+ DIRECTIO, -+ TUR, -+ HP_SW, -+ RDAC, -+ EMC_CLARIION, -+ READSECTOR0, -+ CCISS_TUR, -+ }; -+ unsigned int i; -+ -+ for (i = 0; i < ARRAY_SIZE(all_checkers); i++) -+ add_checker_class(multipath_dir, all_checkers[i]); -+#else - if (!add_checker_class(multipath_dir, DEFAULT_CHECKER)) - return 1; -+#endif - return 0; - } -diff --git a/libmultipath/prio.c b/libmultipath/prio.c -index 3a718ba5..c92bde7f 100644 ---- a/libmultipath/prio.c -+++ b/libmultipath/prio.c -@@ -20,8 +20,30 @@ unsigned int get_prio_timeout(unsigned int timeout_ms, - - int init_prio (const char *multipath_dir) - { -+#ifdef LOAD_ALL_SHARED_LIBS -+ static const char *const all_prios[] = { -+ PRIO_ALUA, -+ PRIO_CONST, -+ PRIO_DATACORE, -+ PRIO_EMC, -+ PRIO_HDS, -+ PRIO_HP_SW, -+ PRIO_ONTAP, -+ PRIO_RANDOM, -+ PRIO_RDAC, -+ PRIO_WEIGHTED_PATH, -+ PRIO_SYSFS, -+ PRIO_PATH_LATENCY, -+ PRIO_ANA, -+ }; -+ unsigned int i; -+ -+ for (i = 0; i < ARRAY_SIZE(all_prios); i++) -+ add_prio(multipath_dir, all_prios[i]); -+#else - if (!add_prio(multipath_dir, DEFAULT_PRIO)) - return 1; -+#endif - return 0; - } - diff --git a/0154-RH-reset-default-find_mutipaths-value-to-off.patch b/0008-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 100% rename from 0154-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0008-RH-reset-default-find_mutipaths-value-to-off.patch diff --git a/0008-multipath-tools-Makefiles-separate-rules-for-.so-and.patch b/0008-multipath-tools-Makefiles-separate-rules-for-.so-and.patch deleted file mode 100644 index 81ee846..0000000 --- a/0008-multipath-tools-Makefiles-separate-rules-for-.so-and.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 22 Sep 2020 12:52:49 +0200 -Subject: [PATCH] multipath-tools Makefiles: separate rules for .so and man - pages - -Rely more on "make" functionality than on sequential command execution. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmpathcmd/Makefile | 8 +++++--- - libmpathpersist/Makefile | 10 +++++++--- - libmultipath/Makefile | 8 +++++--- - 3 files changed, 17 insertions(+), 9 deletions(-) - -diff --git a/libmpathcmd/Makefile b/libmpathcmd/Makefile -index 0f6b8166..08ccb811 100644 ---- a/libmpathcmd/Makefile -+++ b/libmpathcmd/Makefile -@@ -8,13 +8,15 @@ CFLAGS += $(LIB_CFLAGS) - - OBJS = mpath_cmd.o - --all: $(LIBS) -+all: $(DEVLIB) - - $(LIBS): $(OBJS) - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ -o $@ $(OBJS) $(LIBDEPS) -- $(LN) $@ $(DEVLIB) - --install: $(LIBS) -+$(DEVLIB): $(LIBS) -+ $(LN) $(LIBS) $@ -+ -+install: all - $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) - $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) - $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) -diff --git a/libmpathpersist/Makefile b/libmpathpersist/Makefile -index 21fdad80..9e869fdc 100644 ---- a/libmpathpersist/Makefile -+++ b/libmpathpersist/Makefile -@@ -11,15 +11,19 @@ LIBDEPS += -lpthread -ldevmapper -ldl -L$(multipathdir) -lmultipath \ - - OBJS = mpath_persist.o mpath_updatepr.o mpath_pr_ioctl.o - --all: $(LIBS) -+all: $(DEVLIB) man - - $(LIBS): $(OBJS) - $(CC) $(LDFLAGS) $(SHARED_FLAGS) $(LIBDEPS) -Wl,-soname=$@ -o $@ $(OBJS) -- $(LN) $(LIBS) $(DEVLIB) -+ -+$(DEVLIB): $(LIBS) -+ $(LN) $(LIBS) $@ -+ -+man: - $(GZIP) mpath_persistent_reserve_in.3 > mpath_persistent_reserve_in.3.gz - $(GZIP) mpath_persistent_reserve_out.3 > mpath_persistent_reserve_out.3.gz - --install: $(LIBS) -+install: all - $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) - $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) - $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(syslibdir) -diff --git a/libmultipath/Makefile b/libmultipath/Makefile -index 62ba16e8..40028556 100644 ---- a/libmultipath/Makefile -+++ b/libmultipath/Makefile -@@ -54,7 +54,7 @@ OBJS = memory.o parser.o vector.o devmapper.o callout.o \ - io_err_stat.o dm-generic.o generic.o foreign.o nvme-lib.o \ - libsg.o valid.o - --all: $(LIBS) -+all: $(DEVLIB) - - nvme-lib.o: nvme-lib.c nvme-ioctl.c nvme-ioctl.h - $(CC) $(CFLAGS) -Wno-unused-function -c -o $@ $< -@@ -74,9 +74,11 @@ nvme-ioctl.h: nvme/nvme-ioctl.h - - $(LIBS): $(OBJS) - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ -o $@ $(OBJS) $(LIBDEPS) -- $(LN) $@ $(DEVLIB) - --install: -+$(DEVLIB): $(LIBS) -+ $(LN) $(LIBS) $@ -+ -+install: all - $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) - $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) - $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(libdir) diff --git a/0155-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 100% rename from 0155-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch diff --git a/0009-libmultipath-create-separate-.so-for-unit-tests.patch b/0009-libmultipath-create-separate-.so-for-unit-tests.patch deleted file mode 100644 index a342425..0000000 --- a/0009-libmultipath-create-separate-.so-for-unit-tests.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Sat, 19 Sep 2020 00:29:45 +0200 -Subject: [PATCH] libmultipath: create separate .so for unit tests - -The unit tests use a lot of internal symbols that we don't want -to add to the ABI if we don't have to. As long as we don't -have to make incompatible changes to functions, we can work around -that by simply using a non-versioned library for the unit tests. -Therefore we add a seperate rule here. Do this before actually -adding a version script, to avoid breakage during bisection. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/Makefile | 7 +++++++ - tests/Makefile | 10 ++++++---- - 2 files changed, 13 insertions(+), 4 deletions(-) - -diff --git a/libmultipath/Makefile b/libmultipath/Makefile -index 40028556..12bf6300 100644 ---- a/libmultipath/Makefile -+++ b/libmultipath/Makefile -@@ -78,6 +78,13 @@ $(LIBS): $(OBJS) - $(DEVLIB): $(LIBS) - $(LN) $(LIBS) $@ - -+../tests/$(LIBS): $(OBJS) $(VERSION_SCRIPT) -+ $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=`basename $@` \ -+ -o $@ $(OBJS) $(LIBDEPS) -+ $(LN) $@ ${@:.so.0=.so} -+ -+test-lib: ../tests/$(LIBS) -+ - install: all - $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) - $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) -diff --git a/tests/Makefile b/tests/Makefile -index d26b3ce7..9658c9fd 100644 ---- a/tests/Makefile -+++ b/tests/Makefile -@@ -10,7 +10,7 @@ W_MISSING_INITIALIZERS := $(call TEST_MISSING_INITIALIZERS) - - CFLAGS += $(BIN_CFLAGS) -I$(multipathdir) -I$(mpathcmddir) \ - -Wno-unused-parameter $(W_MISSING_INITIALIZERS) --LIBDEPS += -L$(multipathdir) -L$(mpathcmddir) -lmultipath -lmpathcmd -lcmocka -+LIBDEPS += -L. -L$(mpathcmddir) -lmultipath -lmpathcmd -lcmocka - - TESTS := uevent parser util dmevents hwtable blacklist unaligned vpd pgpolicy \ - alias directio valid devt -@@ -68,7 +68,7 @@ lib/libchecktur.so: - - %.out: %-test lib/libchecktur.so - @echo == running $< == -- @LD_LIBRARY_PATH=$(multipathdir):$(mpathcmddir) ./$< >$@ -+ @LD_LIBRARY_PATH=.:$(mpathcmddir) ./$< >$@ - - %.vgr: %-test lib/libchecktur.so - @echo == running valgrind for $< == -@@ -78,7 +78,7 @@ lib/libchecktur.so: - OBJS = $(TESTS:%=%.o) $(HELPERS) - - test_clean: -- $(RM) $(TESTS:%=%.out) $(TESTS:%=%.vgr) -+ $(RM) $(TESTS:%=%.out) $(TESTS:%=%.vgr) *.so* - - valgrind_clean: - $(RM) $(TESTS:%=%.vgr) -@@ -98,12 +98,14 @@ dep_clean: - @sed -n 's/^.*__wrap_\([a-zA-Z0-9_]*\).*$$/-Wl,--wrap=\1/p' $< | \ - sort -u | tr '\n' ' ' >$@ - -+libmultipath.so.0: -+ $(MAKE) -C $(multipathdir) test-lib - - # COLON will get expanded during second expansion below - COLON:=: - .SECONDEXPANSION: - %-test: %.o %.o.wrap $$($$@_OBJDEPS) $$($$@_TESTDEPS) $$($$@_TESTDEPS$$(COLON).o=.o.wrap) \ -- $(multipathdir)/libmultipath.so Makefile -+ libmultipath.so.0 Makefile - $(CC) $(CFLAGS) -o $@ $(LDFLAGS) $< $($@_TESTDEPS) $($@_OBJDEPS) \ - $(LIBDEPS) $($@_LIBDEPS) \ - $(shell cat $<.wrap) $(foreach dep,$($@_TESTDEPS),$(shell cat $(dep).wrap)) diff --git a/0156-RH-make-parse_vpd_pg83-match-scsi_id-output.patch b/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch similarity index 97% rename from 0156-RH-make-parse_vpd_pg83-match-scsi_id-output.patch rename to 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch index 0e30d1f..0ab20c5 100644 --- a/0156-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +++ b/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch @@ -13,7 +13,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index f8044141..e6590d07 100644 +index ec99a7aa..2704270e 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c @@ -1135,12 +1135,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, diff --git a/0010-libmultipath-add-linker-version-script.patch b/0010-libmultipath-add-linker-version-script.patch deleted file mode 100644 index afbb4f3..0000000 --- a/0010-libmultipath-add-linker-version-script.patch +++ /dev/null @@ -1,300 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Sat, 19 Sep 2020 00:00:18 +0200 -Subject: [PATCH] libmultipath: add linker version script - -This version script documents the current ABI of libmultipath, -as used by multipath, multipathd, (lib)mpathpersist, and the -dynamically loaded libraries (prioritizers, checkers, and foreign). -The initial version string is set to "LIBMULTIPATH_1.0.0". - -This reduces the amount of exported symbols of libmultipath.so.0 -by more than a half (199 vs. 434). - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/Makefile | 7 +- - libmultipath/libmultipath.version | 248 ++++++++++++++++++++++++++++++ - 2 files changed, 253 insertions(+), 2 deletions(-) - create mode 100644 libmultipath/libmultipath.version - -diff --git a/libmultipath/Makefile b/libmultipath/Makefile -index 12bf6300..e7254f39 100644 ---- a/libmultipath/Makefile -+++ b/libmultipath/Makefile -@@ -6,6 +6,7 @@ include ../Makefile.inc - SONAME = 0 - DEVLIB = libmultipath.so - LIBS = $(DEVLIB).$(SONAME) -+VERSION_SCRIPT := libmultipath.version - - CFLAGS += $(LIB_CFLAGS) -I$(mpathcmddir) -I$(mpathpersistdir) -I$(nvmedir) - -@@ -72,8 +73,10 @@ nvme-ioctl.c: nvme/nvme-ioctl.c - nvme-ioctl.h: nvme/nvme-ioctl.h - $(call make_static,$<,$@) - --$(LIBS): $(OBJS) -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ -o $@ $(OBJS) $(LIBDEPS) -+ -+$(LIBS): $(OBJS) $(VERSION_SCRIPT) -+ $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ -+ -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) - - $(DEVLIB): $(LIBS) - $(LN) $(LIBS) $@ -diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version -new file mode 100644 -index 00000000..a6bf8218 ---- /dev/null -+++ b/libmultipath/libmultipath.version -@@ -0,0 +1,248 @@ -+/* -+ * Copyright (c) 2020 SUSE LLC -+ * SPDX-License-Identifier: GPL-2.0-or-later -+ * -+ * libmultipath ABI -+ * -+ * libmultipath doesn't have a stable ABI in the usual sense. In particular, -+ * the library does not attempt to ship different versions of the same symbol -+ * for backward compatibility. -+ * -+ * The ABI versioning only serves to avoid linking with a non-matching ABI, to -+ * cut down the set of exported symbols, and to describe it. -+ * The version string is LIBMULTIPATH_$MAJOR.$MINOR.$REL. -+ * -+ * Policy: -+ * -+ * * Bump $MAJOR for incompatible changes, like: -+ * - symbols removed -+ * - parameter list or return values changed for existing functions -+ * - externally visible data structures changed in incompatible ways -+ * (like offsets of previously existing struct members) -+ * In this case, the new version doesn't inherit the previous versions, -+ * because the new library doesn't provide the full previous ABI any more. -+ * All predecessors are merged into the new version. -+ * -+ * * Bump $MINOR for compatible changes, like adding symbols. -+ * The new version inherits the previous ones. -+ * -+ * * Bump $REL to describe deviations from upstream, e.g. in -+ * multipath-tools packages shipped by distributions. -+ * The new version inherits the previous ones. -+ */ -+ -+LIBMULTIPATH_1.0.0 { -+global: -+ /* symbols referenced by multipath and multipathd */ -+ add_foreign; -+ add_map_with_path; -+ adopt_paths; -+ alloc_multipath; -+ alloc_path; -+ alloc_path_with_pathinfo; -+ alloc_strvec; -+ change_foreign; -+ check_alias_settings; -+ checker_clear_message; -+ checker_disable; -+ checker_enable; -+ checker_is_sync; -+ checker_message; -+ checker_name; -+ checker_state_name; -+ check_foreign; -+ cleanup_checkers; -+ cleanup_foreign; -+ cleanup_lock; -+ cleanup_prio; -+ close_fd; -+ coalesce_paths; -+ convert_dev; -+ count_active_paths; -+ delete_all_foreign; -+ delete_foreign; -+ disassemble_map; -+ disassemble_status; -+ dlog; -+ dm_cancel_deferred_remove; -+ dm_drv_version; -+ dm_enablegroup; -+ dm_fail_path; -+ _dm_flush_map; -+ dm_flush_map_nopaths; -+ dm_flush_maps; -+ dm_geteventnr; -+ dm_get_info; -+ dm_get_major_minor; -+ dm_get_map; -+ dm_get_maps; -+ dm_get_multipath; -+ dm_get_status; -+ dm_get_uuid; -+ dm_is_mpath; -+ dm_mapname; -+ dm_map_present; -+ dm_queue_if_no_path; -+ dm_reassign; -+ dm_reinstate_path; -+ dm_simplecmd_noflush; -+ dm_switchgroup; -+ dm_tgt_version; -+ domap; -+ ensure_directories_exist; -+ extract_hwe_from_path; -+ filter_devnode; -+ filter_path; -+ filter_wwid; -+ find_mp_by_alias; -+ find_mp_by_minor; -+ find_mp_by_str; -+ find_mp_by_wwid; -+ find_mpe; -+ find_path_by_dev; -+ find_path_by_devt; -+ find_slot; -+ foreign_multipath_layout; -+ foreign_path_layout; -+ free_config; -+ free_multipath; -+ free_multipathvec; -+ free_path; -+ free_pathvec; -+ free_strvec; -+ get_monotonic_time; -+ get_multipath_layout; -+ get_path_layout; -+ get_pgpolicy_id; -+ get_refwwid; -+ get_state; -+ get_udev_device; -+ get_uid; -+ get_used_hwes; -+ group_by_prio; -+ init_checkers; -+ init_foreign; -+ init_prio; -+ io_err_stat_attr; -+ io_err_stat_handle_pathfail; -+ is_path_valid; -+ is_quote; -+ libmp_dm_task_create; -+ libmp_udev_set_sync_support; -+ load_config; -+ log_thread_reset; -+ log_thread_start; -+ log_thread_stop; -+ need_io_err_check; -+ normalize_timespec; -+ orphan_path; -+ orphan_paths; -+ parse_prkey_flags; -+ pathcount; -+ path_discovery; -+ path_get_tpgs; -+ pathinfo; -+ path_offline; -+ print_all_paths; -+ print_foreign_topology; -+ _print_multipath_topology; -+ pthread_cond_init_mono; -+ recv_packet; -+ recv_packet_from_client; -+ reinstate_paths; -+ remember_wwid; -+ remove_map; -+ remove_map_by_alias; -+ remove_maps; -+ remove_wwid; -+ replace_wwids; -+ reset_checker_classes; -+ select_all_tg_pt; -+ select_action; -+ select_find_multipaths_timeout; -+ select_no_path_retry; -+ select_path_group; -+ select_reservation_key; -+ send_packet; -+ set_max_fds; -+ __set_no_path_retry; -+ set_path_removed; -+ set_prkey; -+ setup_map; -+ setup_thread_attr; -+ should_multipath; -+ snprint_blacklist_report; -+ snprint_config; -+ snprint_devices; -+ snprint_foreign_multipaths; -+ snprint_foreign_paths; -+ snprint_foreign_topology; -+ _snprint_multipath; -+ snprint_multipath_header; -+ snprint_multipath_map_json; -+ _snprint_multipath_topology; -+ snprint_multipath_topology_json; -+ _snprint_path; -+ snprint_path_header; -+ snprint_status; -+ snprint_wildcards; -+ stop_io_err_stat_thread; -+ store_path; -+ store_pathinfo; -+ strchop; -+ strlcpy; -+ sync_map_state; -+ sysfs_attr_set_value; -+ sysfs_get_size; -+ sysfs_is_multipathed; -+ timespecsub; -+ trigger_paths_udev_change; -+ uevent_dispatch; -+ uevent_get_dm_str; -+ uevent_get_env_positive_int; -+ uevent_is_mpath; -+ uevent_listen; -+ update_mpp_paths; -+ update_multipath_status; -+ update_multipath_strings; -+ update_multipath_table; -+ update_pathvec_from_dm; -+ update_queue_mode_add_path; -+ update_queue_mode_del_path; -+ ux_socket_listen; -+ valid_alias; -+ vector_alloc; -+ vector_alloc_slot; -+ vector_del_slot; -+ vector_free; -+ vector_reset; -+ vector_set_slot; -+ verify_paths; -+ -+ /* checkers */ -+ sg_read; -+ -+ /* prioritizers */ -+ get_asymmetric_access_state; -+ get_prio_timeout; -+ get_target_port_group; -+ get_target_port_group_support; -+ libmp_nvme_ana_log; -+ libmp_nvme_get_nsid; -+ libmp_nvme_identify_ns; -+ log_nvme_errcode; -+ nvme_id_ctrl_ana; -+ snprint_host_wwnn; -+ snprint_host_wwpn; -+ snprint_path_serial; -+ snprint_tgt_wwnn; -+ snprint_tgt_wwpn; -+ sysfs_get_asymmetric_access_state; -+ -+ /* foreign */ -+ free_scandir_result; -+ sysfs_attr_get_value; -+ -+local: -+ *; -+}; diff --git a/0011-libmpathpersist-add-linker-version-script.patch b/0011-libmpathpersist-add-linker-version-script.patch deleted file mode 100644 index e43e068..0000000 --- a/0011-libmpathpersist-add-linker-version-script.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Sat, 19 Sep 2020 00:02:16 +0200 -Subject: [PATCH] libmpathpersist: add linker version script - -This defines the ABI of libmpathpersist in the current state. -The initial version is set to "LIBMPATHPERSIST_1.0.0". - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmpathpersist/Makefile | 6 +++-- - libmpathpersist/libmpathpersist.version | 32 +++++++++++++++++++++++++ - 2 files changed, 36 insertions(+), 2 deletions(-) - create mode 100644 libmpathpersist/libmpathpersist.version - -diff --git a/libmpathpersist/Makefile b/libmpathpersist/Makefile -index 9e869fdc..456ce4cf 100644 ---- a/libmpathpersist/Makefile -+++ b/libmpathpersist/Makefile -@@ -3,6 +3,7 @@ include ../Makefile.inc - SONAME = 0 - DEVLIB = libmpathpersist.so - LIBS = $(DEVLIB).$(SONAME) -+VERSION_SCRIPT := libmpathpersist.version - - CFLAGS += $(LIB_CFLAGS) -I$(multipathdir) -I$(mpathpersistdir) -I$(mpathcmddir) - -@@ -13,8 +14,9 @@ OBJS = mpath_persist.o mpath_updatepr.o mpath_pr_ioctl.o - - all: $(DEVLIB) man - --$(LIBS): $(OBJS) -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) $(LIBDEPS) -Wl,-soname=$@ -o $@ $(OBJS) -+$(LIBS): $(OBJS) $(VERSION_SCRIPT) -+ $(CC) $(LDFLAGS) $(SHARED_FLAGS) $(LIBDEPS) -Wl,-soname=$@ \ -+ -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) - - $(DEVLIB): $(LIBS) - $(LN) $(LIBS) $@ -diff --git a/libmpathpersist/libmpathpersist.version b/libmpathpersist/libmpathpersist.version -new file mode 100644 -index 00000000..dc648ce6 ---- /dev/null -+++ b/libmpathpersist/libmpathpersist.version -@@ -0,0 +1,32 @@ -+/* -+ * Copyright (c) 2020 SUSE LLC -+ * SPDX-License-Identifier: GPL-2.0-or-later -+ * -+ * libmpathpersist ABI -+ * -+ * The ABI of libmpathpersist is supposed to remain stable. Removing symbols -+ * or altering existing symbols' semantics is not allowed. When changing a -+ * a symbol, either use a new name, or explicit symver directives. -+ * -+ * See libmultipath.version for general policy about version numbers. -+ */ -+LIBMPATHPERSIST_1.0.0 { -+global: -+ -+ __mpath_persistent_reserve_in; -+ __mpath_persistent_reserve_out; -+ dumpHex; -+ mpath_alloc_prin_response; -+ mpath_lib_exit; -+ mpath_lib_init; -+ mpath_mx_alloc_len; -+ mpath_persistent_reserve_in; -+ mpath_persistent_reserve_init_vecs; -+ mpath_persistent_reserve_out; -+ mpath_persistent_reserve_free_vecs; -+ prin_do_scsi_ioctl; -+ prout_do_scsi_ioctl; -+ update_map_pr; -+ -+local: *; -+}; diff --git a/0012-libmpathcmd-add-linker-version-script.patch b/0012-libmpathcmd-add-linker-version-script.patch deleted file mode 100644 index 15ab67b..0000000 --- a/0012-libmpathcmd-add-linker-version-script.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 22 Sep 2020 12:54:20 +0200 -Subject: [PATCH] libmpathcmd: add linker version script - -For completeness, this isn't really necessary. -The version string is set to "LIBMPATHCMD_1.0.0". - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmpathcmd/Makefile | 6 ++++-- - libmpathcmd/libmpathcmd.version | 25 +++++++++++++++++++++++++ - 2 files changed, 29 insertions(+), 2 deletions(-) - create mode 100644 libmpathcmd/libmpathcmd.version - -diff --git a/libmpathcmd/Makefile b/libmpathcmd/Makefile -index 08ccb811..25910194 100644 ---- a/libmpathcmd/Makefile -+++ b/libmpathcmd/Makefile -@@ -3,6 +3,7 @@ include ../Makefile.inc - SONAME = 0 - DEVLIB = libmpathcmd.so - LIBS = $(DEVLIB).$(SONAME) -+VERSION_SCRIPT := libmpathcmd.version - - CFLAGS += $(LIB_CFLAGS) - -@@ -10,8 +11,9 @@ OBJS = mpath_cmd.o - - all: $(DEVLIB) - --$(LIBS): $(OBJS) -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ -o $@ $(OBJS) $(LIBDEPS) -+$(LIBS): $(OBJS) $(VERSION_SCRIPT) -+ $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ -+ -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) - - $(DEVLIB): $(LIBS) - $(LN) $(LIBS) $@ -diff --git a/libmpathcmd/libmpathcmd.version b/libmpathcmd/libmpathcmd.version -new file mode 100644 -index 00000000..f1006280 ---- /dev/null -+++ b/libmpathcmd/libmpathcmd.version -@@ -0,0 +1,25 @@ -+/* -+ * Copyright (c) 2020 SUSE LLC -+ * SPDX-License-Identifier: GPL-2.0-or-later -+ * -+ * libmpathcmd ABI -+ * -+ * The ABI of libmpathcmd is supposed to remain stable. Removing symbols -+ * or altering existing symbols' semantics is not allowed. When changing a -+ * a symbol, either use a new name, or explicit symver directives. -+ * -+ * See libmultipath.version for general policy about version numbers. -+ */ -+LIBMPATHCMD_1.0.0 { -+global: -+ __mpath_connect; -+ mpath_connect; -+ mpath_disconnect; -+ mpath_process_cmd; -+ mpath_recv_reply; -+ mpath_recv_reply_len; -+ mpath_recv_reply_data; -+ mpath_send_cmd; -+local: -+ *; -+}; diff --git a/0013-libmpathpersist-initialize-mpp-hwe-in-get_mpvec.patch b/0013-libmpathpersist-initialize-mpp-hwe-in-get_mpvec.patch deleted file mode 100644 index 73d5f55..0000000 --- a/0013-libmpathpersist-initialize-mpp-hwe-in-get_mpvec.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 25 Sep 2020 21:37:16 +0200 -Subject: [PATCH] libmpathpersist: initialize mpp->hwe in get_mpvec() - -In __mpath_persistent_reserve_out, we call select_all_tg_pt(), -which requires mpp->hwe to be set. Initialize it in get_mpvec(). - -Fixes: 5b54e77 ("mpathpersist: add all_tg_pt option") -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmpathpersist/mpath_persist.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c -index 1f9817ed..4b3f3e0d 100644 ---- a/libmpathpersist/mpath_persist.c -+++ b/libmpathpersist/mpath_persist.c -@@ -341,11 +341,13 @@ get_mpvec (vector curmp, vector pathvec, char * refwwid) - continue; - - if (update_multipath_table(mpp, pathvec, DI_CHECKER) != DMP_OK || -- update_multipath_status(mpp) != DMP_OK) { -+ update_multipath_status(mpp) != DMP_OK || -+ update_mpp_paths(mpp, pathvec)) { - condlog(1, "error parsing map %s", mpp->wwid); - remove_map(mpp, pathvec, curmp, PURGE_VEC); - i--; -- } -+ } else -+ extract_hwe_from_path(mpp); - } - return MPATH_PR_SUCCESS ; - } diff --git a/0014-multipathd-allow-shutdown-during-configure.patch b/0014-multipathd-allow-shutdown-during-configure.patch deleted file mode 100644 index 951cf53..0000000 --- a/0014-multipathd-allow-shutdown-during-configure.patch +++ /dev/null @@ -1,137 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 4 Jan 2019 16:59:49 +0100 -Subject: [PATCH] multipathd: allow shutdown during configure() - -reconfigure() can be a long-running operation; both initial path -discovery and initial map setup can take a long time. Allow -the main program to indicate that the process should be -interrupted if a shutdown signal was received. - -We take advantage of the dynamic linker's symbol lookup ordering -here. The default implementation of should_exit never returns -true, but callers (like multipathd) can override it. - -Cc: Chongyun Wu -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 6 ++++++ - libmultipath/discovery.c | 3 +++ - libmultipath/util.c | 5 +++++ - libmultipath/util.h | 1 + - multipathd/main.c | 17 +++++++++++++++++ - 5 files changed, 32 insertions(+) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index d7afc915..1c8aac08 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -1173,6 +1173,12 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, - - vector_foreach_slot (pathvec, pp1, k) { - int invalid; -+ -+ if (should_exit()) { -+ ret = CP_FAIL; -+ goto out; -+ } -+ - /* skip this path for some reason */ - - /* 1. if path has no unique id or wwid blacklisted */ -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index c2e1754c..e7084664 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -200,6 +200,9 @@ path_discovery (vector pathvec, int flag) - const char *devtype; - const char *devpath; - -+ if (should_exit()) -+ break; -+ - devpath = udev_list_entry_get_name(entry); - condlog(4, "Discover device %s", devpath); - udevice = udev_device_new_from_syspath(udev, devpath); -diff --git a/libmultipath/util.c b/libmultipath/util.c -index 1748eafe..1f977792 100644 ---- a/libmultipath/util.c -+++ b/libmultipath/util.c -@@ -445,3 +445,8 @@ void _log_bitfield_overflow(const char *f, unsigned int bit, unsigned int len) - { - condlog(0, "%s: bitfield overflow: %u >= %u", f, bit, len); - } -+ -+int should_exit(void) -+{ -+ return 0; -+} -diff --git a/libmultipath/util.h b/libmultipath/util.h -index 2b9703ac..ac19473e 100644 ---- a/libmultipath/util.h -+++ b/libmultipath/util.h -@@ -27,6 +27,7 @@ int parse_prkey(const char *ptr, uint64_t *prkey); - int parse_prkey_flags(const char *ptr, uint64_t *prkey, uint8_t *flags); - int safe_write(int fd, const void *buf, size_t count); - void set_max_fds(rlim_t max_fds); -+int should_exit(void); - - #define KERNEL_VERSION(maj, min, ptc) ((((maj) * 256) + (min)) * 256 + (ptc)) - #define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) -diff --git a/multipathd/main.c b/multipathd/main.c -index eedc6c10..fa53e963 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -141,6 +141,11 @@ static inline enum daemon_status get_running_state(void) - return st; - } - -+int should_exit(void) -+{ -+ return get_running_state() == DAEMON_SHUTDOWN; -+} -+ - /* - * global copy of vecs for use in sig handlers - */ -@@ -2570,6 +2575,9 @@ configure (struct vectors * vecs) - goto fail; - } - -+ if (should_exit()) -+ goto fail; -+ - conf = get_multipath_config(); - pthread_cleanup_push(put_multipath_config, conf); - vector_foreach_slot (vecs->pathvec, pp, i){ -@@ -2586,6 +2594,9 @@ configure (struct vectors * vecs) - goto fail; - } - -+ if (should_exit()) -+ goto fail; -+ - /* - * create new set of maps & push changed ones into dm - * In the first call, use FORCE_RELOAD_WEAK to avoid making -@@ -2600,6 +2611,9 @@ configure (struct vectors * vecs) - goto fail; - } - -+ if (should_exit()) -+ goto fail; -+ - /* - * may need to remove some maps which are no longer relevant - * e.g., due to blacklist changes in conf file -@@ -2611,6 +2625,9 @@ configure (struct vectors * vecs) - - dm_lib_release(); - -+ if (should_exit()) -+ goto fail; -+ - sync_maps_state(mpvec); - vector_foreach_slot(mpvec, mpp, i){ - if (remember_wwid(mpp->wwid) == 1) diff --git a/0015-multipathd-avoid-sending-READY-1-to-systemd-on-early.patch b/0015-multipathd-avoid-sending-READY-1-to-systemd-on-early.patch deleted file mode 100644 index d6a674b..0000000 --- a/0015-multipathd-avoid-sending-READY-1-to-systemd-on-early.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 15 Sep 2020 10:23:05 +0200 -Subject: [PATCH] multipathd: avoid sending "READY=1" to systemd on early - shutdown - -If multipathd gets a shutdown request during initial reconfigure(), -it shouldn't send "READY=1" to systemd. Ensure this by sending -"READY=1" via post_config_state(). - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 16 +++++++--------- - 1 file changed, 7 insertions(+), 9 deletions(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index fa53e963..53a22a43 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -189,6 +189,8 @@ static void do_sd_notify(enum daemon_status old_state, - { - char notify_msg[MSG_SIZE]; - const char *msg; -+ static bool startup_done = false; -+ - /* - * Checkerloop switches back and forth between idle and running state. - * No need to tell systemd each time. -@@ -205,6 +207,11 @@ static void do_sd_notify(enum daemon_status old_state, - - if (msg && !safe_sprintf(notify_msg, "STATUS=%s", msg)) - sd_notify(0, notify_msg); -+ -+ if (new_state == DAEMON_IDLE && !startup_done) { -+ sd_notify(0, "READY=1"); -+ startup_done = true; -+ } - } - #endif - -@@ -2903,9 +2910,6 @@ child (__attribute__((unused)) void *param) - struct vectors * vecs; - struct multipath * mpp; - int i; --#ifdef USE_SYSTEMD -- int startup_done = 0; --#endif - int rc; - int pid_fd = -1; - struct config *conf; -@@ -3065,12 +3069,6 @@ child (__attribute__((unused)) void *param) - } - lock_cleanup_pop(vecs->lock); - post_config_state(DAEMON_IDLE); --#ifdef USE_SYSTEMD -- if (!startup_done) { -- sd_notify(0, "READY=1"); -- startup_done = 1; -- } --#endif - } - } - diff --git a/0016-multipathd-send-STOPPING-1-to-systemd-on-shutdown.patch b/0016-multipathd-send-STOPPING-1-to-systemd-on-shutdown.patch deleted file mode 100644 index fbcfc2d..0000000 --- a/0016-multipathd-send-STOPPING-1-to-systemd-on-shutdown.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 15 Sep 2020 10:47:52 +0200 -Subject: [PATCH] multipathd: send "STOPPING=1" to systemd on shutdown - -Inform systemd that the daemon is shutting down. See sd_notify(3). - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 53a22a43..c264351c 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -208,7 +208,9 @@ static void do_sd_notify(enum daemon_status old_state, - if (msg && !safe_sprintf(notify_msg, "STATUS=%s", msg)) - sd_notify(0, notify_msg); - -- if (new_state == DAEMON_IDLE && !startup_done) { -+ if (new_state == DAEMON_SHUTDOWN) -+ sd_notify(0, "STOPPING=1"); -+ else if (new_state == DAEMON_IDLE && !startup_done) { - sd_notify(0, "READY=1"); - startup_done = true; - } diff --git a/0017-multipathd-send-RELOADING-1-to-systemd-on-DAEMON_CON.patch b/0017-multipathd-send-RELOADING-1-to-systemd-on-DAEMON_CON.patch deleted file mode 100644 index 8b2d70e..0000000 --- a/0017-multipathd-send-RELOADING-1-to-systemd-on-DAEMON_CON.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 15 Sep 2020 10:57:22 +0200 -Subject: [PATCH] multipathd: send "RELOADING=1" to systemd on DAEMON_CONFIGURE - state - -The logic is as follows: child() sets DAEMON_IDLE status after -DAEMON_CONFIGURE when reconfigure() has finished. The only other state change -that can race with that is DAEMON_SHUTDOWN. Other state changes will wait for -DAEMON_IDLE first (see set_config_state()). When DAEMON_CONFIGURE is entered, -and we are not just starting up, send a "RELOADING=1" message to -systemd. After that, we must send "READY=1" when we're done reloading. Also -do that on startup, when DAEMON_IDLE is set for the first time. -See sd_notify(3). - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index c264351c..e3f2328d 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -210,10 +210,11 @@ static void do_sd_notify(enum daemon_status old_state, - - if (new_state == DAEMON_SHUTDOWN) - sd_notify(0, "STOPPING=1"); -- else if (new_state == DAEMON_IDLE && !startup_done) { -+ else if (new_state == DAEMON_IDLE && old_state == DAEMON_CONFIGURE) { - sd_notify(0, "READY=1"); - startup_done = true; -- } -+ } else if (new_state == DAEMON_CONFIGURE && startup_done) -+ sd_notify(0, "RELOADING=1"); - } - #endif - diff --git a/0018-multipathd-use-volatile-qualifier-for-running_state.patch b/0018-multipathd-use-volatile-qualifier-for-running_state.patch deleted file mode 100644 index 7d9e6d2..0000000 --- a/0018-multipathd-use-volatile-qualifier-for-running_state.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 15 Sep 2020 12:44:59 +0200 -Subject: [PATCH] multipathd: use volatile qualifier for running_state - -While we access running_state only under the config_lock, -we sometimes do in a loop. Use the volatile qualifier to make -sure compilers can't optimize away the loads. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index e3f2328d..d081b3e9 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -126,7 +126,7 @@ int poll_dmevents = 0; - int poll_dmevents = 1; - #endif - /* Don't access this variable without holding config_lock */ --enum daemon_status running_state = DAEMON_INIT; -+volatile enum daemon_status running_state = DAEMON_INIT; - pid_t daemon_pid; - pthread_mutex_t config_lock = PTHREAD_MUTEX_INITIALIZER; - pthread_cond_t config_cond; diff --git a/0019-multipathd-generalize-and-fix-wait_for_state_change_.patch b/0019-multipathd-generalize-and-fix-wait_for_state_change_.patch deleted file mode 100644 index a08eacd..0000000 --- a/0019-multipathd-generalize-and-fix-wait_for_state_change_.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 15 Sep 2020 12:46:36 +0200 -Subject: [PATCH] multipathd: generalize and fix wait_for_state_change_if() - -It's unlikely but not impossible that other threads change the state -while we're waiting, and if we grab the lock again, it's still not -what we wanted. We need to continue waiting until either the condition -is met, or time timeout expired. - -Moreover, generalize this code so that it can also be used in -set_config_state(). - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 25 ++++++++++++++++++------- - 1 file changed, 18 insertions(+), 7 deletions(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index d081b3e9..1fb0ee62 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -223,6 +223,23 @@ static void config_cleanup(__attribute__((unused)) void *arg) - pthread_mutex_unlock(&config_lock); - } - -+#define __wait_for_state_change(condition, ms) \ -+ ({ \ -+ struct timespec tmo; \ -+ int rc = 0; \ -+ \ -+ if (condition) { \ -+ get_monotonic_time(&tmo); \ -+ tmo.tv_nsec += (ms) * 1000 * 1000; \ -+ normalize_timespec(&tmo); \ -+ do \ -+ rc = pthread_cond_timedwait( \ -+ &config_cond, &config_lock, &tmo); \ -+ while (rc == 0 && (condition)); \ -+ } \ -+ rc; \ -+ }) -+ - /* - * If the current status is @oldstate, wait for at most @ms milliseconds - * for the state to change, and return the new state, which may still be -@@ -232,20 +249,14 @@ enum daemon_status wait_for_state_change_if(enum daemon_status oldstate, - unsigned long ms) - { - enum daemon_status st; -- struct timespec tmo; - - if (oldstate == DAEMON_SHUTDOWN) - return DAEMON_SHUTDOWN; - - pthread_mutex_lock(&config_lock); - pthread_cleanup_push(config_cleanup, NULL); -+ __wait_for_state_change(running_state == oldstate, ms); - st = running_state; -- if (st == oldstate && clock_gettime(CLOCK_MONOTONIC, &tmo) == 0) { -- tmo.tv_nsec += ms * 1000 * 1000; -- normalize_timespec(&tmo); -- (void)pthread_cond_timedwait(&config_cond, &config_lock, &tmo); -- st = running_state; -- } - pthread_cleanup_pop(1); - return st; - } diff --git a/0020-multipathd-set_config_state-avoid-code-duplication.patch b/0020-multipathd-set_config_state-avoid-code-duplication.patch deleted file mode 100644 index e4dbd04..0000000 --- a/0020-multipathd-set_config_state-avoid-code-duplication.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 15 Sep 2020 12:48:55 +0200 -Subject: [PATCH] multipathd: set_config_state(): avoid code duplication - -Use __post_config_state() and __wait_for_state_change(). This -way __post_config_state() is the only place where running_state -is ever changed, and we avoid code duplication. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 23 +++++------------------ - 1 file changed, 5 insertions(+), 18 deletions(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 1fb0ee62..39aea4ad 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -292,27 +292,14 @@ int set_config_state(enum daemon_status state) - pthread_cleanup_push(config_cleanup, NULL); - pthread_mutex_lock(&config_lock); - if (running_state != state) { --#ifdef USE_SYSTEMD -- enum daemon_status old_state = running_state; --#endif - - if (running_state == DAEMON_SHUTDOWN) - rc = EINVAL; -- else if (running_state != DAEMON_IDLE) { -- struct timespec ts; -- -- get_monotonic_time(&ts); -- ts.tv_sec += 1; -- rc = pthread_cond_timedwait(&config_cond, -- &config_lock, &ts); -- } -- if (!rc && (running_state != DAEMON_SHUTDOWN)) { -- running_state = state; -- pthread_cond_broadcast(&config_cond); --#ifdef USE_SYSTEMD -- do_sd_notify(old_state, state); --#endif -- } -+ else -+ rc = __wait_for_state_change( -+ running_state != DAEMON_IDLE, 1000); -+ if (!rc) -+ __post_config_state(state); - } - pthread_cleanup_pop(1); - return rc; diff --git a/0021-multipathd-cancel-threads-early-during-shutdown.patch b/0021-multipathd-cancel-threads-early-during-shutdown.patch deleted file mode 100644 index 96f9b75..0000000 --- a/0021-multipathd-cancel-threads-early-during-shutdown.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 4 Jan 2019 17:10:25 +0100 -Subject: [PATCH] multipathd: cancel threads early during shutdown - -Cancel the other threads before taking vecs->lock. This avoids -delays during shutdown caused e.g. by the checker thread holding -the vecs lock. - -Note: this makes it possible that cancelled threads leak memory, -because they can now be cancelled before having released the vecs -lock. I believe this is acceptable, as only threads are affected -that are cancelled during multipathd shutdown. - -Cc: Chongyun Wu -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 17 +++++++++-------- - 1 file changed, 9 insertions(+), 8 deletions(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 39aea4ad..d1f8cc1b 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -3073,23 +3073,24 @@ child (__attribute__((unused)) void *param) - } - } - -- lock(&vecs->lock); -+ pthread_cancel(check_thr); -+ pthread_cancel(uevent_thr); -+ pthread_cancel(uxlsnr_thr); -+ pthread_cancel(uevq_thr); -+ if (poll_dmevents) -+ pthread_cancel(dmevent_thr); -+ - conf = get_multipath_config(); - queue_without_daemon = conf->queue_without_daemon; - put_multipath_config(conf); -+ -+ lock(&vecs->lock); - if (queue_without_daemon == QUE_NO_DAEMON_OFF) - vector_foreach_slot(vecs->mpvec, mpp, i) - dm_queue_if_no_path(mpp->alias, 0); - remove_maps_and_stop_waiters(vecs); - unlock(&vecs->lock); - -- pthread_cancel(check_thr); -- pthread_cancel(uevent_thr); -- pthread_cancel(uxlsnr_thr); -- pthread_cancel(uevq_thr); -- if (poll_dmevents) -- pthread_cancel(dmevent_thr); -- - pthread_join(check_thr, NULL); - pthread_join(uevent_thr, NULL); - pthread_join(uxlsnr_thr, NULL); diff --git a/0022-multipath-tools-don-t-call-dm_lib_release-any-more.patch b/0022-multipath-tools-don-t-call-dm_lib_release-any-more.patch deleted file mode 100644 index 447c884..0000000 --- a/0022-multipath-tools-don-t-call-dm_lib_release-any-more.patch +++ /dev/null @@ -1,162 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 15 Sep 2020 17:57:16 +0200 -Subject: [PATCH] multipath-tools: don't call dm_lib_release() any more - -The purpose of dm_lib_release() is to release stacked device node -operations in libdevmapper. This is functionality we don't need and -use any more, as we rely on udev to set up device nodes and symlinks. - -We always set DM_UDEV_DISABLE_LIBRARY_FALLBACK when we run dm tasks. -In the standard CREATE and REMOVE cases, libdevmapper doesn't -stack any operations if this flag is set. The only exceptions are - - a) RESUME operations with DM_ADD_NODE_ON_RESUME set. This happens -implicity when we create new maps - b) RENAME operations - -In both cases, we call dm_udev_wait() after the libdm operation, which -calls update_devs() and thus has the same effect as dm_lib_release(), -cleaning out stacked operations. - -OTOH, dm_lib_releases() accesses static variables in libdevmapper, so -calling it might be racy. - -Drop the calls to dm_lib_release(). - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - kpartx/kpartx.c | 1 - - libmpathpersist/mpath_persist.c | 1 - - multipath/main.c | 1 - - multipathd/cli_handlers.c | 2 -- - multipathd/main.c | 15 ++------------- - 5 files changed, 2 insertions(+), 18 deletions(-) - -diff --git a/kpartx/kpartx.c b/kpartx/kpartx.c -index 4a0aae93..6a7933fa 100644 ---- a/kpartx/kpartx.c -+++ b/kpartx/kpartx.c -@@ -681,7 +681,6 @@ main(int argc, char **argv){ - } - - end: -- dm_lib_release(); - dm_lib_exit(); - - return r; -diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c -index 4b3f3e0d..cc4a088d 100644 ---- a/libmpathpersist/mpath_persist.c -+++ b/libmpathpersist/mpath_persist.c -@@ -56,7 +56,6 @@ mpath_lib_init (void) - int - mpath_lib_exit (struct config *conf) - { -- dm_lib_release(); - dm_lib_exit(); - cleanup_prio(); - cleanup_checkers(); -diff --git a/multipath/main.c b/multipath/main.c -index 9e920d89..dc4974b9 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -1063,7 +1063,6 @@ main (int argc, char *argv[]) - condlog(3, "restart multipath configuration process"); - - out: -- dm_lib_release(); - dm_lib_exit(); - - cleanup_foreign(); -diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c -index 235e2a2e..54635738 100644 ---- a/multipathd/cli_handlers.c -+++ b/multipathd/cli_handlers.c -@@ -860,7 +860,6 @@ cli_add_map (void * v, char ** reply, int * len, void * data) - != CP_OK) - condlog(2, "%s: coalesce_paths failed", - param); -- dm_lib_release(); - FREE(refwwid); - } - } /*we attempt to create device only once*/ -@@ -1032,7 +1031,6 @@ cli_resize(void *v, char **reply, int *len, void *data) - if (resize_map(mpp, size, vecs) != 0) - return 1; - -- dm_lib_release(); - if (setup_multipath(vecs, mpp) != 0) - return 1; - sync_map_state(mpp); -diff --git a/multipathd/main.c b/multipathd/main.c -index d1f8cc1b..5cc34357 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -510,7 +510,6 @@ retry: - sleep(1); - goto retry; - } -- dm_lib_release(); - - fail: - if (new_map && (retries < 0 || wait_for_events(mpp, vecs))) { -@@ -611,10 +610,8 @@ coalesce_maps(struct vectors *vecs, vector nmpv) - vector_del_slot(ompv, i); - i--; - } -- else { -- dm_lib_release(); -+ else - condlog(2, "%s devmap removed", ompp->alias); -- } - } else if (reassign_maps) { - condlog(3, "%s: Reassign existing device-mapper" - " devices", ompp->alias); -@@ -660,10 +657,8 @@ flush_map(struct multipath * mpp, struct vectors * vecs, int nopaths) - } - return r; - } -- else { -- dm_lib_release(); -+ else - condlog(2, "%s: map flushed", mpp->alias); -- } - - orphan_paths(vecs->pathvec, mpp, "map flushed"); - remove_map_and_stop_waiter(mpp, vecs); -@@ -1080,7 +1075,6 @@ rescan: - else - goto fail_map; - } -- dm_lib_release(); - - if ((mpp->action == ACT_CREATE || - (mpp->action == ACT_NOTHING && start_waiter && !mpp->waiter)) && -@@ -1947,8 +1941,6 @@ int reload_and_sync_map(struct multipath *mpp, - { - if (reload_map(vecs, mpp, refresh, 1)) - return 1; -- -- dm_lib_release(); - if (setup_multipath(vecs, mpp) != 0) - return 2; - sync_map_state(mpp); -@@ -2631,8 +2623,6 @@ configure (struct vectors * vecs) - goto fail; - } - -- dm_lib_release(); -- - if (should_exit()) - goto fail; - -@@ -3115,7 +3105,6 @@ child (__attribute__((unused)) void *param) - if (poll_dmevents) - cleanup_dmevent_waiter(); - -- dm_lib_release(); - dm_lib_exit(); - - /* We're done here */ diff --git a/0023-libmultipath-devmapper-refactor-libdm-version-determ.patch b/0023-libmultipath-devmapper-refactor-libdm-version-determ.patch deleted file mode 100644 index 76a14eb..0000000 --- a/0023-libmultipath-devmapper-refactor-libdm-version-determ.patch +++ /dev/null @@ -1,503 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 15 Sep 2020 23:12:15 +0200 -Subject: [PATCH] libmultipath: devmapper: refactor libdm version determination - -As one step towards bundling all possibly racy libdm init calls into a single -function, split the code for determining and checking versions of -libdm and kernel components. Provide a generic helper -libmp_get_version() that makes sure the versions are "lazily" initialized. - -External callers may use dm_prereq(), like before. -Minor API change: dm_prereq() does not nullify the argument any more -if an error is encountered. - -Remove the conf->version field, which isn't needed any more after this -change. This makes it necessary to fixup the hwtable test. Also, it -represents an incompatible ABI change as offsets in "struct config" are -changed, and two symbols removed. Bump the ABI major version to 2. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/config.h | 1 - - libmultipath/devmapper.c | 162 ++++++++++++++++++++---------- - libmultipath/devmapper.h | 10 +- - libmultipath/libmultipath.version | 5 +- - libmultipath/propsel.c | 10 +- - multipathd/dmevents.c | 2 +- - multipathd/main.c | 1 - - tests/Makefile | 2 +- - tests/hwtable.c | 3 - - tests/test-lib.c | 13 +++ - 10 files changed, 141 insertions(+), 68 deletions(-) - -diff --git a/libmultipath/config.h b/libmultipath/config.h -index 290aea58..7af19844 100644 ---- a/libmultipath/config.h -+++ b/libmultipath/config.h -@@ -192,7 +192,6 @@ struct config { - int find_multipaths_timeout; - int marginal_pathgroups; - int skip_delegate; -- unsigned int version[3]; - unsigned int sequence_nr; - - char * multipath_dir; -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index 0bc1d16e..3e36129b 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -26,6 +26,7 @@ - #include "sysfs.h" - #include "config.h" - #include "wwids.h" -+#include "version.h" - - #include "log_pthread.h" - #include -@@ -34,7 +35,13 @@ - #define MAX_WAIT 5 - #define LOOPS_PER_SEC 5 - -+#define INVALID_VERSION ~0U -+static unsigned int dm_library_version[3] = { INVALID_VERSION, }; -+static unsigned int dm_kernel_version[3] = { INVALID_VERSION, }; -+static unsigned int dm_mpath_target_version[3] = { INVALID_VERSION, }; -+ - static pthread_once_t dm_initialized = PTHREAD_ONCE_INIT; -+static pthread_once_t versions_initialized = PTHREAD_ONCE_INIT; - - static int dm_conf_verbosity; - -@@ -102,7 +109,7 @@ dm_write_log (int level, const char *file, int line, const char *f, ...) - return; - } - --void dm_init(int v) -+static void dm_init(int v) - { - /* - * This maps libdm's standard loglevel _LOG_WARN (= 4), which is rather -@@ -112,61 +119,68 @@ void dm_init(int v) - dm_log_init(&dm_write_log); - } - -+static void init_dm_library_version(void) -+{ -+ char version[64]; -+ unsigned int v[3]; -+ -+ dm_get_library_version(version, sizeof(version)); -+ if (sscanf(version, "%u.%u.%u ", &v[0], &v[1], &v[2]) != 3) { -+ condlog(0, "invalid libdevmapper version %s", version); -+ return; -+ } -+ memcpy(dm_library_version, v, sizeof(dm_library_version)); -+ condlog(3, "libdevmapper version %u.%.2u.%.2u", -+ dm_library_version[0], dm_library_version[1], -+ dm_library_version[2]); -+} -+ - static int - dm_lib_prereq (void) - { -- char version[64]; -- int v[3]; -+ - #if defined(LIBDM_API_HOLD_CONTROL) -- int minv[3] = {1, 2, 111}; -+ unsigned int minv[3] = {1, 2, 111}; - #elif defined(LIBDM_API_GET_ERRNO) -- int minv[3] = {1, 2, 99}; -+ unsigned int minv[3] = {1, 2, 99}; - #elif defined(LIBDM_API_DEFERRED) -- int minv[3] = {1, 2, 89}; -+ unsigned int minv[3] = {1, 2, 89}; - #elif defined(DM_SUBSYSTEM_UDEV_FLAG0) -- int minv[3] = {1, 2, 82}; -+ unsigned int minv[3] = {1, 2, 82}; - #elif defined(LIBDM_API_COOKIE) -- int minv[3] = {1, 2, 38}; -+ unsigned int minv[3] = {1, 2, 38}; - #else -- int minv[3] = {1, 2, 8}; -+ unsigned int minv[3] = {1, 2, 8}; - #endif - -- dm_get_library_version(version, sizeof(version)); -- condlog(3, "libdevmapper version %s", version); -- if (sscanf(version, "%d.%d.%d ", &v[0], &v[1], &v[2]) != 3) { -- condlog(0, "invalid libdevmapper version %s", version); -- return 1; -- } -- -- if VERSION_GE(v, minv) -+ if (VERSION_GE(dm_library_version, minv)) - return 0; -- condlog(0, "libdevmapper version must be >= %d.%.2d.%.2d", -+ condlog(0, "libdevmapper version must be >= %u.%.2u.%.2u", - minv[0], minv[1], minv[2]); - return 1; - } - --int --dm_drv_version(unsigned int *v) -+static void init_dm_drv_version(void) - { - char buff[64]; -- -- v[0] = 0; -- v[1] = 0; -- v[2] = 0; -+ unsigned int v[3]; - - if (!dm_driver_version(buff, sizeof(buff))) { - condlog(0, "cannot get kernel dm version"); -- return 1; -+ return; - } - if (sscanf(buff, "%u.%u.%u ", &v[0], &v[1], &v[2]) != 3) { - condlog(0, "invalid kernel dm version '%s'", buff); -- return 1; -+ return; - } -- return 0; -+ memcpy(dm_kernel_version, v, sizeof(dm_library_version)); -+ condlog(3, "kernel device mapper v%u.%u.%u", -+ dm_kernel_version[0], -+ dm_kernel_version[1], -+ dm_kernel_version[2]); - } - --int --dm_tgt_version (unsigned int * version, char * str) -+static int dm_tgt_version (unsigned int *version, char *str) - { - int r = 2; - struct dm_task *dmt; -@@ -174,10 +188,11 @@ dm_tgt_version (unsigned int * version, char * str) - struct dm_versions *last_target; - unsigned int *v; - -- version[0] = 0; -- version[1] = 0; -- version[2] = 0; -- -+ /* -+ * We have to call dm_task_create() and not libmp_dm_task_create() -+ * here to avoid a recursive invocation of -+ * pthread_once(&dm_initialized), which would cause a deadlock. -+ */ - if (!(dmt = dm_task_create(DM_DEVICE_LIST_VERSIONS))) - return 1; - -@@ -213,26 +228,25 @@ out: - return r; - } - --static int --dm_tgt_prereq (unsigned int *ver) -+static void init_dm_mpath_version(void) - { -- unsigned int minv[3] = {1, 0, 3}; -- unsigned int version[3] = {0, 0, 0}; -- unsigned int * v = version; -- -- if (dm_tgt_version(v, TGT_MPATH)) { -- /* in doubt return not capable */ -- return 1; -- } -+ if (!dm_tgt_version(dm_mpath_target_version, TGT_MPATH)) -+ condlog(3, "DM multipath kernel driver v%u.%u.%u", -+ dm_mpath_target_version[0], -+ dm_mpath_target_version[1], -+ dm_mpath_target_version[2]); -+} - -- /* test request based multipath capability */ -- condlog(3, "DM multipath kernel driver v%u.%u.%u", -- v[0], v[1], v[2]); -+static int dm_tgt_prereq (unsigned int *ver) -+{ -+ unsigned int minv[3] = {1, 0, 3}; - -- if (VERSION_GE(v, minv)) { -- ver[0] = v[0]; -- ver[1] = v[1]; -- ver[2] = v[2]; -+ if (VERSION_GE(dm_mpath_target_version, minv)) { -+ if (ver) { -+ ver[0] = dm_mpath_target_version[0]; -+ ver[1] = dm_mpath_target_version[1]; -+ ver[2] = dm_mpath_target_version[2]; -+ } - return 0; - } - -@@ -241,13 +255,60 @@ dm_tgt_prereq (unsigned int *ver) - return 1; - } - -+static void _init_versions(void) -+{ -+ dlog(logsink, 3, VERSION_STRING); -+ init_dm_library_version(); -+ init_dm_drv_version(); -+ init_dm_mpath_version(); -+} -+ -+static int init_versions(void) { -+ pthread_once(&versions_initialized, _init_versions); -+ return (dm_library_version[0] == INVALID_VERSION || -+ dm_kernel_version[0] == INVALID_VERSION || -+ dm_mpath_target_version[0] == INVALID_VERSION); -+} -+ - int dm_prereq(unsigned int *v) - { -+ if (init_versions()) -+ return 1; - if (dm_lib_prereq()) - return 1; - return dm_tgt_prereq(v); - } - -+int libmp_get_version(int which, unsigned int version[3]) -+{ -+ unsigned int *src_version; -+ -+ init_versions(); -+ switch (which) { -+ case DM_LIBRARY_VERSION: -+ src_version = dm_library_version; -+ break; -+ case DM_KERNEL_VERSION: -+ src_version = dm_kernel_version; -+ break; -+ case DM_MPATH_TARGET_VERSION: -+ src_version = dm_mpath_target_version; -+ break; -+ case MULTIPATH_VERSION: -+ version[0] = (VERSION_CODE >> 16) & 0xff; -+ version[1] = (VERSION_CODE >> 8) & 0xff; -+ version[2] = VERSION_CODE & 0xff; -+ return 0; -+ default: -+ condlog(0, "%s: invalid value for 'which'", __func__); -+ return 1; -+ } -+ if (src_version[0] == INVALID_VERSION) -+ return 1; -+ memcpy(version, src_version, 3 * sizeof(*version)); -+ return 0; -+} -+ - static int libmp_dm_udev_sync = 0; - - void libmp_udev_set_sync_support(int on) -@@ -265,7 +326,6 @@ static void libmp_dm_init(void) - exit(1); - conf = get_multipath_config(); - verbosity = conf->verbosity; -- memcpy(conf->version, version, sizeof(version)); - put_multipath_config(conf); - dm_init(verbosity); - #ifdef LIBDM_API_HOLD_CONTROL -diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h -index f469c98a..a0bcd137 100644 ---- a/libmultipath/devmapper.h -+++ b/libmultipath/devmapper.h -@@ -33,13 +33,10 @@ enum { - DMP_NOT_FOUND, - }; - --void dm_init(int verbosity); - int dm_prereq(unsigned int *v); - void skip_libmp_dm_init(void); - void libmp_udev_set_sync_support(int on); - struct dm_task *libmp_dm_task_create(int task); --int dm_drv_version (unsigned int * version); --int dm_tgt_version (unsigned int * version, char * str); - int dm_simplecmd_flush (int, const char *, uint16_t); - int dm_simplecmd_noflush (int, const char *, uint16_t); - int dm_addmap_create (struct multipath *mpp, char *params); -@@ -89,6 +86,13 @@ struct multipath *dm_get_multipath(const char *name); - #include - #define dm_task_get_errno(x) errno - #endif -+enum { -+ DM_LIBRARY_VERSION, -+ DM_KERNEL_VERSION, -+ DM_MPATH_TARGET_VERSION, -+ MULTIPATH_VERSION -+}; -+int libmp_get_version(int which, unsigned int version[3]); - - #define dm_log_error(lvl, cmd, dmt) \ - condlog(lvl, "%s: libdm task=%d error: %s", __func__, \ -diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version -index a6bf8218..ab5bb0ad 100644 ---- a/libmultipath/libmultipath.version -+++ b/libmultipath/libmultipath.version -@@ -31,7 +31,7 @@ - * The new version inherits the previous ones. - */ - --LIBMULTIPATH_1.0.0 { -+LIBMULTIPATH_2.0.0 { - global: - /* symbols referenced by multipath and multipathd */ - add_foreign; -@@ -65,7 +65,6 @@ global: - disassemble_status; - dlog; - dm_cancel_deferred_remove; -- dm_drv_version; - dm_enablegroup; - dm_fail_path; - _dm_flush_map; -@@ -87,7 +86,6 @@ global: - dm_reinstate_path; - dm_simplecmd_noflush; - dm_switchgroup; -- dm_tgt_version; - domap; - ensure_directories_exist; - extract_hwe_from_path; -@@ -128,6 +126,7 @@ global: - is_path_valid; - is_quote; - libmp_dm_task_create; -+ libmp_get_version; - libmp_udev_set_sync_support; - load_config; - log_thread_reset; -diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c -index 40201344..3f2c2cfa 100644 ---- a/libmultipath/propsel.c -+++ b/libmultipath/propsel.c -@@ -735,9 +735,10 @@ out: - - int select_minio(struct config *conf, struct multipath *mp) - { -- unsigned int minv_dmrq[3] = {1, 1, 0}; -+ unsigned int minv_dmrq[3] = {1, 1, 0}, version[3]; - -- if (VERSION_GE(conf->version, minv_dmrq)) -+ if (!libmp_get_version(DM_MPATH_TARGET_VERSION, version) -+ && VERSION_GE(version, minv_dmrq)) - return select_minio_rq(conf, mp); - else - return select_minio_bio(conf, mp); -@@ -820,9 +821,10 @@ out: - int select_retain_hwhandler(struct config *conf, struct multipath *mp) - { - const char *origin; -- unsigned int minv_dm_retain[3] = {1, 5, 0}; -+ unsigned int minv_dm_retain[3] = {1, 5, 0}, version[3]; - -- if (!VERSION_GE(conf->version, minv_dm_retain)) { -+ if (!libmp_get_version(DM_MPATH_TARGET_VERSION, version) && -+ !VERSION_GE(version, minv_dm_retain)) { - mp->retain_hwhandler = RETAIN_HWHANDLER_OFF; - origin = "(setting: WARNING, requires kernel dm-mpath version >= 1.5.0)"; - goto out; -diff --git a/multipathd/dmevents.c b/multipathd/dmevents.c -index 5f2d210d..fc97c8a2 100644 ---- a/multipathd/dmevents.c -+++ b/multipathd/dmevents.c -@@ -60,7 +60,7 @@ int dmevent_poll_supported(void) - { - unsigned int v[3]; - -- if (dm_drv_version(v)) -+ if (libmp_get_version(DM_KERNEL_VERSION, v)) - return 0; - - if (VERSION_GE(v, DM_VERSION_FOR_ARM_POLL)) -diff --git a/multipathd/main.c b/multipathd/main.c -index 5cc34357..00b66ba4 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -2709,7 +2709,6 @@ reconfigure (struct vectors * vecs) - /* Re-read any timezone changes */ - tzset(); - -- dm_tgt_version(conf->version, TGT_MPATH); - if (verbosity) - conf->verbosity = verbosity; - if (bindings_read_only) -diff --git a/tests/Makefile b/tests/Makefile -index 9658c9fd..78777bec 100644 ---- a/tests/Makefile -+++ b/tests/Makefile -@@ -43,7 +43,7 @@ endif - dmevents-test_LIBDEPS = -lpthread -ldevmapper -lurcu - hwtable-test_TESTDEPS := test-lib.o - hwtable-test_OBJDEPS := ../libmultipath/discovery.o ../libmultipath/blacklist.o \ -- ../libmultipath/structs.o -+ ../libmultipath/structs.o ../libmultipath/propsel.o - hwtable-test_LIBDEPS := -ludev -lpthread -ldl - blacklist-test_TESTDEPS := test-log.o - blacklist-test_OBJDEPS := ../libmultipath/blacklist.o -diff --git a/tests/hwtable.c b/tests/hwtable.c -index 12660da2..57f832b7 100644 ---- a/tests/hwtable.c -+++ b/tests/hwtable.c -@@ -30,8 +30,6 @@ - #define N_CONF_FILES 2 - - static const char tmplate[] = "/tmp/hwtable-XXXXXX"; --/* pretend new dm, use minio_rq */ --static const unsigned int dm_tgt_version[3] = { 1, 1, 1 }; - - struct key_value { - const char *key; -@@ -360,7 +358,6 @@ static void write_device(FILE *ff, int nkv, const struct key_value *kv) - assert_ptr_not_equal(__cf, NULL); \ - assert_ptr_not_equal(__cf->hwtable, NULL); \ - __cf->verbosity = VERBOSITY; \ -- memcpy(&__cf->version, dm_tgt_version, sizeof(__cf->version)); \ - __cf; }) - - #define FREE_CONFIG(conf) do { \ -diff --git a/tests/test-lib.c b/tests/test-lib.c -index b7c09cc2..e7663f9a 100644 ---- a/tests/test-lib.c -+++ b/tests/test-lib.c -@@ -56,6 +56,15 @@ int __wrap_execute_program(char *path, char *value, int len) - return 0; - } - -+int __wrap_libmp_get_version(int which, unsigned int version[3]) -+{ -+ unsigned int *vers = mock_ptr_type(unsigned int *); -+ -+ condlog(4, "%s: %d", __func__, which); -+ memcpy(version, vers, 3 * sizeof(unsigned int)); -+ return 0; -+} -+ - struct udev_list_entry - *__wrap_udev_device_get_properties_list_entry(struct udev_device *ud) - { -@@ -339,6 +348,8 @@ struct multipath *__mock_multipath(struct vectors *vecs, struct path *pp) - struct multipath *mp; - struct config *conf; - struct mocked_path mop; -+ /* pretend new dm, use minio_rq, */ -+ static const unsigned int fake_dm_tgt_version[3] = { 1, 1, 1 }; - - mocked_path_from_path(&mop, pp); - /* pathinfo() call in adopt_paths */ -@@ -351,7 +362,9 @@ struct multipath *__mock_multipath(struct vectors *vecs, struct path *pp) - conf = get_multipath_config(); - select_pgpolicy(conf, mp); - select_no_path_retry(conf, mp); -+ will_return(__wrap_libmp_get_version, fake_dm_tgt_version); - select_retain_hwhandler(conf, mp); -+ will_return(__wrap_libmp_get_version, fake_dm_tgt_version); - select_minio(conf, mp); - put_multipath_config(conf); - diff --git a/0024-libmultipath-protect-racy-libdevmapper-calls-with-a-.patch b/0024-libmultipath-protect-racy-libdevmapper-calls-with-a-.patch deleted file mode 100644 index f8dd1e3..0000000 --- a/0024-libmultipath-protect-racy-libdevmapper-calls-with-a-.patch +++ /dev/null @@ -1,434 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 15 Sep 2020 23:38:48 +0200 -Subject: [PATCH] libmultipath: protect racy libdevmapper calls with a mutex - -dm_udev_wait() and dm_task_run() may access global / static state -in libdevmapper. They need to be protected by a lock in in our -multithreaded library. - -The modified call sequence requires fixing the dmevents test: -devmapper.c must be added to dmevents-test_OBJDEPS to catch calls -to dm_task_run(). Also, the call to dmevent_poll_supported() in -setup() will cause init_versions() to be called, which requires -bypassing the wrappers in the test setup phase. - -Cc: lixiaokeng@huawei.com - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/devmapper.c | 73 +++++++++++++++++++------------ - libmultipath/devmapper.h | 2 + - libmultipath/libmultipath.version | 6 +++ - libmultipath/util.c | 5 +++ - libmultipath/util.h | 1 + - multipathd/dmevents.c | 2 +- - multipathd/waiter.c | 2 +- - tests/Makefile | 1 + - tests/dmevents.c | 12 +++++ - 9 files changed, 75 insertions(+), 29 deletions(-) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index 3e36129b..4eb6f539 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -42,6 +42,7 @@ static unsigned int dm_mpath_target_version[3] = { INVALID_VERSION, }; - - static pthread_once_t dm_initialized = PTHREAD_ONCE_INIT; - static pthread_once_t versions_initialized = PTHREAD_ONCE_INIT; -+static pthread_mutex_t libmp_dm_lock = PTHREAD_MUTEX_INITIALIZER; - - static int dm_conf_verbosity; - -@@ -59,16 +60,34 @@ static inline int dm_task_set_cookie(struct dm_task *dmt, uint32_t *c, int a) - return 1; - } - --void dm_udev_wait(unsigned int c) -+static void libmp_udev_wait(unsigned int c) - { - } - --void dm_udev_set_sync_support(int c) -+static void dm_udev_set_sync_support(int c) - { - } -- -+#else -+static void libmp_udev_wait(unsigned int c) -+{ -+ pthread_mutex_lock(&libmp_dm_lock); -+ pthread_cleanup_push(cleanup_mutex, &libmp_dm_lock); -+ dm_udev_wait(c); -+ pthread_cleanup_pop(1); -+} - #endif - -+int libmp_dm_task_run(struct dm_task *dmt) -+{ -+ int r; -+ -+ pthread_mutex_lock(&libmp_dm_lock); -+ pthread_cleanup_push(cleanup_mutex, &libmp_dm_lock); -+ r = dm_task_run(dmt); -+ pthread_cleanup_pop(1); -+ return r; -+} -+ - __attribute__((format(printf, 4, 5))) static void - dm_write_log (int level, const char *file, int line, const char *f, ...) - { -@@ -198,7 +217,7 @@ static int dm_tgt_version (unsigned int *version, char *str) - - dm_task_no_open_count(dmt); - -- if (!dm_task_run(dmt)) { -+ if (!libmp_dm_task_run(dmt)) { - dm_log_error(2, DM_DEVICE_LIST_VERSIONS, dmt); - condlog(0, "Can not communicate with kernel DM"); - goto out; -@@ -382,12 +401,12 @@ dm_simplecmd (int task, const char *name, int no_flush, int need_sync, uint16_t - DM_UDEV_DISABLE_LIBRARY_FALLBACK | udev_flags)) - goto out; - -- r = dm_task_run (dmt); -+ r = libmp_dm_task_run (dmt); - if (!r) - dm_log_error(2, task, dmt); - - if (udev_wait_flag) -- dm_udev_wait(cookie); -+ libmp_udev_wait(cookie); - out: - dm_task_destroy (dmt); - return r; -@@ -474,12 +493,12 @@ dm_addmap (int task, const char *target, struct multipath *mpp, - !dm_task_set_cookie(dmt, &cookie, udev_flags)) - goto freeout; - -- r = dm_task_run (dmt); -+ r = libmp_dm_task_run (dmt); - if (!r) - dm_log_error(2, task, dmt); - - if (task == DM_DEVICE_CREATE) -- dm_udev_wait(cookie); -+ libmp_udev_wait(cookie); - freeout: - if (prefixed_uuid) - FREE(prefixed_uuid); -@@ -589,7 +608,7 @@ do_get_info(const char *name, struct dm_info *info) - - dm_task_no_open_count(dmt); - -- if (!dm_task_run(dmt)) { -+ if (!libmp_dm_task_run(dmt)) { - dm_log_error(3, DM_DEVICE_INFO, dmt); - goto out; - } -@@ -630,7 +649,7 @@ int dm_get_map(const char *name, unsigned long long *size, char *outparams) - dm_task_no_open_count(dmt); - - errno = 0; -- if (!dm_task_run(dmt)) { -+ if (!libmp_dm_task_run(dmt)) { - dm_log_error(3, DM_DEVICE_TABLE, dmt); - if (dm_task_get_errno(dmt) == ENXIO) - r = DMP_NOT_FOUND; -@@ -672,7 +691,7 @@ dm_get_prefixed_uuid(const char *name, char *uuid, int uuid_len) - if (!dm_task_set_name (dmt, name)) - goto uuidout; - -- if (!dm_task_run(dmt)) { -+ if (!libmp_dm_task_run(dmt)) { - dm_log_error(3, DM_DEVICE_INFO, dmt); - goto uuidout; - } -@@ -743,7 +762,7 @@ int dm_get_status(const char *name, char *outstatus) - dm_task_no_open_count(dmt); - - errno = 0; -- if (!dm_task_run(dmt)) { -+ if (!libmp_dm_task_run(dmt)) { - dm_log_error(3, DM_DEVICE_STATUS, dmt); - if (dm_task_get_errno(dmt) == ENXIO) - r = DMP_NOT_FOUND; -@@ -796,7 +815,7 @@ int dm_type(const char *name, char *type) - - dm_task_no_open_count(dmt); - -- if (!dm_task_run(dmt)) { -+ if (!libmp_dm_task_run(dmt)) { - dm_log_error(3, DM_DEVICE_TABLE, dmt); - goto out; - } -@@ -840,7 +859,7 @@ int dm_is_mpath(const char *name) - - dm_task_no_open_count(dmt); - -- if (!dm_task_run(dmt)) { -+ if (!libmp_dm_task_run(dmt)) { - dm_log_error(3, DM_DEVICE_TABLE, dmt); - goto out_task; - } -@@ -904,7 +923,7 @@ dm_map_present_by_uuid(const char *uuid) - if (!dm_task_set_uuid(dmt, prefixed_uuid)) - goto out_task; - -- if (!dm_task_run(dmt)) { -+ if (!libmp_dm_task_run(dmt)) { - dm_log_error(3, DM_DEVICE_INFO, dmt); - goto out_task; - } -@@ -950,7 +969,7 @@ dm_get_opencount (const char * mapname) - if (!dm_task_set_name(dmt, mapname)) - goto out; - -- if (!dm_task_run(dmt)) { -+ if (!libmp_dm_task_run(dmt)) { - dm_log_error(3, DM_DEVICE_INFO, dmt); - goto out; - } -@@ -1110,7 +1129,7 @@ int dm_flush_maps (int need_suspend, int retries) - - dm_task_no_open_count(dmt); - -- if (!dm_task_run (dmt)) { -+ if (!libmp_dm_task_run (dmt)) { - dm_log_error(3, DM_DEVICE_LIST, dmt); - goto out; - } -@@ -1156,7 +1175,7 @@ dm_message(const char * mapname, char * message) - - dm_task_no_open_count(dmt); - -- if (!dm_task_run(dmt)) { -+ if (!libmp_dm_task_run(dmt)) { - dm_log_error(2, DM_DEVICE_TARGET_MSG, dmt); - goto out; - } -@@ -1276,7 +1295,7 @@ dm_get_maps (vector mp) - - dm_task_no_open_count(dmt); - -- if (!dm_task_run(dmt)) { -+ if (!libmp_dm_task_run(dmt)) { - dm_log_error(3, DM_DEVICE_LIST, dmt); - goto out; - } -@@ -1361,7 +1380,7 @@ dm_mapname(int major, int minor) - * daemon uev_trigger -> uev_add_map - */ - while (--loop) { -- r = dm_task_run(dmt); -+ r = libmp_dm_task_run(dmt); - - if (r) - break; -@@ -1406,7 +1425,7 @@ do_foreach_partmaps (const char * mapname, - - dm_task_no_open_count(dmt); - -- if (!dm_task_run(dmt)) { -+ if (!libmp_dm_task_run(dmt)) { - dm_log_error(3, DM_DEVICE_LIST, dmt); - goto out; - } -@@ -1641,11 +1660,11 @@ dm_rename (const char * old, char * new, char *delim, int skip_kpartx) - - if (!dm_task_set_cookie(dmt, &cookie, udev_flags)) - goto out; -- r = dm_task_run(dmt); -+ r = libmp_dm_task_run(dmt); - if (!r) - dm_log_error(2, DM_DEVICE_RENAME, dmt); - -- dm_udev_wait(cookie); -+ libmp_udev_wait(cookie); - - out: - dm_task_destroy(dmt); -@@ -1687,7 +1706,7 @@ int dm_reassign_table(const char *name, char *old, char *new) - - dm_task_no_open_count(dmt); - -- if (!dm_task_run(dmt)) { -+ if (!libmp_dm_task_run(dmt)) { - dm_log_error(3, DM_DEVICE_TABLE, dmt); - goto out; - } -@@ -1720,7 +1739,7 @@ int dm_reassign_table(const char *name, char *old, char *new) - if (modified) { - dm_task_no_open_count(reload_dmt); - -- if (!dm_task_run(reload_dmt)) { -+ if (!libmp_dm_task_run(reload_dmt)) { - dm_log_error(3, DM_DEVICE_RELOAD, reload_dmt); - condlog(3, "%s: failed to reassign targets", name); - goto out_reload; -@@ -1767,7 +1786,7 @@ int dm_reassign(const char *mapname) - - dm_task_no_open_count(dmt); - -- if (!dm_task_run(dmt)) { -+ if (!libmp_dm_task_run(dmt)) { - dm_log_error(3, DM_DEVICE_DEPS, dmt); - goto out; - } -@@ -1835,7 +1854,7 @@ int dm_setgeometry(struct multipath *mpp) - goto out; - } - -- r = dm_task_run(dmt); -+ r = libmp_dm_task_run(dmt); - if (!r) - dm_log_error(3, DM_DEVICE_SET_GEOMETRY, dmt); - out: -diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h -index a0bcd137..fa6b3c53 100644 ---- a/libmultipath/devmapper.h -+++ b/libmultipath/devmapper.h -@@ -93,6 +93,8 @@ enum { - MULTIPATH_VERSION - }; - int libmp_get_version(int which, unsigned int version[3]); -+struct dm_task; -+int libmp_dm_task_run(struct dm_task *dmt); - - #define dm_log_error(lvl, cmd, dmt) \ - condlog(lvl, "%s: libdm task=%d error: %s", __func__, \ -diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version -index ab5bb0ad..97acdbb2 100644 ---- a/libmultipath/libmultipath.version -+++ b/libmultipath/libmultipath.version -@@ -245,3 +245,9 @@ global: - local: - *; - }; -+ -+LIBMULTIPATH_2.1.0 { -+global: -+ libmp_dm_task_run; -+ cleanup_mutex; -+} LIBMULTIPATH_2.0.0; -diff --git a/libmultipath/util.c b/libmultipath/util.c -index 1f977792..0e37f3ff 100644 ---- a/libmultipath/util.c -+++ b/libmultipath/util.c -@@ -424,6 +424,11 @@ void cleanup_free_ptr(void *arg) - free(*p); - } - -+void cleanup_mutex(void *arg) -+{ -+ pthread_mutex_unlock(arg); -+} -+ - struct bitfield *alloc_bitfield(unsigned int maxbit) - { - unsigned int n; -diff --git a/libmultipath/util.h b/libmultipath/util.h -index ac19473e..e9b48f9f 100644 ---- a/libmultipath/util.h -+++ b/libmultipath/util.h -@@ -49,6 +49,7 @@ int should_exit(void); - - void close_fd(void *arg); - void cleanup_free_ptr(void *arg); -+void cleanup_mutex(void *arg); - - struct scandir_result { - struct dirent **di; -diff --git a/multipathd/dmevents.c b/multipathd/dmevents.c -index fc97c8a2..b561cbfd 100644 ---- a/multipathd/dmevents.c -+++ b/multipathd/dmevents.c -@@ -156,7 +156,7 @@ static int dm_get_events(void) - - dm_task_no_open_count(dmt); - -- if (!dm_task_run(dmt)) { -+ if (!libmp_dm_task_run(dmt)) { - dm_log_error(3, DM_DEVICE_LIST, dmt); - goto fail; - } -diff --git a/multipathd/waiter.c b/multipathd/waiter.c -index 3bc69807..bbe6c2a1 100644 ---- a/multipathd/waiter.c -+++ b/multipathd/waiter.c -@@ -118,7 +118,7 @@ static int waiteventloop (struct event_thread *waiter) - pthread_sigmask(SIG_UNBLOCK, &set, &oldset); - - pthread_testcancel(); -- r = dm_task_run(waiter->dmt); -+ r = libmp_dm_task_run(waiter->dmt); - if (!r) - dm_log_error(2, DM_DEVICE_WAITEVENT, waiter->dmt); - pthread_testcancel(); -diff --git a/tests/Makefile b/tests/Makefile -index 78777bec..908407ea 100644 ---- a/tests/Makefile -+++ b/tests/Makefile -@@ -40,6 +40,7 @@ endif - # linker input file). - # XYZ-test_LIBDEPS: Additional libs to link for this test - -+dmevents-test_OBJDEPS = ../libmultipath/devmapper.o - dmevents-test_LIBDEPS = -lpthread -ldevmapper -lurcu - hwtable-test_TESTDEPS := test-lib.o - hwtable-test_OBJDEPS := ../libmultipath/discovery.o ../libmultipath/blacklist.o \ -diff --git a/tests/dmevents.c b/tests/dmevents.c -index bee117ac..b7c5122b 100644 ---- a/tests/dmevents.c -+++ b/tests/dmevents.c -@@ -179,6 +179,8 @@ struct dm_names *build_dm_names(void) - return names; - } - -+static bool setup_done; -+ - static int setup(void **state) - { - if (dmevent_poll_supported()) { -@@ -186,6 +188,7 @@ static int setup(void **state) - *state = &data; - } else - *state = NULL; -+ setup_done = true; - return 0; - } - -@@ -262,14 +265,20 @@ struct dm_task *__wrap_libmp_dm_task_create(int task) - return mock_type(struct dm_task *); - } - -+int __real_dm_task_no_open_count(struct dm_task *dmt); - int __wrap_dm_task_no_open_count(struct dm_task *dmt) - { -+ if (!setup_done) -+ return __real_dm_task_no_open_count(dmt); - assert_ptr_equal((struct test_data *)dmt, &data); - return mock_type(int); - } - -+int __real_dm_task_run(struct dm_task *dmt); - int __wrap_dm_task_run(struct dm_task *dmt) - { -+ if (!setup_done) -+ return __real_dm_task_run(dmt); - assert_ptr_equal((struct test_data *)dmt, &data); - return mock_type(int); - } -@@ -291,8 +300,11 @@ struct dm_names * __wrap_dm_task_get_names(struct dm_task *dmt) - return data.names; - } - -+void __real_dm_task_destroy(struct dm_task *dmt); - void __wrap_dm_task_destroy(struct dm_task *dmt) - { -+ if (!setup_done) -+ return __real_dm_task_destroy(dmt); - assert_ptr_equal((struct test_data *)dmt, &data); - - if (data.names) { diff --git a/0025-libmultipath-constify-file-argument-in-config-parser.patch b/0025-libmultipath-constify-file-argument-in-config-parser.patch deleted file mode 100644 index 4344b92..0000000 --- a/0025-libmultipath-constify-file-argument-in-config-parser.patch +++ /dev/null @@ -1,95 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 16 Sep 2020 12:02:01 +0200 -Subject: [PATCH] libmultipath: constify file argument in config parser - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/config.c | 3 +-- - libmultipath/config.h | 2 +- - libmultipath/parser.c | 9 +++++---- - libmultipath/parser.h | 2 +- - 4 files changed, 8 insertions(+), 8 deletions(-) - -diff --git a/libmultipath/config.c b/libmultipath/config.c -index df0f8f45..5c91a09d 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -719,8 +719,7 @@ static void set_max_checkint_from_watchdog(struct config *conf) - } - #endif - --struct config * --load_config (char * file) -+struct config *load_config(const char *file) - { - struct config *conf = alloc_config(); - -diff --git a/libmultipath/config.h b/libmultipath/config.h -index 7af19844..ace403b8 100644 ---- a/libmultipath/config.h -+++ b/libmultipath/config.h -@@ -251,7 +251,7 @@ void free_mptable (vector mptable); - - int store_hwe (vector hwtable, struct hwentry *); - --struct config *load_config (char * file); -+struct config *load_config (const char *file); - struct config * alloc_config (void); - void free_config (struct config * conf); - extern struct config *get_multipath_config(void); -diff --git a/libmultipath/parser.c b/libmultipath/parser.c -index ed6d5d6d..163ffbc9 100644 ---- a/libmultipath/parser.c -+++ b/libmultipath/parser.c -@@ -390,7 +390,7 @@ oom: - /* non-recursive configuration stream handler */ - static int kw_level = 0; - --int warn_on_duplicates(vector uniques, char *str, char *file) -+int warn_on_duplicates(vector uniques, char *str, const char *file) - { - char *tmp; - int i; -@@ -434,7 +434,7 @@ is_sublevel_keyword(char *str) - } - - int --validate_config_strvec(vector strvec, char *file) -+validate_config_strvec(vector strvec, const char *file) - { - char *str = NULL; - int i; -@@ -499,7 +499,8 @@ validate_config_strvec(vector strvec, char *file) - } - - static int --process_stream(struct config *conf, FILE *stream, vector keywords, char *file) -+process_stream(struct config *conf, FILE *stream, vector keywords, -+ const char *file) - { - int i; - int r = 0, t; -@@ -584,7 +585,7 @@ out: - - /* Data initialization */ - int --process_file(struct config *conf, char *file) -+process_file(struct config *conf, const char *file) - { - int r; - FILE *stream; -diff --git a/libmultipath/parser.h b/libmultipath/parser.h -index 62906e98..06666ccf 100644 ---- a/libmultipath/parser.h -+++ b/libmultipath/parser.h -@@ -77,7 +77,7 @@ extern void dump_keywords(vector keydump, int level); - extern void free_keywords(vector keywords); - extern vector alloc_strvec(char *string); - extern void *set_value(vector strvec); --extern int process_file(struct config *conf, char *conf_file); -+extern int process_file(struct config *conf, const char *conf_file); - extern struct keyword * find_keyword(vector keywords, vector v, char * name); - int snprint_keyword(char *buff, int len, char *fmt, struct keyword *kw, - const void *data); diff --git a/0026-libmultipath-provide-defaults-for-get-put-_multipath.patch b/0026-libmultipath-provide-defaults-for-get-put-_multipath.patch deleted file mode 100644 index 9a0af2a..0000000 --- a/0026-libmultipath-provide-defaults-for-get-put-_multipath.patch +++ /dev/null @@ -1,201 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 16 Sep 2020 12:06:56 +0200 -Subject: [PATCH] libmultipath: provide defaults for {get,put}_multipath_config - -Add an implementation of get_multipath_config() and put_multipath_config() -to libmultipath. The linker's symbol lookup rules will make sure that -applications can override these functions if they need to. Defining -these functions in libmultipath avoids the need to provide stubs -for these functions in every appliation linking to libmultipath. - -libmultipath's internal functions simply refer to a static "struct config". -It must be initialized with init_config() rather than load_config(), -which always allocates a new struct for backward compatibility, and must -be teared down using uninit_config(). - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/config.c | 75 ++++++++++++++++++++++++++----- - libmultipath/config.h | 21 +++++++-- - libmultipath/libmultipath.version | 10 +++++ - 3 files changed, 93 insertions(+), 13 deletions(-) - -diff --git a/libmultipath/config.c b/libmultipath/config.c -index 5c91a09d..01b77dfe 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -27,6 +27,26 @@ - #include "mpath_cmd.h" - #include "propsel.h" - -+static struct config __internal_config; -+struct config *libmp_get_multipath_config(void) -+{ -+ if (!__internal_config.hwtable) -+ /* not initialized */ -+ return NULL; -+ return &__internal_config; -+} -+ -+struct config *get_multipath_config(void) -+ __attribute__((weak, alias("libmp_get_multipath_config"))); -+ -+void libmp_put_multipath_config(void *conf __attribute__((unused))) -+{ -+ /* empty */ -+} -+ -+void put_multipath_config(void *conf) -+ __attribute__((weak, alias("libmp_put_multipath_config"))); -+ - static int - hwe_strmatch (const struct hwentry *hwe1, const struct hwentry *hwe2) - { -@@ -574,17 +594,15 @@ restart: - return; - } - --struct config * --alloc_config (void) -+static struct config *alloc_config (void) - { - return (struct config *)MALLOC(sizeof(struct config)); - } - --void --free_config (struct config * conf) -+static void _uninit_config(struct config *conf) - { - if (!conf) -- return; -+ conf = &__internal_config; - - if (conf->multipath_dir) - FREE(conf->multipath_dir); -@@ -650,7 +668,27 @@ free_config (struct config * conf) - free_hwtable(conf->hwtable); - free_hwe(conf->overrides); - free_keywords(conf->keywords); -- FREE(conf); -+ -+ memset(conf, 0, sizeof(*conf)); -+} -+ -+void uninit_config(void) -+{ -+ _uninit_config(&__internal_config); -+} -+ -+void free_config(struct config *conf) -+{ -+ if (!conf) -+ return; -+ else if (conf == &__internal_config) { -+ condlog(0, "ERROR: %s called for internal config. Use uninit_config() instead", -+ __func__); -+ return; -+ } -+ -+ _uninit_config(conf); -+ free(conf); - } - - /* if multipath fails to process the config directory, it should continue, -@@ -719,12 +757,29 @@ static void set_max_checkint_from_watchdog(struct config *conf) - } - #endif - -+static int _init_config (const char *file, struct config *conf); -+ -+int init_config(const char *file) -+{ -+ return _init_config(file, &__internal_config); -+} -+ - struct config *load_config(const char *file) - { - struct config *conf = alloc_config(); - -+ if (conf && !_init_config(file, conf)) -+ return conf; -+ -+ free(conf); -+ return NULL; -+} -+ -+int _init_config (const char *file, struct config *conf) -+{ -+ - if (!conf) -- return NULL; -+ conf = &__internal_config; - - /* - * internal defaults -@@ -896,10 +951,10 @@ struct config *load_config(const char *file) - !conf->wwids_file || !conf->prkeys_file) - goto out; - -- return conf; -+ return 0; - out: -- free_config(conf); -- return NULL; -+ _uninit_config(conf); -+ return 1; - } - - char *get_uid_attribute_by_attrs(struct config *conf, -diff --git a/libmultipath/config.h b/libmultipath/config.h -index ace403b8..0329de29 100644 ---- a/libmultipath/config.h -+++ b/libmultipath/config.h -@@ -252,10 +252,25 @@ void free_mptable (vector mptable); - int store_hwe (vector hwtable, struct hwentry *); - - struct config *load_config (const char *file); --struct config * alloc_config (void); - void free_config (struct config * conf); --extern struct config *get_multipath_config(void); --extern void put_multipath_config(void *); -+int init_config(const char *file); -+void uninit_config(void); -+ -+/* -+ * libmultipath provides default implementations of -+ * get_multipath_config() and put_multipath_config(). -+ * Applications using these should use init_config(file, NULL) -+ * to load the configuration, rather than load_config(file). -+ * Likewise, uninit_config() should be used for teardown, but -+ * using free_config() for that is supported, too. -+ * Applications can define their own {get,put}_multipath_config() -+ * functions, which override the library-internal ones, but -+ * could still call libmp_{get,put}_multipath_config(). -+ */ -+struct config *libmp_get_multipath_config(void); -+struct config *get_multipath_config(void); -+void libmp_put_multipath_config(void *); -+void put_multipath_config(void *); - - int parse_uid_attrs(char *uid_attrs, struct config *conf); - char *get_uid_attribute_by_attrs(struct config *conf, -diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version -index 97acdbb2..3e780fce 100644 ---- a/libmultipath/libmultipath.version -+++ b/libmultipath/libmultipath.version -@@ -251,3 +251,13 @@ global: - libmp_dm_task_run; - cleanup_mutex; - } LIBMULTIPATH_2.0.0; -+ -+LIBMULTIPATH_2.2.0 { -+global: -+ libmp_get_multipath_config; -+ get_multipath_config; -+ libmp_put_multipath_config; -+ put_multipath_config; -+ init_config; -+ uninit_config; -+} LIBMULTIPATH_2.1.0; diff --git a/0027-libmpathpersist-allow-using-libmultipath-get-put-_mu.patch b/0027-libmpathpersist-allow-using-libmultipath-get-put-_mu.patch deleted file mode 100644 index 13e8b10..0000000 --- a/0027-libmpathpersist-allow-using-libmultipath-get-put-_mu.patch +++ /dev/null @@ -1,153 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 16 Sep 2020 12:11:46 +0200 -Subject: [PATCH] libmpathpersist: allow using libmultipath - {get,put}_multipath_config - -Provide an alternative init function libmpathpersist_init() which -avoids allocating a new struct config, simply using libmultipath's -internal implementation. This causes a minor version bump for -libmpathpersist. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmpathpersist/libmpathpersist.version | 6 ++++ - libmpathpersist/mpath_persist.c | 42 +++++++++++++++++++++---- - libmpathpersist/mpath_persist.h | 28 +++++++++++++++++ - 3 files changed, 70 insertions(+), 6 deletions(-) - -diff --git a/libmpathpersist/libmpathpersist.version b/libmpathpersist/libmpathpersist.version -index dc648ce6..e0748138 100644 ---- a/libmpathpersist/libmpathpersist.version -+++ b/libmpathpersist/libmpathpersist.version -@@ -30,3 +30,9 @@ global: - - local: *; - }; -+ -+LIBMPATHPERSIST_1.1.0 { -+global: -+ libmpathpersist_init; -+ libmpathpersist_exit; -+} LIBMPATHPERSIST_1.0.0; -diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c -index cc4a088d..febf4758 100644 ---- a/libmpathpersist/mpath_persist.c -+++ b/libmpathpersist/mpath_persist.c -@@ -37,6 +37,27 @@ - - extern struct udev *udev; - -+static void adapt_config(struct config *conf) -+{ -+ conf->force_sync = 1; -+ set_max_fds(conf->max_fds); -+} -+ -+int libmpathpersist_init(void) -+{ -+ struct config *conf; -+ int rc = 0; -+ -+ if (init_config(DEFAULT_CONFIGFILE)) { -+ condlog(0, "Failed to initialize multipath config."); -+ return 1; -+ } -+ conf = libmp_get_multipath_config(); -+ adapt_config(conf); -+ libmp_put_multipath_config(conf); -+ return rc; -+} -+ - struct config * - mpath_lib_init (void) - { -@@ -47,20 +68,29 @@ mpath_lib_init (void) - condlog(0, "Failed to initialize multipath config."); - return NULL; - } -- conf->force_sync = 1; -- set_max_fds(conf->max_fds); -- -+ adapt_config(conf); - return conf; - } - --int --mpath_lib_exit (struct config *conf) -+static void libmpathpersist_cleanup(void) - { - dm_lib_exit(); - cleanup_prio(); - cleanup_checkers(); -+} -+ -+int -+mpath_lib_exit (struct config *conf) -+{ -+ libmpathpersist_cleanup(); - free_config(conf); -- conf = NULL; -+ return 0; -+} -+ -+int libmpathpersist_exit(void) -+{ -+ libmpathpersist_cleanup(); -+ uninit_config(); - return 0; - } - -diff --git a/libmpathpersist/mpath_persist.h b/libmpathpersist/mpath_persist.h -index 7cf4faf9..91606efc 100644 ---- a/libmpathpersist/mpath_persist.h -+++ b/libmpathpersist/mpath_persist.h -@@ -175,6 +175,22 @@ struct prout_param_descriptor { /* PROUT parameter descriptor */ - * DESCRIPTION : - * Initialize device mapper multipath configuration. This function must be invoked first - * before performing reservation management functions. -+ * Either this function or mpath_lib_init() may be used. -+ * Use this function to work with libmultipath's internal "struct config". -+ * Call libmpathpersist_exit() for cleanup. -+ * RESTRICTIONS: -+ * -+ * RETURNS: 0->Success, 1->Failed. -+ */ -+extern int libmpathpersist_init (void); -+ -+/* -+ * DESCRIPTION : -+ * Initialize device mapper multipath configuration. This function must be invoked first -+ * before performing reservation management functions. -+ * Either this function or libmpathpersist_init() may be used. -+ * Use this function to work with an application-specific "struct config". -+ * Call mpath_lib_exit() for cleanup. - * RESTRICTIONS: - * - * RETURNS: struct config ->Success, NULL->Failed. -@@ -186,12 +202,24 @@ extern struct config * mpath_lib_init (void); - * DESCRIPTION : - * Release device mapper multipath configuration. This function must be invoked after - * performing reservation management functions. -+ * Use this after initialization with mpath_lib_init(). - * RESTRICTIONS: - * - * RETURNS: 0->Success, 1->Failed. - */ - extern int mpath_lib_exit (struct config *conf); - -+/* -+ * DESCRIPTION : -+ * Release device mapper multipath configuration. This function must be invoked after -+ * performing reservation management functions. -+ * Use this after initialization with libmpathpersist_init(). -+ * RESTRICTIONS: -+ * -+ * RETURNS: 0->Success, 1->Failed. -+ */ -+extern int libmpathpersist_exit (void); -+ - - /* - * DESCRIPTION : diff --git a/0028-multipath-use-get_put-_multipath_config-from-libmult.patch b/0028-multipath-use-get_put-_multipath_config-from-libmult.patch deleted file mode 100644 index 6ccc2ea..0000000 --- a/0028-multipath-use-get_put-_multipath_config-from-libmult.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 16 Sep 2020 12:27:09 +0200 -Subject: [PATCH] multipath: use {get_put}_multipath_config from libmultipath - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/main.c | 20 ++++---------------- - 1 file changed, 4 insertions(+), 16 deletions(-) - -diff --git a/multipath/main.c b/multipath/main.c -index dc4974b9..4bbfce9a 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -68,7 +68,6 @@ - - int logsink; - struct udev *udev; --struct config *multipath_conf; - - /* - * Return values of configure(), check_path_valid(), and main(). -@@ -79,16 +78,6 @@ enum { - RTVL_RETRY, /* returned by configure(), not by main() */ - }; - --struct config *get_multipath_config(void) --{ -- return multipath_conf; --} -- --void put_multipath_config(__attribute__((unused)) void *arg) --{ -- /* Noop for now */ --} -- - static int - dump_config (struct config *conf, vector hwes, vector mpvec) - { -@@ -823,10 +812,9 @@ main (int argc, char *argv[]) - - udev = udev_new(); - logsink = 0; -- conf = load_config(DEFAULT_CONFIGFILE); -- if (!conf) -+ if (init_config(DEFAULT_CONFIGFILE)) - exit(RTVL_FAIL); -- multipath_conf = conf; -+ conf = get_multipath_config(); - conf->retrigger_tries = 0; - conf->force_sync = 1; - while ((arg = getopt(argc, argv, ":adDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { -@@ -1078,8 +1066,8 @@ out_free_config: - * the logging function (dm_write_log()), which is called there, - * references the config. - */ -- free_config(conf); -- conf = NULL; -+ put_multipath_config(conf); -+ uninit_config(); - udev_unref(udev); - if (dev) - FREE(dev); diff --git a/0029-mpathpersist-use-get-put-_multipath_config-from-libm.patch b/0029-mpathpersist-use-get-put-_multipath_config-from-libm.patch deleted file mode 100644 index 09c4ad8..0000000 --- a/0029-mpathpersist-use-get-put-_multipath_config-from-libm.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 16 Sep 2020 12:39:01 +0200 -Subject: [PATCH] mpathpersist: use {get,put}_multipath_config() from - libmultipath - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - mpathpersist/main.c | 16 ++-------------- - 1 file changed, 2 insertions(+), 14 deletions(-) - -diff --git a/mpathpersist/main.c b/mpathpersist/main.c -index a6a3bcf6..278e48f7 100644 ---- a/mpathpersist/main.c -+++ b/mpathpersist/main.c -@@ -43,17 +43,6 @@ void mpath_print_transport_id(struct prin_fulldescr *fdesc); - int construct_transportid(const char * inp, struct transportid transid[], int num_transportids); - - int logsink; --struct config *multipath_conf; -- --struct config *get_multipath_config(void) --{ -- return multipath_conf; --} -- --void put_multipath_config(__attribute__((unused)) void * arg) --{ -- /* Noop for now */ --} - - void rcu_register_thread_memb(void) {} - -@@ -653,15 +642,14 @@ int main(int argc, char *argv[]) - } - - udev = udev_new(); -- multipath_conf = mpath_lib_init(); -- if(!multipath_conf) { -+ if (libmpathpersist_init()) { - udev_unref(udev); - exit(1); - } - - ret = handle_args(argc, argv, 0); - -- mpath_lib_exit(multipath_conf); -+ libmpathpersist_exit(); - udev_unref(udev); - - return (ret >= 0) ? ret : MPATH_PR_OTHER; diff --git a/0030-libmultipath-add-udev-and-logsink-symbols.patch b/0030-libmultipath-add-udev-and-logsink-symbols.patch deleted file mode 100644 index d936a42..0000000 --- a/0030-libmultipath-add-udev-and-logsink-symbols.patch +++ /dev/null @@ -1,165 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 16 Sep 2020 15:06:12 +0200 -Subject: [PATCH] libmultipath: add udev and logsink symbols - -With these symbols added, applications using libmultipath don't -need to define global variables "udev" and "logsink" any more. -This comes at the cost of having to call an init function. -Currently, libmultipath_init() does nothing but initialize -"udev". - -The linker's symbol lookup order still allows applications to use -their own "logsink" and "udev" variables, which will take precendence -over libmultipath's internal ones. In this case, calling -libmultipath_init() can be skipped, but like before, -udev should be initialized (using udev_new()) before making any -libmultipath calls. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/config.c | 41 +++++++++++++++++++++++++++ - libmultipath/config.h | 46 ++++++++++++++++++++++++++++++- - libmultipath/debug.c | 2 ++ - libmultipath/libmultipath.version | 8 ++++++ - 4 files changed, 96 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/config.c b/libmultipath/config.c -index 01b77dfe..f74417c6 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -27,6 +27,47 @@ - #include "mpath_cmd.h" - #include "propsel.h" - -+/* -+ * We don't support re-initialization after -+ * libmultipath_exit(). -+ */ -+static bool libmultipath_exit_called; -+static pthread_once_t _init_once = PTHREAD_ONCE_INIT; -+static pthread_once_t _exit_once = PTHREAD_ONCE_INIT; -+struct udev *udev; -+ -+static void _udev_init(void) -+{ -+ if (udev) -+ udev_ref(udev); -+ else -+ udev = udev_new(); -+ if (!udev) -+ condlog(0, "%s: failed to initialize udev", __func__); -+} -+ -+static bool _is_libmultipath_initialized(void) -+{ -+ return !libmultipath_exit_called && !!udev; -+} -+ -+int libmultipath_init(void) -+{ -+ pthread_once(&_init_once, _udev_init); -+ return !_is_libmultipath_initialized(); -+} -+ -+static void _libmultipath_exit(void) -+{ -+ libmultipath_exit_called = true; -+ udev_unref(udev); -+} -+ -+void libmultipath_exit(void) -+{ -+ pthread_once(&_exit_once, _libmultipath_exit); -+} -+ - static struct config __internal_config; - struct config *libmp_get_multipath_config(void) - { -diff --git a/libmultipath/config.h b/libmultipath/config.h -index 0329de29..f478df71 100644 ---- a/libmultipath/config.h -+++ b/libmultipath/config.h -@@ -233,7 +233,51 @@ struct config { - char *enable_foreign; - }; - --extern struct udev * udev; -+/** -+ * extern variable: udev -+ * -+ * A &struct udev instance used by libmultipath. libmultipath expects -+ * a valid, initialized &struct udev in this variable. -+ * An application can define this variable itself, in which case -+ * the applications's instance will take precedence. -+ * The application can initialize and destroy this variable by -+ * calling libmultipath_init() and libmultipath_exit(), respectively, -+ * whether or not it defines the variable itself. -+ * An application can initialize udev with udev_new() before calling -+ * libmultipath_init(), e.g. if it has to make libudev calls before -+ * libmultipath calls. If an application wants to keep using the -+ * udev variable after calling libmultipath_exit(), it should have taken -+ * an additional reference on it beforehand. This is the case e.g. -+ * after initiazing udev with udev_new(). -+ */ -+extern struct udev *udev; -+ -+/** -+ * libmultipath_init() - library initialization -+ * -+ * This function initializes libmultipath data structures. -+ * It is light-weight; some other initializations, like device-mapper -+ * initialization, are done lazily when the respective functionality -+ * is required. -+ * -+ * Clean up by libmultipath_exit() when the program terminates. -+ * It is an error to call libmultipath_init() after libmultipath_exit(). -+ * Return: 0 on success, 1 on failure. -+ */ -+int libmultipath_init(void); -+ -+/** -+ * libmultipath_exit() - library un-initialization -+ * -+ * This function un-initializes libmultipath data structures. -+ * It is recommended to call this function at program exit. -+ * -+ * Calls to libmultipath_init() after libmultipath_exit() will fail -+ * (in other words, libmultipath can't be re-initialized). -+ * Any other libmultipath calls after libmultipath_exit() may cause -+ * undefined behavior. -+ */ -+void libmultipath_exit(void); - - int find_hwe (const struct _vector *hwtable, - const char * vendor, const char * product, const char *revision, -diff --git a/libmultipath/debug.c b/libmultipath/debug.c -index 4128cb90..b3a1de9e 100644 ---- a/libmultipath/debug.c -+++ b/libmultipath/debug.c -@@ -15,6 +15,8 @@ - #include "defaults.h" - #include "debug.h" - -+int logsink; -+ - void dlog (int sink, int prio, const char * fmt, ...) - { - va_list ap; -diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version -index 3e780fce..0c300c81 100644 ---- a/libmultipath/libmultipath.version -+++ b/libmultipath/libmultipath.version -@@ -261,3 +261,11 @@ global: - init_config; - uninit_config; - } LIBMULTIPATH_2.1.0; -+ -+LIBMULTIPATH_2.3.0 { -+global: -+ udev; -+ logsink; -+ libmultipath_init; -+ libmultipath_exit; -+} LIBMULTIPATH_2.2.0; diff --git a/0031-multipath-remove-logsink-and-udev.patch b/0031-multipath-remove-logsink-and-udev.patch deleted file mode 100644 index 4faf540..0000000 --- a/0031-multipath-remove-logsink-and-udev.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 16 Sep 2020 16:06:17 +0200 -Subject: [PATCH] multipath: remove logsink and udev - -We can use libmultipath's symbols now. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/main.c | 7 ++----- - 1 file changed, 2 insertions(+), 5 deletions(-) - -diff --git a/multipath/main.c b/multipath/main.c -index 4bbfce9a..9ae46ed5 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -66,9 +66,6 @@ - #include "valid.h" - #include "alias.h" - --int logsink; --struct udev *udev; -- - /* - * Return values of configure(), check_path_valid(), and main(). - */ -@@ -810,7 +807,7 @@ main (int argc, char *argv[]) - int retries = -1; - bool enable_foreign = false; - -- udev = udev_new(); -+ libmultipath_init(); - logsink = 0; - if (init_config(DEFAULT_CONFIGFILE)) - exit(RTVL_FAIL); -@@ -1068,7 +1065,7 @@ out_free_config: - */ - put_multipath_config(conf); - uninit_config(); -- udev_unref(udev); -+ libmultipath_exit(); - if (dev) - FREE(dev); - #ifdef _DEBUG_ diff --git a/0032-libmpathpersist-call-libmultipath_-init-exit.patch b/0032-libmpathpersist-call-libmultipath_-init-exit.patch deleted file mode 100644 index 9671dfd..0000000 --- a/0032-libmpathpersist-call-libmultipath_-init-exit.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 22 Sep 2020 14:23:14 +0200 -Subject: [PATCH] libmpathpersist: call libmultipath_{init,exit}() - -Have libmpathpersist_{init,exit} do the udev initialization, too. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmpathpersist/mpath_persist.c | 11 ++++++++--- - libmpathpersist/mpath_persist.h | 9 ++++++--- - 2 files changed, 14 insertions(+), 6 deletions(-) - -diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c -index febf4758..e1d1cb76 100644 ---- a/libmpathpersist/mpath_persist.c -+++ b/libmpathpersist/mpath_persist.c -@@ -48,6 +48,10 @@ int libmpathpersist_init(void) - struct config *conf; - int rc = 0; - -+ if (libmultipath_init()) { -+ condlog(0, "Failed to initialize libmultipath."); -+ return 1; -+ } - if (init_config(DEFAULT_CONFIGFILE)) { - condlog(0, "Failed to initialize multipath config."); - return 1; -@@ -74,23 +78,24 @@ mpath_lib_init (void) - - static void libmpathpersist_cleanup(void) - { -- dm_lib_exit(); - cleanup_prio(); - cleanup_checkers(); -+ libmultipath_exit(); -+ dm_lib_exit(); - } - - int - mpath_lib_exit (struct config *conf) - { -- libmpathpersist_cleanup(); - free_config(conf); -+ libmpathpersist_cleanup(); - return 0; - } - - int libmpathpersist_exit(void) - { -- libmpathpersist_cleanup(); - uninit_config(); -+ libmpathpersist_cleanup(); - return 0; - } - -diff --git a/libmpathpersist/mpath_persist.h b/libmpathpersist/mpath_persist.h -index 91606efc..5435eae4 100644 ---- a/libmpathpersist/mpath_persist.h -+++ b/libmpathpersist/mpath_persist.h -@@ -176,7 +176,8 @@ struct prout_param_descriptor { /* PROUT parameter descriptor */ - * Initialize device mapper multipath configuration. This function must be invoked first - * before performing reservation management functions. - * Either this function or mpath_lib_init() may be used. -- * Use this function to work with libmultipath's internal "struct config". -+ * Use this function to work with libmultipath's internal "struct config" -+ * and "struct udev". The latter will be initialized automatically. - * Call libmpathpersist_exit() for cleanup. - * RESTRICTIONS: - * -@@ -189,7 +190,8 @@ extern int libmpathpersist_init (void); - * Initialize device mapper multipath configuration. This function must be invoked first - * before performing reservation management functions. - * Either this function or libmpathpersist_init() may be used. -- * Use this function to work with an application-specific "struct config". -+ * Use this function to work with an application-specific "struct config" -+ * and "struct udev". The latter must be initialized by the application. - * Call mpath_lib_exit() for cleanup. - * RESTRICTIONS: - * -@@ -211,9 +213,10 @@ extern int mpath_lib_exit (struct config *conf); - - /* - * DESCRIPTION : -- * Release device mapper multipath configuration. This function must be invoked after -+ * Release device mapper multipath configuration a. This function must be invoked after - * performing reservation management functions. - * Use this after initialization with libmpathpersist_init(). -+ * Calling libmpathpersist_init() after libmpathpersist_exit() will fail. - * RESTRICTIONS: - * - * RETURNS: 0->Success, 1->Failed. diff --git a/0033-mpathpersist-remove-logsink-and-udev.patch b/0033-mpathpersist-remove-logsink-and-udev.patch deleted file mode 100644 index bf508c6..0000000 --- a/0033-mpathpersist-remove-logsink-and-udev.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 16 Sep 2020 16:08:43 +0200 -Subject: [PATCH] mpathpersist: remove logsink and udev - -We can use libmultipath's internal symbols now. The libmultipath -initialization is taken care of by libmpathpersist_init(). - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - mpathpersist/main.c | 6 ------ - 1 file changed, 6 deletions(-) - -diff --git a/mpathpersist/main.c b/mpathpersist/main.c -index 278e48f7..3c2e6576 100644 ---- a/mpathpersist/main.c -+++ b/mpathpersist/main.c -@@ -42,13 +42,10 @@ void * mpath_alloc_prin_response(int prin_sa); - void mpath_print_transport_id(struct prin_fulldescr *fdesc); - int construct_transportid(const char * inp, struct transportid transid[], int num_transportids); - --int logsink; -- - void rcu_register_thread_memb(void) {} - - void rcu_unregister_thread_memb(void) {} - --struct udev *udev; - - static int verbose, loglevel, noisy; - -@@ -641,16 +638,13 @@ int main(int argc, char *argv[]) - exit (1); - } - -- udev = udev_new(); - if (libmpathpersist_init()) { -- udev_unref(udev); - exit(1); - } - - ret = handle_args(argc, argv, 0); - - libmpathpersist_exit(); -- udev_unref(udev); - - return (ret >= 0) ? ret : MPATH_PR_OTHER; - } diff --git a/0034-multipathd-remove-logsink-and-udev.patch b/0034-multipathd-remove-logsink-and-udev.patch deleted file mode 100644 index f974fd5..0000000 --- a/0034-multipathd-remove-logsink-and-udev.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 23 Sep 2020 11:28:22 +0200 -Subject: [PATCH] multipathd: remove logsink and udev - -We can use the symbols from libmultipath now. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 9 +++------ - 1 file changed, 3 insertions(+), 6 deletions(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 00b66ba4..c5c374b7 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -115,7 +115,6 @@ struct mpath_event_param - struct multipath *mpp; - }; - --int logsink; - int uxsock_timeout; - int verbosity; - int bindings_read_only; -@@ -151,8 +150,6 @@ int should_exit(void) - */ - struct vectors * gvecs; - --struct udev * udev; -- - struct config *multipath_conf; - - /* Local variables */ -@@ -3123,8 +3120,6 @@ child (__attribute__((unused)) void *param) - conf = rcu_dereference(multipath_conf); - rcu_assign_pointer(multipath_conf, NULL); - call_rcu(&conf->rcu, rcu_free_config); -- udev_unref(udev); -- udev = NULL; - pthread_attr_destroy(&waiter_attr); - pthread_attr_destroy(&io_err_stat_attr); - #ifdef _DEBUG_ -@@ -3228,7 +3223,9 @@ main (int argc, char *argv[]) - - pthread_cond_init_mono(&config_cond); - -- udev = udev_new(); -+ libmultipath_init(); -+ if (atexit(libmultipath_exit)) -+ condlog(3, "failed to register exit handler for libmultipath"); - libmp_udev_set_sync_support(0); - - while ((arg = getopt(argc, argv, ":dsv:k::Bniw")) != EOF ) { diff --git a/0035-multipath-tools-add-Vexata-by-StorCentric-VX-arrays.patch b/0035-multipath-tools-add-Vexata-by-StorCentric-VX-arrays.patch deleted file mode 100644 index 3c50b70..0000000 --- a/0035-multipath-tools-add-Vexata-by-StorCentric-VX-arrays.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Wed, 16 Dec 2020 23:17:39 +0100 -Subject: [PATCH] multipath-tools: add Vexata(by StorCentric) VX arrays - -https://support.sas.com/resources/papers/performance-tuning-sas-vexata-systems.pdf - -Reviewed-by: Martin Wilck -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez -Signed-off-by: Benjamin Marzinski ---- - libmultipath/hwtable.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index cd65afcc..c1d6f7ae 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -1191,6 +1191,14 @@ static struct hwentry default_hw[] = { - .product = "Magnitude", - .pgpolicy = MULTIBUS, - .no_path_retry = 30, -+ }, -+ /* Vexata */ -+ { -+ /* VX */ -+ .vendor = "Vexata", -+ .product = "VX", -+ .pgpolicy = MULTIBUS, -+ .no_path_retry = 30, - }, - /* - * Promise Technology diff --git a/0036-multipath-tools-Violin-and-Nexsan-were-bought-by-Sto.patch b/0036-multipath-tools-Violin-and-Nexsan-were-bought-by-Sto.patch deleted file mode 100644 index 1ba6166..0000000 --- a/0036-multipath-tools-Violin-and-Nexsan-were-bought-by-Sto.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Wed, 16 Dec 2020 23:17:40 +0100 -Subject: [PATCH] multipath-tools: Violin and Nexsan were bought by StorCentric - -Reviewed-by: Martin Wilck -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez -Signed-off-by: Benjamin Marzinski ---- - libmultipath/hwtable.c | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index c1d6f7ae..a54cc0a3 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -1113,8 +1113,9 @@ static struct hwentry default_hw[] = { - .pgpolicy = MULTIBUS, - }, - /* -- * Imation/Nexsan -+ * StorCentric - */ -+ /* Nexsan */ - { - /* E-Series */ - .vendor = "NEXSAN", -@@ -1143,9 +1144,7 @@ static struct hwentry default_hw[] = { - .prio_name = PRIO_ALUA, - .no_path_retry = 30, - }, -- /* -- * Violin Systems -- */ -+ /* Violin Systems */ - { - /* 3000 / 6000 Series */ - .vendor = "VIOLIN", diff --git a/0037-libmultipath-fix-memory-leaks-in-coalesce_paths.patch b/0037-libmultipath-fix-memory-leaks-in-coalesce_paths.patch deleted file mode 100644 index a40bf11..0000000 --- a/0037-libmultipath-fix-memory-leaks-in-coalesce_paths.patch +++ /dev/null @@ -1,114 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: lixiaokeng -Date: Mon, 9 Nov 2020 12:32:05 +0800 -Subject: [PATCH] libmultipath: fix memory leaks in coalesce_paths - -When multipath -F are executed first and multipath -v2 or --d are executed later, asan will warn memory leaks. The -reason is that the mpp allocated in coalesce_paths isn't -freed. Here we use newmp to store mpp. If newmp need not -be copied to mpvec, we free newmp at the end of the func. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Lixiaokeng -Signed-off-by: Zhiqiang Liu -Signed-off-by: Linfeilong -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 40 +++++++++++++++++++++++++++++----------- - 1 file changed, 29 insertions(+), 11 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 1c8aac08..d36f0d0d 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -1139,7 +1139,7 @@ out: - * FORCE_RELOAD_WEAK: existing maps are compared to the current conf and only - * reloaded in DM if there's a difference. This is useful during startup. - */ --int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, -+int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid, - int force_reload, enum mpath_cmds cmd) - { - int ret = CP_FAIL; -@@ -1151,6 +1151,7 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, - struct path * pp2; - vector curmp = vecs->mpvec; - vector pathvec = vecs->pathvec; -+ vector newmp; - struct config *conf; - int allow_queueing; - struct bitfield *size_mismatch_seen; -@@ -1171,6 +1172,15 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, - if (size_mismatch_seen == NULL) - return CP_FAIL; - -+ if (mpvec) -+ newmp = mpvec; -+ else -+ newmp = vector_alloc(); -+ if (!newmp) { -+ condlog(0, "can not allocate newmp"); -+ goto out; -+ } -+ - vector_foreach_slot (pathvec, pp1, k) { - int invalid; - -@@ -1283,8 +1293,14 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, - goto out; - } - } -- if (r == DOMAP_DRY) -+ if (r == DOMAP_DRY) { -+ if (!vector_alloc_slot(newmp)) { -+ remove_map(mpp, vecs->pathvec, vecs->mpvec, KEEP_VEC); -+ goto out; -+ } -+ vector_set_slot(newmp, mpp); - continue; -+ } - - if (r == DOMAP_EXIST && mpp->action == ACT_NOTHING && - force_reload == FORCE_RELOAD_WEAK) -@@ -1320,22 +1336,22 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, - print_multipath_topology(mpp, verbosity); - } - -- if (newmp) { -- if (mpp->action != ACT_REJECT) { -- if (!vector_alloc_slot(newmp)) -- goto out; -- vector_set_slot(newmp, mpp); -+ if (mpp->action != ACT_REJECT) { -+ if (!vector_alloc_slot(newmp)) { -+ remove_map(mpp, vecs->pathvec, vecs->mpvec, KEEP_VEC); -+ goto out; - } -- else -- remove_map(mpp, vecs->pathvec, vecs->mpvec, -- KEEP_VEC); -+ vector_set_slot(newmp, mpp); - } -+ else -+ remove_map(mpp, vecs->pathvec, vecs->mpvec, -+ KEEP_VEC); - } - /* - * Flush maps with only dead paths (ie not in sysfs) - * Keep maps with only failed paths - */ -- if (newmp) { -+ if (mpvec) { - vector_foreach_slot (newmp, mpp, i) { - char alias[WWID_SIZE]; - -@@ -1358,6 +1374,8 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, - ret = CP_OK; - out: - free(size_mismatch_seen); -+ if (!mpvec) -+ free_multipathvec(newmp, KEEP_PATHS); - return ret; - } - diff --git a/0038-multipath-tools-replace-hidden-tab-by-space-in-hwtab.patch b/0038-multipath-tools-replace-hidden-tab-by-space-in-hwtab.patch deleted file mode 100644 index f75dd91..0000000 --- a/0038-multipath-tools-replace-hidden-tab-by-space-in-hwtab.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Thu, 17 Dec 2020 16:49:38 +0100 -Subject: [PATCH] multipath-tools: replace hidden tab by space in hwtable - -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez -Signed-off-by: Benjamin Marzinski ---- - libmultipath/hwtable.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index a54cc0a3..921aadc5 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -819,7 +819,7 @@ static struct hwentry default_hw[] = { - * - * The hwtable is searched backwards, so place this after "Generic NVMe" - */ -- .vendor = "NVME", -+ .vendor = "NVME", - .product = "^NetApp ONTAP Controller", - .pgpolicy = MULTIBUS, - .no_path_retry = NO_PATH_RETRY_QUEUE, diff --git a/0039-multipathd-uxlsnr-avoid-deadlock-on-exit.patch b/0039-multipathd-uxlsnr-avoid-deadlock-on-exit.patch deleted file mode 100644 index db589ac..0000000 --- a/0039-multipathd-uxlsnr-avoid-deadlock-on-exit.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 22 Sep 2020 20:59:25 +0200 -Subject: [PATCH] multipathd: uxlsnr: avoid deadlock on exit - -The uxlsnr wouldn't always release the client lock when cancelled, -causing a deadlock in uxsock_cleanup(). While this hasn't been -caused by commit 3d611a2, the deadlock seems to have become much -more likely after that patch. Solving this means that we have to -treat reallocation failure of the pollfd array differently. -We will now just ignore any clients above the last valid pfd index. -That's a minor problem, as we're in an OOM situation anyway. - -Moreover, client_lock is not a "struct lock", but a plain -pthread_mutex_t. - -Fixes: 3d611a2 ("multipathd: cancel threads early during shutdown") -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipathd/uxlsnr.c | 24 ++++++++++++++---------- - 1 file changed, 14 insertions(+), 10 deletions(-) - -diff --git a/multipathd/uxlsnr.c b/multipathd/uxlsnr.c -index 1c5ce9d2..ce2b6800 100644 ---- a/multipathd/uxlsnr.c -+++ b/multipathd/uxlsnr.c -@@ -35,6 +35,7 @@ - #include "config.h" - #include "mpath_cmd.h" - #include "time-util.h" -+#include "util.h" - - #include "main.h" - #include "cli.h" -@@ -116,7 +117,7 @@ static void _dead_client(struct client *c) - - static void dead_client(struct client *c) - { -- pthread_cleanup_push(cleanup_lock, &client_lock); -+ pthread_cleanup_push(cleanup_mutex, &client_lock); - pthread_mutex_lock(&client_lock); - _dead_client(c); - pthread_cleanup_pop(1); -@@ -302,10 +303,11 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, long ux_sock, - sigdelset(&mask, SIGUSR1); - while (1) { - struct client *c, *tmp; -- int i, poll_count, num_clients; -+ int i, n_pfds, poll_count, num_clients; - - /* setup for a poll */ - pthread_mutex_lock(&client_lock); -+ pthread_cleanup_push(cleanup_mutex, &client_lock); - num_clients = 0; - list_for_each_entry(c, &clients, node) { - num_clients++; -@@ -322,14 +324,13 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, long ux_sock, - sizeof(struct pollfd)); - } - if (!new) { -- pthread_mutex_unlock(&client_lock); - condlog(0, "%s: failed to realloc %d poll fds", - "uxsock", 2 + num_clients); -- sched_yield(); -- continue; -+ num_clients = old_clients; -+ } else { -+ old_clients = num_clients; -+ polls = new; - } -- old_clients = num_clients; -- polls = new; - } - polls[0].fd = ux_sock; - polls[0].events = POLLIN; -@@ -347,11 +348,14 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, long ux_sock, - polls[i].fd = c->fd; - polls[i].events = POLLIN; - i++; -+ if (i >= 2 + num_clients) -+ break; - } -- pthread_mutex_unlock(&client_lock); -+ n_pfds = i; -+ pthread_cleanup_pop(1); - - /* most of our life is spent in this call */ -- poll_count = ppoll(polls, i, &sleep_time, &mask); -+ poll_count = ppoll(polls, n_pfds, &sleep_time, &mask); - - handle_signals(false); - if (poll_count == -1) { -@@ -384,7 +388,7 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, long ux_sock, - } - - /* see if a client wants to speak to us */ -- for (i = 2; i < num_clients + 2; i++) { -+ for (i = 2; i < n_pfds; i++) { - if (polls[i].revents & POLLIN) { - struct timespec start_time; - diff --git a/0040-multipathd-Fix-liburcu-memory-leak.patch b/0040-multipathd-Fix-liburcu-memory-leak.patch deleted file mode 100644 index 0416db3..0000000 --- a/0040-multipathd-Fix-liburcu-memory-leak.patch +++ /dev/null @@ -1,95 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 23 Sep 2020 18:02:39 +0200 -Subject: [PATCH] multipathd: Fix liburcu memory leak - -Fix this leak in multipathd, reported by valgrind, that messes up -multipathd's otherwise clean leak report: - -==23823== 336 bytes in 1 blocks are possibly lost in loss record 3 of 3 -==23823== at 0x483AB65: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) -==23823== by 0x4012F16: _dl_allocate_tls (in /lib64/ld-2.31.so) -==23823== by 0x493BB8E: pthread_create@@GLIBC_2.2.5 (in /lib64/libpthread-2.31.so) -==23823== by 0x492A9A9: call_rcu_data_init (urcu-call-rcu-impl.h:437) -==23823== by 0x492AD2F: UnknownInlinedFun (urcu-call-rcu-impl.h:492) -==23823== by 0x492AD2F: create_call_rcu_data_memb (urcu-call-rcu-impl.h:504) -==23823== by 0x1164E3: child.constprop.0.isra.0 (main.c:2915) -==23823== by 0x10F50C: main (main.c:3335) -==23823== -==23823== LEAK SUMMARY: -==23823== definitely lost: 0 bytes in 0 blocks -==23823== indirectly lost: 0 bytes in 0 blocks -==23823== possibly lost: 336 bytes in 1 blocks - -The problem is caused by using liburcu's default RCU call handler, -which liburcu refuses to stop/join. See comments in the code. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 44 insertions(+), 1 deletion(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index c5c374b7..ce14bb66 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -2889,6 +2889,48 @@ set_oom_adj (void) - condlog(0, "couldn't adjust oom score"); - } - -+/* -+ * Use a non-default call_rcu_data for child(). -+ * -+ * We do this to avoid a memory leak from liburcu. -+ * liburcu never frees the default rcu handler (see comments on -+ * call_rcu_data_free() in urcu-call-rcu-impl.h), its thread -+ * can't be joined with pthread_join(), leaving a memory leak. -+ * -+ * Therefore we create our own, which can be destroyed and joined. -+ */ -+static struct call_rcu_data *setup_rcu(void) -+{ -+ struct call_rcu_data *crdp; -+ -+ rcu_init(); -+ rcu_register_thread(); -+ crdp = create_call_rcu_data(0UL, -1); -+ if (crdp != NULL) -+ set_thread_call_rcu_data(crdp); -+ return crdp; -+} -+ -+static struct call_rcu_data *mp_rcu_data; -+ -+static void cleanup_rcu(void) -+{ -+ pthread_t rcu_thread; -+ -+ /* Wait for any pending RCU calls */ -+ rcu_barrier(); -+ if (mp_rcu_data != NULL) { -+ rcu_thread = get_call_rcu_thread(mp_rcu_data); -+ /* detach this thread from the RCU thread */ -+ set_thread_call_rcu_data(NULL); -+ synchronize_rcu(); -+ /* tell RCU thread to exit */ -+ call_rcu_data_free(mp_rcu_data); -+ pthread_join(rcu_thread, NULL); -+ } -+ rcu_unregister_thread(); -+} -+ - static int - child (__attribute__((unused)) void *param) - { -@@ -2906,7 +2948,8 @@ child (__attribute__((unused)) void *param) - - mlockall(MCL_CURRENT | MCL_FUTURE); - signal_init(); -- rcu_init(); -+ mp_rcu_data = setup_rcu(); -+ atexit(cleanup_rcu); - - setup_thread_attr(&misc_attr, 64 * 1024, 0); - setup_thread_attr(&uevent_attr, DEFAULT_UEVENT_STACKSIZE * 1024, 0); diff --git a/0041-multipathd-move-handling-of-io_err_stat_attr-into-li.patch b/0041-multipathd-move-handling-of-io_err_stat_attr-into-li.patch deleted file mode 100644 index 8a0e23d..0000000 --- a/0041-multipathd-move-handling-of-io_err_stat_attr-into-li.patch +++ /dev/null @@ -1,143 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 23 Sep 2020 10:33:12 +0200 -Subject: [PATCH] multipathd: move handling of io_err_stat_attr into - libmultipath - -This thread attribute can be dynamically initialized and destroyed. -No need to carry it along in multipathd. Removal of the symbol -requires to bump the ABI version to 3. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/io_err_stat.c | 7 +++++-- - libmultipath/libmultipath.version | 23 ++++++++--------------- - multipathd/main.c | 2 -- - 3 files changed, 13 insertions(+), 19 deletions(-) - -diff --git a/libmultipath/io_err_stat.c b/libmultipath/io_err_stat.c -index 58bc1dd2..5363049d 100644 ---- a/libmultipath/io_err_stat.c -+++ b/libmultipath/io_err_stat.c -@@ -34,6 +34,7 @@ - #include "lock.h" - #include "time-util.h" - #include "io_err_stat.h" -+#include "util.h" - - #define TIMEOUT_NO_IO_NSEC 10000000 /*10ms = 10000000ns*/ - #define FLAKY_PATHFAIL_THRESHOLD 2 -@@ -70,8 +71,7 @@ struct io_err_stat_path { - int err_rate_threshold; - }; - --pthread_t io_err_stat_thr; --pthread_attr_t io_err_stat_attr; -+static pthread_t io_err_stat_thr; - - static pthread_mutex_t io_err_thread_lock = PTHREAD_MUTEX_INITIALIZER; - static pthread_cond_t io_err_thread_cond = PTHREAD_COND_INITIALIZER; -@@ -727,6 +727,7 @@ static void *io_err_stat_loop(void *data) - int start_io_err_stat_thread(void *data) - { - int ret; -+ pthread_attr_t io_err_stat_attr; - - if (uatomic_read(&io_err_thread_running) == 1) - return 0; -@@ -739,6 +740,7 @@ int start_io_err_stat_thread(void *data) - if (!paths) - goto destroy_ctx; - -+ setup_thread_attr(&io_err_stat_attr, 32 * 1024, 0); - pthread_mutex_lock(&io_err_thread_lock); - pthread_cleanup_push(cleanup_unlock, &io_err_thread_lock); - -@@ -750,6 +752,7 @@ int start_io_err_stat_thread(void *data) - &io_err_thread_lock) == 0); - - pthread_cleanup_pop(1); -+ pthread_attr_destroy(&io_err_stat_attr); - - if (ret) { - io_err_stat_log(0, "cannot create io_error statistic thread"); -diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version -index 0c300c81..84beb7f0 100644 ---- a/libmultipath/libmultipath.version -+++ b/libmultipath/libmultipath.version -@@ -31,7 +31,7 @@ - * The new version inherits the previous ones. - */ - --LIBMULTIPATH_2.0.0 { -+LIBMULTIPATH_3.0.0 { - global: - /* symbols referenced by multipath and multipathd */ - add_foreign; -@@ -121,7 +121,6 @@ global: - init_checkers; - init_foreign; - init_prio; -- io_err_stat_attr; - io_err_stat_handle_pathfail; - is_path_valid; - is_quote; -@@ -242,30 +241,24 @@ global: - free_scandir_result; - sysfs_attr_get_value; - --local: -- *; --}; -- --LIBMULTIPATH_2.1.0 { --global: -+ /* added in 2.1.0 */ - libmp_dm_task_run; - cleanup_mutex; --} LIBMULTIPATH_2.0.0; - --LIBMULTIPATH_2.2.0 { --global: -+ /* added in 2.2.0 */ - libmp_get_multipath_config; - get_multipath_config; - libmp_put_multipath_config; - put_multipath_config; - init_config; - uninit_config; --} LIBMULTIPATH_2.1.0; - --LIBMULTIPATH_2.3.0 { --global: -+ /* added in 2.3.0 */ - udev; - logsink; - libmultipath_init; - libmultipath_exit; --} LIBMULTIPATH_2.2.0; -+ -+local: -+ *; -+}; -diff --git a/multipathd/main.c b/multipathd/main.c -index ce14bb66..abc6a9f7 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -2954,7 +2954,6 @@ child (__attribute__((unused)) void *param) - setup_thread_attr(&misc_attr, 64 * 1024, 0); - setup_thread_attr(&uevent_attr, DEFAULT_UEVENT_STACKSIZE * 1024, 0); - setup_thread_attr(&waiter_attr, 32 * 1024, 1); -- setup_thread_attr(&io_err_stat_attr, 32 * 1024, 0); - - if (logsink == 1) { - setup_thread_attr(&log_attr, 64 * 1024, 0); -@@ -3164,7 +3163,6 @@ child (__attribute__((unused)) void *param) - rcu_assign_pointer(multipath_conf, NULL); - call_rcu(&conf->rcu, rcu_free_config); - pthread_attr_destroy(&waiter_attr); -- pthread_attr_destroy(&io_err_stat_attr); - #ifdef _DEBUG_ - dbg_free_final(NULL); - #endif diff --git a/0042-multipathd-move-vecs-desctruction-into-cleanup-funct.patch b/0042-multipathd-move-vecs-desctruction-into-cleanup-funct.patch deleted file mode 100644 index 1c0c3fd..0000000 --- a/0042-multipathd-move-vecs-desctruction-into-cleanup-funct.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 23 Sep 2020 18:05:40 +0200 -Subject: [PATCH] multipathd: move vecs desctruction into cleanup function - -This will make it easer to move the stuff around later. -The only functional change is that map destuction now happens after -joining all threads, which should actually improve robustness. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 64 +++++++++++++++++++++++++++++------------------ - 1 file changed, 40 insertions(+), 24 deletions(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index abc6a9f7..3da0d7cc 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -148,7 +148,7 @@ int should_exit(void) - /* - * global copy of vecs for use in sig handlers - */ --struct vectors * gvecs; -+static struct vectors * gvecs; - - struct config *multipath_conf; - -@@ -2889,6 +2889,44 @@ set_oom_adj (void) - condlog(0, "couldn't adjust oom score"); - } - -+static void cleanup_maps(struct vectors *vecs) -+{ -+ int queue_without_daemon, i; -+ struct multipath *mpp; -+ struct config *conf; -+ -+ conf = get_multipath_config(); -+ queue_without_daemon = conf->queue_without_daemon; -+ put_multipath_config(conf); -+ if (queue_without_daemon == QUE_NO_DAEMON_OFF) -+ vector_foreach_slot(vecs->mpvec, mpp, i) -+ dm_queue_if_no_path(mpp->alias, 0); -+ remove_maps_and_stop_waiters(vecs); -+ vecs->mpvec = NULL; -+} -+ -+static void cleanup_paths(struct vectors *vecs) -+{ -+ free_pathvec(vecs->pathvec, FREE_PATHS); -+ vecs->pathvec = NULL; -+} -+ -+static void cleanup_vecs(void) -+{ -+ if (!gvecs) -+ return; -+ /* -+ * We can't take the vecs lock here, because exit() may -+ * have been called from the child() thread, holding the lock already. -+ * Anyway, by the time we get here, all threads that might access -+ * vecs should have been joined already (in cleanup_threads). -+ */ -+ cleanup_maps(gvecs); -+ cleanup_paths(gvecs); -+ pthread_mutex_destroy(&gvecs->lock.mutex); -+ FREE(gvecs); -+} -+ - /* - * Use a non-default call_rcu_data for child(). - * -@@ -2937,13 +2975,10 @@ child (__attribute__((unused)) void *param) - pthread_t check_thr, uevent_thr, uxlsnr_thr, uevq_thr, dmevent_thr; - pthread_attr_t log_attr, misc_attr, uevent_attr; - struct vectors * vecs; -- struct multipath * mpp; -- int i; - int rc; - int pid_fd = -1; - struct config *conf; - char *envp; -- int queue_without_daemon; - enum daemon_status state; - - mlockall(MCL_CURRENT | MCL_FUTURE); -@@ -3108,17 +3143,6 @@ child (__attribute__((unused)) void *param) - if (poll_dmevents) - pthread_cancel(dmevent_thr); - -- conf = get_multipath_config(); -- queue_without_daemon = conf->queue_without_daemon; -- put_multipath_config(conf); -- -- lock(&vecs->lock); -- if (queue_without_daemon == QUE_NO_DAEMON_OFF) -- vector_foreach_slot(vecs->mpvec, mpp, i) -- dm_queue_if_no_path(mpp->alias, 0); -- remove_maps_and_stop_waiters(vecs); -- unlock(&vecs->lock); -- - pthread_join(check_thr, NULL); - pthread_join(uevent_thr, NULL); - pthread_join(uxlsnr_thr, NULL); -@@ -3128,15 +3152,7 @@ child (__attribute__((unused)) void *param) - - stop_io_err_stat_thread(); - -- lock(&vecs->lock); -- free_pathvec(vecs->pathvec, FREE_PATHS); -- vecs->pathvec = NULL; -- unlock(&vecs->lock); -- -- pthread_mutex_destroy(&vecs->lock.mutex); -- FREE(vecs); -- vecs = NULL; -- -+ cleanup_vecs(); - cleanup_foreign(); - cleanup_checkers(); - cleanup_prio(); diff --git a/0043-multipathd-make-some-globals-static.patch b/0043-multipathd-make-some-globals-static.patch deleted file mode 100644 index c7fb5ce..0000000 --- a/0043-multipathd-make-some-globals-static.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 23 Sep 2020 11:18:02 +0200 -Subject: [PATCH] multipathd: make some globals static - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 14 +++++++------- - 1 file changed, 7 insertions(+), 7 deletions(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 3da0d7cc..eb760a71 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -116,19 +116,19 @@ struct mpath_event_param - }; - - int uxsock_timeout; --int verbosity; --int bindings_read_only; -+static int verbosity; -+static int bindings_read_only; - int ignore_new_devs; - #ifdef NO_DMEVENTS_POLL --int poll_dmevents = 0; -+static int poll_dmevents = 0; - #else --int poll_dmevents = 1; -+static int poll_dmevents = 1; - #endif - /* Don't access this variable without holding config_lock */ --volatile enum daemon_status running_state = DAEMON_INIT; -+static volatile enum daemon_status running_state = DAEMON_INIT; - pid_t daemon_pid; --pthread_mutex_t config_lock = PTHREAD_MUTEX_INITIALIZER; --pthread_cond_t config_cond; -+static pthread_mutex_t config_lock = PTHREAD_MUTEX_INITIALIZER; -+static pthread_cond_t config_cond; - - static inline enum daemon_status get_running_state(void) - { diff --git a/0044-multipathd-move-threads-destruction-into-separate-fu.patch b/0044-multipathd-move-threads-destruction-into-separate-fu.patch deleted file mode 100644 index 2e069ff..0000000 --- a/0044-multipathd-move-threads-destruction-into-separate-fu.patch +++ /dev/null @@ -1,161 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 23 Sep 2020 11:18:44 +0200 -Subject: [PATCH] multipathd: move threads destruction into separate function - -Also, introduce booleans that indicate a certain thread has -been started successfully. Using these booleans, we can avoid -crashing by cancelling threads that have never been started. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 76 +++++++++++++++++++++++++++++++---------------- - 1 file changed, 51 insertions(+), 25 deletions(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index eb760a71..9eb658d4 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -129,6 +129,9 @@ static volatile enum daemon_status running_state = DAEMON_INIT; - pid_t daemon_pid; - static pthread_mutex_t config_lock = PTHREAD_MUTEX_INITIALIZER; - static pthread_cond_t config_cond; -+static pthread_t check_thr, uevent_thr, uxlsnr_thr, uevq_thr, dmevent_thr; -+static bool check_thr_started, uevent_thr_started, uxlsnr_thr_started, -+ uevq_thr_started, dmevent_thr_started; - - static inline enum daemon_status get_running_state(void) - { -@@ -2927,6 +2930,39 @@ static void cleanup_vecs(void) - FREE(gvecs); - } - -+static void cleanup_threads(void) -+{ -+ stop_io_err_stat_thread(); -+ -+ if (check_thr_started) -+ pthread_cancel(check_thr); -+ if (uevent_thr_started) -+ pthread_cancel(uevent_thr); -+ if (uxlsnr_thr_started) -+ pthread_cancel(uxlsnr_thr); -+ if (uevq_thr_started) -+ pthread_cancel(uevq_thr); -+ if (dmevent_thr_started) -+ pthread_cancel(dmevent_thr); -+ -+ if (check_thr_started) -+ pthread_join(check_thr, NULL); -+ if (uevent_thr_started) -+ pthread_join(uevent_thr, NULL); -+ if (uxlsnr_thr_started) -+ pthread_join(uxlsnr_thr, NULL); -+ if (uevq_thr_started) -+ pthread_join(uevq_thr, NULL); -+ if (dmevent_thr_started) -+ pthread_join(dmevent_thr, NULL); -+ -+ /* -+ * As all threads are joined now, and we're in DAEMON_SHUTDOWN -+ * state, no new waiter threads will be created any more. -+ */ -+ pthread_attr_destroy(&waiter_attr); -+} -+ - /* - * Use a non-default call_rcu_data for child(). - * -@@ -2972,7 +3008,6 @@ static void cleanup_rcu(void) - static int - child (__attribute__((unused)) void *param) - { -- pthread_t check_thr, uevent_thr, uxlsnr_thr, uevq_thr, dmevent_thr; - pthread_attr_t log_attr, misc_attr, uevent_attr; - struct vectors * vecs; - int rc; -@@ -3070,9 +3105,12 @@ child (__attribute__((unused)) void *param) - condlog(0, "failed to create cli listener: %d", rc); - goto failed; - } -- else if (state != DAEMON_CONFIGURE) { -- condlog(0, "cli listener failed to start"); -- goto failed; -+ else { -+ uxlsnr_thr_started = true; -+ if (state != DAEMON_CONFIGURE) { -+ condlog(0, "cli listener failed to start"); -+ goto failed; -+ } - } - - if (poll_dmevents) { -@@ -3085,7 +3123,8 @@ child (__attribute__((unused)) void *param) - condlog(0, "failed to create dmevent waiter thread: %d", - rc); - goto failed; -- } -+ } else -+ dmevent_thr_started = true; - } - - /* -@@ -3094,7 +3133,8 @@ child (__attribute__((unused)) void *param) - if ((rc = pthread_create(&uevent_thr, &uevent_attr, ueventloop, udev))) { - condlog(0, "failed to create uevent thread: %d", rc); - goto failed; -- } -+ } else -+ uevent_thr_started = true; - pthread_attr_destroy(&uevent_attr); - - /* -@@ -3103,11 +3143,13 @@ child (__attribute__((unused)) void *param) - if ((rc = pthread_create(&check_thr, &misc_attr, checkerloop, vecs))) { - condlog(0,"failed to create checker loop thread: %d", rc); - goto failed; -- } -+ } else -+ check_thr_started = true; - if ((rc = pthread_create(&uevq_thr, &misc_attr, uevqloop, vecs))) { - condlog(0, "failed to create uevent dispatcher: %d", rc); - goto failed; -- } -+ } else -+ uevq_thr_started = true; - pthread_attr_destroy(&misc_attr); - - while (1) { -@@ -3136,22 +3178,7 @@ child (__attribute__((unused)) void *param) - } - } - -- pthread_cancel(check_thr); -- pthread_cancel(uevent_thr); -- pthread_cancel(uxlsnr_thr); -- pthread_cancel(uevq_thr); -- if (poll_dmevents) -- pthread_cancel(dmevent_thr); -- -- pthread_join(check_thr, NULL); -- pthread_join(uevent_thr, NULL); -- pthread_join(uxlsnr_thr, NULL); -- pthread_join(uevq_thr, NULL); -- if (poll_dmevents) -- pthread_join(dmevent_thr, NULL); -- -- stop_io_err_stat_thread(); -- -+ cleanup_threads(); - cleanup_vecs(); - cleanup_foreign(); - cleanup_checkers(); -@@ -3178,7 +3205,6 @@ child (__attribute__((unused)) void *param) - conf = rcu_dereference(multipath_conf); - rcu_assign_pointer(multipath_conf, NULL); - call_rcu(&conf->rcu, rcu_free_config); -- pthread_attr_destroy(&waiter_attr); - #ifdef _DEBUG_ - dbg_free_final(NULL); - #endif diff --git a/0045-multipathd-move-conf-destruction-into-separate-funct.patch b/0045-multipathd-move-conf-destruction-into-separate-funct.patch deleted file mode 100644 index c6ea6b2..0000000 --- a/0045-multipathd-move-conf-destruction-into-separate-funct.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 23 Sep 2020 12:38:50 +0200 -Subject: [PATCH] multipathd: move conf destruction into separate function - -Also removing the comment about dlog() and dm_write_log(). -dlog() can cope with get_multipath_config() returning NULL, -and dm_write_log() hasn't accessed the configuration for a while. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 20 +++++++++++--------- - 1 file changed, 11 insertions(+), 9 deletions(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 9eb658d4..07973e85 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -2892,6 +2892,16 @@ set_oom_adj (void) - condlog(0, "couldn't adjust oom score"); - } - -+static void cleanup_conf(void) { -+ struct config *conf; -+ -+ conf = rcu_dereference(multipath_conf); -+ if (!conf) -+ return; -+ rcu_assign_pointer(multipath_conf, NULL); -+ call_rcu(&conf->rcu, rcu_free_config); -+} -+ - static void cleanup_maps(struct vectors *vecs) - { - int queue_without_daemon, i; -@@ -3196,15 +3206,7 @@ child (__attribute__((unused)) void *param) - - if (logsink == 1) - log_thread_stop(); -- -- /* -- * Freeing config must be done after condlog() and dm_lib_exit(), -- * because logging functions like dlog() and dm_write_log() -- * reference the config. -- */ -- conf = rcu_dereference(multipath_conf); -- rcu_assign_pointer(multipath_conf, NULL); -- call_rcu(&conf->rcu, rcu_free_config); -+ cleanup_conf(); - #ifdef _DEBUG_ - dbg_free_final(NULL); - #endif diff --git a/0046-multipathd-move-pid-destruction-into-separate-functi.patch b/0046-multipathd-move-pid-destruction-into-separate-functi.patch deleted file mode 100644 index 70220dd..0000000 --- a/0046-multipathd-move-pid-destruction-into-separate-functi.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 23 Sep 2020 16:10:19 +0200 -Subject: [PATCH] multipathd: move pid destruction into separate function - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 10 +++++++--- - 1 file changed, 7 insertions(+), 3 deletions(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 07973e85..fc1f8d7f 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -2892,6 +2892,12 @@ set_oom_adj (void) - condlog(0, "couldn't adjust oom score"); - } - -+static void cleanup_pidfile(void) -+{ -+ condlog(3, "unlink pidfile"); -+ unlink(DEFAULT_PIDFILE); -+} -+ - static void cleanup_conf(void) { - struct config *conf; - -@@ -3199,9 +3205,7 @@ child (__attribute__((unused)) void *param) - dm_lib_exit(); - - /* We're done here */ -- condlog(3, "unlink pidfile"); -- unlink(DEFAULT_PIDFILE); -- -+ cleanup_pidfile(); - condlog(2, "--------shut down-------"); - - if (logsink == 1) diff --git a/0047-multipathd-close-pidfile-on-exit.patch b/0047-multipathd-close-pidfile-on-exit.patch deleted file mode 100644 index fa3a5e9..0000000 --- a/0047-multipathd-close-pidfile-on-exit.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 23 Sep 2020 16:27:33 +0200 -Subject: [PATCH] multipathd: close pidfile on exit - -It seems we've been doing this only in the failure case, for ages. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index fc1f8d7f..f6b80668 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -132,6 +132,7 @@ static pthread_cond_t config_cond; - static pthread_t check_thr, uevent_thr, uxlsnr_thr, uevq_thr, dmevent_thr; - static bool check_thr_started, uevent_thr_started, uxlsnr_thr_started, - uevq_thr_started, dmevent_thr_started; -+static int pid_fd = -1; - - static inline enum daemon_status get_running_state(void) - { -@@ -2894,6 +2895,8 @@ set_oom_adj (void) - - static void cleanup_pidfile(void) - { -+ if (pid_fd >= 0) -+ close(pid_fd); - condlog(3, "unlink pidfile"); - unlink(DEFAULT_PIDFILE); - } -@@ -3027,7 +3030,6 @@ child (__attribute__((unused)) void *param) - pthread_attr_t log_attr, misc_attr, uevent_attr; - struct vectors * vecs; - int rc; -- int pid_fd = -1; - struct config *conf; - char *envp; - enum daemon_status state; diff --git a/0048-multipathd-add-helper-for-systemd-notification-at-ex.patch b/0048-multipathd-add-helper-for-systemd-notification-at-ex.patch deleted file mode 100644 index 8dfe28e..0000000 --- a/0048-multipathd-add-helper-for-systemd-notification-at-ex.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 23 Sep 2020 17:49:02 +0200 -Subject: [PATCH] multipathd: add helper for systemd notification at exit - -Add sd_notify_exit(). - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 22 +++++++++++++--------- - 1 file changed, 13 insertions(+), 9 deletions(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index f6b80668..07068e4a 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -3024,6 +3024,17 @@ static void cleanup_rcu(void) - rcu_unregister_thread(); - } - -+static int sd_notify_exit(int err) -+{ -+#ifdef USE_SYSTEMD -+ char msg[24]; -+ -+ snprintf(msg, sizeof(msg), "ERRNO=%d", err); -+ sd_notify(0, msg); -+#endif -+ return err; -+} -+ - static int - child (__attribute__((unused)) void *param) - { -@@ -3216,19 +3227,12 @@ child (__attribute__((unused)) void *param) - #ifdef _DEBUG_ - dbg_free_final(NULL); - #endif -- --#ifdef USE_SYSTEMD -- sd_notify(0, "ERRNO=0"); --#endif -- exit(0); -+ exit(sd_notify_exit(0)); - - failed: --#ifdef USE_SYSTEMD -- sd_notify(0, "ERRNO=1"); --#endif - if (pid_fd >= 0) - close(pid_fd); -- exit(1); -+ exit(sd_notify_exit(1)); - } - - static int diff --git a/0049-multipathd-child-call-cleanups-in-failure-case-too.patch b/0049-multipathd-child-call-cleanups-in-failure-case-too.patch deleted file mode 100644 index 85bd5f4..0000000 --- a/0049-multipathd-child-call-cleanups-in-failure-case-too.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 23 Sep 2020 17:57:16 +0200 -Subject: [PATCH] multipathd: child(): call cleanups in failure case, too - -So far we haven't called any cleanup code if child() failed. -Fix it. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 10 ++++------ - 1 file changed, 4 insertions(+), 6 deletions(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 07068e4a..6b9e323e 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -3044,6 +3044,7 @@ child (__attribute__((unused)) void *param) - struct config *conf; - char *envp; - enum daemon_status state; -+ int exit_code = 1; - - mlockall(MCL_CURRENT | MCL_FUTURE); - signal_init(); -@@ -3207,6 +3208,8 @@ child (__attribute__((unused)) void *param) - } - } - -+ exit_code = 0; -+failed: - cleanup_threads(); - cleanup_vecs(); - cleanup_foreign(); -@@ -3227,12 +3230,7 @@ child (__attribute__((unused)) void *param) - #ifdef _DEBUG_ - dbg_free_final(NULL); - #endif -- exit(sd_notify_exit(0)); -- --failed: -- if (pid_fd >= 0) -- close(pid_fd); -- exit(sd_notify_exit(1)); -+ return sd_notify_exit(exit_code); - } - - static int diff --git a/0050-multipathd-unwatch_all_dmevents-check-if-waiter-is-i.patch b/0050-multipathd-unwatch_all_dmevents-check-if-waiter-is-i.patch deleted file mode 100644 index 2629bab..0000000 --- a/0050-multipathd-unwatch_all_dmevents-check-if-waiter-is-i.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 23 Sep 2020 18:45:30 +0200 -Subject: [PATCH] multipathd: unwatch_all_dmevents: check if waiter is - initialized - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipathd/dmevents.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/multipathd/dmevents.c b/multipathd/dmevents.c -index b561cbfd..f52f5970 100644 ---- a/multipathd/dmevents.c -+++ b/multipathd/dmevents.c -@@ -257,6 +257,8 @@ void unwatch_all_dmevents(void) - struct dev_event *dev_evt; - int i; - -+ if (!waiter) -+ return; - pthread_mutex_lock(&waiter->events_lock); - vector_foreach_slot(waiter->events, dev_evt, i) - free(dev_evt); diff --git a/0051-multipathd-print-error-message-if-config-can-t-be-lo.patch b/0051-multipathd-print-error-message-if-config-can-t-be-lo.patch deleted file mode 100644 index 0d51d12..0000000 --- a/0051-multipathd-print-error-message-if-config-can-t-be-lo.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 23 Sep 2020 18:45:51 +0200 -Subject: [PATCH] multipathd: print error message if config can't be loaded - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 6b9e323e..7ab3eab8 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -3074,8 +3074,10 @@ child (__attribute__((unused)) void *param) - condlog(2, "read " DEFAULT_CONFIGFILE); - - conf = load_config(DEFAULT_CONFIGFILE); -- if (!conf) -+ if (!conf) { -+ condlog(0, "failed to load configuration"); - goto failed; -+ } - - if (verbosity) - conf->verbosity = verbosity; diff --git a/0052-libmultipath-add-libmp_dm_exit.patch b/0052-libmultipath-add-libmp_dm_exit.patch deleted file mode 100644 index 86baccd..0000000 --- a/0052-libmultipath-add-libmp_dm_exit.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 23 Sep 2020 21:02:45 +0200 -Subject: [PATCH] libmultipath: add libmp_dm_exit() - -This function prepares for calling dm_lib_exit() on program exit. -It undoes changes to libdm internals done by libmultipath. -It doesn't call dm_lib_exit(), as the caller may want to keep -libdm active. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/config.c | 1 + - libmultipath/config.h | 2 ++ - libmultipath/devmapper.c | 15 +++++++++++++++ - libmultipath/devmapper.h | 1 + - 4 files changed, 19 insertions(+) - -diff --git a/libmultipath/config.c b/libmultipath/config.c -index f74417c6..b9cb4131 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -60,6 +60,7 @@ int libmultipath_init(void) - static void _libmultipath_exit(void) - { - libmultipath_exit_called = true; -+ libmp_dm_exit(); - udev_unref(udev); - } - -diff --git a/libmultipath/config.h b/libmultipath/config.h -index f478df71..5d460359 100644 ---- a/libmultipath/config.h -+++ b/libmultipath/config.h -@@ -271,6 +271,8 @@ int libmultipath_init(void); - * - * This function un-initializes libmultipath data structures. - * It is recommended to call this function at program exit. -+ * If the application also calls dm_lib_exit(), it should do so -+ * after libmultipath_exit(). - * - * Calls to libmultipath_init() after libmultipath_exit() will fail - * (in other words, libmultipath can't be re-initialized). -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index 4eb6f539..e60ab493 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -335,6 +335,20 @@ void libmp_udev_set_sync_support(int on) - libmp_dm_udev_sync = !!on; - } - -+static bool libmp_dm_init_called; -+void libmp_dm_exit(void) -+{ -+ if (!libmp_dm_init_called) -+ return; -+ -+ /* switch back to default libdm logging */ -+ dm_log_init(NULL); -+#ifdef LIBDM_API_HOLD_CONTROL -+ /* make sure control fd is closed in dm_lib_release() */ -+ dm_hold_control_dev(0); -+#endif -+} -+ - static void libmp_dm_init(void) - { - struct config *conf; -@@ -351,6 +365,7 @@ static void libmp_dm_init(void) - dm_hold_control_dev(1); - #endif - dm_udev_set_sync_support(libmp_dm_udev_sync); -+ libmp_dm_init_called = true; - } - - static void _do_skip_libmp_dm_init(void) -diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h -index fa6b3c53..e29b4d41 100644 ---- a/libmultipath/devmapper.h -+++ b/libmultipath/devmapper.h -@@ -35,6 +35,7 @@ enum { - - int dm_prereq(unsigned int *v); - void skip_libmp_dm_init(void); -+void libmp_dm_exit(void); - void libmp_udev_set_sync_support(int on); - struct dm_task *libmp_dm_task_create(int task); - int dm_simplecmd_flush (int, const char *, uint16_t); diff --git a/0053-multipathd-fixup-libdm-deinitialization.patch b/0053-multipathd-fixup-libdm-deinitialization.patch deleted file mode 100644 index b12d925..0000000 --- a/0053-multipathd-fixup-libdm-deinitialization.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 23 Sep 2020 21:06:13 +0200 -Subject: [PATCH] multipathd: fixup libdm deinitialization - -With libmp_dm_exit() in place, we can make sure that the -calls are made in the right order. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 7ab3eab8..4c4e2eab 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -3220,8 +3220,6 @@ failed: - if (poll_dmevents) - cleanup_dmevent_waiter(); - -- dm_lib_exit(); -- - /* We're done here */ - cleanup_pidfile(); - condlog(2, "--------shut down-------"); -@@ -3318,6 +3316,9 @@ main (int argc, char *argv[]) - - pthread_cond_init_mono(&config_cond); - -+ if (atexit(dm_lib_exit)) -+ condlog(3, "failed to register exit handler for libdm"); -+ - libmultipath_init(); - if (atexit(libmultipath_exit)) - condlog(3, "failed to register exit handler for libmultipath"); diff --git a/0054-libmultipath-log_thread_stop-check-if-logarea-is-ini.patch b/0054-libmultipath-log_thread_stop-check-if-logarea-is-ini.patch deleted file mode 100644 index 32a6fc8..0000000 --- a/0054-libmultipath-log_thread_stop-check-if-logarea-is-ini.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 23 Sep 2020 21:04:04 +0200 -Subject: [PATCH] libmultipath: log_thread_stop(): check if logarea is - initialized - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/log_pthread.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/libmultipath/log_pthread.c b/libmultipath/log_pthread.c -index 15baef88..0c327ffc 100644 ---- a/libmultipath/log_pthread.c -+++ b/libmultipath/log_pthread.c -@@ -112,6 +112,9 @@ void log_thread_reset (void) - - void log_thread_stop (void) - { -+ if (!la) -+ return; -+ - logdbg(stderr,"enter log_thread_stop\n"); - - pthread_mutex_lock(&logev_lock); diff --git a/0055-multipathd-add-cleanup_child-exit-handler.patch b/0055-multipathd-add-cleanup_child-exit-handler.patch deleted file mode 100644 index a031baa..0000000 --- a/0055-multipathd-add-cleanup_child-exit-handler.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 23 Sep 2020 21:08:19 +0200 -Subject: [PATCH] multipathd: add cleanup_child() exit handler - -cleanup_child() calls all cleanups in the right order, in an -exit handler. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 45 +++++++++++++++++++++++++-------------------- - 1 file changed, 25 insertions(+), 20 deletions(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 4c4e2eab..50cc3356 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -3024,6 +3024,27 @@ static void cleanup_rcu(void) - rcu_unregister_thread(); - } - -+static void cleanup_child(void) -+{ -+ cleanup_threads(); -+ cleanup_vecs(); -+ cleanup_foreign(); -+ cleanup_checkers(); -+ cleanup_prio(); -+ if (poll_dmevents) -+ cleanup_dmevent_waiter(); -+ -+ cleanup_pidfile(); -+ if (logsink == 1) -+ log_thread_stop(); -+ -+ cleanup_conf(); -+ -+#ifdef _DEBUG_ -+ dbg_free_final(NULL); -+#endif -+} -+ - static int sd_notify_exit(int err) - { - #ifdef USE_SYSTEMD -@@ -3049,7 +3070,9 @@ child (__attribute__((unused)) void *param) - mlockall(MCL_CURRENT | MCL_FUTURE); - signal_init(); - mp_rcu_data = setup_rcu(); -- atexit(cleanup_rcu); -+ -+ if (atexit(cleanup_rcu) || atexit(cleanup_child)) -+ fprintf(stderr, "failed to register cleanup handlers\n"); - - setup_thread_attr(&misc_attr, 64 * 1024, 0); - setup_thread_attr(&uevent_attr, DEFAULT_UEVENT_STACKSIZE * 1024, 0); -@@ -3063,8 +3086,6 @@ child (__attribute__((unused)) void *param) - pid_fd = pidfile_create(DEFAULT_PIDFILE, daemon_pid); - if (pid_fd < 0) { - condlog(1, "failed to create pidfile"); -- if (logsink == 1) -- log_thread_stop(); - exit(1); - } - -@@ -3212,24 +3233,8 @@ child (__attribute__((unused)) void *param) - - exit_code = 0; - failed: -- cleanup_threads(); -- cleanup_vecs(); -- cleanup_foreign(); -- cleanup_checkers(); -- cleanup_prio(); -- if (poll_dmevents) -- cleanup_dmevent_waiter(); -- -- /* We're done here */ -- cleanup_pidfile(); - condlog(2, "--------shut down-------"); -- -- if (logsink == 1) -- log_thread_stop(); -- cleanup_conf(); --#ifdef _DEBUG_ -- dbg_free_final(NULL); --#endif -+ /* All cleanup is done in the cleanup_child() exit handler */ - return sd_notify_exit(exit_code); - } - diff --git a/0056-libmultipath-fix-log_thread-startup-and-teardown.patch b/0056-libmultipath-fix-log_thread-startup-and-teardown.patch deleted file mode 100644 index 0804551..0000000 --- a/0056-libmultipath-fix-log_thread-startup-and-teardown.patch +++ /dev/null @@ -1,145 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 26 Oct 2020 16:44:32 +0100 -Subject: [PATCH] libmultipath: fix log_thread startup and teardown - -This fixes several issues with the log_thread. First, the running flag -logq_running should be set by the thread itself, not by -log_thread_start()/_stop(). Second, the thread was both cancelled and -terminated via a flag (again, logq_running). It's sufficient to just cancel -and join it. Third, the locking wasn't cancel-safe in some places. Forth, -log_thread_start() didn't wait for startup properly. Fifth, using (pthread_t)0 -is wrong (pthread_t is opaque; there's no guarantee that 0 is not a valid -pthread_t value). Sixth, pthread_cancel() was called under logq_lock, which -doesn't make sense to me. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/log_pthread.c | 62 +++++++++++++++++++++++++++----------- - 1 file changed, 45 insertions(+), 17 deletions(-) - -diff --git a/libmultipath/log_pthread.c b/libmultipath/log_pthread.c -index 0c327ffc..3a2566ae 100644 ---- a/libmultipath/log_pthread.c -+++ b/libmultipath/log_pthread.c -@@ -13,6 +13,7 @@ - #include "log_pthread.h" - #include "log.h" - #include "lock.h" -+#include "util.h" - - static pthread_t log_thr; - -@@ -56,35 +57,52 @@ static void flush_logqueue (void) - } while (empty == 0); - } - -+static void cleanup_log_thread(__attribute((unused)) void *arg) -+{ -+ logdbg(stderr, "log thread exiting"); -+ pthread_mutex_lock(&logev_lock); -+ logq_running = 0; -+ pthread_mutex_unlock(&logev_lock); -+} -+ - static void * log_thread (__attribute__((unused)) void * et) - { - int running; - - pthread_mutex_lock(&logev_lock); -- logq_running = 1; -+ running = logq_running; -+ if (!running) -+ logq_running = 1; -+ pthread_cond_signal(&logev_cond); - pthread_mutex_unlock(&logev_lock); -+ if (running) -+ /* already started */ -+ return NULL; -+ pthread_cleanup_push(cleanup_log_thread, NULL); - - mlockall(MCL_CURRENT | MCL_FUTURE); - logdbg(stderr,"enter log_thread\n"); - - while (1) { - pthread_mutex_lock(&logev_lock); -- if (logq_running && !log_messages_pending) -+ pthread_cleanup_push(cleanup_mutex, &logev_lock); -+ while (!log_messages_pending) -+ /* this is a cancellation point */ - pthread_cond_wait(&logev_cond, &logev_lock); - log_messages_pending = 0; -- running = logq_running; -- pthread_mutex_unlock(&logev_lock); -- if (!running) -- break; -+ pthread_cleanup_pop(1); -+ - flush_logqueue(); - } -+ pthread_cleanup_pop(1); - return NULL; - } - - void log_thread_start (pthread_attr_t *attr) - { -- logdbg(stderr,"enter log_thread_start\n"); -+ int running = 0; - -+ logdbg(stderr,"enter log_thread_start\n"); - pthread_mutex_init(&logq_lock, NULL); - pthread_mutex_init(&logev_lock, NULL); - pthread_cond_init(&logev_cond, NULL); -@@ -93,7 +111,15 @@ void log_thread_start (pthread_attr_t *attr) - fprintf(stderr,"can't initialize log buffer\n"); - exit(1); - } -- if (pthread_create(&log_thr, attr, log_thread, NULL)) { -+ -+ pthread_mutex_lock(&logev_lock); -+ pthread_cleanup_push(cleanup_mutex, &logev_lock); -+ if (!pthread_create(&log_thr, attr, log_thread, NULL)) -+ while (!(running = logq_running)) -+ pthread_cond_wait(&logev_cond, &logev_lock); -+ pthread_cleanup_pop(1); -+ -+ if (!running) { - fprintf(stderr,"can't start log thread\n"); - exit(1); - } -@@ -112,23 +138,25 @@ void log_thread_reset (void) - - void log_thread_stop (void) - { -+ int running; -+ - if (!la) - return; - - logdbg(stderr,"enter log_thread_stop\n"); - - pthread_mutex_lock(&logev_lock); -- logq_running = 0; -- pthread_cond_signal(&logev_cond); -- pthread_mutex_unlock(&logev_lock); -- -- pthread_mutex_lock(&logq_lock); -- pthread_cancel(log_thr); -- pthread_mutex_unlock(&logq_lock); -- pthread_join(log_thr, NULL); -- log_thr = (pthread_t)0; -+ pthread_cleanup_push(cleanup_mutex, &logev_lock); -+ running = logq_running; -+ if (running) { -+ pthread_cancel(log_thr); -+ pthread_cond_signal(&logev_cond); -+ } -+ pthread_cleanup_pop(1); - - flush_logqueue(); -+ if (running) -+ pthread_join(log_thr, NULL); - - pthread_mutex_destroy(&logq_lock); - pthread_mutex_destroy(&logev_lock); diff --git a/0057-multipathd-move-cleanup_-prio-checkers-foreign-to-li.patch b/0057-multipathd-move-cleanup_-prio-checkers-foreign-to-li.patch deleted file mode 100644 index 891b54f..0000000 --- a/0057-multipathd-move-cleanup_-prio-checkers-foreign-to-li.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 23 Sep 2020 21:57:22 +0200 -Subject: [PATCH] multipathd: move cleanup_{prio,checkers,foreign} to - libmultipath_exit - -This requires another major ABI bump. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmpathpersist/mpath_persist.c | 2 -- - libmultipath/config.c | 4 ++++ - libmultipath/libmultipath.version | 5 +---- - multipathd/main.c | 3 --- - 4 files changed, 5 insertions(+), 9 deletions(-) - -diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c -index e1d1cb76..9ebf91dd 100644 ---- a/libmpathpersist/mpath_persist.c -+++ b/libmpathpersist/mpath_persist.c -@@ -78,8 +78,6 @@ mpath_lib_init (void) - - static void libmpathpersist_cleanup(void) - { -- cleanup_prio(); -- cleanup_checkers(); - libmultipath_exit(); - dm_lib_exit(); - } -diff --git a/libmultipath/config.c b/libmultipath/config.c -index b9cb4131..52b1447b 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -26,6 +26,7 @@ - #include "devmapper.h" - #include "mpath_cmd.h" - #include "propsel.h" -+#include "foreign.h" - - /* - * We don't support re-initialization after -@@ -60,6 +61,9 @@ int libmultipath_init(void) - static void _libmultipath_exit(void) - { - libmultipath_exit_called = true; -+ cleanup_foreign(); -+ cleanup_checkers(); -+ cleanup_prio(); - libmp_dm_exit(); - udev_unref(udev); - } -diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version -index 84beb7f0..800cff22 100644 ---- a/libmultipath/libmultipath.version -+++ b/libmultipath/libmultipath.version -@@ -31,7 +31,7 @@ - * The new version inherits the previous ones. - */ - --LIBMULTIPATH_3.0.0 { -+LIBMULTIPATH_4.0.0 { - global: - /* symbols referenced by multipath and multipathd */ - add_foreign; -@@ -51,10 +51,7 @@ global: - checker_name; - checker_state_name; - check_foreign; -- cleanup_checkers; -- cleanup_foreign; - cleanup_lock; -- cleanup_prio; - close_fd; - coalesce_paths; - convert_dev; -diff --git a/multipathd/main.c b/multipathd/main.c -index 50cc3356..4de0978e 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -3028,9 +3028,6 @@ static void cleanup_child(void) - { - cleanup_threads(); - cleanup_vecs(); -- cleanup_foreign(); -- cleanup_checkers(); -- cleanup_prio(); - if (poll_dmevents) - cleanup_dmevent_waiter(); - diff --git a/0058-multipath-use-atexit-for-cleanup-handlers.patch b/0058-multipath-use-atexit-for-cleanup-handlers.patch deleted file mode 100644 index b07cf95..0000000 --- a/0058-multipath-use-atexit-for-cleanup-handlers.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 23 Sep 2020 00:30:02 +0200 -Subject: [PATCH] multipath: use atexit() for cleanup handlers - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/main.c | 37 ++++++++++++++++--------------------- - 1 file changed, 16 insertions(+), 21 deletions(-) - -diff --git a/multipath/main.c b/multipath/main.c -index 9ae46ed5..1949a1cd 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -452,13 +452,19 @@ static bool released_to_systemd(void) - return ret; - } - -+static struct vectors vecs; -+static void cleanup_vecs(void) -+{ -+ free_multipathvec(vecs.mpvec, KEEP_PATHS); -+ free_pathvec(vecs.pathvec, FREE_PATHS); -+} -+ - static int - configure (struct config *conf, enum mpath_cmds cmd, - enum devtypes dev_type, char *devpath) - { - vector curmp = NULL; - vector pathvec = NULL; -- struct vectors vecs; - int r = RTVL_FAIL, rc; - int di_flag = 0; - char * refwwid = NULL; -@@ -469,6 +475,7 @@ configure (struct config *conf, enum mpath_cmds cmd, - */ - curmp = vector_alloc(); - pathvec = vector_alloc(); -+ atexit(cleanup_vecs); - - if (!curmp || !pathvec) { - condlog(0, "can not allocate memory"); -@@ -580,9 +587,6 @@ out: - if (refwwid) - FREE(refwwid); - -- free_multipathvec(curmp, KEEP_PATHS); -- free_pathvec(pathvec, FREE_PATHS); -- - return r; - } - -@@ -808,9 +812,13 @@ main (int argc, char *argv[]) - bool enable_foreign = false; - - libmultipath_init(); -+ if (atexit(dm_lib_exit) || atexit(libmultipath_exit)) -+ condlog(1, "failed to register cleanup handler for libmultipath: %m"); - logsink = 0; - if (init_config(DEFAULT_CONFIGFILE)) - exit(RTVL_FAIL); -+ if (atexit(uninit_config)) -+ condlog(1, "failed to register cleanup handler for config: %m"); - conf = get_multipath_config(); - conf->retrigger_tries = 0; - conf->force_sync = 1; -@@ -887,7 +895,7 @@ main (int argc, char *argv[]) - break; - case 't': - r = dump_config(conf, NULL, NULL) ? RTVL_FAIL : RTVL_OK; -- goto out_free_config; -+ goto out; - case 'T': - cmd = CMD_DUMP_CONFIG; - break; -@@ -1048,26 +1056,13 @@ main (int argc, char *argv[]) - condlog(3, "restart multipath configuration process"); - - out: -- dm_lib_exit(); -- -- cleanup_foreign(); -- cleanup_prio(); -- cleanup_checkers(); -+ put_multipath_config(conf); -+ if (dev) -+ FREE(dev); - - if (dev_type == DEV_UEVENT) - closelog(); - --out_free_config: -- /* -- * Freeing config must be done after dm_lib_exit(), because -- * the logging function (dm_write_log()), which is called there, -- * references the config. -- */ -- put_multipath_config(conf); -- uninit_config(); -- libmultipath_exit(); -- if (dev) -- FREE(dev); - #ifdef _DEBUG_ - dbg_free_final(NULL); - #endif diff --git a/0059-mpathpersist-use-atexit-for-cleanup-handlers.patch b/0059-mpathpersist-use-atexit-for-cleanup-handlers.patch deleted file mode 100644 index 0c88e70..0000000 --- a/0059-mpathpersist-use-atexit-for-cleanup-handlers.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 23 Sep 2020 00:32:48 +0200 -Subject: [PATCH] mpathpersist: use atexit() for cleanup handlers - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - mpathpersist/main.c | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - -diff --git a/mpathpersist/main.c b/mpathpersist/main.c -index 3c2e6576..14245cc3 100644 ---- a/mpathpersist/main.c -+++ b/mpathpersist/main.c -@@ -641,11 +641,10 @@ int main(int argc, char *argv[]) - if (libmpathpersist_init()) { - exit(1); - } -+ if (atexit((void(*)(void))libmpathpersist_exit)) -+ fprintf(stderr, "failed to register cleanup handler for libmpathpersist: %m"); - - ret = handle_args(argc, argv, 0); -- -- libmpathpersist_exit(); -- - return (ret >= 0) ? ret : MPATH_PR_OTHER; - } - diff --git a/0060-multipath-fix-leak-in-check_path_valid.patch b/0060-multipath-fix-leak-in-check_path_valid.patch deleted file mode 100644 index 5c82a35..0000000 --- a/0060-multipath-fix-leak-in-check_path_valid.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 23 Sep 2020 23:30:50 +0200 -Subject: [PATCH] multipath: fix leak in check_path_valid() - -If path status was successfully determined before calling store_pathvec(), -free_path() wasn't called. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/main.c | 30 ++++++++++++++++++++---------- - 1 file changed, 20 insertions(+), 10 deletions(-) - -diff --git a/multipath/main.c b/multipath/main.c -index 1949a1cd..043d8fa7 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -93,7 +93,7 @@ void rcu_register_thread_memb(void) {} - void rcu_unregister_thread_memb(void) {} - - static int --filter_pathvec (vector pathvec, char * refwwid) -+filter_pathvec (vector pathvec, const char *refwwid) - { - int i; - struct path * pp; -@@ -594,8 +594,9 @@ static int - check_path_valid(const char *name, struct config *conf, bool is_uevent) - { - int fd, r = PATH_IS_ERROR; -- struct path *pp = NULL; -+ struct path *pp; - vector pathvec = NULL; -+ const char *wwid; - - pp = alloc_path(); - if (!pp) -@@ -664,14 +665,19 @@ check_path_valid(const char *name, struct config *conf, bool is_uevent) - - if (store_path(pathvec, pp) != 0) { - free_path(pp); -+ pp = NULL; - goto fail; -+ } else { -+ /* make sure path isn't freed twice */ -+ wwid = pp->wwid; -+ pp = NULL; - } - - /* For find_multipaths = SMART, if there is more than one path - * matching the refwwid, then the path is valid */ - if (path_discovery(pathvec, DI_SYSFS | DI_WWID) < 0) - goto fail; -- filter_pathvec(pathvec, pp->wwid); -+ filter_pathvec(pathvec, wwid); - if (VECTOR_SIZE(pathvec) > 1) - r = PATH_IS_VALID; - else -@@ -679,21 +685,25 @@ check_path_valid(const char *name, struct config *conf, bool is_uevent) - - out: - r = print_cmd_valid(r, pathvec, conf); -- free_pathvec(pathvec, FREE_PATHS); - /* - * multipath -u must exit with status 0, otherwise udev won't - * import its output. - */ - if (!is_uevent && r == PATH_IS_NOT_VALID) -- return RTVL_FAIL; -- return RTVL_OK; -+ r = RTVL_FAIL; -+ else -+ r = RTVL_OK; -+ goto cleanup; - - fail: -- if (pathvec) -- free_pathvec(pathvec, FREE_PATHS); -- else -+ r = RTVL_FAIL; -+ -+cleanup: -+ if (pp != NULL) - free_path(pp); -- return RTVL_FAIL; -+ if (pathvec != NULL) -+ free_pathvec(pathvec, FREE_PATHS); -+ return r; - } - - static int diff --git a/0061-multipath-tools-mpath-tools.supp-file-with-valgrind-.patch b/0061-multipath-tools-mpath-tools.supp-file-with-valgrind-.patch deleted file mode 100644 index 7eb6471..0000000 --- a/0061-multipath-tools-mpath-tools.supp-file-with-valgrind-.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 24 Sep 2020 15:13:06 +0200 -Subject: [PATCH] multipath-tools: mpath-tools.supp: file with valgrind - suppressions - -These leaks are caused by other libraries (libsystemd, glibc, -libgcrypt) and should be ignored when debugging with valgrind - -Usage example: - -valgrind --suppressions=mpath-tools.supp \ - --leak-check=full --show-leak-kinds=all $COMMAND - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - third-party/valgrind/mpath-tools.supp | 32 +++++++++++++++++++++++++++ - 1 file changed, 32 insertions(+) - create mode 100644 third-party/valgrind/mpath-tools.supp - -diff --git a/third-party/valgrind/mpath-tools.supp b/third-party/valgrind/mpath-tools.supp -new file mode 100644 -index 00000000..0537fd56 ---- /dev/null -+++ b/third-party/valgrind/mpath-tools.supp -@@ -0,0 +1,32 @@ -+{ -+ glibc _dlerror_run leak: https://stackoverflow.com/questions/1542457/memory-leak-reported-by-valgrind-in-dlopen -+ Memcheck:Leak -+ match-leak-kinds: reachable -+ fun:calloc -+ fun:_dlerror_run -+ fun:dlopen* -+} -+ -+{ -+ systemd mempools are never freed: https://bugzilla.redhat.com/show_bug.cgi?id=1215670 -+ Memcheck:Leak -+ match-leak-kinds: reachable -+ fun:malloc -+ fun:mempool_alloc_tile -+ fun:mempool_alloc0_tile -+ fun:hashmap_base_new -+ fun:hashmap_base_ensure_allocated -+} -+ -+{ -+ libgcrypt library initialization -+ Memcheck:Leak -+ match-leak-kinds: reachable -+ fun:malloc -+ ... -+ fun:_gcry_xmalloc -+ ... -+ fun:global_init.* -+ ... -+ fun:_dl_init -+} diff --git a/0062-libmultipath-use-libmp_verbosity-to-track-verbosity.patch b/0062-libmultipath-use-libmp_verbosity-to-track-verbosity.patch deleted file mode 100644 index 400656e..0000000 --- a/0062-libmultipath-use-libmp_verbosity-to-track-verbosity.patch +++ /dev/null @@ -1,438 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Sat, 26 Sep 2020 00:04:53 +0200 -Subject: [PATCH] libmultipath: use libmp_verbosity to track verbosity - -Introduce a new global variable to set the verbosity of libmultipath. -This avoids accessing the configuration in every dlog() call. -When libmultipath reads its configuration in init_config() or -load_config(), it will use the current value of libmp_verbosity -for logging. Immediately before returning, libmp_verbosity will be -overwritten with the verbosity value from the configuration file, -if it was set there. An application is free to set libmp_verbosity -back to the previous value or not after that, depending on whether -command line options or configuration file settings should take -precedence. - -Replace internal access to conf->verbosity with the new variable. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmpathpersist/mpath_persist.c | 5 +--- - libmultipath/config.c | 9 +++++-- - libmultipath/configure.c | 16 +++---------- - libmultipath/debug.c | 10 ++------ - libmultipath/debug.h | 1 + - libmultipath/devmapper.c | 7 +----- - libmultipath/libmultipath.version | 5 ++++ - multipath/main.c | 21 ++++++---------- - multipathd/main.c | 40 ++++++++++++++++++------------- - tests/alias.c | 1 + - tests/blacklist.c | 2 ++ - 11 files changed, 53 insertions(+), 64 deletions(-) - -diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c -index 9ebf91dd..79322e86 100644 ---- a/libmpathpersist/mpath_persist.c -+++ b/libmpathpersist/mpath_persist.c -@@ -170,10 +170,7 @@ void mpath_persistent_reserve_free_vecs(void) - - int mpath_persistent_reserve_init_vecs(int verbose) - { -- struct config *conf = get_multipath_config(); -- -- conf->verbosity = verbose; -- put_multipath_config(conf); -+ libmp_verbosity = verbose; - - if (curmp) - return MPATH_PR_SUCCESS; -diff --git a/libmultipath/config.c b/libmultipath/config.c -index 52b1447b..49e7fb81 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -828,10 +828,14 @@ int _init_config (const char *file, struct config *conf) - conf = &__internal_config; - - /* -- * internal defaults -+ * Processing the config file will overwrite conf->verbosity if set -+ * When we return, we'll copy the config value back - */ -- conf->verbosity = DEFAULT_VERBOSITY; -+ conf->verbosity = libmp_verbosity; - -+ /* -+ * internal defaults -+ */ - get_sys_max_fds(&conf->max_fds); - conf->bindings_file = set_default(DEFAULT_BINDINGS_FILE); - conf->wwids_file = set_default(DEFAULT_WWIDS_FILE); -@@ -997,6 +1001,7 @@ int _init_config (const char *file, struct config *conf) - !conf->wwids_file || !conf->prkeys_file) - goto out; - -+ libmp_verbosity = conf->verbosity; - return 0; - out: - _uninit_config(conf); -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index d36f0d0d..20536e60 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -934,16 +934,12 @@ int domap(struct multipath *mpp, char *params, int is_daemon) - { - int r = DOMAP_FAIL; - struct config *conf; -- int verbosity; - - /* - * last chance to quit before touching the devmaps - */ - if (mpp->action == ACT_DRY_RUN) { -- conf = get_multipath_config(); -- verbosity = conf->verbosity; -- put_multipath_config(conf); -- print_multipath_topology(mpp, verbosity); -+ print_multipath_topology(mpp, libmp_verbosity); - return DOMAP_DRY; - } - -@@ -1327,14 +1323,8 @@ int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid, - "queue_if_no_path"); - } - -- if (!is_daemon && mpp->action != ACT_NOTHING) { -- int verbosity; -- -- conf = get_multipath_config(); -- verbosity = conf->verbosity; -- put_multipath_config(conf); -- print_multipath_topology(mpp, verbosity); -- } -+ if (!is_daemon && mpp->action != ACT_NOTHING) -+ print_multipath_topology(mpp, libmp_verbosity); - - if (mpp->action != ACT_REJECT) { - if (!vector_alloc_slot(newmp)) { -diff --git a/libmultipath/debug.c b/libmultipath/debug.c -index b3a1de9e..a1713b95 100644 ---- a/libmultipath/debug.c -+++ b/libmultipath/debug.c -@@ -16,21 +16,15 @@ - #include "debug.h" - - int logsink; -+int libmp_verbosity = DEFAULT_VERBOSITY; - - void dlog (int sink, int prio, const char * fmt, ...) - { - va_list ap; -- int thres; -- struct config *conf; - - va_start(ap, fmt); -- conf = get_multipath_config(); -- ANNOTATE_IGNORE_READS_BEGIN(); -- thres = (conf) ? conf->verbosity : DEFAULT_VERBOSITY; -- ANNOTATE_IGNORE_READS_END(); -- put_multipath_config(conf); - -- if (prio <= thres) { -+ if (prio <= libmp_verbosity) { - if (sink < 1) { - if (sink == 0) { - time_t t = time(NULL); -diff --git a/libmultipath/debug.h b/libmultipath/debug.h -index c6120c1d..1f3bc8be 100644 ---- a/libmultipath/debug.h -+++ b/libmultipath/debug.h -@@ -8,6 +8,7 @@ void dlog (int sink, int prio, const char * fmt, ...) - #include "log_pthread.h" - - extern int logsink; -+extern int libmp_verbosity; - - #define condlog(prio, fmt, args...) \ - dlog(logsink, prio, fmt "\n", ##args) -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index e60ab493..dfe95d2f 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -351,16 +351,11 @@ void libmp_dm_exit(void) - - static void libmp_dm_init(void) - { -- struct config *conf; -- int verbosity; - unsigned int version[3]; - - if (dm_prereq(version)) - exit(1); -- conf = get_multipath_config(); -- verbosity = conf->verbosity; -- put_multipath_config(conf); -- dm_init(verbosity); -+ dm_init(libmp_verbosity); - #ifdef LIBDM_API_HOLD_CONTROL - dm_hold_control_dev(1); - #endif -diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version -index 800cff22..67a7379f 100644 ---- a/libmultipath/libmultipath.version -+++ b/libmultipath/libmultipath.version -@@ -259,3 +259,8 @@ global: - local: - *; - }; -+ -+LIBMULTIPATH_4.1.0 { -+global: -+ libmp_verbosity; -+} LIBMULTIPATH_4.0.0; -diff --git a/multipath/main.c b/multipath/main.c -index 043d8fa7..98d93c58 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -208,22 +208,15 @@ get_dm_mpvec (enum mpath_cmds cmd, vector curmp, vector pathvec, char * refwwid) - mpp->bestpg = select_path_group(mpp); - - if (cmd == CMD_LIST_SHORT || -- cmd == CMD_LIST_LONG) { -- struct config *conf = get_multipath_config(); -- print_multipath_topology(mpp, conf->verbosity); -- put_multipath_config(conf); -- } -+ cmd == CMD_LIST_LONG) -+ print_multipath_topology(mpp, libmp_verbosity); - - if (cmd == CMD_CREATE) - reinstate_paths(mpp); - } - -- if (cmd == CMD_LIST_SHORT || cmd == CMD_LIST_LONG) { -- struct config *conf = get_multipath_config(); -- -- print_foreign_topology(conf->verbosity); -- put_multipath_config(conf); -- } -+ if (cmd == CMD_LIST_SHORT || cmd == CMD_LIST_LONG) -+ print_foreign_topology(libmp_verbosity); - - return 0; - } -@@ -552,7 +545,7 @@ configure (struct config *conf, enum mpath_cmds cmd, - if (path_discovery(pathvec, di_flag) < 0) - goto out; - -- if (conf->verbosity > 2) -+ if (libmp_verbosity > 2) - print_all_paths(pathvec, 1); - - get_path_layout(pathvec, 0); -@@ -843,7 +836,7 @@ main (int argc, char *argv[]) - exit(RTVL_FAIL); - } - -- conf->verbosity = atoi(optarg); -+ libmp_verbosity = atoi(optarg); - break; - case 'b': - conf->bindings_file = strdup(optarg); -@@ -974,7 +967,7 @@ main (int argc, char *argv[]) - } - if (dev_type == DEV_UEVENT) { - openlog("multipath", 0, LOG_DAEMON); -- setlogmask(LOG_UPTO(conf->verbosity + 3)); -+ setlogmask(LOG_UPTO(libmp_verbosity + 3)); - logsink = 1; - } - -diff --git a/multipathd/main.c b/multipathd/main.c -index 4de0978e..ba257515 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -88,10 +88,10 @@ - #define CMDSIZE 160 - #define MSG_SIZE 32 - --#define LOG_MSG(lvl, verb, pp) \ -+#define LOG_MSG(lvl, pp) \ - do { \ - if (pp->mpp && checker_selected(&pp->checker) && \ -- lvl <= verb) { \ -+ lvl <= libmp_verbosity) { \ - if (pp->offline) \ - condlog(lvl, "%s: %s - path offline", \ - pp->mpp->alias, pp->dev); \ -@@ -2070,7 +2070,7 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) - int chkr_new_path_up = 0; - int disable_reinstate = 0; - int oldchkrstate = pp->chkrstate; -- int retrigger_tries, verbosity; -+ int retrigger_tries; - unsigned int checkint, max_checkint; - struct config *conf; - int marginal_pathgroups, marginal_changed = 0; -@@ -2090,7 +2090,6 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) - retrigger_tries = conf->retrigger_tries; - checkint = conf->checkint; - max_checkint = conf->max_checkint; -- verbosity = conf->verbosity; - marginal_pathgroups = conf->marginal_pathgroups; - put_multipath_config(conf); - -@@ -2152,7 +2151,7 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) - if (newstate == PATH_WILD || newstate == PATH_UNCHECKED) { - condlog(2, "%s: unusable path (%s) - checker failed", - pp->dev, checker_state_name(newstate)); -- LOG_MSG(2, verbosity, pp); -+ LOG_MSG(2, pp); - conf = get_multipath_config(); - pthread_cleanup_push(put_multipath_config, conf); - pathinfo(pp, conf, 0); -@@ -2257,7 +2256,7 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) - int oldstate = pp->state; - pp->state = newstate; - -- LOG_MSG(1, verbosity, pp); -+ LOG_MSG(1, pp); - - /* - * upon state change, reset the checkint -@@ -2321,7 +2320,7 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) - /* Clear IO errors */ - reinstate_path(pp); - else { -- LOG_MSG(4, verbosity, pp); -+ LOG_MSG(4, pp); - if (pp->checkint != max_checkint) { - /* - * double the next check delay. -@@ -2349,9 +2348,9 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) - log_checker_err = conf->log_checker_err; - put_multipath_config(conf); - if (log_checker_err == LOG_CHKR_ERR_ONCE) -- LOG_MSG(3, verbosity, pp); -+ LOG_MSG(3, pp); - else -- LOG_MSG(2, verbosity, pp); -+ LOG_MSG(2, pp); - } - } - -@@ -2696,6 +2695,10 @@ reconfigure (struct vectors * vecs) - if (!conf) - return 1; - -+ if (verbosity) -+ libmp_verbosity = verbosity; -+ setlogmask(LOG_UPTO(libmp_verbosity + 3)); -+ - /* - * free old map and path vectors ... they use old conf state - */ -@@ -2710,8 +2713,6 @@ reconfigure (struct vectors * vecs) - /* Re-read any timezone changes */ - tzset(); - -- if (verbosity) -- conf->verbosity = verbosity; - if (bindings_read_only) - conf->bindings_read_only = bindings_read_only; - check_alias_settings(conf); -@@ -3091,14 +3092,18 @@ child (__attribute__((unused)) void *param) - condlog(2, "--------start up--------"); - condlog(2, "read " DEFAULT_CONFIGFILE); - -+ if (verbosity) -+ libmp_verbosity = verbosity; - conf = load_config(DEFAULT_CONFIGFILE); -+ if (verbosity) -+ libmp_verbosity = verbosity; -+ setlogmask(LOG_UPTO(libmp_verbosity + 3)); -+ - if (!conf) { - condlog(0, "failed to load configuration"); - goto failed; - } - -- if (verbosity) -- conf->verbosity = verbosity; - if (bindings_read_only) - conf->bindings_read_only = bindings_read_only; - uxsock_timeout = conf->uxsock_timeout; -@@ -3117,7 +3122,6 @@ child (__attribute__((unused)) void *param) - - if (poll_dmevents) - poll_dmevents = dmevent_poll_supported(); -- setlogmask(LOG_UPTO(conf->verbosity + 3)); - - envp = getenv("LimitNOFILE"); - -@@ -3339,7 +3343,7 @@ main (int argc, char *argv[]) - !isdigit(optarg[0])) - exit(1); - -- verbosity = atoi(optarg); -+ libmp_verbosity = verbosity = atoi(optarg); - break; - case 's': - logsink = -1; -@@ -3350,7 +3354,7 @@ main (int argc, char *argv[]) - if (!conf) - exit(1); - if (verbosity) -- conf->verbosity = verbosity; -+ libmp_verbosity = verbosity; - uxsock_timeout = conf->uxsock_timeout; - err = uxclnt(optarg, uxsock_timeout + 100); - free_config(conf); -@@ -3376,11 +3380,13 @@ main (int argc, char *argv[]) - char * c = s; - - logsink = 0; -+ if (verbosity) -+ libmp_verbosity = verbosity; - conf = load_config(DEFAULT_CONFIGFILE); - if (!conf) - exit(1); - if (verbosity) -- conf->verbosity = verbosity; -+ libmp_verbosity = verbosity; - uxsock_timeout = conf->uxsock_timeout; - memset(cmd, 0x0, CMDSIZE); - while (optind < argc) { -diff --git a/tests/alias.c b/tests/alias.c -index 7fda679d..0311faa6 100644 ---- a/tests/alias.c -+++ b/tests/alias.c -@@ -735,6 +735,7 @@ static int test_allocate_binding(void) - int main(void) - { - int ret = 0; -+ libmp_verbosity = conf.verbosity; - - ret += test_format_devname(); - ret += test_scan_devname(); -diff --git a/tests/blacklist.c b/tests/blacklist.c -index 84a3ba2f..0b42e255 100644 ---- a/tests/blacklist.c -+++ b/tests/blacklist.c -@@ -22,6 +22,7 @@ - #include "globals.c" - #include "blacklist.h" - #include "test-log.h" -+#include "debug.h" - - struct udev_device { - const char *sysname; -@@ -152,6 +153,7 @@ static int setup(void **state) - store_ble(blist_property_wwn_inv, "!ID_WWN", ORIGIN_CONFIG)) - return -1; - -+ libmp_verbosity = conf.verbosity = 4; - return 0; - } - diff --git a/0063-libmultipath-introduce-symbolic-values-for-logsink.patch b/0063-libmultipath-introduce-symbolic-values-for-logsink.patch deleted file mode 100644 index 936bb6f..0000000 --- a/0063-libmultipath-introduce-symbolic-values-for-logsink.patch +++ /dev/null @@ -1,182 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Sat, 26 Sep 2020 00:32:05 +0200 -Subject: [PATCH] libmultipath: introduce symbolic values for logsink - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/debug.c | 4 ++-- - libmultipath/debug.h | 6 ++++++ - libmultipath/devmapper.c | 4 ++-- - multipath/main.c | 4 ++-- - multipathd/main.c | 17 ++++++++--------- - tests/globals.c | 3 ++- - tests/hwtable.c | 2 +- - 7 files changed, 23 insertions(+), 17 deletions(-) - -diff --git a/libmultipath/debug.c b/libmultipath/debug.c -index a1713b95..f9b77552 100644 ---- a/libmultipath/debug.c -+++ b/libmultipath/debug.c -@@ -25,8 +25,8 @@ void dlog (int sink, int prio, const char * fmt, ...) - va_start(ap, fmt); - - if (prio <= libmp_verbosity) { -- if (sink < 1) { -- if (sink == 0) { -+ if (sink != LOGSINK_SYSLOG) { -+ if (sink == LOGSINK_STDERR_WITH_TIME) { - time_t t = time(NULL); - struct tm *tb = localtime(&t); - char buff[16]; -diff --git a/libmultipath/debug.h b/libmultipath/debug.h -index 1f3bc8be..b6ce70a7 100644 ---- a/libmultipath/debug.h -+++ b/libmultipath/debug.h -@@ -12,3 +12,9 @@ extern int libmp_verbosity; - - #define condlog(prio, fmt, args...) \ - dlog(logsink, prio, fmt "\n", ##args) -+ -+enum { -+ LOGSINK_STDERR_WITH_TIME = 0, -+ LOGSINK_STDERR_WITHOUT_TIME = -1, -+ LOGSINK_SYSLOG = 1, -+}; -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index dfe95d2f..f8b180e1 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -104,8 +104,8 @@ dm_write_log (int level, const char *file, int line, const char *f, ...) - return; - - va_start(ap, f); -- if (logsink < 1) { -- if (logsink == 0) { -+ if (logsink != LOGSINK_SYSLOG) { -+ if (logsink == LOGSINK_STDERR_WITH_TIME) { - time_t t = time(NULL); - struct tm *tb = localtime(&t); - char buff[16]; -diff --git a/multipath/main.c b/multipath/main.c -index 98d93c58..9ac42869 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -817,7 +817,7 @@ main (int argc, char *argv[]) - libmultipath_init(); - if (atexit(dm_lib_exit) || atexit(libmultipath_exit)) - condlog(1, "failed to register cleanup handler for libmultipath: %m"); -- logsink = 0; -+ logsink = LOGSINK_STDERR_WITH_TIME; - if (init_config(DEFAULT_CONFIGFILE)) - exit(RTVL_FAIL); - if (atexit(uninit_config)) -@@ -968,7 +968,7 @@ main (int argc, char *argv[]) - if (dev_type == DEV_UEVENT) { - openlog("multipath", 0, LOG_DAEMON); - setlogmask(LOG_UPTO(libmp_verbosity + 3)); -- logsink = 1; -+ logsink = LOGSINK_SYSLOG; - } - - set_max_fds(conf->max_fds); -diff --git a/multipathd/main.c b/multipathd/main.c -index ba257515..867f0f84 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -2780,7 +2780,7 @@ handle_signals(bool nonfatal) - } - if (log_reset_sig) { - condlog(2, "reset log (signal)"); -- if (logsink == 1) -+ if (logsink == LOGSINK_SYSLOG) - log_thread_reset(); - } - reconfig_sig = 0; -@@ -3033,7 +3033,7 @@ static void cleanup_child(void) - cleanup_dmevent_waiter(); - - cleanup_pidfile(); -- if (logsink == 1) -+ if (logsink == LOGSINK_SYSLOG) - log_thread_stop(); - - cleanup_conf(); -@@ -3076,7 +3076,7 @@ child (__attribute__((unused)) void *param) - setup_thread_attr(&uevent_attr, DEFAULT_UEVENT_STACKSIZE * 1024, 0); - setup_thread_attr(&waiter_attr, 32 * 1024, 1); - -- if (logsink == 1) { -+ if (logsink == LOGSINK_SYSLOG) { - setup_thread_attr(&log_attr, 64 * 1024, 0); - log_thread_start(&log_attr); - pthread_attr_destroy(&log_attr); -@@ -3307,7 +3307,7 @@ main (int argc, char *argv[]) - ANNOTATE_BENIGN_RACE_SIZED(&uxsock_timeout, sizeof(uxsock_timeout), - "Suppress complaints about this scalar variable"); - -- logsink = 1; -+ logsink = LOGSINK_SYSLOG; - - if (getuid() != 0) { - fprintf(stderr, "need to be root\n"); -@@ -3334,9 +3334,8 @@ main (int argc, char *argv[]) - switch(arg) { - case 'd': - foreground = 1; -- if (logsink > 0) -- logsink = 0; -- //debug=1; /* ### comment me out ### */ -+ if (logsink == LOGSINK_SYSLOG) -+ logsink = LOGSINK_STDERR_WITH_TIME; - break; - case 'v': - if (sizeof(optarg) > sizeof(char *) || -@@ -3346,7 +3345,7 @@ main (int argc, char *argv[]) - libmp_verbosity = verbosity = atoi(optarg); - break; - case 's': -- logsink = -1; -+ logsink = LOGSINK_STDERR_WITHOUT_TIME; - break; - case 'k': - logsink = 0; -@@ -3379,7 +3378,7 @@ main (int argc, char *argv[]) - char * s = cmd; - char * c = s; - -- logsink = 0; -+ logsink = LOGSINK_STDERR_WITH_TIME; - if (verbosity) - libmp_verbosity = verbosity; - conf = load_config(DEFAULT_CONFIGFILE); -diff --git a/tests/globals.c b/tests/globals.c -index 8add5eb7..fc0c07ad 100644 ---- a/tests/globals.c -+++ b/tests/globals.c -@@ -1,9 +1,10 @@ - #include "structs.h" - #include "config.h" -+#include "debug.h" - - /* Required globals */ - struct udev *udev; --int logsink = -1; -+int logsink = LOGSINK_STDERR_WITHOUT_TIME; - struct config conf = { - .verbosity = 4, - }; -diff --git a/tests/hwtable.c b/tests/hwtable.c -index 57f832b7..4dd0873b 100644 ---- a/tests/hwtable.c -+++ b/tests/hwtable.c -@@ -53,7 +53,7 @@ struct hwt_state { - - static struct config *_conf; - struct udev *udev; --int logsink = -1; -+int logsink = LOGSINK_STDERR_WITHOUT_TIME; - - struct config *get_multipath_config(void) - { diff --git a/0064-libmultipath-simplify-dlog.patch b/0064-libmultipath-simplify-dlog.patch deleted file mode 100644 index 67985a1..0000000 --- a/0064-libmultipath-simplify-dlog.patch +++ /dev/null @@ -1,149 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Sat, 26 Sep 2020 00:39:22 +0200 -Subject: [PATCH] libmultipath: simplify dlog() - -By checking the log level in condlog() directly, we can simplify -dlog(). Also, it's now possible to limit the log level at compile -time by setting MAX_VERBOSITY, enabling the compiler to optimize -away log messages with higher loglevel. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/debug.c | 30 +++++++++++++----------------- - libmultipath/debug.h | 20 ++++++++++++++++---- - libmultipath/devmapper.c | 4 +++- - tests/test-log.c | 4 ++-- - tests/test-log.h | 3 ++- - 5 files changed, 36 insertions(+), 25 deletions(-) - -diff --git a/libmultipath/debug.c b/libmultipath/debug.c -index f9b77552..429f2699 100644 ---- a/libmultipath/debug.c -+++ b/libmultipath/debug.c -@@ -18,29 +18,25 @@ - int logsink; - int libmp_verbosity = DEFAULT_VERBOSITY; - --void dlog (int sink, int prio, const char * fmt, ...) -+void dlog(int prio, const char * fmt, ...) - { - va_list ap; - - va_start(ap, fmt); -+ if (logsink != LOGSINK_SYSLOG) { -+ if (logsink == LOGSINK_STDERR_WITH_TIME) { -+ time_t t = time(NULL); -+ struct tm *tb = localtime(&t); -+ char buff[16]; - -- if (prio <= libmp_verbosity) { -- if (sink != LOGSINK_SYSLOG) { -- if (sink == LOGSINK_STDERR_WITH_TIME) { -- time_t t = time(NULL); -- struct tm *tb = localtime(&t); -- char buff[16]; -- -- strftime(buff, sizeof(buff), -- "%b %d %H:%M:%S", tb); -- buff[sizeof(buff)-1] = '\0'; -- -- fprintf(stderr, "%s | ", buff); -- } -- vfprintf(stderr, fmt, ap); -+ strftime(buff, sizeof(buff), -+ "%b %d %H:%M:%S", tb); -+ buff[sizeof(buff)-1] = '\0'; -+ fprintf(stderr, "%s | ", buff); - } -- else -- log_safe(prio + 3, fmt, ap); -+ vfprintf(stderr, fmt, ap); - } -+ else -+ log_safe(prio + 3, fmt, ap); - va_end(ap); - } -diff --git a/libmultipath/debug.h b/libmultipath/debug.h -index b6ce70a7..705a5d73 100644 ---- a/libmultipath/debug.h -+++ b/libmultipath/debug.h -@@ -1,5 +1,7 @@ --void dlog (int sink, int prio, const char * fmt, ...) -- __attribute__((format(printf, 3, 4))); -+#ifndef _DEBUG_H -+#define _DEBUG_H -+void dlog (int prio, const char *fmt, ...) -+ __attribute__((format(printf, 2, 3))); - - - #include -@@ -10,11 +12,21 @@ void dlog (int sink, int prio, const char * fmt, ...) - extern int logsink; - extern int libmp_verbosity; - --#define condlog(prio, fmt, args...) \ -- dlog(logsink, prio, fmt "\n", ##args) -+#ifndef MAX_VERBOSITY -+#define MAX_VERBOSITY 4 -+#endif - - enum { - LOGSINK_STDERR_WITH_TIME = 0, - LOGSINK_STDERR_WITHOUT_TIME = -1, - LOGSINK_SYSLOG = 1, - }; -+ -+#define condlog(prio, fmt, args...) \ -+ do { \ -+ int __p = (prio); \ -+ \ -+ if (__p <= MAX_VERBOSITY && __p <= libmp_verbosity) \ -+ dlog(__p, fmt "\n", ##args); \ -+ } while (0) -+#endif /* _DEBUG_H */ -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index f8b180e1..4977b311 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -276,7 +276,9 @@ static int dm_tgt_prereq (unsigned int *ver) - - static void _init_versions(void) - { -- dlog(logsink, 3, VERSION_STRING); -+ /* Can't use condlog here because of how VERSION_STRING is defined */ -+ if (3 <= libmp_verbosity) -+ dlog(3, VERSION_STRING); - init_dm_library_version(); - init_dm_drv_version(); - init_dm_mpath_version(); -diff --git a/tests/test-log.c b/tests/test-log.c -index 1c901cba..14f25b9b 100644 ---- a/tests/test-log.c -+++ b/tests/test-log.c -@@ -7,8 +7,8 @@ - #include "log.h" - #include "test-log.h" - --__attribute__((format(printf, 3, 0))) --void __wrap_dlog (int sink, int prio, const char * fmt, ...) -+__attribute__((format(printf, 2, 0))) -+void __wrap_dlog (int prio, const char * fmt, ...) - { - char buff[MAX_MSG_SIZE]; - va_list ap; -diff --git a/tests/test-log.h b/tests/test-log.h -index 2c878c63..6d22cd23 100644 ---- a/tests/test-log.h -+++ b/tests/test-log.h -@@ -1,7 +1,8 @@ - #ifndef _TEST_LOG_H - #define _TEST_LOG_H - --void __wrap_dlog (int sink, int prio, const char * fmt, ...); -+__attribute__((format(printf, 2, 0))) -+void __wrap_dlog (int prio, const char * fmt, ...); - void expect_condlog(int prio, char *string); - - #endif diff --git a/0065-multipathd-common-code-for-k-and-command-args.patch b/0065-multipathd-common-code-for-k-and-command-args.patch deleted file mode 100644 index d31afd7..0000000 --- a/0065-multipathd-common-code-for-k-and-command-args.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Sat, 26 Sep 2020 00:43:12 +0200 -Subject: [PATCH] multipathd: common code for "-k" and command args - -'multipathd -k"cmd"' and 'multipath cmd' are the same thing. -Treat it with common code. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 37 +++++++++++++++++++------------------ - 1 file changed, 19 insertions(+), 18 deletions(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 867f0f84..b6a5f5b7 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -3301,6 +3301,8 @@ main (int argc, char *argv[]) - int err; - int foreground = 0; - struct config *conf; -+ char *opt_k_arg = NULL; -+ bool opt_k = false; - - ANNOTATE_BENIGN_RACE_SIZED(&multipath_conf, sizeof(multipath_conf), - "Manipulated through RCU"); -@@ -3348,16 +3350,9 @@ main (int argc, char *argv[]) - logsink = LOGSINK_STDERR_WITHOUT_TIME; - break; - case 'k': -- logsink = 0; -- conf = load_config(DEFAULT_CONFIGFILE); -- if (!conf) -- exit(1); -- if (verbosity) -- libmp_verbosity = verbosity; -- uxsock_timeout = conf->uxsock_timeout; -- err = uxclnt(optarg, uxsock_timeout + 100); -- free_config(conf); -- return err; -+ opt_k = true; -+ opt_k_arg = optarg; -+ break; - case 'B': - bindings_read_only = 1; - break; -@@ -3373,7 +3368,7 @@ main (int argc, char *argv[]) - exit(1); - } - } -- if (optind < argc) { -+ if (opt_k || optind < argc) { - char cmd[CMDSIZE]; - char * s = cmd; - char * c = s; -@@ -3388,14 +3383,20 @@ main (int argc, char *argv[]) - libmp_verbosity = verbosity; - uxsock_timeout = conf->uxsock_timeout; - memset(cmd, 0x0, CMDSIZE); -- while (optind < argc) { -- if (strchr(argv[optind], ' ')) -- c += snprintf(c, s + CMDSIZE - c, "\"%s\" ", argv[optind]); -- else -- c += snprintf(c, s + CMDSIZE - c, "%s ", argv[optind]); -- optind++; -+ if (opt_k) -+ s = opt_k_arg; -+ else { -+ while (optind < argc) { -+ if (strchr(argv[optind], ' ')) -+ c += snprintf(c, s + CMDSIZE - c, -+ "\"%s\" ", argv[optind]); -+ else -+ c += snprintf(c, s + CMDSIZE - c, -+ "%s ", argv[optind]); -+ optind++; -+ } -+ c += snprintf(c, s + CMDSIZE - c, "\n"); - } -- c += snprintf(c, s + CMDSIZE - c, "\n"); - err = uxclnt(s, uxsock_timeout + 100); - free_config(conf); - return err; diff --git a/0066-multipathd-sanitize-uxsock_listen.patch b/0066-multipathd-sanitize-uxsock_listen.patch deleted file mode 100644 index bffb94c..0000000 --- a/0066-multipathd-sanitize-uxsock_listen.patch +++ /dev/null @@ -1,154 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Sat, 26 Sep 2020 15:22:34 +0200 -Subject: [PATCH] multipathd: sanitize uxsock_listen() - -We were allocating 1025 poll fds, which is weird. Change it to a power of two, -and make this more easily customizable in general. Use POLLFDS_BASE rather -than the hard-coded "2" for the number of fds we poll besides client -connections. Introduce a maximum number of clients that can connect. When -this number is reached, we simply stop polling the accept socket, so that new -connections aren't accepted any more. Don't attempt to realloc() the pollfd -array if the number of clients decreases. It's unlikely to ever be more than -one or two pages. Finally, there's no need to wake up every 5s. Our signal -handling is robust. Just sleep forever in ppoll() if nothing happens. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipathd/uxlsnr.c | 70 ++++++++++++++++++++++++++++----------------- - 1 file changed, 43 insertions(+), 27 deletions(-) - -diff --git a/multipathd/uxlsnr.c b/multipathd/uxlsnr.c -index ce2b6800..cd462b6d 100644 ---- a/multipathd/uxlsnr.c -+++ b/multipathd/uxlsnr.c -@@ -41,14 +41,25 @@ - #include "cli.h" - #include "uxlsnr.h" - --static struct timespec sleep_time = {5, 0}; -- - struct client { - struct list_head node; - int fd; - }; - --#define MIN_POLLS 1023 -+/* The number of fds we poll on, other than individual client connections */ -+#define POLLFDS_BASE 2 -+#define POLLFD_CHUNK (4096 / sizeof(struct pollfd)) -+/* Minimum mumber of pollfds to reserve for clients */ -+#define MIN_POLLS (POLLFD_CHUNK - POLLFDS_BASE) -+/* -+ * Max number of client connections allowed -+ * During coldplug, there may be a large number of "multipath -u" -+ * processes connecting. -+ */ -+#define MAX_CLIENTS (16384 - POLLFDS_BASE) -+ -+/* Compile-time error if POLLFD_CHUNK is too small */ -+static __attribute__((unused)) char ___a[-(MIN_POLLS <= 0)]; - - static LIST_HEAD(clients); - static pthread_mutex_t client_lock = PTHREAD_MUTEX_INITIALIZER; -@@ -282,13 +293,13 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, long ux_sock, - char *inbuf; - char *reply; - sigset_t mask; -- int old_clients = MIN_POLLS; -+ int max_pfds = MIN_POLLS + POLLFDS_BASE; - /* conf->sequence_nr will be 1 when uxsock_listen is first called */ - unsigned int sequence_nr = 0; - struct watch_descriptors wds = { .conf_wd = -1, .dir_wd = -1 }; - - condlog(3, "uxsock: startup listener"); -- polls = (struct pollfd *)MALLOC((MIN_POLLS + 2) * sizeof(struct pollfd)); -+ polls = MALLOC(max_pfds * sizeof(*polls)); - if (!polls) { - condlog(0, "uxsock: failed to allocate poll fds"); - exit_daemon(); -@@ -312,28 +323,33 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, long ux_sock, - list_for_each_entry(c, &clients, node) { - num_clients++; - } -- if (num_clients != old_clients) { -+ if (num_clients + POLLFDS_BASE > max_pfds) { - struct pollfd *new; -- if (num_clients <= MIN_POLLS && old_clients > MIN_POLLS) { -- new = REALLOC(polls, (2 + MIN_POLLS) * -- sizeof(struct pollfd)); -- } else if (num_clients <= MIN_POLLS && old_clients <= MIN_POLLS) { -- new = polls; -- } else { -- new = REALLOC(polls, (2 + num_clients) * -- sizeof(struct pollfd)); -- } -- if (!new) { -- condlog(0, "%s: failed to realloc %d poll fds", -- "uxsock", 2 + num_clients); -- num_clients = old_clients; -- } else { -- old_clients = num_clients; -+ int n_new = max_pfds + POLLFD_CHUNK; -+ -+ new = REALLOC(polls, n_new * sizeof(*polls)); -+ if (new) { -+ max_pfds = n_new; - polls = new; -+ } else { -+ condlog(1, "%s: realloc failure, %d clients not served", -+ __func__, -+ num_clients + POLLFDS_BASE - max_pfds); -+ num_clients = max_pfds - POLLFDS_BASE; - } - } -- polls[0].fd = ux_sock; -- polls[0].events = POLLIN; -+ if (num_clients < MAX_CLIENTS) { -+ polls[0].fd = ux_sock; -+ polls[0].events = POLLIN; -+ } else { -+ /* -+ * New clients can't connect, num_clients won't grow -+ * to MAX_CLIENTS or higher -+ */ -+ condlog(1, "%s: max client connections reached, pausing polling", -+ __func__); -+ polls[0].fd = -1; -+ } - - reset_watch(notify_fd, &wds, &sequence_nr); - if (notify_fd == -1 || (wds.conf_wd == -1 && wds.dir_wd == -1)) -@@ -343,19 +359,19 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, long ux_sock, - polls[1].events = POLLIN; - - /* setup the clients */ -- i = 2; -+ i = POLLFDS_BASE; - list_for_each_entry(c, &clients, node) { - polls[i].fd = c->fd; - polls[i].events = POLLIN; - i++; -- if (i >= 2 + num_clients) -+ if (i >= max_pfds) - break; - } - n_pfds = i; - pthread_cleanup_pop(1); - - /* most of our life is spent in this call */ -- poll_count = ppoll(polls, n_pfds, &sleep_time, &mask); -+ poll_count = ppoll(polls, n_pfds, NULL, &mask); - - handle_signals(false); - if (poll_count == -1) { -@@ -388,7 +404,7 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, long ux_sock, - } - - /* see if a client wants to speak to us */ -- for (i = 2; i < n_pfds; i++) { -+ for (i = POLLFDS_BASE; i < n_pfds; i++) { - if (polls[i].revents & POLLIN) { - struct timespec start_time; - diff --git a/0067-libmultipath-fix-race-between-log_safe-and-log_threa.patch b/0067-libmultipath-fix-race-between-log_safe-and-log_threa.patch deleted file mode 100644 index cc6e5d3..0000000 --- a/0067-libmultipath-fix-race-between-log_safe-and-log_threa.patch +++ /dev/null @@ -1,104 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 15 Oct 2020 16:13:14 +0200 -Subject: [PATCH] libmultipath: fix race between log_safe and log_thread_stop() - -log_safe() could race with log_thread_stop(); simply -checking the value of log_thr has never been safe. By converting the -mutexes to static initializers, we avoid having to destroy them, and thus -possibly accessing a destroyed mutex in log_safe(). Furthermore, taking -both the logev_lock and the logq_lock makes sure the logarea isn't freed -while we are writing to it. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/log_pthread.c | 48 +++++++++++++++++++++----------------- - 1 file changed, 26 insertions(+), 22 deletions(-) - -diff --git a/libmultipath/log_pthread.c b/libmultipath/log_pthread.c -index 3a2566ae..0d48c52c 100644 ---- a/libmultipath/log_pthread.c -+++ b/libmultipath/log_pthread.c -@@ -17,31 +17,42 @@ - - static pthread_t log_thr; - --static pthread_mutex_t logq_lock; --static pthread_mutex_t logev_lock; --static pthread_cond_t logev_cond; -+/* logev_lock must not be taken with logq_lock held */ -+static pthread_mutex_t logq_lock = PTHREAD_MUTEX_INITIALIZER; -+static pthread_mutex_t logev_lock = PTHREAD_MUTEX_INITIALIZER; -+static pthread_cond_t logev_cond = PTHREAD_COND_INITIALIZER; - - static int logq_running; - static int log_messages_pending; - - void log_safe (int prio, const char * fmt, va_list ap) - { -+ bool running; -+ - if (prio > LOG_DEBUG) - prio = LOG_DEBUG; - -- if (log_thr == (pthread_t)0) { -- vsyslog(prio, fmt, ap); -- return; -- } -+ /* -+ * logev_lock protects logq_running. By holding it, we avoid a race -+ * with log_thread_stop() -> log_close(), which would free the logarea. -+ */ -+ pthread_mutex_lock(&logev_lock); -+ pthread_cleanup_push(cleanup_mutex, &logev_lock); -+ running = logq_running; - -- pthread_mutex_lock(&logq_lock); -- log_enqueue(prio, fmt, ap); -- pthread_mutex_unlock(&logq_lock); -+ if (running) { -+ pthread_mutex_lock(&logq_lock); -+ pthread_cleanup_push(cleanup_mutex, &logq_lock); -+ log_enqueue(prio, fmt, ap); -+ pthread_cleanup_pop(1); - -- pthread_mutex_lock(&logev_lock); -- log_messages_pending = 1; -- pthread_cond_signal(&logev_cond); -- pthread_mutex_unlock(&logev_lock); -+ log_messages_pending = 1; -+ pthread_cond_signal(&logev_cond); -+ } -+ pthread_cleanup_pop(1); -+ -+ if (!running) -+ vsyslog(prio, fmt, ap); - } - - static void flush_logqueue (void) -@@ -103,9 +114,6 @@ void log_thread_start (pthread_attr_t *attr) - int running = 0; - - logdbg(stderr,"enter log_thread_start\n"); -- pthread_mutex_init(&logq_lock, NULL); -- pthread_mutex_init(&logev_lock, NULL); -- pthread_cond_init(&logev_cond, NULL); - - if (log_init("multipathd", 0)) { - fprintf(stderr,"can't initialize log buffer\n"); -@@ -154,13 +162,9 @@ void log_thread_stop (void) - } - pthread_cleanup_pop(1); - -- flush_logqueue(); - if (running) - pthread_join(log_thr, NULL); - -- pthread_mutex_destroy(&logq_lock); -- pthread_mutex_destroy(&logev_lock); -- pthread_cond_destroy(&logev_cond); -- -+ flush_logqueue(); - log_close(); - } diff --git a/0068-multipath-add-libmpathvalid-library.patch b/0068-multipath-add-libmpathvalid-library.patch deleted file mode 100644 index 2a19329..0000000 --- a/0068-multipath-add-libmpathvalid-library.patch +++ /dev/null @@ -1,502 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 21 Oct 2020 16:39:23 -0500 -Subject: [PATCH] multipath: add libmpathvalid library - -This library allows other programs to check if a path should be claimed -by multipath. It exports an init function, that needs to be called -before and after all other library calls, an exit function, that needs -to be called after all library calls, a function to reread the multipath -configuration files, and two more functions. - -mpath_get_mode() get the configured find_multipaths mode. -mpath_is_path() returns whether the device is claimed by multipath, and -optionally returns the wwid. This code works slightly different than -the multipath -c/u code for SMART mode. Instead of checking all the -existing paths to see if another has the same wwid, it expects the -caller to pass in an array of the already known path wwids, and checks -if the current path matches any of those. - -The library also doesn't set up the device-mapper library. It leaves -this up to the caller. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - Makefile | 3 +- - libmpathvalid/Makefile | 39 ++++++ - libmpathvalid/libmpathvalid.version | 10 ++ - libmpathvalid/mpath_valid.c | 202 ++++++++++++++++++++++++++++ - libmpathvalid/mpath_valid.h | 155 +++++++++++++++++++++ - libmultipath/libmultipath.version | 6 + - 6 files changed, 414 insertions(+), 1 deletion(-) - create mode 100644 libmpathvalid/Makefile - create mode 100644 libmpathvalid/libmpathvalid.version - create mode 100644 libmpathvalid/mpath_valid.c - create mode 100644 libmpathvalid/mpath_valid.h - -diff --git a/Makefile b/Makefile -index 4a3491da..f127ff91 100644 ---- a/Makefile -+++ b/Makefile -@@ -9,6 +9,7 @@ BUILDDIRS := \ - libmultipath/checkers \ - libmultipath/foreign \ - libmpathpersist \ -+ libmpathvalid \ - multipath \ - multipathd \ - mpathpersist \ -@@ -29,7 +30,7 @@ $(BUILDDIRS): - $(MAKE) -C $@ - - libmultipath libdmmp: libmpathcmd --libmpathpersist multipath multipathd: libmultipath -+libmpathpersist libmpathvalid multipath multipathd: libmultipath - mpathpersist multipathd: libmpathpersist - - libmultipath/checkers.install \ -diff --git a/libmpathvalid/Makefile b/libmpathvalid/Makefile -new file mode 100644 -index 00000000..6bea4bcd ---- /dev/null -+++ b/libmpathvalid/Makefile -@@ -0,0 +1,39 @@ -+include ../Makefile.inc -+ -+SONAME = 0 -+DEVLIB = libmpathvalid.so -+LIBS = $(DEVLIB).$(SONAME) -+VERSION_SCRIPT := libmpathvalid.version -+ -+CFLAGS += $(LIB_CFLAGS) -I$(multipathdir) -I$(mpathcmddir) -+ -+LIBDEPS += -lpthread -ldevmapper -ldl -L$(multipathdir) \ -+ -lmultipath -L$(mpathcmddir) -lmpathcmd -ludev -+ -+OBJS = mpath_valid.o -+ -+all: $(LIBS) -+ -+$(LIBS): $(OBJS) $(VERSION_SCRIPT) -+ $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ -o $@ $(OBJS) $(LIBDEPS) -Wl,--version-script=libmpathvalid.version -+ $(LN) $(LIBS) $(DEVLIB) -+ -+install: $(LIBS) -+ $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(syslibdir) -+ $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) -+ $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) -+ $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(includedir) -+ $(INSTALL_PROGRAM) -m 644 mpath_valid.h $(DESTDIR)$(includedir) -+ -+uninstall: -+ $(RM) $(DESTDIR)$(syslibdir)/$(LIBS) -+ $(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) -+ $(RM) $(DESTDIR)$(includedir)/mpath_valid.h -+ -+clean: dep_clean -+ $(RM) core *.a *.o *.so *.so.* *.gz -+ -+include $(wildcard $(OBJS:.o=.d)) -+ -+dep_clean: -+ $(RM) $(OBJS:.o=.d) -diff --git a/libmpathvalid/libmpathvalid.version b/libmpathvalid/libmpathvalid.version -new file mode 100644 -index 00000000..3bd0d3c5 ---- /dev/null -+++ b/libmpathvalid/libmpathvalid.version -@@ -0,0 +1,10 @@ -+MPATH_1.0 { -+ global: -+ mpathvalid_init; -+ mpathvalid_reload_config; -+ mpathvalid_exit; -+ mpathvalid_is_path; -+ mpathvalid_get_mode; -+ local: -+ *; -+}; -diff --git a/libmpathvalid/mpath_valid.c b/libmpathvalid/mpath_valid.c -new file mode 100644 -index 00000000..7073d17d ---- /dev/null -+++ b/libmpathvalid/mpath_valid.c -@@ -0,0 +1,202 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "devmapper.h" -+#include "structs.h" -+#include "util.h" -+#include "config.h" -+#include "discovery.h" -+#include "wwids.h" -+#include "sysfs.h" -+#include "mpath_cmd.h" -+#include "valid.h" -+#include "mpath_valid.h" -+#include "debug.h" -+ -+static unsigned int -+get_conf_mode(struct config *conf) -+{ -+ if (conf->find_multipaths == FIND_MULTIPATHS_SMART) -+ return MPATH_SMART; -+ if (conf->find_multipaths == FIND_MULTIPATHS_GREEDY) -+ return MPATH_GREEDY; -+ return MPATH_STRICT; -+} -+ -+static void -+set_conf_mode(struct config *conf, unsigned int mode) -+{ -+ if (mode == MPATH_SMART) -+ conf->find_multipaths = FIND_MULTIPATHS_SMART; -+ else if (mode == MPATH_GREEDY) -+ conf->find_multipaths = FIND_MULTIPATHS_GREEDY; -+ else -+ conf->find_multipaths = FIND_MULTIPATHS_STRICT; -+} -+ -+unsigned int -+mpathvalid_get_mode(void) -+{ -+ int mode; -+ struct config *conf; -+ -+ conf = get_multipath_config(); -+ if (!conf) -+ mode = MPATH_MODE_ERROR; -+ else -+ mode = get_conf_mode(conf); -+ put_multipath_config(conf); -+ return mode; -+} -+ -+static int -+convert_result(int result) { -+ switch (result) { -+ case PATH_IS_ERROR: -+ return MPATH_IS_ERROR; -+ case PATH_IS_NOT_VALID: -+ return MPATH_IS_NOT_VALID; -+ case PATH_IS_VALID: -+ return MPATH_IS_VALID; -+ case PATH_IS_VALID_NO_CHECK: -+ return MPATH_IS_VALID_NO_CHECK; -+ case PATH_IS_MAYBE_VALID: -+ return MPATH_IS_MAYBE_VALID; -+ } -+ return MPATH_IS_ERROR; -+} -+ -+static void -+set_log_style(int log_style) -+{ -+ /* -+ * convert MPATH_LOG_* to LOGSINK_* -+ * currently there is no work to do here. -+ */ -+ logsink = log_style; -+} -+ -+static int -+load_default_config(int verbosity) -+{ -+ /* need to set verbosity here to control logging during init_config() */ -+ libmp_verbosity = verbosity; -+ if (init_config(DEFAULT_CONFIGFILE)) -+ return -1; -+ /* Need to override verbosity from init_config() */ -+ libmp_verbosity = verbosity; -+ -+ return 0; -+} -+ -+int -+mpathvalid_init(int verbosity, int log_style) -+{ -+ unsigned int version[3]; -+ -+ set_log_style(log_style); -+ if (libmultipath_init()) -+ return -1; -+ -+ skip_libmp_dm_init(); -+ if (load_default_config(verbosity)) -+ goto fail; -+ -+ if (dm_prereq(version)) -+ goto fail_config; -+ -+ return 0; -+ -+fail_config: -+ uninit_config(); -+fail: -+ libmultipath_exit(); -+ return -1; -+} -+ -+int -+mpathvalid_reload_config(void) -+{ -+ uninit_config(); -+ return load_default_config(libmp_verbosity); -+} -+ -+int -+mpathvalid_exit(void) -+{ -+ uninit_config(); -+ libmultipath_exit(); -+ return 0; -+} -+ -+/* -+ * name: name of path to check -+ * mode: mode to use for determination. MPATH_DEFAULT uses configured mode -+ * info: on success, contains the path wwid -+ * paths: array of the returned mpath_info from other claimed paths -+ * nr_paths: the size of the paths array -+ */ -+int -+mpathvalid_is_path(const char *name, unsigned int mode, char **wwid, -+ const char **path_wwids, unsigned int nr_paths) -+{ -+ struct config *conf; -+ int find_multipaths_saved, r = MPATH_IS_ERROR; -+ unsigned int i; -+ struct path *pp; -+ -+ if (!name || mode >= MPATH_MODE_ERROR) -+ return r; -+ if (nr_paths > 0 && !path_wwids) -+ return r; -+ if (!udev) -+ return r; -+ -+ pp = alloc_path(); -+ if (!pp) -+ return r; -+ -+ if (wwid) { -+ *wwid = (char *)malloc(WWID_SIZE); -+ if (!*wwid) -+ goto out; -+ } -+ -+ conf = get_multipath_config(); -+ if (!conf) -+ goto out_wwid; -+ find_multipaths_saved = conf->find_multipaths; -+ if (mode != MPATH_DEFAULT) -+ set_conf_mode(conf, mode); -+ r = convert_result(is_path_valid(name, conf, pp, true)); -+ conf->find_multipaths = find_multipaths_saved; -+ put_multipath_config(conf); -+ -+ if (r == MPATH_IS_MAYBE_VALID) { -+ for (i = 0; i < nr_paths; i++) { -+ if (path_wwids[i] && -+ strncmp(path_wwids[i], pp->wwid, WWID_SIZE) == 0) { -+ r = MPATH_IS_VALID; -+ break; -+ } -+ } -+ } -+ -+out_wwid: -+ if (wwid) { -+ if (r == MPATH_IS_VALID || r == MPATH_IS_VALID_NO_CHECK || -+ r == MPATH_IS_MAYBE_VALID) -+ strlcpy(*wwid, pp->wwid, WWID_SIZE); -+ else { -+ free(*wwid); -+ *wwid = NULL; -+ } -+ } -+out: -+ free_path(pp); -+ return r; -+} -diff --git a/libmpathvalid/mpath_valid.h b/libmpathvalid/mpath_valid.h -new file mode 100644 -index 00000000..63de4e1c ---- /dev/null -+++ b/libmpathvalid/mpath_valid.h -@@ -0,0 +1,155 @@ -+/* -+ * Copyright (C) 2015 Red Hat, Inc. -+ * -+ * This file is part of the device-mapper multipath userspace tools. -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser 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 Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public License -+ * along with this program. If not, see . -+ */ -+ -+#ifndef LIB_MPATH_VALID_H -+#define LIB_MPATH_VALID_H -+ -+#ifdef __cpluscplus -+extern "C" { -+#endif -+ -+enum mpath_valid_mode { -+ MPATH_DEFAULT, -+ MPATH_STRICT, -+ MPATH_SMART, -+ MPATH_GREEDY, -+ MPATH_MODE_ERROR, -+}; -+ -+/* -+ * MPATH_IS_VALID_NO_CHECK is used to indicate that it is safe to skip -+ * checks to see if the device has already been released to the system -+ * for use by things other that multipath. -+ * MPATH_IS_MAYBE_VALID is used to indicate that this device would -+ * be a valid multipath path device if another device with the same -+ * wwid existed */ -+enum mpath_valid_result { -+ MPATH_IS_ERROR = -1, -+ MPATH_IS_NOT_VALID, -+ MPATH_IS_VALID, -+ MPATH_IS_VALID_NO_CHECK, -+ MPATH_IS_MAYBE_VALID, -+}; -+ -+enum mpath_valid_log_style { -+ MPATH_LOG_STDERR = -1, /* log to STDERR */ -+ MPATH_LOG_STDERR_TIMESTAMP, /* log to STDERR, with timestamps */ -+ MPATH_LOG_SYSLOG, /* log to system log */ -+}; -+ -+enum mpath_valid_verbosity { -+ MPATH_LOG_PRIO_NOLOG = -1, /* log nothing */ -+ MPATH_LOG_PRIO_ERR, -+ MPATH_LOG_PRIO_WARN, -+ MPATH_LOG_PRIO_NOTICE, -+ MPATH_LOG_PRIO_INFO, -+ MPATH_LOG_PRIO_DEBUG, -+}; -+ -+/* Function declarations */ -+ -+/* -+ * DESCRIPTION: -+ * Initialize the device mapper multipath configuration. This -+ * function must be invoked before calling any other -+ * libmpathvalid functions. Call mpathvalid_exit() to cleanup. -+ * @verbosity: the logging level (mpath_valid_verbosity) -+ * @log_style: the logging style (mpath_valid_log_style) -+ * -+ * RESTRICTIONS: -+ * Calling mpathvalid_init() after calling mpathvalid_exit() has no -+ * effect. -+ * -+ * RETURNS: 0 = Success, -1 = Failure -+ */ -+int mpathvalid_init(int verbosity, int log_style); -+ -+ -+/* -+ * DESCRIPTION: -+ * Reread the multipath configuration files and reinitalize -+ * the device mapper multipath configuration. This function can -+ * be called as many times as necessary. -+ * -+ * RETURNS: 0 = Success, -1 = Failure -+ */ -+int mpathvalid_reload_config(void); -+ -+ -+/* -+ * DESCRIPTION: -+ * Release the device mapper multipath configuration. This -+ * function must be called to cleanup resoures allocated by -+ * mpathvalid_init(). After calling this function, no futher -+ * libmpathvalid functions may be called. -+ * -+ * RETURNS: 0 = Success, -1 = Failure -+ */ -+int mpathvalid_exit(void); -+ -+/* -+ * DESCRIPTION: -+ * Return the configured find_multipaths claim mode, using the -+ * configuration from either mpathvalid_init() or -+ * mpathvalid_reload_config() -+ * -+ * RETURNS: -+ * MPATH_STRICT, MPATH_SMART, MPATH_GREEDY, or MPATH_MODE_ERROR -+ * -+ * MPATH_STRICT = find_multiapths (yes|on|no|off) -+ * MPATH_SMART = find_multipaths smart -+ * MPATH_GREEDY = find_multipaths greedy -+ * MPATH_MODE_ERROR = multipath configuration not initialized -+ */ -+unsigned int mpathvalid_get_mode(void); -+/* -+ * DESCRIPTION: -+ * Return whether device-mapper multipath claims a path device, -+ * using the configuration read from either mpathvalid_init() or -+ * mpathvalid_reload_config(). If the device is either claimed or -+ * potentially claimed (MPATH_IS_VALID, MPATH_IS_VALID_NO_CHECK, -+ * or MPATH_IS_MAYBE_VALID) and wwid is not NULL, then *wiid will -+ * be set to point to the wwid of device. If set, *wwid must be -+ * freed by the caller. path_wwids is an obptional parameter that -+ * points to an array of wwids, that were returned from previous -+ * calls to mpathvalid_is_path(). These are wwids of existing -+ * devices that are or potentially are claimed by device-mapper -+ * multipath. path_wwids is used with the MPATH_SMART claim mode, -+ * to claim devices when another device with the same wwid exists. -+ * nr_paths must either be set to the number of elements of -+ * path_wwids, or 0, if path_wwids is NULL. -+ * @name: The kernel name of the device. input argument -+ * @mode: the find_multipaths claim mode (mpath_valid_mode). input argument -+ * @wwid: address of a pointer to the path wwid, or NULL. Output argument. -+ * Set if path is/may be claimed. If set, must be freed by caller -+ * @path_wwids: Array of pointers to path wwids, or NULL. input argument -+ * @nr_paths: number of elements in path_wwids array. input argument. -+ * -+ * RETURNS: device claim result (mpath_valid_result) -+ * Also sets *wwid if wwid is not NULL, and the claim result is -+ * MPATH_IS_VALID, MPATH_IS_VALID_NO_CHECK, or -+ * MPATH_IS_MAYBE_VALID -+ */ -+int mpathvalid_is_path(const char *name, unsigned int mode, char **wwid, -+ const char **path_wwids, unsigned int nr_paths); -+ -+#ifdef __cplusplus -+} -+#endif -+#endif /* LIB_PATH_VALID_H */ -diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version -index 67a7379f..2e3583f5 100644 ---- a/libmultipath/libmultipath.version -+++ b/libmultipath/libmultipath.version -@@ -264,3 +264,9 @@ LIBMULTIPATH_4.1.0 { - global: - libmp_verbosity; - } LIBMULTIPATH_4.0.0; -+ -+LIBMULTIPATH_4.2.0 { -+global: -+ dm_prereq; -+ skip_libmp_dm_init; -+} LIBMULTIPATH_4.1.0; diff --git a/0069-multipath-tools-tests-and-unit-tests-for-libmpathval.patch b/0069-multipath-tools-tests-and-unit-tests-for-libmpathval.patch deleted file mode 100644 index e8a56a3..0000000 --- a/0069-multipath-tools-tests-and-unit-tests-for-libmpathval.patch +++ /dev/null @@ -1,529 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 21 Oct 2020 16:39:24 -0500 -Subject: [PATCH] multipath-tools tests: and unit tests for libmpathvalid - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - Makefile.inc | 1 + - tests/Makefile | 5 +- - tests/mpathvalid.c | 467 +++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 472 insertions(+), 1 deletion(-) - create mode 100644 tests/mpathvalid.c - -diff --git a/Makefile.inc b/Makefile.inc -index e05f3a91..13587a9f 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -66,6 +66,7 @@ libdir = $(prefix)/$(LIB)/multipath - unitdir = $(prefix)/$(SYSTEMDPATH)/systemd/system - mpathpersistdir = $(TOPDIR)/libmpathpersist - mpathcmddir = $(TOPDIR)/libmpathcmd -+mpathvaliddir = $(TOPDIR)/libmpathvalid - thirdpartydir = $(TOPDIR)/third-party - libdmmpdir = $(TOPDIR)/libdmmp - nvmedir = $(TOPDIR)/libmultipath/nvme -diff --git a/tests/Makefile b/tests/Makefile -index 908407ea..54da774e 100644 ---- a/tests/Makefile -+++ b/tests/Makefile -@@ -13,7 +13,7 @@ CFLAGS += $(BIN_CFLAGS) -I$(multipathdir) -I$(mpathcmddir) \ - LIBDEPS += -L. -L$(mpathcmddir) -lmultipath -lmpathcmd -lcmocka - - TESTS := uevent parser util dmevents hwtable blacklist unaligned vpd pgpolicy \ -- alias directio valid devt -+ alias directio valid devt mpathvalid - HELPERS := test-lib.o test-log.o - - .SILENT: $(TESTS:%=%.o) -@@ -31,6 +31,7 @@ endif - ifneq ($(DIO_TEST_DEV),) - directio-test_FLAGS := -DDIO_TEST_DEV=\"$(DIO_TEST_DEV)\" - endif -+mpathvalid-test_FLAGS := -I$(mpathvaliddir) - - # test-specific linker flags - # XYZ-test_TESTDEPS: test libraries containing __wrap_xyz functions -@@ -56,6 +57,8 @@ alias-test_LIBDEPS := -lpthread -ldl - valid-test_OBJDEPS := ../libmultipath/valid.o - valid-test_LIBDEPS := -ludev -lpthread -ldl - devt-test_LIBDEPS := -ludev -+mpathvalid-test_LIBDEPS := -ludev -lpthread -ldl -+mpathvalid-test_OBJDEPS := ../libmpathvalid/mpath_valid.o - ifneq ($(DIO_TEST_DEV),) - directio-test_LIBDEPS := -laio - endif -diff --git a/tests/mpathvalid.c b/tests/mpathvalid.c -new file mode 100644 -index 00000000..5ffabb9d ---- /dev/null -+++ b/tests/mpathvalid.c -@@ -0,0 +1,467 @@ -+/* -+ * Copyright (c) 2020 Benjamin Marzinski, Red Hat -+ * -+ * SPDX-License-Identifier: GPL-2.0-or-later -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "structs.h" -+#include "config.h" -+#include "mpath_valid.h" -+#include "util.h" -+#include "debug.h" -+ -+const char *test_dev = "test_name"; -+#define TEST_WWID "WWID_123" -+#define CONF_TEMPLATE "mpathvalid-testconf-XXXXXXXX" -+char conf_name[] = CONF_TEMPLATE; -+bool initialized; -+ -+#if 0 -+static int mode_to_findmp(unsigned int mode) -+{ -+ switch (mode) { -+ case MPATH_SMART: -+ return FIND_MULTIPATHS_SMART; -+ case MPATH_GREEDY: -+ return FIND_MULTIPATHS_GREEDY; -+ case MPATH_STRICT: -+ return FIND_MULTIPATHS_STRICT; -+ } -+ fail_msg("invalid mode: %u", mode); -+ return FIND_MULTIPATHS_UNDEF; -+} -+#endif -+ -+static unsigned int findmp_to_mode(int findmp) -+{ -+ switch (findmp) { -+ case FIND_MULTIPATHS_SMART: -+ return MPATH_SMART; -+ case FIND_MULTIPATHS_GREEDY: -+ return MPATH_GREEDY; -+ case FIND_MULTIPATHS_STRICT: -+ case FIND_MULTIPATHS_OFF: -+ case FIND_MULTIPATHS_ON: -+ return MPATH_STRICT; -+ } -+ fail_msg("invalid find_multipaths value: %d", findmp); -+ return MPATH_DEFAULT; -+} -+ -+int __wrap_is_path_valid(const char *name, struct config *conf, struct path *pp, -+ bool check_multipathd) -+{ -+ int r = mock_type(int); -+ int findmp = mock_type(int); -+ -+ assert_ptr_equal(name, test_dev); -+ assert_ptr_not_equal(conf, NULL); -+ assert_ptr_not_equal(pp, NULL); -+ assert_true(check_multipathd); -+ -+ assert_int_equal(findmp, conf->find_multipaths); -+ if (r == MPATH_IS_ERROR || r == MPATH_IS_NOT_VALID) -+ return r; -+ -+ strlcpy(pp->wwid, mock_ptr_type(char *), WWID_SIZE); -+ return r; -+} -+ -+int __wrap_libmultipath_init(void) -+{ -+ int r = mock_type(int); -+ -+ assert_false(initialized); -+ if (r != 0) -+ return r; -+ initialized = true; -+ return 0; -+} -+ -+void __wrap_libmultipath_exit(void) -+{ -+ assert_true(initialized); -+ initialized = false; -+} -+ -+int __wrap_dm_prereq(unsigned int *v) -+{ -+ assert_ptr_not_equal(v, NULL); -+ return mock_type(int); -+} -+ -+int __real_init_config(const char *file); -+ -+int __wrap_init_config(const char *file) -+{ -+ int r = mock_type(int); -+ struct config *conf; -+ -+ assert_ptr_equal(file, DEFAULT_CONFIGFILE); -+ if (r != 0) -+ return r; -+ -+ assert_string_not_equal(conf_name, CONF_TEMPLATE); -+ r = __real_init_config(conf_name); -+ conf = get_multipath_config(); -+ assert_ptr_not_equal(conf, NULL); -+ assert_int_equal(conf->find_multipaths, mock_type(int)); -+ return 0; -+} -+ -+static const char * const find_multipaths_optvals[] = { -+ [FIND_MULTIPATHS_OFF] = "off", -+ [FIND_MULTIPATHS_ON] = "on", -+ [FIND_MULTIPATHS_STRICT] = "strict", -+ [FIND_MULTIPATHS_GREEDY] = "greedy", -+ [FIND_MULTIPATHS_SMART] = "smart", -+}; -+ -+void make_config_file(int findmp) -+{ -+ int r, fd; -+ char buf[64]; -+ -+ assert_true(findmp > FIND_MULTIPATHS_UNDEF && -+ findmp < __FIND_MULTIPATHS_LAST); -+ -+ r = snprintf(buf, sizeof(buf), "defaults {\nfind_multipaths %s\n}\n", -+ find_multipaths_optvals[findmp]); -+ assert_true(r > 0 && (long unsigned int)r < sizeof(buf)); -+ -+ memcpy(conf_name, CONF_TEMPLATE, sizeof(conf_name)); -+ fd = mkstemp(conf_name); -+ assert_true(fd >= 0); -+ assert_int_equal(safe_write(fd, buf, r), 0); -+ assert_int_equal(close(fd), 0); -+} -+ -+int setup(void **state) -+{ -+ initialized = false; -+ udev = udev_new(); -+ if (udev == NULL) -+ return -1; -+ return 0; -+} -+ -+int teardown(void **state) -+{ -+ struct config *conf; -+ conf = get_multipath_config(); -+ put_multipath_config(conf); -+ if (conf) -+ uninit_config(); -+ if (strcmp(conf_name, CONF_TEMPLATE) != 0) -+ unlink(conf_name); -+ udev_unref(udev); -+ udev = NULL; -+ return 0; -+} -+ -+static void check_config(bool valid_config) -+{ -+ struct config *conf; -+ -+ conf = get_multipath_config(); -+ put_multipath_config(conf); -+ if (valid_config) -+ assert_ptr_not_equal(conf, NULL); -+} -+ -+/* libmultipath_init fails */ -+static void test_mpathvalid_init_bad1(void **state) -+{ -+ will_return(__wrap_libmultipath_init, 1); -+ assert_int_equal(mpathvalid_init(MPATH_LOG_PRIO_DEBUG, -+ MPATH_LOG_STDERR), -1); -+ assert_false(initialized); -+ check_config(false); -+} -+ -+/* init_config fails */ -+static void test_mpathvalid_init_bad2(void **state) -+{ -+ will_return(__wrap_libmultipath_init, 0); -+ will_return(__wrap_init_config, 1); -+ assert_int_equal(mpathvalid_init(MPATH_LOG_PRIO_ERR, -+ MPATH_LOG_STDERR_TIMESTAMP), -1); -+ assert_false(initialized); -+ check_config(false); -+} -+ -+/* dm_prereq fails */ -+static void test_mpathvalid_init_bad3(void **state) -+{ -+ make_config_file(FIND_MULTIPATHS_STRICT); -+ will_return(__wrap_libmultipath_init, 0); -+ will_return(__wrap_init_config, 0); -+ will_return(__wrap_init_config, FIND_MULTIPATHS_STRICT); -+ will_return(__wrap_dm_prereq, 1); -+ assert_int_equal(mpathvalid_init(MPATH_LOG_STDERR, MPATH_LOG_PRIO_ERR), -+ -1); -+ assert_false(initialized); -+ check_config(false); -+} -+ -+static void check_mpathvalid_init(int findmp, int prio, int log_style) -+{ -+ make_config_file(findmp); -+ will_return(__wrap_libmultipath_init, 0); -+ will_return(__wrap_init_config, 0); -+ will_return(__wrap_init_config, findmp); -+ will_return(__wrap_dm_prereq, 0); -+ assert_int_equal(mpathvalid_init(prio, log_style), 0); -+ assert_true(initialized); -+ check_config(true); -+ assert_int_equal(logsink, log_style); -+ assert_int_equal(libmp_verbosity, prio); -+ assert_int_equal(findmp_to_mode(findmp), mpathvalid_get_mode()); -+} -+ -+static void check_mpathvalid_exit(void) -+{ -+ assert_int_equal(mpathvalid_exit(), 0); -+ assert_false(initialized); -+ check_config(false); -+} -+ -+static void test_mpathvalid_init_good1(void **state) -+{ -+ check_mpathvalid_init(FIND_MULTIPATHS_OFF, MPATH_LOG_PRIO_ERR, -+ MPATH_LOG_STDERR_TIMESTAMP); -+} -+ -+static void test_mpathvalid_init_good2(void **state) -+{ -+ check_mpathvalid_init(FIND_MULTIPATHS_STRICT, MPATH_LOG_PRIO_DEBUG, -+ MPATH_LOG_STDERR); -+} -+ -+static void test_mpathvalid_init_good3(void **state) -+{ -+ check_mpathvalid_init(FIND_MULTIPATHS_ON, MPATH_LOG_PRIO_NOLOG, -+ MPATH_LOG_SYSLOG); -+} -+ -+static void test_mpathvalid_exit(void **state) -+{ -+ check_mpathvalid_init(FIND_MULTIPATHS_ON, MPATH_LOG_PRIO_ERR, -+ MPATH_LOG_STDERR); -+ check_mpathvalid_exit(); -+} -+ -+/* fails if config hasn't been set */ -+static void test_mpathvalid_get_mode_bad(void **state) -+{ -+#if 1 -+ assert_int_equal(mpathvalid_get_mode(), MPATH_MODE_ERROR); -+#else -+ assert_int_equal(mpathvalid_get_mode(), 1); -+#endif -+} -+ -+/*fails if config hasn't been set */ -+static void test_mpathvalid_reload_config_bad1(void **state) -+{ -+#if 1 -+ will_return(__wrap_init_config, 1); -+#endif -+ assert_int_equal(mpathvalid_reload_config(), -1); -+ check_config(false); -+} -+ -+/* init_config fails */ -+static void test_mpathvalid_reload_config_bad2(void **state) -+{ -+ check_mpathvalid_init(FIND_MULTIPATHS_ON, MPATH_LOG_PRIO_ERR, -+ MPATH_LOG_STDERR); -+ will_return(__wrap_init_config, 1); -+ assert_int_equal(mpathvalid_reload_config(), -1); -+ check_config(false); -+ check_mpathvalid_exit(); -+} -+ -+static void check_mpathvalid_reload_config(int findmp) -+{ -+ assert_string_not_equal(conf_name, CONF_TEMPLATE); -+ unlink(conf_name); -+ make_config_file(findmp); -+ will_return(__wrap_init_config, 0); -+ will_return(__wrap_init_config, findmp); -+ assert_int_equal(mpathvalid_reload_config(), 0); -+ check_config(true); -+ assert_int_equal(findmp_to_mode(findmp), mpathvalid_get_mode()); -+} -+ -+static void test_mpathvalid_reload_config_good(void **state) -+{ -+ check_mpathvalid_init(FIND_MULTIPATHS_OFF, MPATH_LOG_PRIO_ERR, -+ MPATH_LOG_STDERR); -+ check_mpathvalid_reload_config(FIND_MULTIPATHS_ON); -+ check_mpathvalid_reload_config(FIND_MULTIPATHS_GREEDY); -+ check_mpathvalid_reload_config(FIND_MULTIPATHS_SMART); -+ check_mpathvalid_reload_config(FIND_MULTIPATHS_STRICT); -+ check_mpathvalid_exit(); -+} -+ -+/* NULL name */ -+static void test_mpathvalid_is_path_bad1(void **state) -+{ -+ assert_int_equal(mpathvalid_is_path(NULL, MPATH_STRICT, NULL, NULL, 0), -+ MPATH_IS_ERROR); -+} -+ -+/* bad mode */ -+static void test_mpathvalid_is_path_bad2(void **state) -+{ -+ assert_int_equal(mpathvalid_is_path(test_dev, MPATH_MODE_ERROR, NULL, -+ NULL, 0), MPATH_IS_ERROR); -+} -+ -+/* NULL path_wwids and non-zero nr_paths */ -+static void test_mpathvalid_is_path_bad3(void **state) -+{ -+ assert_int_equal(mpathvalid_is_path(test_dev, MPATH_MODE_ERROR, NULL, -+ NULL, 1), MPATH_IS_ERROR); -+} -+ -+/*fails if config hasn't been set */ -+static void test_mpathvalid_is_path_bad4(void **state) -+{ -+#if 0 -+ will_return(__wrap_is_path_valid, MPATH_IS_ERROR); -+ will_return(__wrap_is_path_valid, FIND_MULTIPATHS_STRICT); -+#endif -+ assert_int_equal(mpathvalid_is_path(test_dev, MPATH_STRICT, NULL, -+ NULL, 0), MPATH_IS_ERROR); -+} -+ -+/* is_path_valid fails */ -+static void test_mpathvalid_is_path_bad5(void **state) -+{ -+ check_mpathvalid_init(FIND_MULTIPATHS_OFF, MPATH_LOG_PRIO_ERR, -+ MPATH_LOG_STDERR); -+ will_return(__wrap_is_path_valid, MPATH_IS_ERROR); -+ will_return(__wrap_is_path_valid, FIND_MULTIPATHS_GREEDY); -+ assert_int_equal(mpathvalid_is_path(test_dev, MPATH_GREEDY, NULL, -+ NULL, 0), MPATH_IS_ERROR); -+ check_mpathvalid_exit(); -+} -+ -+static void test_mpathvalid_is_path_good1(void **state) -+{ -+ char *wwid; -+ check_mpathvalid_init(FIND_MULTIPATHS_STRICT, MPATH_LOG_PRIO_ERR, -+ MPATH_LOG_STDERR); -+ will_return(__wrap_is_path_valid, MPATH_IS_NOT_VALID); -+ will_return(__wrap_is_path_valid, FIND_MULTIPATHS_STRICT); -+ assert_int_equal(mpathvalid_is_path(test_dev, MPATH_DEFAULT, &wwid, -+ NULL, 0), MPATH_IS_NOT_VALID); -+ assert_ptr_equal(wwid, NULL); -+ check_mpathvalid_exit(); -+} -+ -+static void test_mpathvalid_is_path_good2(void **state) -+{ -+ const char *wwids[] = { "WWID_A", "WWID_B", "WWID_C", "WWID_D" }; -+ char *wwid; -+ check_mpathvalid_init(FIND_MULTIPATHS_ON, MPATH_LOG_PRIO_ERR, -+ MPATH_LOG_STDERR); -+ will_return(__wrap_is_path_valid, MPATH_IS_VALID); -+ will_return(__wrap_is_path_valid, FIND_MULTIPATHS_ON); -+ will_return(__wrap_is_path_valid, TEST_WWID); -+ assert_int_equal(mpathvalid_is_path(test_dev, MPATH_DEFAULT, &wwid, -+ wwids, 4), MPATH_IS_VALID); -+ assert_string_equal(wwid, TEST_WWID); -+} -+ -+static void test_mpathvalid_is_path_good3(void **state) -+{ -+ const char *wwids[] = { "WWID_A", "WWID_B", "WWID_C", "WWID_D" }; -+ char *wwid; -+ check_mpathvalid_init(FIND_MULTIPATHS_OFF, MPATH_LOG_PRIO_ERR, -+ MPATH_LOG_STDERR); -+ will_return(__wrap_is_path_valid, MPATH_IS_VALID); -+ will_return(__wrap_is_path_valid, FIND_MULTIPATHS_SMART); -+ will_return(__wrap_is_path_valid, TEST_WWID); -+ assert_int_equal(mpathvalid_is_path(test_dev, MPATH_SMART, &wwid, -+ wwids, 4), MPATH_IS_VALID); -+ assert_string_equal(wwid, TEST_WWID); -+} -+ -+/* mabybe valid with no matching paths */ -+static void test_mpathvalid_is_path_good4(void **state) -+{ -+ const char *wwids[] = { "WWID_A", "WWID_B", "WWID_C", "WWID_D" }; -+ char *wwid; -+ check_mpathvalid_init(FIND_MULTIPATHS_SMART, MPATH_LOG_PRIO_ERR, -+ MPATH_LOG_STDERR); -+ will_return(__wrap_is_path_valid, MPATH_IS_MAYBE_VALID); -+ will_return(__wrap_is_path_valid, FIND_MULTIPATHS_SMART); -+ will_return(__wrap_is_path_valid, TEST_WWID); -+ assert_int_equal(mpathvalid_is_path(test_dev, MPATH_DEFAULT, &wwid, -+ wwids, 4), MPATH_IS_MAYBE_VALID); -+ assert_string_equal(wwid, TEST_WWID); -+} -+ -+/* maybe valid with matching paths */ -+static void test_mpathvalid_is_path_good5(void **state) -+{ -+ const char *wwids[] = { "WWID_A", "WWID_B", TEST_WWID, "WWID_D" }; -+ char *wwid; -+ check_mpathvalid_init(FIND_MULTIPATHS_SMART, MPATH_LOG_PRIO_ERR, -+ MPATH_LOG_STDERR); -+ will_return(__wrap_is_path_valid, MPATH_IS_MAYBE_VALID); -+ will_return(__wrap_is_path_valid, FIND_MULTIPATHS_SMART); -+ will_return(__wrap_is_path_valid, TEST_WWID); -+ assert_int_equal(mpathvalid_is_path(test_dev, MPATH_DEFAULT, &wwid, -+ wwids, 4), MPATH_IS_VALID); -+ assert_string_equal(wwid, TEST_WWID); -+} -+ -+#define setup_test(name) \ -+ cmocka_unit_test_setup_teardown(name, setup, teardown) -+ -+int test_mpathvalid(void) -+{ -+ const struct CMUnitTest tests[] = { -+ setup_test(test_mpathvalid_init_bad1), -+ setup_test(test_mpathvalid_init_bad2), -+ setup_test(test_mpathvalid_init_bad3), -+ setup_test(test_mpathvalid_init_good1), -+ setup_test(test_mpathvalid_init_good2), -+ setup_test(test_mpathvalid_init_good3), -+ setup_test(test_mpathvalid_exit), -+ setup_test(test_mpathvalid_get_mode_bad), -+ setup_test(test_mpathvalid_reload_config_bad1), -+ setup_test(test_mpathvalid_reload_config_bad2), -+ setup_test(test_mpathvalid_reload_config_good), -+ setup_test(test_mpathvalid_is_path_bad1), -+ setup_test(test_mpathvalid_is_path_bad2), -+ setup_test(test_mpathvalid_is_path_bad3), -+ setup_test(test_mpathvalid_is_path_bad4), -+ setup_test(test_mpathvalid_is_path_bad5), -+ setup_test(test_mpathvalid_is_path_good1), -+ setup_test(test_mpathvalid_is_path_good2), -+ setup_test(test_mpathvalid_is_path_good3), -+ setup_test(test_mpathvalid_is_path_good4), -+ setup_test(test_mpathvalid_is_path_good5), -+ }; -+ return cmocka_run_group_tests(tests, NULL, NULL); -+} -+ -+int main(void) -+{ -+ int r = 0; -+ -+ r += test_mpathvalid(); -+ return r; -+} diff --git a/0070-libmultipath-add-uid-failback-for-dasd-devices.patch b/0070-libmultipath-add-uid-failback-for-dasd-devices.patch deleted file mode 100644 index 9a26734..0000000 --- a/0070-libmultipath-add-uid-failback-for-dasd-devices.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 21 Oct 2020 16:39:25 -0500 -Subject: [PATCH] libmultipath: add uid failback for dasd devices - -Add failback code to get the uid for dasd devices from sysfs. Copied -from dasdinfo - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/defaults.h | 1 + - libmultipath/discovery.c | 37 ++++++++++++++++++++++++++++++++++++- - 2 files changed, 37 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h -index 39a5e415..947ba467 100644 ---- a/libmultipath/defaults.h -+++ b/libmultipath/defaults.h -@@ -8,6 +8,7 @@ - */ - #define DEFAULT_UID_ATTRIBUTE "ID_SERIAL" - #define DEFAULT_NVME_UID_ATTRIBUTE "ID_WWN" -+#define DEFAULT_DASD_UID_ATTRIBUTE "ID_UID" - #define DEFAULT_UDEVDIR "/dev" - #define DEFAULT_MULTIPATHDIR "/" LIB_STRING "/multipath" - #define DEFAULT_SELECTOR "service-time 0" -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index e7084664..877e8f2b 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -1959,12 +1959,44 @@ get_vpd_uid(struct path * pp) - return get_vpd_sysfs(parent, 0x83, pp->wwid, WWID_SIZE); - } - -+/* based on code from s390-tools/dasdinfo/dasdinfo.c */ -+static ssize_t dasd_get_uid(struct path *pp) -+{ -+ struct udev_device *parent; -+ char value[80]; -+ char *p; -+ int i; -+ -+ parent = udev_device_get_parent_with_subsystem_devtype(pp->udev, "ccw", -+ NULL); -+ if (!parent) -+ return -1; -+ -+ if (sysfs_attr_get_value(parent, "uid", value, 80) < 0) -+ return -1; -+ -+ p = value - 1; -+ /* look for the 4th '.' and cut there */ -+ for (i = 0; i < 4; i++) { -+ p = index(p + 1, '.'); -+ if (!p) -+ break; -+ } -+ if (p) -+ *p = '\0'; -+ -+ return strlcpy(pp->wwid, value, WWID_SIZE); -+} -+ - static ssize_t uid_fallback(struct path *pp, int path_state, - const char **origin) - { - ssize_t len = -1; - -- if (pp->bus == SYSFS_BUS_SCSI) { -+ if (pp->bus == SYSFS_BUS_CCW) { -+ len = dasd_get_uid(pp); -+ *origin = "sysfs"; -+ } else if (pp->bus == SYSFS_BUS_SCSI) { - len = get_vpd_uid(pp); - *origin = "sysfs"; - if (len < 0 && path_state == PATH_UP) { -@@ -2012,6 +2044,9 @@ static bool has_uid_fallback(struct path *pp) - !strcmp(pp->uid_attribute, ""))) || - (pp->bus == SYSFS_BUS_NVME && - (!strcmp(pp->uid_attribute, DEFAULT_NVME_UID_ATTRIBUTE) || -+ !strcmp(pp->uid_attribute, ""))) || -+ (pp->bus == SYSFS_BUS_CCW && -+ (!strcmp(pp->uid_attribute, DEFAULT_DASD_UID_ATTRIBUTE) || - !strcmp(pp->uid_attribute, "")))); - } - diff --git a/0071-libmultipath-change-log-level-for-null-uid_attribute.patch b/0071-libmultipath-change-log-level-for-null-uid_attribute.patch deleted file mode 100644 index de48c1b..0000000 --- a/0071-libmultipath-change-log-level-for-null-uid_attribute.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 21 Oct 2020 16:39:26 -0500 -Subject: [PATCH] libmultipath: change log level for null uid_attribute - -If uid_attribute is explicitly set to an empty string, multipath should -log the uid at the default log level, since using the fallback code is -the expected behavior. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/discovery.c | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 877e8f2b..c74f13bf 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -2086,8 +2086,11 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev, - len = strlen(pp->wwid); - origin = "callout"; - } else { -- bool udev_available = udev && pp->uid_attribute -+ bool valid_uid_attr = pp->uid_attribute - && *pp->uid_attribute; -+ bool empty_uid_attr = pp->uid_attribute -+ && !*pp->uid_attribute; -+ bool udev_available = udev && valid_uid_attr; - - if (udev_available) { - len = get_udev_uid(pp, pp->uid_attribute, udev); -@@ -2097,7 +2100,8 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev, - } - if ((!udev_available || (len <= 0 && allow_fallback)) - && has_uid_fallback(pp)) { -- used_fallback = 1; -+ if (!udev || !empty_uid_attr) -+ used_fallback = 1; - len = uid_fallback(pp, path_state, &origin); - } - } diff --git a/0072-libmultipath-move-fast_io_fail-defines-to-structs.h.patch b/0072-libmultipath-move-fast_io_fail-defines-to-structs.h.patch deleted file mode 100644 index 557763c..0000000 --- a/0072-libmultipath-move-fast_io_fail-defines-to-structs.h.patch +++ /dev/null @@ -1,157 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 17 Dec 2020 16:50:59 -0600 -Subject: [PATCH] libmultipath: move fast_io_fail defines to structs.h - -Since fast_io_fail is part of the multipath struct, its symbolic values -belong in structs.h. Also, make it an instance of a general enum, which -will be used again in future patches, and change the set/print functions -which use it to use the general enum instead. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/config.h | 8 -------- - libmultipath/dict.c | 30 +++++++++++++++--------------- - libmultipath/dict.h | 2 +- - libmultipath/propsel.c | 2 +- - libmultipath/structs.h | 17 +++++++++++++++++ - 5 files changed, 34 insertions(+), 25 deletions(-) - -diff --git a/libmultipath/config.h b/libmultipath/config.h -index 5d460359..661dd586 100644 ---- a/libmultipath/config.h -+++ b/libmultipath/config.h -@@ -10,14 +10,6 @@ - #define ORIGIN_DEFAULT 0 - #define ORIGIN_CONFIG 1 - --/* -- * In kernel, fast_io_fail == 0 means immediate failure on rport delete. -- * OTOH '0' means not-configured in various places in multipath-tools. -- */ --#define MP_FAST_IO_FAIL_UNSET (0) --#define MP_FAST_IO_FAIL_OFF (-1) --#define MP_FAST_IO_FAIL_ZERO (-2) -- - enum devtypes { - DEV_NONE, - DEV_DEVT, -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index f12c2e5c..f4357da1 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -822,7 +822,7 @@ declare_mp_attr_handler(gid, set_gid) - declare_mp_attr_snprint(gid, print_gid) - - static int --set_fast_io_fail(vector strvec, void *ptr) -+set_undef_off_zero(vector strvec, void *ptr) - { - char * buff; - int *int_ptr = (int *)ptr; -@@ -832,36 +832,36 @@ set_fast_io_fail(vector strvec, void *ptr) - return 1; - - if (strcmp(buff, "off") == 0) -- *int_ptr = MP_FAST_IO_FAIL_OFF; -+ *int_ptr = UOZ_OFF; - else if (sscanf(buff, "%d", int_ptr) != 1 || -- *int_ptr < MP_FAST_IO_FAIL_ZERO) -- *int_ptr = MP_FAST_IO_FAIL_UNSET; -+ *int_ptr < UOZ_ZERO) -+ *int_ptr = UOZ_UNDEF; - else if (*int_ptr == 0) -- *int_ptr = MP_FAST_IO_FAIL_ZERO; -+ *int_ptr = UOZ_ZERO; - - FREE(buff); - return 0; - } - - int --print_fast_io_fail(char * buff, int len, long v) -+print_undef_off_zero(char * buff, int len, long v) - { -- if (v == MP_FAST_IO_FAIL_UNSET) -+ if (v == UOZ_UNDEF) - return 0; -- if (v == MP_FAST_IO_FAIL_OFF) -+ if (v == UOZ_OFF) - return snprintf(buff, len, "\"off\""); -- if (v == MP_FAST_IO_FAIL_ZERO) -+ if (v == UOZ_ZERO) - return snprintf(buff, len, "0"); - return snprintf(buff, len, "%ld", v); - } - --declare_def_handler(fast_io_fail, set_fast_io_fail) --declare_def_snprint_defint(fast_io_fail, print_fast_io_fail, -+declare_def_handler(fast_io_fail, set_undef_off_zero) -+declare_def_snprint_defint(fast_io_fail, print_undef_off_zero, - DEFAULT_FAST_IO_FAIL) --declare_ovr_handler(fast_io_fail, set_fast_io_fail) --declare_ovr_snprint(fast_io_fail, print_fast_io_fail) --declare_hw_handler(fast_io_fail, set_fast_io_fail) --declare_hw_snprint(fast_io_fail, print_fast_io_fail) -+declare_ovr_handler(fast_io_fail, set_undef_off_zero) -+declare_ovr_snprint(fast_io_fail, print_undef_off_zero) -+declare_hw_handler(fast_io_fail, set_undef_off_zero) -+declare_hw_snprint(fast_io_fail, print_undef_off_zero) - - static int - set_dev_loss(vector strvec, void *ptr) -diff --git a/libmultipath/dict.h b/libmultipath/dict.h -index a40ac66f..a917e1ca 100644 ---- a/libmultipath/dict.h -+++ b/libmultipath/dict.h -@@ -13,7 +13,7 @@ int print_rr_weight(char *buff, int len, long v); - int print_pgfailback(char *buff, int len, long v); - 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_undef_off_zero(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, uint8_t - flags, int source); -diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c -index 3f2c2cfa..67d025cf 100644 ---- a/libmultipath/propsel.c -+++ b/libmultipath/propsel.c -@@ -754,7 +754,7 @@ int select_fast_io_fail(struct config *conf, struct multipath *mp) - mp_set_conf(fast_io_fail); - mp_set_default(fast_io_fail, DEFAULT_FAST_IO_FAIL); - out: -- print_fast_io_fail(buff, 12, mp->fast_io_fail); -+ print_undef_off_zero(buff, 12, mp->fast_io_fail); - condlog(3, "%s: fast_io_fail_tmo = %s %s", mp->alias, buff, origin); - return 0; - } -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index 4ce30551..cfa7b649 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -219,6 +219,23 @@ enum vpd_vendor_ids { - VPD_VP_ARRAY_SIZE, /* This must remain the last entry */ - }; - -+/* -+ * Multipath treats 0 as undefined for optional config parameters. -+ * Use this for cases where 0 is a valid option for systems multipath -+ * is communicating with -+ */ -+enum undefined_off_zero { -+ UOZ_UNDEF = 0, -+ UOZ_OFF = -1, -+ UOZ_ZERO = -2, -+}; -+ -+enum fast_io_fail_states { -+ MP_FAST_IO_FAIL_UNSET = UOZ_UNDEF, -+ MP_FAST_IO_FAIL_OFF = UOZ_OFF, -+ MP_FAST_IO_FAIL_ZERO = UOZ_ZERO, -+}; -+ - struct vpd_vendor_page { - int pg; - const char *name; diff --git a/0073-libmultipath-add-eh_deadline-multipath.conf-paramete.patch b/0073-libmultipath-add-eh_deadline-multipath.conf-paramete.patch deleted file mode 100644 index 96b8d5c..0000000 --- a/0073-libmultipath-add-eh_deadline-multipath.conf-paramete.patch +++ /dev/null @@ -1,335 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 17 Dec 2020 16:51:00 -0600 -Subject: [PATCH] libmultipath: add eh_deadline multipath.conf parameter - -There are times a fc rport is never lost, meaning that fast_io_fail_tmo -and dev_loss_tmo never trigger, but scsi commands still hang. This can -cause problems in cases where users have strict timing requirements, and -the easiest way to solve these issues is to set eh_deadline. Since it's -already possible to set fast_io_fail_tmo and dev_loss_tmo from -multipath.conf, and have multipath take care of setting it correctly for -the scsi devices in sysfs, it makes sense to allow users to set -eh_deadline here as well. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/config.c | 2 ++ - libmultipath/config.h | 2 ++ - libmultipath/configure.c | 1 + - libmultipath/dict.c | 10 +++++++ - libmultipath/discovery.c | 60 +++++++++++++++++++++++++++++++++----- - libmultipath/propsel.c | 17 +++++++++++ - libmultipath/propsel.h | 1 + - libmultipath/structs.h | 7 +++++ - multipath/multipath.conf.5 | 16 ++++++++++ - 9 files changed, 109 insertions(+), 7 deletions(-) - -diff --git a/libmultipath/config.c b/libmultipath/config.c -index 49e7fb81..9f3cb38d 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -424,6 +424,7 @@ merge_hwe (struct hwentry * dst, struct hwentry * src) - merge_num(flush_on_last_del); - merge_num(fast_io_fail); - merge_num(dev_loss); -+ merge_num(eh_deadline); - merge_num(user_friendly_names); - merge_num(retain_hwhandler); - merge_num(detect_prio); -@@ -579,6 +580,7 @@ store_hwe (vector hwtable, struct hwentry * dhwe) - hwe->flush_on_last_del = dhwe->flush_on_last_del; - hwe->fast_io_fail = dhwe->fast_io_fail; - hwe->dev_loss = dhwe->dev_loss; -+ hwe->eh_deadline = dhwe->eh_deadline; - hwe->user_friendly_names = dhwe->user_friendly_names; - hwe->retain_hwhandler = dhwe->retain_hwhandler; - hwe->detect_prio = dhwe->detect_prio; -diff --git a/libmultipath/config.h b/libmultipath/config.h -index 661dd586..9ce37f16 100644 ---- a/libmultipath/config.h -+++ b/libmultipath/config.h -@@ -63,6 +63,7 @@ struct hwentry { - int flush_on_last_del; - int fast_io_fail; - unsigned int dev_loss; -+ int eh_deadline; - int user_friendly_names; - int retain_hwhandler; - int detect_prio; -@@ -148,6 +149,7 @@ struct config { - int attribute_flags; - int fast_io_fail; - unsigned int dev_loss; -+ int eh_deadline; - int log_checker_err; - int allow_queueing; - int allow_usb_devices; -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 20536e60..c076be72 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -368,6 +368,7 @@ int setup_map(struct multipath *mpp, char *params, int params_size, - select_gid(conf, mpp); - select_fast_io_fail(conf, mpp); - select_dev_loss(conf, mpp); -+ select_eh_deadline(conf, mpp); - select_reservation_key(conf, mpp); - select_deferred_remove(conf, mpp); - select_marginal_path_err_sample_time(conf, mpp); -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index f4357da1..bab96146 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -899,6 +899,13 @@ declare_ovr_snprint(dev_loss, print_dev_loss) - declare_hw_handler(dev_loss, set_dev_loss) - declare_hw_snprint(dev_loss, print_dev_loss) - -+declare_def_handler(eh_deadline, set_undef_off_zero) -+declare_def_snprint(eh_deadline, print_undef_off_zero) -+declare_ovr_handler(eh_deadline, set_undef_off_zero) -+declare_ovr_snprint(eh_deadline, print_undef_off_zero) -+declare_hw_handler(eh_deadline, set_undef_off_zero) -+declare_hw_snprint(eh_deadline, print_undef_off_zero) -+ - static int - set_pgpolicy(vector strvec, void *ptr) - { -@@ -1771,6 +1778,7 @@ init_keywords(vector keywords) - install_keyword("gid", &def_gid_handler, &snprint_def_gid); - install_keyword("fast_io_fail_tmo", &def_fast_io_fail_handler, &snprint_def_fast_io_fail); - install_keyword("dev_loss_tmo", &def_dev_loss_handler, &snprint_def_dev_loss); -+ install_keyword("eh_deadline", &def_eh_deadline_handler, &snprint_def_eh_deadline); - install_keyword("bindings_file", &def_bindings_file_handler, &snprint_def_bindings_file); - install_keyword("wwids_file", &def_wwids_file_handler, &snprint_def_wwids_file); - install_keyword("prkeys_file", &def_prkeys_file_handler, &snprint_def_prkeys_file); -@@ -1880,6 +1888,7 @@ init_keywords(vector keywords) - install_keyword("flush_on_last_del", &hw_flush_on_last_del_handler, &snprint_hw_flush_on_last_del); - install_keyword("fast_io_fail_tmo", &hw_fast_io_fail_handler, &snprint_hw_fast_io_fail); - install_keyword("dev_loss_tmo", &hw_dev_loss_handler, &snprint_hw_dev_loss); -+ install_keyword("eh_deadline", &hw_eh_deadline_handler, &snprint_hw_eh_deadline); - install_keyword("user_friendly_names", &hw_user_friendly_names_handler, &snprint_hw_user_friendly_names); - install_keyword("retain_attached_hw_handler", &hw_retain_hwhandler_handler, &snprint_hw_retain_hwhandler); - install_keyword("detect_prio", &hw_detect_prio_handler, &snprint_hw_detect_prio); -@@ -1920,6 +1929,7 @@ init_keywords(vector keywords) - install_keyword("flush_on_last_del", &ovr_flush_on_last_del_handler, &snprint_ovr_flush_on_last_del); - install_keyword("fast_io_fail_tmo", &ovr_fast_io_fail_handler, &snprint_ovr_fast_io_fail); - install_keyword("dev_loss_tmo", &ovr_dev_loss_handler, &snprint_ovr_dev_loss); -+ install_keyword("eh_deadline", &ovr_eh_deadline_handler, &snprint_ovr_eh_deadline); - install_keyword("user_friendly_names", &ovr_user_friendly_names_handler, &snprint_ovr_user_friendly_names); - install_keyword("retain_attached_hw_handler", &ovr_retain_hwhandler_handler, &snprint_ovr_retain_hwhandler); - install_keyword("detect_prio", &ovr_detect_prio_handler, &snprint_ovr_detect_prio); -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index c74f13bf..add7bb97 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -587,6 +587,42 @@ sysfs_get_asymmetric_access_state(struct path *pp, char *buff, int buflen) - return !!preferred; - } - -+static int -+sysfs_set_eh_deadline(struct multipath *mpp, struct path *pp) -+{ -+ struct udev_device *hostdev; -+ char host_name[HOST_NAME_LEN], value[16]; -+ int ret, len; -+ -+ if (mpp->eh_deadline == EH_DEADLINE_UNSET) -+ return 0; -+ -+ sprintf(host_name, "host%d", pp->sg_id.host_no); -+ hostdev = udev_device_new_from_subsystem_sysname(udev, -+ "scsi_host", host_name); -+ if (!hostdev) -+ return 1; -+ -+ if (mpp->eh_deadline == EH_DEADLINE_OFF) -+ len = sprintf(value, "off"); -+ else if (mpp->eh_deadline == EH_DEADLINE_ZERO) -+ len = sprintf(value, "0"); -+ else -+ len = sprintf(value, "%d", mpp->eh_deadline); -+ -+ ret = sysfs_attr_set_value(hostdev, "eh_deadline", -+ value, len + 1); -+ /* -+ * not all scsi drivers support setting eh_deadline, so failing -+ * is totally reasonable -+ */ -+ if (ret <= 0) -+ condlog(3, "%s: failed to set eh_deadline to %s, error %d", udev_device_get_sysname(hostdev), value, -ret); -+ -+ udev_device_unref(hostdev); -+ return (ret <= 0); -+} -+ - static void - sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp) - { -@@ -596,6 +632,10 @@ sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp) - unsigned int tmo; - int ret; - -+ if (mpp->dev_loss == DEV_LOSS_TMO_UNSET && -+ mpp->fast_io_fail == MP_FAST_IO_FAIL_UNSET) -+ return; -+ - sprintf(rport_id, "rport-%d:%d-%d", - pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.transport_id); - rport_dev = udev_device_new_from_subsystem_sysname(udev, -@@ -703,6 +743,11 @@ sysfs_set_session_tmo(struct multipath *mpp, struct path *pp) - char session_id[64]; - char value[11]; - -+ if (mpp->dev_loss != DEV_LOSS_TMO_UNSET) -+ condlog(3, "%s: ignoring dev_loss_tmo on iSCSI", pp->dev); -+ if (mpp->fast_io_fail == MP_FAST_IO_FAIL_UNSET) -+ return; -+ - sprintf(session_id, "session%d", pp->sg_id.transport_id); - session_dev = udev_device_new_from_subsystem_sysname(udev, - "iscsi_session", session_id); -@@ -714,9 +759,6 @@ sysfs_set_session_tmo(struct multipath *mpp, struct path *pp) - condlog(4, "target%d:%d:%d -> %s", pp->sg_id.host_no, - pp->sg_id.channel, pp->sg_id.scsi_id, session_id); - -- if (mpp->dev_loss != DEV_LOSS_TMO_UNSET) { -- condlog(3, "%s: ignoring dev_loss_tmo on iSCSI", pp->dev); -- } - if (mpp->fast_io_fail != MP_FAST_IO_FAIL_UNSET) { - if (mpp->fast_io_fail == MP_FAST_IO_FAIL_OFF) { - condlog(3, "%s: can't switch off fast_io_fail_tmo " -@@ -744,6 +786,8 @@ sysfs_set_nexus_loss_tmo(struct multipath *mpp, struct path *pp) - char end_dev_id[64]; - char value[11]; - -+ if (mpp->dev_loss == DEV_LOSS_TMO_UNSET) -+ return; - sprintf(end_dev_id, "end_device-%d:%d", - pp->sg_id.host_no, pp->sg_id.transport_id); - sas_dev = udev_device_new_from_subsystem_sysname(udev, -@@ -801,7 +845,8 @@ sysfs_set_scsi_tmo (struct multipath *mpp, unsigned int checkint) - mpp->fast_io_fail = MP_FAST_IO_FAIL_OFF; - } - if (mpp->dev_loss == DEV_LOSS_TMO_UNSET && -- mpp->fast_io_fail == MP_FAST_IO_FAIL_UNSET) -+ mpp->fast_io_fail == MP_FAST_IO_FAIL_UNSET && -+ mpp->eh_deadline == EH_DEADLINE_UNSET) - return 0; - - vector_foreach_slot(mpp->paths, pp, i) { -@@ -814,17 +859,18 @@ sysfs_set_scsi_tmo (struct multipath *mpp, unsigned int checkint) - switch (pp->sg_id.proto_id) { - case SCSI_PROTOCOL_FCP: - sysfs_set_rport_tmo(mpp, pp); -- continue; -+ break; - case SCSI_PROTOCOL_ISCSI: - sysfs_set_session_tmo(mpp, pp); -- continue; -+ break; - case SCSI_PROTOCOL_SAS: - sysfs_set_nexus_loss_tmo(mpp, pp); -- continue; -+ break; - default: - if (!err_path) - err_path = pp; - } -+ sysfs_set_eh_deadline(mpp, pp); - } - - if (err_path) { -diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c -index 67d025cf..fa4ac5d9 100644 ---- a/libmultipath/propsel.c -+++ b/libmultipath/propsel.c -@@ -775,6 +775,23 @@ out: - return 0; - } - -+int select_eh_deadline(struct config *conf, struct multipath *mp) -+{ -+ const char *origin; -+ char buff[12]; -+ -+ mp_set_ovr(eh_deadline); -+ mp_set_hwe(eh_deadline); -+ mp_set_conf(eh_deadline); -+ mp->eh_deadline = EH_DEADLINE_UNSET; -+ /* not changing sysfs in default cause, so don't print anything */ -+ return 0; -+out: -+ print_undef_off_zero(buff, 12, mp->eh_deadline); -+ condlog(3, "%s: eh_deadline = %s %s", mp->alias, buff, origin); -+ return 0; -+} -+ - int select_flush_on_last_del(struct config *conf, struct multipath *mp) - { - const char *origin; -diff --git a/libmultipath/propsel.h b/libmultipath/propsel.h -index 3d6edd8a..a68bacf0 100644 ---- a/libmultipath/propsel.h -+++ b/libmultipath/propsel.h -@@ -17,6 +17,7 @@ int select_uid(struct config *conf, struct multipath *mp); - int select_gid(struct config *conf, struct multipath *mp); - int select_fast_io_fail(struct config *conf, struct multipath *mp); - int select_dev_loss(struct config *conf, struct multipath *mp); -+int select_eh_deadline(struct config *conf, struct multipath *mp); - int select_reservation_key(struct config *conf, struct multipath *mp); - int select_retain_hwhandler (struct config *conf, struct multipath * mp); - int select_detect_prio(struct config *conf, struct path * pp); -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index cfa7b649..d6ff6762 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -236,6 +236,12 @@ enum fast_io_fail_states { - MP_FAST_IO_FAIL_ZERO = UOZ_ZERO, - }; - -+enum eh_deadline_states { -+ EH_DEADLINE_UNSET = UOZ_UNDEF, -+ EH_DEADLINE_OFF = UOZ_OFF, -+ EH_DEADLINE_ZERO = UOZ_ZERO, -+}; -+ - struct vpd_vendor_page { - int pg; - const char *name; -@@ -356,6 +362,7 @@ struct multipath { - int ghost_delay; - int ghost_delay_tick; - unsigned int dev_loss; -+ int eh_deadline; - uid_t uid; - gid_t gid; - mode_t mode; -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 7242d39b..ea66a01e 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -717,6 +717,22 @@ The default is: \fB600\fR - . - . - .TP -+.B eh_deadline -+Specify the maximum number of seconds the SCSI layer will spend doing error -+handling when scsi devices fail. After this timeout the scsi layer will perform -+a full HBA reset. Setting this may be necessary in cases where the rport is -+never lost, so \fIfast_io_fail_tmo\fR and \fIdev_loss_tmo\fR will never -+trigger, but (frequently do to load) scsi commands still hang. \fBNote:\fR when -+the scsi error handler performs the HBA reset, all target paths on that HBA -+will be affected. eh_deadline should only be set in cases where all targets on -+the affected HBAs are multipathed. -+.RS -+.TP -+The default is: \fB\fR -+.RE -+. -+. -+.TP - .B bindings_file - The full pathname of the binding file to be used when the user_friendly_names - option is set. diff --git a/0074-multipathd-remove-redundant-vector_free-int-configur.patch b/0074-multipathd-remove-redundant-vector_free-int-configur.patch deleted file mode 100644 index 5d1fd0a..0000000 --- a/0074-multipathd-remove-redundant-vector_free-int-configur.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 17 Dec 2020 16:51:01 -0600 -Subject: [PATCH] multipathd: remove redundant vector_free() int configure - -remove_maps(vecs) already calls vector_free(vecs->mpvec) - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - multipathd/main.c | 8 ++------ - 1 file changed, 2 insertions(+), 6 deletions(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index b6a5f5b7..2eab4854 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -2634,14 +2634,10 @@ configure (struct vectors * vecs) - } - - /* -- * purge dm of old maps -+ * purge dm of old maps and save new set of maps formed by -+ * considering current path state - */ - remove_maps(vecs); -- -- /* -- * save new set of maps formed by considering current path state -- */ -- vector_free(vecs->mpvec); - vecs->mpvec = mpvec; - - /* diff --git a/0075-libmultipath-factor-out-code-to-get-vpd-page-data.patch b/0075-libmultipath-factor-out-code-to-get-vpd-page-data.patch deleted file mode 100644 index 1d7b142..0000000 --- a/0075-libmultipath-factor-out-code-to-get-vpd-page-data.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 17 Dec 2020 16:51:02 -0600 -Subject: [PATCH] libmultipath: factor out code to get vpd page data - -A future patch will reuse the code to get the vpd page data, so factor -it out from get_vpd_sgio(). - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/discovery.c | 27 +++++++++++++++++++-------- - 1 file changed, 19 insertions(+), 8 deletions(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index add7bb97..f901e9ff 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -1321,14 +1321,13 @@ get_vpd_sysfs (struct udev_device *parent, int pg, char * str, int maxlen) - return len; - } - --int --get_vpd_sgio (int fd, int pg, int vend_id, char * str, int maxlen) -+static int -+fetch_vpd_page(int fd, int pg, unsigned char *buff, int maxlen) - { -- int len, buff_len; -- unsigned char buff[4096]; -+ int buff_len; - -- memset(buff, 0x0, 4096); -- if (sgio_get_vpd(buff, 4096, fd, pg) < 0) { -+ memset(buff, 0x0, maxlen); -+ if (sgio_get_vpd(buff, maxlen, fd, pg) < 0) { - int lvl = pg == 0x80 || pg == 0x83 ? 3 : 4; - - condlog(lvl, "failed to issue vpd inquiry for pg%02x", -@@ -1342,10 +1341,22 @@ get_vpd_sgio (int fd, int pg, int vend_id, char * str, int maxlen) - return -ENODATA; - } - buff_len = get_unaligned_be16(&buff[2]) + 4; -- if (buff_len > 4096) { -+ if (buff_len > maxlen) { - condlog(3, "vpd pg%02x page truncated", pg); -- buff_len = 4096; -+ buff_len = maxlen; - } -+ return buff_len; -+} -+ -+int -+get_vpd_sgio (int fd, int pg, int vend_id, char * str, int maxlen) -+{ -+ int len, buff_len; -+ unsigned char buff[4096]; -+ -+ buff_len = fetch_vpd_page(fd, pg, buff, sizeof(buff)); -+ if (buff_len < 0) -+ return buff_len; - if (pg == 0x80) - len = parse_vpd_pg80(buff, str, maxlen); - else if (pg == 0x83) diff --git a/0076-libmultipath-limit-reading-0xc9-vpd-page.patch b/0076-libmultipath-limit-reading-0xc9-vpd-page.patch deleted file mode 100644 index f5483b2..0000000 --- a/0076-libmultipath-limit-reading-0xc9-vpd-page.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 17 Dec 2020 16:51:03 -0600 -Subject: [PATCH] libmultipath: limit reading 0xc9 vpd page - -Only rdac arrays support 0xC9 vpd page inquiries. All other arrays will -return a failure. Only do the rdac inquiry when detecting array -capabilities if the array's path checker is explicitly set to rdac, or -the path checker is not set, and the array reports that it supports vpd -page 0xC9 in the Supported VPD Pages (0x00) vpd page. - -Multipath was doing the check if either the path checker was set to -rdac, or no path checker was set. This means that for almost all -non-rdac arrays, multipath was issuing a bad inquiry. This was annoying -users. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/discovery.c | 17 +++++++++++++++++ - libmultipath/discovery.h | 1 + - libmultipath/propsel.c | 10 ++++++---- - 3 files changed, 24 insertions(+), 4 deletions(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index f901e9ff..e818585a 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -1348,6 +1348,23 @@ fetch_vpd_page(int fd, int pg, unsigned char *buff, int maxlen) - return buff_len; - } - -+/* based on sg_inq.c from sg3_utils */ -+bool -+is_vpd_page_supported(int fd, int pg) -+{ -+ int i, len; -+ unsigned char buff[4096]; -+ -+ len = fetch_vpd_page(fd, 0x00, buff, sizeof(buff)); -+ if (len < 0) -+ return false; -+ -+ for (i = 4; i < len; ++i) -+ if (buff[i] == pg) -+ return true; -+ return false; -+} -+ - int - get_vpd_sgio (int fd, int pg, int vend_id, char * str, int maxlen) - { -diff --git a/libmultipath/discovery.h b/libmultipath/discovery.h -index 6444887d..d3193daf 100644 ---- a/libmultipath/discovery.h -+++ b/libmultipath/discovery.h -@@ -56,6 +56,7 @@ int sysfs_get_asymmetric_access_state(struct path *pp, - char *buff, int buflen); - int get_uid(struct path * pp, int path_state, struct udev_device *udev, - int allow_fallback); -+bool is_vpd_page_supported(int fd, int pg); - - /* - * discovery bitmask -diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c -index fa4ac5d9..f771a830 100644 ---- a/libmultipath/propsel.c -+++ b/libmultipath/propsel.c -@@ -496,13 +496,15 @@ check_rdac(struct path * pp) - { - int len; - char buff[44]; -- const char *checker_name; -+ const char *checker_name = NULL; - - if (pp->bus != SYSFS_BUS_SCSI) - return 0; -- /* Avoid ioctl if this is likely not an RDAC array */ -- if (__do_set_from_hwe(checker_name, pp, checker_name) && -- strcmp(checker_name, RDAC)) -+ /* Avoid checking 0xc9 if this is likely not an RDAC array */ -+ if (!__do_set_from_hwe(checker_name, pp, checker_name) && -+ !is_vpd_page_supported(pp->fd, 0xC9)) -+ return 0; -+ if (checker_name && strcmp(checker_name, RDAC)) - return 0; - len = get_vpd_sgio(pp->fd, 0xC9, 0, buff, 44); - if (len <= 0) diff --git a/0077-libmultipath-move-logq_lock-handling-to-log.c.patch b/0077-libmultipath-move-logq_lock-handling-to-log.c.patch deleted file mode 100644 index b2799a8..0000000 --- a/0077-libmultipath-move-logq_lock-handling-to-log.c.patch +++ /dev/null @@ -1,138 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 26 Oct 2020 22:01:18 +0100 -Subject: [PATCH] libmultipath: move logq_lock handling to log.c - -logq_lock protects internal data structures of log.c, and should -be handled there. This patch doesn't change functionality, except -improving cancel-safety somewhat. -Reviewed-by: Benjamin Marzinski - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/log.c | 34 ++++++++++++++++++++++++++++++++-- - libmultipath/log_pthread.c | 9 --------- - 2 files changed, 32 insertions(+), 11 deletions(-) - -diff --git a/libmultipath/log.c b/libmultipath/log.c -index debd36de..7f337879 100644 ---- a/libmultipath/log.c -+++ b/libmultipath/log.c -@@ -9,13 +9,16 @@ - #include - #include - #include -+#include - - #include "memory.h" - #include "log.h" -+#include "util.h" - - #define ALIGN(len, s) (((len)+(s)-1)/(s)*(s)) - - struct logarea* la; -+static pthread_mutex_t logq_lock = PTHREAD_MUTEX_INITIALIZER; - - #if LOGDBG - static void dump_logarea (void) -@@ -101,12 +104,17 @@ void log_close (void) - - void log_reset (char *program_name) - { -+ pthread_mutex_lock(&logq_lock); -+ pthread_cleanup_push(cleanup_mutex, &logq_lock); -+ - closelog(); - tzset(); - openlog(program_name, 0, LOG_DAEMON); -+ -+ pthread_cleanup_pop(1); - } - --int log_enqueue (int prio, const char * fmt, va_list ap) -+static int _log_enqueue(int prio, const char * fmt, va_list ap) - { - int len, fwd; - char buff[MAX_MSG_SIZE]; -@@ -165,7 +173,18 @@ int log_enqueue (int prio, const char * fmt, va_list ap) - return 0; - } - --int log_dequeue (void * buff) -+int log_enqueue(int prio, const char *fmt, va_list ap) -+{ -+ int ret; -+ -+ pthread_mutex_lock(&logq_lock); -+ pthread_cleanup_push(cleanup_mutex, &logq_lock); -+ ret = _log_enqueue(prio, fmt, ap); -+ pthread_cleanup_pop(1); -+ return ret; -+} -+ -+static int _log_dequeue(void *buff) - { - struct logmsg * src = (struct logmsg *)la->head; - struct logmsg * dst = (struct logmsg *)buff; -@@ -194,6 +213,17 @@ int log_dequeue (void * buff) - return 0; - } - -+int log_dequeue(void *buff) -+{ -+ int ret; -+ -+ pthread_mutex_lock(&logq_lock); -+ pthread_cleanup_push(cleanup_mutex, &logq_lock); -+ ret = _log_dequeue(buff); -+ pthread_cleanup_pop(1); -+ return ret; -+} -+ - /* - * this one can block under memory pressure - */ -diff --git a/libmultipath/log_pthread.c b/libmultipath/log_pthread.c -index 0d48c52c..65992101 100644 ---- a/libmultipath/log_pthread.c -+++ b/libmultipath/log_pthread.c -@@ -18,7 +18,6 @@ - static pthread_t log_thr; - - /* logev_lock must not be taken with logq_lock held */ --static pthread_mutex_t logq_lock = PTHREAD_MUTEX_INITIALIZER; - static pthread_mutex_t logev_lock = PTHREAD_MUTEX_INITIALIZER; - static pthread_cond_t logev_cond = PTHREAD_COND_INITIALIZER; - -@@ -41,10 +40,7 @@ void log_safe (int prio, const char * fmt, va_list ap) - running = logq_running; - - if (running) { -- pthread_mutex_lock(&logq_lock); -- pthread_cleanup_push(cleanup_mutex, &logq_lock); - log_enqueue(prio, fmt, ap); -- pthread_cleanup_pop(1); - - log_messages_pending = 1; - pthread_cond_signal(&logev_cond); -@@ -60,9 +56,7 @@ static void flush_logqueue (void) - int empty; - - do { -- pthread_mutex_lock(&logq_lock); - empty = log_dequeue(la->buff); -- pthread_mutex_unlock(&logq_lock); - if (!empty) - log_syslog(la->buff); - } while (empty == 0); -@@ -138,10 +132,7 @@ void log_thread_start (pthread_attr_t *attr) - void log_thread_reset (void) - { - logdbg(stderr,"resetting log\n"); -- -- pthread_mutex_lock(&logq_lock); - log_reset("multipathd"); -- pthread_mutex_unlock(&logq_lock); - } - - void log_thread_stop (void) diff --git a/0078-libmultipath-protect-logarea-with-logq_lock.patch b/0078-libmultipath-protect-logarea-with-logq_lock.patch deleted file mode 100644 index d59a9b8..0000000 --- a/0078-libmultipath-protect-logarea-with-logq_lock.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 26 Oct 2020 22:13:40 +0100 -Subject: [PATCH] libmultipath: protect logarea with logq_lock - -Make sure the global logarea (la) is only allocated and freed -hile holding logq_lock. This avoids invalid memory access. - -This patch makes free_logarea() static. libmultipath.version -is unchanged, as free_logarea() wasn't exported anyway. -Reviewed-by: Benjamin Marzinski - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/log.c | 32 +++++++++++++++++++++++--------- - libmultipath/log.h | 1 - - 2 files changed, 23 insertions(+), 10 deletions(-) - -diff --git a/libmultipath/log.c b/libmultipath/log.c -index 7f337879..95c8f01a 100644 ---- a/libmultipath/log.c -+++ b/libmultipath/log.c -@@ -77,16 +77,23 @@ static int logarea_init (int size) - - int log_init(char *program_name, int size) - { -+ int ret = 1; -+ - logdbg(stderr,"enter log_init\n"); -+ -+ pthread_mutex_lock(&logq_lock); -+ pthread_cleanup_push(cleanup_mutex, &logq_lock); -+ - openlog(program_name, 0, LOG_DAEMON); -+ if (!la) -+ ret = logarea_init(size); - -- if (logarea_init(size)) -- return 1; -+ pthread_cleanup_pop(1); - -- return 0; -+ return ret; - } - --void free_logarea (void) -+static void free_logarea (void) - { - FREE(la->start); - FREE(la->buff); -@@ -96,9 +103,14 @@ void free_logarea (void) - - void log_close (void) - { -- free_logarea(); -+ pthread_mutex_lock(&logq_lock); -+ pthread_cleanup_push(cleanup_mutex, &logq_lock); -+ -+ if (la) -+ free_logarea(); - closelog(); - -+ pthread_cleanup_pop(1); - return; - } - -@@ -175,11 +187,12 @@ static int _log_enqueue(int prio, const char * fmt, va_list ap) - - int log_enqueue(int prio, const char *fmt, va_list ap) - { -- int ret; -+ int ret = 1; - - pthread_mutex_lock(&logq_lock); - pthread_cleanup_push(cleanup_mutex, &logq_lock); -- ret = _log_enqueue(prio, fmt, ap); -+ if (la) -+ ret = _log_enqueue(prio, fmt, ap); - pthread_cleanup_pop(1); - return ret; - } -@@ -215,11 +228,12 @@ static int _log_dequeue(void *buff) - - int log_dequeue(void *buff) - { -- int ret; -+ int ret = 1; - - pthread_mutex_lock(&logq_lock); - pthread_cleanup_push(cleanup_mutex, &logq_lock); -- ret = _log_dequeue(buff); -+ if (la) -+ ret = _log_dequeue(buff); - pthread_cleanup_pop(1); - return ret; - } -diff --git a/libmultipath/log.h b/libmultipath/log.h -index d2448f6a..fa224e4d 100644 ---- a/libmultipath/log.h -+++ b/libmultipath/log.h -@@ -39,6 +39,5 @@ int log_enqueue (int prio, const char * fmt, va_list ap) - int log_dequeue (void *); - void log_syslog (void *); - void dump_logmsg (void *); --void free_logarea (void); - - #endif /* LOG_H */ diff --git a/0079-libmultipath-prevent-DSO-unloading-with-astray-check.patch b/0079-libmultipath-prevent-DSO-unloading-with-astray-check.patch deleted file mode 100644 index 8a81d79..0000000 --- a/0079-libmultipath-prevent-DSO-unloading-with-astray-check.patch +++ /dev/null @@ -1,281 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 5 Nov 2020 12:43:25 +0100 -Subject: [PATCH] libmultipath: prevent DSO unloading with astray checker - threads - -The multipathd tur checker thread is designed to be able to finish at -any time, even after the tur checker itself has been freed. The -multipathd shutdown code makes sure all the checkers have been freed -before freeing the checker_class and calling dlclose() to unload the -DSO, but this doesn't guarantee that the checker threads have finished. -If one hasn't, the DSO will get unloaded while the thread still running -code from it, causing a segfault. - -This patch fixes the issue by further incrementing the DSO's refcount -for every running thread. To avoid race conditions leading to segfaults, -the thread's entrypoint must be in libmultipath, not in the DSO itself. -Therefore we add a new optional checker method, libcheck_thread(). -Checkers defining this method may create a detached thread with -entrypoint checker_thread_entry(), which will call the DSO's -libcheck_thread and take care of the refcount handling. - -Reported-by: Benjamin Marzinski -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/checkers.c | 68 +++++++++++++++++++++++++++---- - libmultipath/checkers.h | 25 ++++++++++++ - libmultipath/checkers/tur.c | 12 +++--- - libmultipath/libmultipath.version | 5 +++ - 4 files changed, 97 insertions(+), 13 deletions(-) - -diff --git a/libmultipath/checkers.c b/libmultipath/checkers.c -index 18b1f5eb..2dd9915d 100644 ---- a/libmultipath/checkers.c -+++ b/libmultipath/checkers.c -@@ -3,6 +3,8 @@ - #include - #include - #include -+#include -+#include - - #include "debug.h" - #include "checkers.h" -@@ -20,6 +22,7 @@ struct checker_class { - int (*mp_init)(struct checker *); /* to allocate the mpcontext */ - void (*free)(struct checker *); /* to free the context */ - void (*reset)(void); /* to reset the global variables */ -+ void *(*thread)(void *); /* async thread entry point */ - const char **msgtable; - short msgtable_size; - }; -@@ -55,19 +58,32 @@ static struct checker_class *alloc_checker_class(void) - c = MALLOC(sizeof(struct checker_class)); - if (c) { - INIT_LIST_HEAD(&c->node); -- c->refcount = 1; -+ uatomic_set(&c->refcount, 1); - } - return c; - } - -+/* Use uatomic_{sub,add}_return() to ensure proper memory barriers */ -+static int checker_class_ref(struct checker_class *cls) -+{ -+ return uatomic_add_return(&cls->refcount, 1); -+} -+ -+static int checker_class_unref(struct checker_class *cls) -+{ -+ return uatomic_sub_return(&cls->refcount, 1); -+} -+ - void free_checker_class(struct checker_class *c) - { -+ int cnt; -+ - if (!c) - return; -- c->refcount--; -- if (c->refcount) { -- condlog(4, "%s checker refcount %d", -- c->name, c->refcount); -+ cnt = checker_class_unref(c); -+ if (cnt != 0) { -+ condlog(cnt < 0 ? 1 : 4, "%s checker refcount %d", -+ c->name, cnt); - return; - } - condlog(3, "unloading %s checker", c->name); -@@ -161,7 +177,8 @@ static struct checker_class *add_checker_class(const char *multipath_dir, - - c->mp_init = (int (*)(struct checker *)) dlsym(c->handle, "libcheck_mp_init"); - c->reset = (void (*)(void)) dlsym(c->handle, "libcheck_reset"); -- /* These 2 functions can be NULL. call dlerror() to clear out any -+ c->thread = (void *(*)(void*)) dlsym(c->handle, "libcheck_thread"); -+ /* These 3 functions can be NULL. call dlerror() to clear out any - * error string */ - dlerror(); - -@@ -347,6 +364,43 @@ bad_id: - return generic_msg[CHECKER_MSGID_NONE]; - } - -+static void checker_cleanup_thread(void *arg) -+{ -+ struct checker_class *cls = arg; -+ -+ (void)checker_class_unref(cls); -+ rcu_unregister_thread(); -+} -+ -+static void *checker_thread_entry(void *arg) -+{ -+ struct checker_context *ctx = arg; -+ void *rv; -+ -+ rcu_register_thread(); -+ pthread_cleanup_push(checker_cleanup_thread, ctx->cls); -+ rv = ctx->cls->thread(ctx); -+ pthread_cleanup_pop(1); -+ return rv; -+} -+ -+int start_checker_thread(pthread_t *thread, const pthread_attr_t *attr, -+ struct checker_context *ctx) -+{ -+ int rv; -+ -+ assert(ctx && ctx->cls && ctx->cls->thread); -+ /* Take a ref here, lest the class be freed before the thread starts */ -+ (void)checker_class_ref(ctx->cls); -+ rv = pthread_create(thread, attr, checker_thread_entry, ctx); -+ if (rv != 0) { -+ condlog(1, "failed to start checker thread for %s: %m", -+ ctx->cls->name); -+ checker_class_unref(ctx->cls); -+ } -+ return rv; -+} -+ - void checker_clear_message (struct checker *c) - { - if (!c) -@@ -371,7 +425,7 @@ void checker_get(const char *multipath_dir, struct checker *dst, - if (!src) - return; - -- src->refcount++; -+ (void)checker_class_ref(dst->cls); - } - - int init_checkers(const char *multipath_dir) -diff --git a/libmultipath/checkers.h b/libmultipath/checkers.h -index 9d5f90b9..2fd1d1c6 100644 ---- a/libmultipath/checkers.h -+++ b/libmultipath/checkers.h -@@ -1,6 +1,7 @@ - #ifndef _CHECKERS_H - #define _CHECKERS_H - -+#include - #include "list.h" - #include "memory.h" - #include "defaults.h" -@@ -148,6 +149,28 @@ void checker_set_async (struct checker *); - void checker_set_fd (struct checker *, int); - void checker_enable (struct checker *); - void checker_disable (struct checker *); -+/* -+ * start_checker_thread(): start async path checker thread -+ * -+ * This function provides a wrapper around pthread_create(). -+ * The created thread will call the DSO's "libcheck_thread" function with the -+ * checker context as argument. -+ * -+ * Rationale: -+ * Path checkers that do I/O may hang forever. To avoid blocking, some -+ * checkers therefore use asyncronous, detached threads for checking -+ * the paths. These threads may continue hanging if multipathd is stopped. -+ * In this case, we can't unload the checker DSO at exit. In order to -+ * avoid race conditions and crashes, the entry point of the thread -+ * needs to be in libmultipath, not in the DSO itself. -+ * -+ * @param arg: pointer to struct checker_context. -+ */ -+struct checker_context { -+ struct checker_class *cls; -+}; -+int start_checker_thread (pthread_t *thread, const pthread_attr_t *attr, -+ struct checker_context *ctx); - int checker_check (struct checker *, int); - int checker_is_sync(const struct checker *); - const char *checker_name (const struct checker *); -@@ -164,6 +187,8 @@ void checker_get(const char *, struct checker *, const char *); - int libcheck_check(struct checker *); - int libcheck_init(struct checker *); - void libcheck_free(struct checker *); -+void *libcheck_thread(struct checker_context *ctx); -+ - /* - * msgid => message map. - * -diff --git a/libmultipath/checkers/tur.c b/libmultipath/checkers/tur.c -index e886fcf8..a4b4a213 100644 ---- a/libmultipath/checkers/tur.c -+++ b/libmultipath/checkers/tur.c -@@ -15,7 +15,6 @@ - #include - #include - #include --#include - #include - - #include "checkers.h" -@@ -55,6 +54,7 @@ struct tur_checker_context { - pthread_cond_t active; - int holders; /* uatomic access only */ - int msgid; -+ struct checker_context ctx; - }; - - int libcheck_init (struct checker * c) -@@ -74,6 +74,7 @@ int libcheck_init (struct checker * c) - pthread_mutex_init(&ct->lock, NULL); - if (fstat(c->fd, &sb) == 0) - ct->devt = sb.st_rdev; -+ ct->ctx.cls = c->cls; - c->context = ct; - - return 0; -@@ -204,7 +205,6 @@ static void cleanup_func(void *data) - holders = uatomic_sub_return(&ct->holders, 1); - if (!holders) - cleanup_context(ct); -- rcu_unregister_thread(); - } - - /* -@@ -251,15 +251,15 @@ static void tur_deep_sleep(const struct tur_checker_context *ct) - #define tur_deep_sleep(x) do {} while (0) - #endif /* TUR_TEST_MAJOR */ - --static void *tur_thread(void *ctx) -+void *libcheck_thread(struct checker_context *ctx) - { -- struct tur_checker_context *ct = ctx; -+ struct tur_checker_context *ct = -+ container_of(ctx, struct tur_checker_context, ctx); - int state, running; - short msgid; - - /* This thread can be canceled, so setup clean up */ - tur_thread_cleanup_push(ct); -- rcu_register_thread(); - - condlog(4, "%d:%d : tur checker starting up", major(ct->devt), - minor(ct->devt)); -@@ -394,7 +394,7 @@ int libcheck_check(struct checker * c) - uatomic_set(&ct->running, 1); - tur_set_async_timeout(c); - setup_thread_attr(&attr, 32 * 1024, 1); -- r = pthread_create(&ct->thread, &attr, tur_thread, ct); -+ r = start_checker_thread(&ct->thread, &attr, &ct->ctx); - pthread_attr_destroy(&attr); - if (r) { - uatomic_sub(&ct->holders, 1); -diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version -index 2e3583f5..751099dc 100644 ---- a/libmultipath/libmultipath.version -+++ b/libmultipath/libmultipath.version -@@ -270,3 +270,8 @@ global: - dm_prereq; - skip_libmp_dm_init; - } LIBMULTIPATH_4.1.0; -+ -+LIBMULTIPATH_4.3.0 { -+global: -+ start_checker_thread; -+} LIBMULTIPATH_4.2.0; diff --git a/0080-libmultipath-force-map-reload-if-udev-incomplete.patch b/0080-libmultipath-force-map-reload-if-udev-incomplete.patch deleted file mode 100644 index 4de3108..0000000 --- a/0080-libmultipath-force-map-reload-if-udev-incomplete.patch +++ /dev/null @@ -1,148 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 14 Dec 2020 18:22:55 +0100 -Subject: [PATCH] libmultipath: force map reload if udev incomplete - -We've recently observed various cases of incompletely processed uevents -during initrd processing. Typically, this would leave a dm device in -the state it had after the initial "add" uevent, which is basically unusable, -because udevd had been killed by systemd before processing the subsequent -"change" event. After switching root, the coldplug event would re-read -the db file, which would be in unusable state, and would not do anything. -In such cases, a RELOAD action with force_udev_reload=1 is in order to -make udev re-process the device completely (DM_UDEV_PRIMARY_SOURCE_FLAG=1 and -DM_SUBSYSTEM_UDEV_FLAG0=0). - -The previous commits - -2b25a9e libmultipath: select_action(): force udev reload for uninitialized maps -cb10d38 multipathd: uev_trigger(): handle incomplete ADD events - -addressed the same issue, but incompletely. They would miss cases where the -map was configured correctly but none of the RELOAD criteria were met. -This patch partially reverts 2b25a9e by converting select_reload_action() into -a trivial helper. Instead, we now check for incompletely initialized udev now -before checking any of the other reload criteria. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 45 ++++++++++++++++++++++++++-------------- - 1 file changed, 29 insertions(+), 16 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index c076be72..d9fd9cb8 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -696,12 +696,11 @@ sysfs_set_max_sectors_kb(struct multipath *mpp, int is_reload) - return err; - } - --static void --select_reload_action(struct multipath *mpp, const struct multipath *cmpp, -- const char *reason) -+static bool is_udev_ready(struct multipath *cmpp) - { - struct udev_device *mpp_ud; - const char *env; -+ bool rc; - - /* - * MPATH_DEVICE_READY != 1 can mean two things: -@@ -713,14 +712,20 @@ select_reload_action(struct multipath *mpp, const struct multipath *cmpp, - */ - - mpp_ud = get_udev_for_mpp(cmpp); -+ if (!mpp_ud) -+ return true; - env = udev_device_get_property_value(mpp_ud, "MPATH_DEVICE_READY"); -- if ((!env || strcmp(env, "1")) && count_active_paths(mpp) > 0) -- mpp->force_udev_reload = 1; -+ rc = (env != NULL && !strcmp(env, "1")); - udev_device_unref(mpp_ud); -+ condlog(4, "%s: %s: \"%s\" -> %d\n", __func__, cmpp->alias, env, rc); -+ return rc; -+} -+ -+static void -+select_reload_action(struct multipath *mpp, const char *reason) -+{ - mpp->action = ACT_RELOAD; -- condlog(3, "%s: set ACT_RELOAD (%s%s)", mpp->alias, -- mpp->force_udev_reload ? "forced, " : "", -- reason); -+ condlog(3, "%s: set ACT_RELOAD (%s)", mpp->alias, reason); - } - - void select_action (struct multipath *mpp, const struct _vector *curmp, -@@ -789,10 +794,18 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, - return; - } - -+ if (!is_udev_ready(cmpp) && count_active_paths(mpp) > 0) { -+ mpp->force_udev_reload = 1; -+ mpp->action = ACT_RELOAD; -+ condlog(3, "%s: set ACT_RELOAD (udev incomplete)", -+ mpp->alias); -+ return; -+ } -+ - if (mpp->no_path_retry != NO_PATH_RETRY_UNDEF && - !!strstr(mpp->features, "queue_if_no_path") != - !!strstr(cmpp->features, "queue_if_no_path")) { -- select_reload_action(mpp, cmpp, "no_path_retry change"); -+ select_reload_action(mpp, "no_path_retry change"); - return; - } - if ((mpp->retain_hwhandler != RETAIN_HWHANDLER_ON || -@@ -800,7 +813,7 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, - (strlen(cmpp->hwhandler) != strlen(mpp->hwhandler) || - strncmp(cmpp->hwhandler, mpp->hwhandler, - strlen(mpp->hwhandler)))) { -- select_reload_action(mpp, cmpp, "hwhandler change"); -+ select_reload_action(mpp, "hwhandler change"); - return; - } - -@@ -808,7 +821,7 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, - !!strstr(mpp->features, "retain_attached_hw_handler") != - !!strstr(cmpp->features, "retain_attached_hw_handler") && - get_linux_version_code() < KERNEL_VERSION(4, 3, 0)) { -- select_reload_action(mpp, cmpp, "retain_hwhandler change"); -+ select_reload_action(mpp, "retain_hwhandler change"); - return; - } - -@@ -820,7 +833,7 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, - remove_feature(&cmpp_feat, "queue_if_no_path"); - remove_feature(&cmpp_feat, "retain_attached_hw_handler"); - if (strncmp(mpp_feat, cmpp_feat, PARAMS_SIZE)) { -- select_reload_action(mpp, cmpp, "features change"); -+ select_reload_action(mpp, "features change"); - FREE(cmpp_feat); - FREE(mpp_feat); - return; -@@ -831,19 +844,19 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, - - if (!cmpp->selector || strncmp(cmpp->selector, mpp->selector, - strlen(mpp->selector))) { -- select_reload_action(mpp, cmpp, "selector change"); -+ select_reload_action(mpp, "selector change"); - return; - } - if (cmpp->minio != mpp->minio) { -- select_reload_action(mpp, cmpp, "minio change"); -+ select_reload_action(mpp, "minio change"); - return; - } - if (!cmpp->pg || VECTOR_SIZE(cmpp->pg) != VECTOR_SIZE(mpp->pg)) { -- select_reload_action(mpp, cmpp, "path group number change"); -+ select_reload_action(mpp, "path group number change"); - return; - } - if (pgcmp(mpp, cmpp)) { -- select_reload_action(mpp, cmpp, "path group topology change"); -+ select_reload_action(mpp, "path group topology change"); - return; - } - if (cmpp->nextpg != mpp->bestpg) { diff --git a/0081-multipath-tools-avoid-access-to-etc-localtime.patch b/0081-multipath-tools-avoid-access-to-etc-localtime.patch deleted file mode 100644 index 1286fa5..0000000 --- a/0081-multipath-tools-avoid-access-to-etc-localtime.patch +++ /dev/null @@ -1,109 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 15 Dec 2020 17:09:49 +0100 -Subject: [PATCH] multipath-tools: avoid access to /etc/localtime - -If the root file system is multipathed, and IO is queued because all paths -are failed, multipathd may block trying to access the root FS, and thus be -unable to reinstate paths. One file that is frequently accessed is -/etc/localtime. Avoid that by printing monotonic timestamps instead. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/debug.c | 14 ++++++++------ - libmultipath/devmapper.c | 12 ++++++------ - libmultipath/log.c | 1 - - multipathd/main.c | 3 --- - 4 files changed, 14 insertions(+), 16 deletions(-) - -diff --git a/libmultipath/debug.c b/libmultipath/debug.c -index 429f2699..510e15e5 100644 ---- a/libmultipath/debug.c -+++ b/libmultipath/debug.c -@@ -14,6 +14,8 @@ - #include "config.h" - #include "defaults.h" - #include "debug.h" -+#include "time-util.h" -+#include "util.h" - - int logsink; - int libmp_verbosity = DEFAULT_VERBOSITY; -@@ -25,13 +27,13 @@ void dlog(int prio, const char * fmt, ...) - va_start(ap, fmt); - if (logsink != LOGSINK_SYSLOG) { - if (logsink == LOGSINK_STDERR_WITH_TIME) { -- time_t t = time(NULL); -- struct tm *tb = localtime(&t); -- char buff[16]; -+ struct timespec ts; -+ char buff[32]; - -- strftime(buff, sizeof(buff), -- "%b %d %H:%M:%S", tb); -- buff[sizeof(buff)-1] = '\0'; -+ get_monotonic_time(&ts); -+ safe_sprintf(buff, "%ld.%06ld", -+ (long)ts.tv_sec, -+ ts.tv_nsec/1000); - fprintf(stderr, "%s | ", buff); - } - vfprintf(stderr, fmt, ap); -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index 4977b311..095cbc0c 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -27,6 +27,7 @@ - #include "config.h" - #include "wwids.h" - #include "version.h" -+#include "time-util.h" - - #include "log_pthread.h" - #include -@@ -106,13 +107,12 @@ dm_write_log (int level, const char *file, int line, const char *f, ...) - va_start(ap, f); - if (logsink != LOGSINK_SYSLOG) { - if (logsink == LOGSINK_STDERR_WITH_TIME) { -- time_t t = time(NULL); -- struct tm *tb = localtime(&t); -- char buff[16]; -- -- strftime(buff, sizeof(buff), "%b %d %H:%M:%S", tb); -- buff[sizeof(buff)-1] = '\0'; -+ struct timespec ts; -+ char buff[32]; - -+ get_monotonic_time(&ts); -+ safe_sprintf(buff, "%ld.%06ld", -+ (long)ts.tv_sec, ts.tv_nsec/1000); - fprintf(stderr, "%s | ", buff); - } - fprintf(stderr, "libdevmapper: %s(%i): ", file, line); -diff --git a/libmultipath/log.c b/libmultipath/log.c -index 95c8f01a..6498c88c 100644 ---- a/libmultipath/log.c -+++ b/libmultipath/log.c -@@ -120,7 +120,6 @@ void log_reset (char *program_name) - pthread_cleanup_push(cleanup_mutex, &logq_lock); - - closelog(); -- tzset(); - openlog(program_name, 0, LOG_DAEMON); - - pthread_cleanup_pop(1); -diff --git a/multipathd/main.c b/multipathd/main.c -index 2eab4854..4417860b 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -2706,9 +2706,6 @@ reconfigure (struct vectors * vecs) - delete_all_foreign(); - - reset_checker_classes(); -- /* Re-read any timezone changes */ -- tzset(); -- - if (bindings_read_only) - conf->bindings_read_only = bindings_read_only; - check_alias_settings(conf); diff --git a/0082-multipath-tools-make-sure-plugin-DSOs-use-symbol-ver.patch b/0082-multipath-tools-make-sure-plugin-DSOs-use-symbol-ver.patch deleted file mode 100644 index 1dcc7f0..0000000 --- a/0082-multipath-tools-make-sure-plugin-DSOs-use-symbol-ver.patch +++ /dev/null @@ -1,146 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 16 Dec 2020 23:14:59 +0100 -Subject: [PATCH] multipath-tools: make sure plugin DSOs use symbol versions - -By adding -Wl,-z,defs, we'll get warnings about unresolved symbols -at the linking stage. This way we make sure our plugins (checkers etc.) -will use versioned symbols from libmultipath, and incompatible plugins -can't be loaded any more. Doing this requires explicitly linking -the plugins with all libraries they use, in particular libmultipath. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - Makefile | 1 + - Makefile.inc | 2 +- - libmpathpersist/Makefile | 8 ++++---- - libmultipath/checkers/Makefile | 7 +++---- - libmultipath/foreign/Makefile | 4 +++- - libmultipath/prioritizers/Makefile | 7 +++---- - 6 files changed, 15 insertions(+), 14 deletions(-) - -diff --git a/Makefile b/Makefile -index f127ff91..bddb2bf7 100644 ---- a/Makefile -+++ b/Makefile -@@ -31,6 +31,7 @@ $(BUILDDIRS): - - libmultipath libdmmp: libmpathcmd - libmpathpersist libmpathvalid multipath multipathd: libmultipath -+libmultipath/prioritizers libmultipath/checkers libmultipath/foreign: libmultipath - mpathpersist multipathd: libmpathpersist - - libmultipath/checkers.install \ -diff --git a/Makefile.inc b/Makefile.inc -index 13587a9f..05429307 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -105,7 +105,7 @@ CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ - BIN_CFLAGS = -fPIE -DPIE - LIB_CFLAGS = -fPIC - SHARED_FLAGS = -shared --LDFLAGS := $(LDFLAGS) -Wl,-z,relro -Wl,-z,now -+LDFLAGS := $(LDFLAGS) -Wl,-z,relro -Wl,-z,now -Wl,-z,defs - BIN_LDFLAGS = -pie - - # Check whether a function with name $1 has been declared in header file $2. -diff --git a/libmpathpersist/Makefile b/libmpathpersist/Makefile -index 456ce4cf..57103e58 100644 ---- a/libmpathpersist/Makefile -+++ b/libmpathpersist/Makefile -@@ -6,17 +6,17 @@ LIBS = $(DEVLIB).$(SONAME) - VERSION_SCRIPT := libmpathpersist.version - - CFLAGS += $(LIB_CFLAGS) -I$(multipathdir) -I$(mpathpersistdir) -I$(mpathcmddir) -+LDFLAGS += -L$(multipathdir) -L$(mpathcmddir) - --LIBDEPS += -lpthread -ldevmapper -ldl -L$(multipathdir) -lmultipath \ -- -L$(mpathcmddir) -lmpathcmd -+LIBDEPS += -lmultipath -lmpathcmd -ldevmapper -lpthread -ldl - - OBJS = mpath_persist.o mpath_updatepr.o mpath_pr_ioctl.o - - all: $(DEVLIB) man - - $(LIBS): $(OBJS) $(VERSION_SCRIPT) -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) $(LIBDEPS) -Wl,-soname=$@ \ -- -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) -+ $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ -+ -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) - - $(DEVLIB): $(LIBS) - $(LN) $(LIBS) $@ -diff --git a/libmultipath/checkers/Makefile b/libmultipath/checkers/Makefile -index 01c04510..8e0ed5e9 100644 ---- a/libmultipath/checkers/Makefile -+++ b/libmultipath/checkers/Makefile -@@ -4,6 +4,8 @@ - include ../../Makefile.inc - - CFLAGS += $(LIB_CFLAGS) -I.. -+LDFLAGS += -L.. -lmultipath -+LIBDEPS = -lmultipath -laio -lpthread -lrt - - # If you add or remove a checker also update multipath/multipath.conf.5 - LIBS= \ -@@ -17,11 +19,8 @@ LIBS= \ - - all: $(LIBS) - --libcheckdirectio.so: directio.o -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ -laio -- - libcheck%.so: %.o -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ -+ $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) - - install: - $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(libdir) -diff --git a/libmultipath/foreign/Makefile b/libmultipath/foreign/Makefile -index fae58a0d..f447a1c4 100644 ---- a/libmultipath/foreign/Makefile -+++ b/libmultipath/foreign/Makefile -@@ -5,13 +5,15 @@ TOPDIR=../.. - include ../../Makefile.inc - - CFLAGS += $(LIB_CFLAGS) -I.. -I$(nvmedir) -+LDFLAGS += -L.. -+LIBDEPS = -lmultipath -ludev -lpthread -lrt - - LIBS = libforeign-nvme.so - - all: $(LIBS) - - libforeign-%.so: %.o -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ -+ $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) - - install: - $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(libdir) -diff --git a/libmultipath/prioritizers/Makefile b/libmultipath/prioritizers/Makefile -index fc6e0e0c..8d34ae32 100644 ---- a/libmultipath/prioritizers/Makefile -+++ b/libmultipath/prioritizers/Makefile -@@ -4,6 +4,8 @@ - include ../../Makefile.inc - - CFLAGS += $(LIB_CFLAGS) -I.. -+LDFLAGS += -L.. -+LIBDEPS = -lmultipath -lm -lpthread -lrt - - # If you add or remove a prioritizer also update multipath/multipath.conf.5 - LIBS = \ -@@ -28,11 +30,8 @@ endif - - all: $(LIBS) - --libpriopath_latency.so: path_latency.o -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ -lm -- - libprio%.so: %.o -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ -+ $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) - - install: $(LIBS) - $(INSTALL_PROGRAM) -m 755 libprio*.so $(DESTDIR)$(libdir) diff --git a/0083-libmultipath.version-add-missing-symbol.patch b/0083-libmultipath.version-add-missing-symbol.patch deleted file mode 100644 index 11edbd0..0000000 --- a/0083-libmultipath.version-add-missing-symbol.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 17 Dec 2020 01:30:30 +0100 -Subject: [PATCH] libmultipath.version: add missing symbol - -The weightedpath prioritizer uses get_next_string(). I'd overlooked -this before. This was found with the help of the previous patch. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/libmultipath.version | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version -index 751099dc..2228f4ec 100644 ---- a/libmultipath/libmultipath.version -+++ b/libmultipath/libmultipath.version -@@ -275,3 +275,8 @@ LIBMULTIPATH_4.3.0 { - global: - start_checker_thread; - } LIBMULTIPATH_4.2.0; -+ -+LIBMULTIPATH_4.4.0 { -+global: -+ get_next_string; -+} LIBMULTIPATH_4.3.0; diff --git a/0084-multipath-tools-tests-unversioned-.so-for-valgrind-t.patch b/0084-multipath-tools-tests-unversioned-.so-for-valgrind-t.patch deleted file mode 100644 index fa83da7..0000000 --- a/0084-multipath-tools-tests-unversioned-.so-for-valgrind-t.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 18 Dec 2020 23:11:47 +0100 -Subject: [PATCH] multipath-tools tests: unversioned .so for valgrind tests - -We need to the same thing for valgrind tests as we did in -448752f ("libmultipath: create separate .so for unit tests"). - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - tests/Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/tests/Makefile b/tests/Makefile -index 54da774e..50673fae 100644 ---- a/tests/Makefile -+++ b/tests/Makefile -@@ -76,7 +76,7 @@ lib/libchecktur.so: - - %.vgr: %-test lib/libchecktur.so - @echo == running valgrind for $< == -- @LD_LIBRARY_PATH=$(multipathdir):$(mpathcmddir) \ -+ @LD_LIBRARY_PATH=.:$(mpathcmddir) \ - valgrind --leak-check=full --error-exitcode=128 ./$< >$@ 2>&1 - - OBJS = $(TESTS:%=%.o) $(HELPERS) diff --git a/0085-multipath-tools-unit-tests-fix-memory-leaks-in-mpath.patch b/0085-multipath-tools-unit-tests-fix-memory-leaks-in-mpath.patch deleted file mode 100644 index cfbf24c..0000000 --- a/0085-multipath-tools-unit-tests-fix-memory-leaks-in-mpath.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 18 Dec 2020 23:17:48 +0100 -Subject: [PATCH] multipath-tools unit tests: fix memory leaks in mpathvalid - tests - -They break "make valgrind-test". - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - tests/mpathvalid.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/tests/mpathvalid.c b/tests/mpathvalid.c -index 5ffabb9d..cfe4bae1 100644 ---- a/tests/mpathvalid.c -+++ b/tests/mpathvalid.c -@@ -381,6 +381,7 @@ static void test_mpathvalid_is_path_good2(void **state) - assert_int_equal(mpathvalid_is_path(test_dev, MPATH_DEFAULT, &wwid, - wwids, 4), MPATH_IS_VALID); - assert_string_equal(wwid, TEST_WWID); -+ free(wwid); - } - - static void test_mpathvalid_is_path_good3(void **state) -@@ -395,6 +396,7 @@ static void test_mpathvalid_is_path_good3(void **state) - assert_int_equal(mpathvalid_is_path(test_dev, MPATH_SMART, &wwid, - wwids, 4), MPATH_IS_VALID); - assert_string_equal(wwid, TEST_WWID); -+ free(wwid); - } - - /* mabybe valid with no matching paths */ -@@ -410,6 +412,7 @@ static void test_mpathvalid_is_path_good4(void **state) - assert_int_equal(mpathvalid_is_path(test_dev, MPATH_DEFAULT, &wwid, - wwids, 4), MPATH_IS_MAYBE_VALID); - assert_string_equal(wwid, TEST_WWID); -+ free(wwid); - } - - /* maybe valid with matching paths */ -@@ -425,6 +428,7 @@ static void test_mpathvalid_is_path_good5(void **state) - assert_int_equal(mpathvalid_is_path(test_dev, MPATH_DEFAULT, &wwid, - wwids, 4), MPATH_IS_VALID); - assert_string_equal(wwid, TEST_WWID); -+ free(wwid); - } - - #define setup_test(name) \ diff --git a/0086-mpathpersist-Fix-Register-and-Ignore-with-0x00-SARK.patch b/0086-mpathpersist-Fix-Register-and-Ignore-with-0x00-SARK.patch deleted file mode 100644 index 323176f..0000000 --- a/0086-mpathpersist-Fix-Register-and-Ignore-with-0x00-SARK.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 18 Dec 2020 17:06:37 -0600 -Subject: [PATCH] mpathpersist: Fix Register and Ignore with 0x00 SARK - -When the Register and Ignore command is run with sg_persist, if a 0x00 -Service Action Reservation Key is given or the --param-sark option is -not used at all, sg_persist will clear the registration. mpathpersist -will fail with an error. This patch fixes mpathpersist to work like -sg_persist in this case. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmpathpersist/mpath_persist.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c -index 79322e86..41789c46 100644 ---- a/libmpathpersist/mpath_persist.c -+++ b/libmpathpersist/mpath_persist.c -@@ -304,7 +304,8 @@ int __mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, - } - - if (memcmp(paramp->key, &mpp->reservation_key, 8) && -- memcmp(paramp->sa_key, &mpp->reservation_key, 8)) { -+ memcmp(paramp->sa_key, &mpp->reservation_key, 8) && -+ (prkey || rq_servact != MPATH_PROUT_REG_IGN_SA)) { - condlog(0, "%s: configured reservation key doesn't match: 0x%" PRIx64, alias, get_be64(mpp->reservation_key)); - ret = MPATH_PR_SYNTAX_ERROR; - goto out1; diff --git a/0087-mpathpersist-update-prkeys-file-on-changing-registra.patch b/0087-mpathpersist-update-prkeys-file-on-changing-registra.patch deleted file mode 100644 index f555825..0000000 --- a/0087-mpathpersist-update-prkeys-file-on-changing-registra.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 18 Dec 2020 17:06:38 -0600 -Subject: [PATCH] mpathpersist: update prkeys file on changing registrations - -When the "reservation_key" option is set to "file" and Register command -is run with both the current Reservation Key and a new Service Action -Reservation Key, mpathpersist will change the registration, but will not -update the prkeys file. This means that future paths that come online -will not be able to register, since multipathd is still using the old -reservation key. Fix this. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmpathpersist/mpath_persist.c | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - -diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c -index 41789c46..08077936 100644 ---- a/libmpathpersist/mpath_persist.c -+++ b/libmpathpersist/mpath_persist.c -@@ -290,9 +290,10 @@ int __mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, - - memcpy(&prkey, paramp->sa_key, 8); - if (mpp->prkey_source == PRKEY_SOURCE_FILE && prkey && -- ((!get_be64(mpp->reservation_key) && -- rq_servact == MPATH_PROUT_REG_SA) || -- rq_servact == MPATH_PROUT_REG_IGN_SA)) { -+ (rq_servact == MPATH_PROUT_REG_IGN_SA || -+ (rq_servact == MPATH_PROUT_REG_SA && -+ (!get_be64(mpp->reservation_key) || -+ memcmp(paramp->key, &mpp->reservation_key, 8) == 0)))) { - memcpy(&mpp->reservation_key, paramp->sa_key, 8); - if (update_prkey_flags(alias, get_be64(mpp->reservation_key), - paramp->sa_flags)) { diff --git a/0088-libmultipath-warn-about-missing-braces-at-end-of-mul.patch b/0088-libmultipath-warn-about-missing-braces-at-end-of-mul.patch deleted file mode 100644 index 4534b41..0000000 --- a/0088-libmultipath-warn-about-missing-braces-at-end-of-mul.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 18 Dec 2020 17:06:39 -0600 -Subject: [PATCH] libmultipath: warn about missing braces at end of - multipath.conf - -Multipath doesn't warn when multipath.conf is missing closing braces at -the end of the file. This has confused people about the correct config -file syntax, so add a warning. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/parser.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/parser.c b/libmultipath/parser.c -index 163ffbc9..c70243c3 100644 ---- a/libmultipath/parser.c -+++ b/libmultipath/parser.c -@@ -537,7 +537,7 @@ process_stream(struct config *conf, FILE *stream, vector keywords, - if (!strcmp(str, EOB)) { - if (kw_level > 0) { - free_strvec(strvec); -- break; -+ goto out; - } - condlog(0, "unmatched '%s' at line %d of %s", - EOB, line_nr, file); -@@ -576,7 +576,8 @@ process_stream(struct config *conf, FILE *stream, vector keywords, - - free_strvec(strvec); - } -- -+ if (kw_level == 1) -+ condlog(1, "missing '%s' at end of %s", EOB, file); - out: - FREE(buf); - free_uniques(uniques); diff --git a/0089-libmultipath-ignore-multipaths-sections-without-wwid.patch b/0089-libmultipath-ignore-multipaths-sections-without-wwid.patch deleted file mode 100644 index f49f461..0000000 --- a/0089-libmultipath-ignore-multipaths-sections-without-wwid.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 18 Dec 2020 17:06:40 -0600 -Subject: [PATCH] libmultipath: ignore multipaths sections without wwid option - -"multipathd show config local" was crashing in find_mp_by_wwid() if -the multipath configuration included a multipaths section that did -not set a wwid option. There is no reason to keep a mpentry that -didn't set its wwid. Remove it in merge_mptable(). - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/config.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/libmultipath/config.c b/libmultipath/config.c -index 9f3cb38d..a643703e 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -509,6 +509,13 @@ void merge_mptable(vector mptable) - int i, j; - - vector_foreach_slot(mptable, mp1, i) { -+ /* drop invalid multipath configs */ -+ if (!mp1->wwid) { -+ condlog(0, "multipaths config section missing wwid"); -+ vector_del_slot(mptable, i--); -+ free_mpe(mp1); -+ continue; -+ } - j = i + 1; - vector_foreach_slot_after(mptable, mp2, j) { - if (strcmp(mp1->wwid, mp2->wwid)) diff --git a/0090-libmultipath-fix-format-warning-with-clang.patch b/0090-libmultipath-fix-format-warning-with-clang.patch deleted file mode 100644 index 24bbe92..0000000 --- a/0090-libmultipath-fix-format-warning-with-clang.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 18 Dec 2020 23:34:35 +0100 -Subject: [PATCH] libmultipath: fix format warning with clang - -Reported-by: Xose Vazquez Perez -Tested-by: Xose Vazquez Perez -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/log.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/libmultipath/log.c b/libmultipath/log.c -index 6498c88c..10fa32cd 100644 ---- a/libmultipath/log.c -+++ b/libmultipath/log.c -@@ -125,6 +125,7 @@ void log_reset (char *program_name) - pthread_cleanup_pop(1); - } - -+__attribute__((format(printf, 2, 0))) - static int _log_enqueue(int prio, const char * fmt, va_list ap) - { - int len, fwd; diff --git a/0091-libmultipath-check-for-null-wwid-before-strcmp.patch b/0091-libmultipath-check-for-null-wwid-before-strcmp.patch deleted file mode 100644 index 3162352..0000000 --- a/0091-libmultipath-check-for-null-wwid-before-strcmp.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 4 Jan 2021 21:59:54 -0600 -Subject: [PATCH] libmultipath: check for null wwid before strcmp - -Commit 749aabd0 (libmultipath: ignore multipaths sections without wwid -option) removed all mpentries with a NULL wwid, but didn't stop strcmp() -from being run on them in merge_mptable(). The result of strcmp() with -a NULL parameter is undefined, so fix that. - -Signed-off-by: Benjamin Marzinski - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/config.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/config.c b/libmultipath/config.c -index a643703e..be310159 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -518,7 +518,7 @@ void merge_mptable(vector mptable) - } - j = i + 1; - vector_foreach_slot_after(mptable, mp2, j) { -- if (strcmp(mp1->wwid, mp2->wwid)) -+ if (!mp2->wwid || strcmp(mp1->wwid, mp2->wwid)) - continue; - condlog(1, "%s: duplicate multipath config section for %s", - __func__, mp1->wwid); diff --git a/0092-multipath.conf.5-Improve-checker_timeout-description.patch b/0092-multipath.conf.5-Improve-checker_timeout-description.patch deleted file mode 100644 index 09f108c..0000000 --- a/0092-multipath.conf.5-Improve-checker_timeout-description.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 4 Jan 2021 21:59:55 -0600 -Subject: [PATCH] multipath.conf.5: Improve checker_timeout description - -I was asked to explain how checker_timeout works for checkers like -directio, that don't issue scsi commands with an explicit timeout. -Also, undeprecate the directio checker. - -Signed-off-by: Benjamin Marzinski - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - multipath/multipath.conf.5 | 20 ++++++++++++-------- - 1 file changed, 12 insertions(+), 8 deletions(-) - -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index ea66a01e..8ef3a747 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -472,8 +472,12 @@ The default is: \fB\fR - . - .TP - .B path_checker --The default method used to determine the paths state. Possible values --are: -+The default method used to determine the path's state. The synchronous -+checkers (all except \fItur\fR and \fIdirectio\fR) will cause multipathd to -+pause most activity, waiting up to \fIchecker_timeout\fR seconds for the path -+to respond. The asynchronous checkers (\fItur\fR and \fIdirectio\fR) will not -+pause multipathd. Instead, multipathd will check for a response once per -+second, until \fIchecker_timeout\fR seconds have elapsed. Possible values are: - .RS - .TP 12 - .I readsector0 -@@ -499,10 +503,8 @@ Check the path state for LSI/Engenio/NetApp RDAC class as NetApp SANtricity E/EF - Series, and OEM arrays from IBM DELL SGI STK and SUN. - .TP - .I directio --(Deprecated) Read the first sector with direct I/O. If you have a large number --of paths, or many AIO users on a system, you may need to use sysctl to --increase fs.aio-max-nr. This checker is being deprecated, it could cause --spurious path failures under high load. Please use \fItur\fR instead. -+Read the first sector with direct I/O. This checker could cause spurious path -+failures under high load. Increasing \fIchecker_timeout\fR can help with this. - .TP - .I cciss_tur - (Hardware-dependent) -@@ -639,8 +641,10 @@ The default is: \fBno\fR - . - .TP - .B checker_timeout --Specify the timeout to use for path checkers and prioritizers that issue SCSI --commands with an explicit timeout, in seconds. -+Specify the timeout to use for path checkers and prioritizers, in seconds. -+Only prioritizers that issue scsi commands use checker_timeout. If a path -+does not respond to the checker command after \fIchecker_timeout\fR -+seconds have elapsed, it is considered down. - .RS - .TP - The default is: in \fB/sys/block/sd/device/timeout\fR diff --git a/0093-multipathd-fix-path-checkint-not-changed-when-path-s.patch b/0093-multipathd-fix-path-checkint-not-changed-when-path-s.patch deleted file mode 100644 index 0fa29be..0000000 --- a/0093-multipathd-fix-path-checkint-not-changed-when-path-s.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Chongyun Wu -Date: Wed, 6 Jan 2021 09:39:12 +0800 -Subject: [PATCH] multipathd: fix path checkint not changed when path state - changed from delay to failed - -Check_path: when path state change back to failed from delay state, -should change this path's check interval time to the shortest delay -to faster path state check. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Chongyun Wu -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 4417860b..7612430a 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -2161,6 +2161,11 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) - (pp->state == PATH_DELAYED)) { - /* If path state become failed again cancel path delay state */ - pp->state = newstate; -+ /* -+ * path state bad again should change the check interval time -+ * to the shortest delay -+ */ -+ pp->checkint = checkint; - return 1; - } - if (!pp->mpp) { diff --git a/0094-libmultipath-select_action-skip-is_mpp_known_to_udev.patch b/0094-libmultipath-select_action-skip-is_mpp_known_to_udev.patch deleted file mode 100644 index b129afa..0000000 --- a/0094-libmultipath-select_action-skip-is_mpp_known_to_udev.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 8 Jan 2021 17:22:09 +0100 -Subject: [PATCH] libmultipath: select_action(): skip is_mpp_known_to_udev() - test - -This test is now superseded by the check introduced in -0d66e03 ("libmultipath: force map reload if udev incomplete"). - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 15 --------------- - 1 file changed, 15 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index d9fd9cb8..999f3106 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -635,15 +635,6 @@ trigger_paths_udev_change(struct multipath *mpp, bool is_mpath) - mpp->needs_paths_uevent = 0; - } - --static int --is_mpp_known_to_udev(const struct multipath *mpp) --{ -- struct udev_device *udd = get_udev_for_mpp(mpp); -- int ret = (udd != NULL); -- udev_device_unref(udd); -- return ret; --} -- - static int - sysfs_set_max_sectors_kb(struct multipath *mpp, int is_reload) - { -@@ -865,12 +856,6 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, - mpp->alias); - return; - } -- if (!is_mpp_known_to_udev(cmpp)) { -- mpp->action = ACT_RELOAD; -- condlog(3, "%s: set ACT_RELOAD (udev device not initialized)", -- mpp->alias); -- return; -- } - mpp->action = ACT_NOTHING; - condlog(3, "%s: set ACT_NOTHING (map unchanged)", - mpp->alias); diff --git a/0095-libmultipath-coalesce_paths-stop-triggering-spurious.patch b/0095-libmultipath-coalesce_paths-stop-triggering-spurious.patch deleted file mode 100644 index 0f8e520..0000000 --- a/0095-libmultipath-coalesce_paths-stop-triggering-spurious.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 8 Jan 2021 17:36:40 +0100 -Subject: [PATCH] libmultipath: coalesce_paths(): stop triggering spurious - uevents - -Since 0d66e03 ("libmultipath: force map reload if udev incomplete"), we -force-reload maps that we find incompletely initialized by udev. If -select_action returns ACT_NOTHING nonetheless, the map must be initialized -in udev, and thus and "add" uevent must have been seen already. Triggering -this event once more is unlikely to fix anything for real. - -Reverts: b516118 ("libmultipath: coalesce_paths: trigger uevent if nothing done") - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 24 ------------------------ - 1 file changed, 24 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 999f3106..3263bb01 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -527,18 +527,6 @@ get_udev_for_mpp(const struct multipath *mpp) - return udd; - } - --static void --trigger_udev_change(const struct multipath *mpp) --{ -- static const char change[] = "change"; -- struct udev_device *udd = get_udev_for_mpp(mpp); -- if (!udd) -- return; -- condlog(3, "triggering %s uevent for %s", change, mpp->alias); -- sysfs_attr_set_value(udd, "uevent", change, sizeof(change)-1); -- udev_device_unref(udd); --} -- - static void trigger_partitions_udev_change(struct udev_device *dev, - const char *action, int len) - { -@@ -1297,18 +1285,6 @@ int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid, - continue; - } - -- if (r == DOMAP_EXIST && mpp->action == ACT_NOTHING && -- force_reload == FORCE_RELOAD_WEAK) -- /* -- * First time we're called, and no changes applied. -- * domap() was a noop. But we can't be sure that -- * udev has already finished setting up this device -- * (udev in initrd may have been shut down while -- * processing this device or its children). -- * Trigger a change event, just in case. -- */ -- trigger_udev_change(find_mp_by_wwid(curmp, mpp->wwid)); -- - conf = get_multipath_config(); - allow_queueing = conf->allow_queueing; - put_multipath_config(conf); diff --git a/0096-Revert-multipathd-uev_trigger-handle-incomplete-ADD-.patch b/0096-Revert-multipathd-uev_trigger-handle-incomplete-ADD-.patch deleted file mode 100644 index 49cf1b0..0000000 --- a/0096-Revert-multipathd-uev_trigger-handle-incomplete-ADD-.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 8 Jan 2021 17:27:10 +0100 -Subject: [PATCH] Revert "multipathd: uev_trigger(): handle incomplete ADD - events" - -cb10d38 ("multipathd: uev_trigger(): handle incomplete ADD events") was an -attempt to fix issues with incompletely initialized multipath maps observed -in various scenarious. However, that patch was wrong. Spurious "change" events -as this patch would generate have no effect, because they are ignored by -the device-mapper udev rules. The correct fix for the problem we were -facing is 0d66e03 ("libmultipath: force map reload if udev incomplete"), -which forces a full map reload. - -Reverts: cb10d38 ("multipathd: uev_trigger(): handle incomplete ADD events") - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 25 ------------------------- - 1 file changed, 25 deletions(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 7612430a..92c45d44 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -1499,31 +1499,6 @@ uev_trigger (struct uevent * uev, void * trigger_data) - uev_pathfail_check(uev, vecs); - } else if (!strncmp(uev->action, "remove", 6)) { - r = uev_remove_map(uev, vecs); -- } else if (!strncmp(uev->action, "add", 3)) { -- const char *ev_name; -- char *dm_name; -- int major = -1, minor = -1; -- -- /* -- * If DM_NAME is not set for a valid map, trigger a -- * change event. This can happen during coldplug -- * if udev was killed between handling the 'add' and -- * 'change' events before. -- */ -- ev_name = uevent_get_dm_name(uev); -- if (!ev_name) { -- major = uevent_get_major(uev); -- minor = uevent_get_minor(uev); -- dm_name = dm_mapname(major, minor); -- if (dm_name && *dm_name) { -- condlog(2, "%s: received incomplete 'add' uevent, triggering change", -- dm_name); -- udev_device_set_sysattr_value(uev->udev, -- "uevent", -- "change"); -- free(dm_name); -- } -- } - } - goto out; - } diff --git a/0097-libmultipath-make-find_err_path_by_dev-static.patch b/0097-libmultipath-make-find_err_path_by_dev-static.patch deleted file mode 100644 index 19f0a01..0000000 --- a/0097-libmultipath-make-find_err_path_by_dev-static.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 14 Jan 2021 20:20:22 -0600 -Subject: [PATCH] libmultipath: make find_err_path_by_dev() static - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/io_err_stat.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/io_err_stat.c b/libmultipath/io_err_stat.c -index 5363049d..2e48ee81 100644 ---- a/libmultipath/io_err_stat.c -+++ b/libmultipath/io_err_stat.c -@@ -88,7 +88,7 @@ static void rcu_unregister(__attribute__((unused)) void *param) - rcu_unregister_thread(); - } - --struct io_err_stat_path *find_err_path_by_dev(vector pathvec, char *dev) -+static struct io_err_stat_path *find_err_path_by_dev(vector pathvec, char *dev) - { - int i; - struct io_err_stat_path *pp; diff --git a/0098-multipathd-avoid-io_err_stat-crash-during-shutdown.patch b/0098-multipathd-avoid-io_err_stat-crash-during-shutdown.patch deleted file mode 100644 index 2cab5a8..0000000 --- a/0098-multipathd-avoid-io_err_stat-crash-during-shutdown.patch +++ /dev/null @@ -1,254 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 14 Jan 2021 20:20:23 -0600 -Subject: [PATCH] multipathd: avoid io_err_stat crash during shutdown - -The checker thread is reponsible for enqueueing paths for the -io_err_stat thread to check. During shutdown, the io_err_stat thread is -shut down and cleaned up before the checker thread. There is no code -to make sure that the checker thread isn't accessing the io_err_stat -pathvec or its mutex while they are being freed, which can lead to -memory corruption crashes. - -To solve this, get rid of the io_err_stat_pathvec structure, and -statically define the mutex. This means that the mutex is always valid -to access, and the io_err_stat pathvec can only be accessed while -holding it. If the io_err_stat thread has already been cleaned up -when the checker tries to access the pathvec, it will be NULL, and the -checker will simply fail to enqueue the path. - -This change also fixes a bug in free_io_err_pathvec(), which previously -only attempted to free the pathvec if it was not set, instead of when it -was set. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/io_err_stat.c | 111 ++++++++++++++----------------------- - 1 file changed, 43 insertions(+), 68 deletions(-) - -diff --git a/libmultipath/io_err_stat.c b/libmultipath/io_err_stat.c -index 2e48ee81..feb66469 100644 ---- a/libmultipath/io_err_stat.c -+++ b/libmultipath/io_err_stat.c -@@ -46,12 +46,6 @@ - #define io_err_stat_log(prio, fmt, args...) \ - condlog(prio, "io error statistic: " fmt, ##args) - -- --struct io_err_stat_pathvec { -- pthread_mutex_t mutex; -- vector pathvec; --}; -- - struct dio_ctx { - struct timespec io_starttime; - unsigned int blksize; -@@ -75,9 +69,10 @@ static pthread_t io_err_stat_thr; - - static pthread_mutex_t io_err_thread_lock = PTHREAD_MUTEX_INITIALIZER; - static pthread_cond_t io_err_thread_cond = PTHREAD_COND_INITIALIZER; -+static pthread_mutex_t io_err_pathvec_lock = PTHREAD_MUTEX_INITIALIZER; - static int io_err_thread_running = 0; - --static struct io_err_stat_pathvec *paths; -+static vector io_err_pathvec; - struct vectors *vecs; - io_context_t ioctx; - -@@ -207,46 +202,23 @@ static void free_io_err_stat_path(struct io_err_stat_path *p) - FREE(p); - } - --static struct io_err_stat_pathvec *alloc_pathvec(void) --{ -- struct io_err_stat_pathvec *p; -- int r; -- -- p = (struct io_err_stat_pathvec *)MALLOC(sizeof(*p)); -- if (!p) -- return NULL; -- p->pathvec = vector_alloc(); -- if (!p->pathvec) -- goto out_free_struct_pathvec; -- r = pthread_mutex_init(&p->mutex, NULL); -- if (r) -- goto out_free_member_pathvec; -- -- return p; -- --out_free_member_pathvec: -- vector_free(p->pathvec); --out_free_struct_pathvec: -- FREE(p); -- return NULL; --} -- --static void free_io_err_pathvec(struct io_err_stat_pathvec *p) -+static void free_io_err_pathvec(void) - { - struct io_err_stat_path *path; - int i; - -- if (!p) -- return; -- pthread_mutex_destroy(&p->mutex); -- if (!p->pathvec) { -- vector_foreach_slot(p->pathvec, path, i) { -- destroy_directio_ctx(path); -- free_io_err_stat_path(path); -- } -- vector_free(p->pathvec); -+ pthread_mutex_lock(&io_err_pathvec_lock); -+ pthread_cleanup_push(cleanup_mutex, &io_err_pathvec_lock); -+ if (!io_err_pathvec) -+ goto out; -+ vector_foreach_slot(io_err_pathvec, path, i) { -+ destroy_directio_ctx(path); -+ free_io_err_stat_path(path); - } -- FREE(p); -+ vector_free(io_err_pathvec); -+ io_err_pathvec = NULL; -+out: -+ pthread_cleanup_pop(1); - } - - /* -@@ -258,13 +230,13 @@ static int enqueue_io_err_stat_by_path(struct path *path) - { - struct io_err_stat_path *p; - -- pthread_mutex_lock(&paths->mutex); -- p = find_err_path_by_dev(paths->pathvec, path->dev); -+ pthread_mutex_lock(&io_err_pathvec_lock); -+ p = find_err_path_by_dev(io_err_pathvec, path->dev); - if (p) { -- pthread_mutex_unlock(&paths->mutex); -+ pthread_mutex_unlock(&io_err_pathvec_lock); - return 0; - } -- pthread_mutex_unlock(&paths->mutex); -+ pthread_mutex_unlock(&io_err_pathvec_lock); - - p = alloc_io_err_stat_path(); - if (!p) -@@ -276,18 +248,18 @@ static int enqueue_io_err_stat_by_path(struct path *path) - - if (setup_directio_ctx(p)) - goto free_ioerr_path; -- pthread_mutex_lock(&paths->mutex); -- if (!vector_alloc_slot(paths->pathvec)) -+ pthread_mutex_lock(&io_err_pathvec_lock); -+ if (!vector_alloc_slot(io_err_pathvec)) - goto unlock_destroy; -- vector_set_slot(paths->pathvec, p); -- pthread_mutex_unlock(&paths->mutex); -+ vector_set_slot(io_err_pathvec, p); -+ pthread_mutex_unlock(&io_err_pathvec_lock); - - io_err_stat_log(2, "%s: enqueue path %s to check", - path->mpp->alias, path->dev); - return 0; - - unlock_destroy: -- pthread_mutex_unlock(&paths->mutex); -+ pthread_mutex_unlock(&io_err_pathvec_lock); - destroy_directio_ctx(p); - free_ioerr_path: - free_io_err_stat_path(p); -@@ -412,9 +384,9 @@ static int delete_io_err_stat_by_addr(struct io_err_stat_path *p) - { - int i; - -- i = find_slot(paths->pathvec, p); -+ i = find_slot(io_err_pathvec, p); - if (i != -1) -- vector_del_slot(paths->pathvec, i); -+ vector_del_slot(io_err_pathvec, i); - - destroy_directio_ctx(p); - free_io_err_stat_path(p); -@@ -585,7 +557,7 @@ static void poll_async_io_timeout(void) - - if (clock_gettime(CLOCK_MONOTONIC, &curr_time) != 0) - return; -- vector_foreach_slot(paths->pathvec, pp, i) { -+ vector_foreach_slot(io_err_pathvec, pp, i) { - for (j = 0; j < CONCUR_NR_EVENT; j++) { - rc = try_to_cancel_timeout_io(pp->dio_ctx_array + j, - &curr_time, pp->devname); -@@ -631,7 +603,7 @@ static void handle_async_io_done_event(struct io_event *io_evt) - int rc = PATH_UNCHECKED; - int i, j; - -- vector_foreach_slot(paths->pathvec, pp, i) { -+ vector_foreach_slot(io_err_pathvec, pp, i) { - for (j = 0; j < CONCUR_NR_EVENT; j++) { - ct = pp->dio_ctx_array + j; - if (&ct->io == io_evt->obj) { -@@ -665,19 +637,14 @@ static void service_paths(void) - struct io_err_stat_path *pp; - int i; - -- pthread_mutex_lock(&paths->mutex); -- vector_foreach_slot(paths->pathvec, pp, i) { -+ pthread_mutex_lock(&io_err_pathvec_lock); -+ vector_foreach_slot(io_err_pathvec, pp, i) { - send_batch_async_ios(pp); - process_async_ios_event(TIMEOUT_NO_IO_NSEC, pp->devname); - poll_async_io_timeout(); - poll_io_err_stat(vecs, pp); - } -- pthread_mutex_unlock(&paths->mutex); --} -- --static void cleanup_unlock(void *arg) --{ -- pthread_mutex_unlock((pthread_mutex_t*) arg); -+ pthread_mutex_unlock(&io_err_pathvec_lock); - } - - static void cleanup_exited(__attribute__((unused)) void *arg) -@@ -736,13 +703,18 @@ int start_io_err_stat_thread(void *data) - io_err_stat_log(4, "io_setup failed"); - return 1; - } -- paths = alloc_pathvec(); -- if (!paths) -+ -+ pthread_mutex_lock(&io_err_pathvec_lock); -+ io_err_pathvec = vector_alloc(); -+ if (!io_err_pathvec) { -+ pthread_mutex_unlock(&io_err_pathvec_lock); - goto destroy_ctx; -+ } -+ pthread_mutex_unlock(&io_err_pathvec_lock); - - setup_thread_attr(&io_err_stat_attr, 32 * 1024, 0); - pthread_mutex_lock(&io_err_thread_lock); -- pthread_cleanup_push(cleanup_unlock, &io_err_thread_lock); -+ pthread_cleanup_push(cleanup_mutex, &io_err_thread_lock); - - ret = pthread_create(&io_err_stat_thr, &io_err_stat_attr, - io_err_stat_loop, data); -@@ -763,7 +735,10 @@ int start_io_err_stat_thread(void *data) - return 0; - - out_free: -- free_io_err_pathvec(paths); -+ pthread_mutex_lock(&io_err_pathvec_lock); -+ vector_free(io_err_pathvec); -+ io_err_pathvec = NULL; -+ pthread_mutex_unlock(&io_err_pathvec_lock); - destroy_ctx: - io_destroy(ioctx); - io_err_stat_log(0, "failed to start io_error statistic thread"); -@@ -779,6 +754,6 @@ void stop_io_err_stat_thread(void) - pthread_cancel(io_err_stat_thr); - - pthread_join(io_err_stat_thr, NULL); -- free_io_err_pathvec(paths); -+ free_io_err_pathvec(); - io_destroy(ioctx); - } diff --git a/0099-multipathd-avoid-io_err_stat-ABBA-deadlock.patch b/0099-multipathd-avoid-io_err_stat-ABBA-deadlock.patch deleted file mode 100644 index e6bf72d..0000000 --- a/0099-multipathd-avoid-io_err_stat-ABBA-deadlock.patch +++ /dev/null @@ -1,143 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 14 Jan 2021 20:20:24 -0600 -Subject: [PATCH] multipathd: avoid io_err_stat ABBA deadlock - -When the checker thread enqueues paths for the io_err_stat thread to -check, it calls enqueue_io_err_stat_by_path() with the vecs lock held. -start_io_err_stat_thread() is also called with the vecs lock held. -These two functions both lock io_err_pathvec_lock. When the io_err_stat -thread updates the paths in vecs->pathvec in poll_io_err_stat(), it has -the io_err_pathvec_lock held, and then locks the vecs lock. This can -cause an ABBA deadlock. - -To solve this, service_paths() no longer updates the paths in -vecs->pathvec with the io_err_pathvec_lock held. It does this by moving -the io_err_stat_path from io_err_pathvec to a local vector when it needs -to update the path. After releasing the io_err_pathvec_lock, it goes -through this temporary vector, updates the paths with the vecs lock -held, and then frees everything. - -This change fixes a bug in service_paths() where elements were being -deleted from io_err_pathvec, without the index being decremented, -causing the loop to skip elements. Also, service_paths() could be -cancelled while holding the io_err_pathvec_lock, so it should have a -cleanup handler. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/io_err_stat.c | 56 ++++++++++++++++++++++---------------- - 1 file changed, 32 insertions(+), 24 deletions(-) - -diff --git a/libmultipath/io_err_stat.c b/libmultipath/io_err_stat.c -index feb66469..775e7259 100644 ---- a/libmultipath/io_err_stat.c -+++ b/libmultipath/io_err_stat.c -@@ -380,20 +380,6 @@ recover: - return 0; - } - --static int delete_io_err_stat_by_addr(struct io_err_stat_path *p) --{ -- int i; -- -- i = find_slot(io_err_pathvec, p); -- if (i != -1) -- vector_del_slot(io_err_pathvec, i); -- -- destroy_directio_ctx(p); -- free_io_err_stat_path(p); -- -- return 0; --} -- - static void account_async_io_state(struct io_err_stat_path *pp, int rc) - { - switch (rc) { -@@ -410,17 +396,26 @@ static void account_async_io_state(struct io_err_stat_path *pp, int rc) - } - } - --static int poll_io_err_stat(struct vectors *vecs, struct io_err_stat_path *pp) -+static int io_err_stat_time_up(struct io_err_stat_path *pp) - { - struct timespec currtime, difftime; -- struct path *path; -- double err_rate; - - if (clock_gettime(CLOCK_MONOTONIC, &currtime) != 0) -- return 1; -+ return 0; - timespecsub(&currtime, &pp->start_time, &difftime); - if (difftime.tv_sec < pp->total_time) - return 0; -+ return 1; -+} -+ -+static void end_io_err_stat(struct io_err_stat_path *pp) -+{ -+ struct timespec currtime; -+ struct path *path; -+ double err_rate; -+ -+ if (clock_gettime(CLOCK_MONOTONIC, &currtime) != 0) -+ currtime = pp->start_time; - - io_err_stat_log(4, "%s: check end", pp->devname); - -@@ -459,10 +454,6 @@ static int poll_io_err_stat(struct vectors *vecs, struct io_err_stat_path *pp) - pp->devname); - } - lock_cleanup_pop(vecs->lock); -- -- delete_io_err_stat_by_addr(pp); -- -- return 0; - } - - static int send_each_async_io(struct dio_ctx *ct, int fd, char *dev) -@@ -622,6 +613,7 @@ static void process_async_ios_event(int timeout_nsecs, char *dev) - struct timespec timeout = { .tv_nsec = timeout_nsecs }; - - errno = 0; -+ pthread_testcancel(); - n = io_getevents(ioctx, 1L, CONCUR_NR_EVENT, events, &timeout); - if (n < 0) { - io_err_stat_log(3, "%s: async io events returned %d (errno=%s)", -@@ -634,17 +626,33 @@ static void process_async_ios_event(int timeout_nsecs, char *dev) - - static void service_paths(void) - { -+ struct _vector _pathvec = {0}; -+ /* avoid gcc warnings that &_pathvec will never be NULL in vector ops */ -+ struct _vector * const tmp_pathvec = &_pathvec; - struct io_err_stat_path *pp; - int i; - - pthread_mutex_lock(&io_err_pathvec_lock); -+ pthread_cleanup_push(cleanup_mutex, &io_err_pathvec_lock); - vector_foreach_slot(io_err_pathvec, pp, i) { - send_batch_async_ios(pp); - process_async_ios_event(TIMEOUT_NO_IO_NSEC, pp->devname); - poll_async_io_timeout(); -- poll_io_err_stat(vecs, pp); -+ if (io_err_stat_time_up(pp)) { -+ if (!vector_alloc_slot(tmp_pathvec)) -+ continue; -+ vector_del_slot(io_err_pathvec, i--); -+ vector_set_slot(tmp_pathvec, pp); -+ } - } -- pthread_mutex_unlock(&io_err_pathvec_lock); -+ pthread_cleanup_pop(1); -+ vector_foreach_slot_backwards(tmp_pathvec, pp, i) { -+ end_io_err_stat(pp); -+ vector_del_slot(tmp_pathvec, i); -+ destroy_directio_ctx(pp); -+ free_io_err_stat_path(pp); -+ } -+ vector_reset(tmp_pathvec); - } - - static void cleanup_exited(__attribute__((unused)) void *arg) diff --git a/0100-multipathd-use-get_monotonic_time-in-io_err_stat-cod.patch b/0100-multipathd-use-get_monotonic_time-in-io_err_stat-cod.patch deleted file mode 100644 index a5ef865..0000000 --- a/0100-multipathd-use-get_monotonic_time-in-io_err_stat-cod.patch +++ /dev/null @@ -1,108 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 14 Jan 2021 20:20:25 -0600 -Subject: [PATCH] multipathd: use get_monotonic_time() in io_err_stat code - -Instead of calling clock_gettime(), and dealing with failure -conditions, just call get_monotonic_time(). - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/io_err_stat.c | 34 +++++++++++----------------------- - 1 file changed, 11 insertions(+), 23 deletions(-) - -diff --git a/libmultipath/io_err_stat.c b/libmultipath/io_err_stat.c -index 775e7259..92871f40 100644 ---- a/libmultipath/io_err_stat.c -+++ b/libmultipath/io_err_stat.c -@@ -295,8 +295,7 @@ int io_err_stat_handle_pathfail(struct path *path) - * the repeated count threshold and time frame, we assume a path - * which fails at least twice within 60 seconds is flaky. - */ -- if (clock_gettime(CLOCK_MONOTONIC, &curr_time) != 0) -- return 1; -+ get_monotonic_time(&curr_time); - if (path->io_err_pathfail_cnt == 0) { - path->io_err_pathfail_cnt++; - path->io_err_pathfail_starttime = curr_time.tv_sec; -@@ -352,9 +351,9 @@ int need_io_err_check(struct path *pp) - } - if (pp->io_err_pathfail_cnt != PATH_IO_ERR_WAITING_TO_CHECK) - return 1; -- if (clock_gettime(CLOCK_MONOTONIC, &curr_time) != 0 || -- (curr_time.tv_sec - pp->io_err_dis_reinstate_time) > -- pp->mpp->marginal_path_err_recheck_gap_time) { -+ get_monotonic_time(&curr_time); -+ if ((curr_time.tv_sec - pp->io_err_dis_reinstate_time) > -+ pp->mpp->marginal_path_err_recheck_gap_time) { - io_err_stat_log(4, "%s: reschedule checking after %d seconds", - pp->dev, - pp->mpp->marginal_path_err_recheck_gap_time); -@@ -400,8 +399,7 @@ static int io_err_stat_time_up(struct io_err_stat_path *pp) - { - struct timespec currtime, difftime; - -- if (clock_gettime(CLOCK_MONOTONIC, &currtime) != 0) -- return 0; -+ get_monotonic_time(&currtime); - timespecsub(&currtime, &pp->start_time, &difftime); - if (difftime.tv_sec < pp->total_time) - return 0; -@@ -414,8 +412,7 @@ static void end_io_err_stat(struct io_err_stat_path *pp) - struct path *path; - double err_rate; - -- if (clock_gettime(CLOCK_MONOTONIC, &currtime) != 0) -- currtime = pp->start_time; -+ get_monotonic_time(&currtime); - - io_err_stat_log(4, "%s: check end", pp->devname); - -@@ -464,11 +461,7 @@ static int send_each_async_io(struct dio_ctx *ct, int fd, char *dev) - ct->io_starttime.tv_sec == 0) { - struct iocb *ios[1] = { &ct->io }; - -- if (clock_gettime(CLOCK_MONOTONIC, &ct->io_starttime) != 0) { -- ct->io_starttime.tv_sec = 0; -- ct->io_starttime.tv_nsec = 0; -- return rc; -- } -+ get_monotonic_time(&ct->io_starttime); - io_prep_pread(&ct->io, fd, ct->buf, ct->blksize, 0); - if (io_submit(ioctx, 1, ios) != 1) { - io_err_stat_log(5, "%s: io_submit error %i", -@@ -487,8 +480,7 @@ static void send_batch_async_ios(struct io_err_stat_path *pp) - struct dio_ctx *ct; - struct timespec currtime, difftime; - -- if (clock_gettime(CLOCK_MONOTONIC, &currtime) != 0) -- return; -+ get_monotonic_time(&currtime); - /* - * Give a free time for all IO to complete or timeout - */ -@@ -503,11 +495,8 @@ static void send_batch_async_ios(struct io_err_stat_path *pp) - if (!send_each_async_io(ct, pp->fd, pp->devname)) - pp->io_nr++; - } -- if (pp->start_time.tv_sec == 0 && pp->start_time.tv_nsec == 0 && -- clock_gettime(CLOCK_MONOTONIC, &pp->start_time)) { -- pp->start_time.tv_sec = 0; -- pp->start_time.tv_nsec = 0; -- } -+ if (pp->start_time.tv_sec == 0 && pp->start_time.tv_nsec == 0) -+ get_monotonic_time(&pp->start_time); - } - - static int try_to_cancel_timeout_io(struct dio_ctx *ct, struct timespec *t, -@@ -546,8 +535,7 @@ static void poll_async_io_timeout(void) - int rc = PATH_UNCHECKED; - int i, j; - -- if (clock_gettime(CLOCK_MONOTONIC, &curr_time) != 0) -- return; -+ get_monotonic_time(&curr_time); - vector_foreach_slot(io_err_pathvec, pp, i) { - for (j = 0; j < CONCUR_NR_EVENT; j++) { - rc = try_to_cancel_timeout_io(pp->dio_ctx_array + j, diff --git a/0101-multipathd-combine-free_io_err_stat_path-and-destroy.patch b/0101-multipathd-combine-free_io_err_stat_path-and-destroy.patch deleted file mode 100644 index d6d015e..0000000 --- a/0101-multipathd-combine-free_io_err_stat_path-and-destroy.patch +++ /dev/null @@ -1,98 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 14 Jan 2021 20:20:26 -0600 -Subject: [PATCH] multipathd: combine free_io_err_stat_path and - destroy_directio_ctx - -destroy_directio_ctx() is only called from free_io_err_stat_path(), and -free_io_err_stat_path() is very short, so combine them. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/io_err_stat.c | 24 ++++++++++-------------- - 1 file changed, 10 insertions(+), 14 deletions(-) - -diff --git a/libmultipath/io_err_stat.c b/libmultipath/io_err_stat.c -index 92871f40..bf78a236 100644 ---- a/libmultipath/io_err_stat.c -+++ b/libmultipath/io_err_stat.c -@@ -161,12 +161,15 @@ fail_close: - return 1; - } - --static void destroy_directio_ctx(struct io_err_stat_path *p) -+static void free_io_err_stat_path(struct io_err_stat_path *p) - { - int i; - -- if (!p || !p->dio_ctx_array) -+ if (!p) - return; -+ if (!p->dio_ctx_array) -+ goto free_path; -+ - cancel_inflight_io(p); - - for (i = 0; i < CONCUR_NR_EVENT; i++) -@@ -175,6 +178,8 @@ static void destroy_directio_ctx(struct io_err_stat_path *p) - - if (p->fd > 0) - close(p->fd); -+free_path: -+ FREE(p); - } - - static struct io_err_stat_path *alloc_io_err_stat_path(void) -@@ -197,11 +202,6 @@ static struct io_err_stat_path *alloc_io_err_stat_path(void) - return p; - } - --static void free_io_err_stat_path(struct io_err_stat_path *p) --{ -- FREE(p); --} -- - static void free_io_err_pathvec(void) - { - struct io_err_stat_path *path; -@@ -211,10 +211,8 @@ static void free_io_err_pathvec(void) - pthread_cleanup_push(cleanup_mutex, &io_err_pathvec_lock); - if (!io_err_pathvec) - goto out; -- vector_foreach_slot(io_err_pathvec, path, i) { -- destroy_directio_ctx(path); -+ vector_foreach_slot(io_err_pathvec, path, i) - free_io_err_stat_path(path); -- } - vector_free(io_err_pathvec); - io_err_pathvec = NULL; - out: -@@ -250,7 +248,7 @@ static int enqueue_io_err_stat_by_path(struct path *path) - goto free_ioerr_path; - pthread_mutex_lock(&io_err_pathvec_lock); - if (!vector_alloc_slot(io_err_pathvec)) -- goto unlock_destroy; -+ goto unlock_pathvec; - vector_set_slot(io_err_pathvec, p); - pthread_mutex_unlock(&io_err_pathvec_lock); - -@@ -258,9 +256,8 @@ static int enqueue_io_err_stat_by_path(struct path *path) - path->mpp->alias, path->dev); - return 0; - --unlock_destroy: -+unlock_pathvec: - pthread_mutex_unlock(&io_err_pathvec_lock); -- destroy_directio_ctx(p); - free_ioerr_path: - free_io_err_stat_path(p); - -@@ -637,7 +634,6 @@ static void service_paths(void) - vector_foreach_slot_backwards(tmp_pathvec, pp, i) { - end_io_err_stat(pp); - vector_del_slot(tmp_pathvec, i); -- destroy_directio_ctx(pp); - free_io_err_stat_path(pp); - } - vector_reset(tmp_pathvec); diff --git a/0102-multipathd-cleanup-logging-for-marginal-paths.patch b/0102-multipathd-cleanup-logging-for-marginal-paths.patch deleted file mode 100644 index a88c07b..0000000 --- a/0102-multipathd-cleanup-logging-for-marginal-paths.patch +++ /dev/null @@ -1,120 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 18 Jan 2021 22:46:04 -0600 -Subject: [PATCH] multipathd: cleanup logging for marginal paths - -io_err_stat logged at level 2 whenever it enqueued a path to check, -which could happen multiple times while a path was marginal. On the -other hand if marginal_pathgroups wasn't set, multipathd didn't log when -paths were set to marginal. Now io_err_stat only logs at level 2 when -something unexpected happens, but multipathd will always log when a -path switches its marginal state. - -This patch also fixes an issue where paths in the delayed state could -get set to the pending state if they could not be checked in time. -Aside from going against the idea the paths should not be set to pending -if they already have a valid state, this caused multipathd to log a -message whenever the path state switched to from delayed to pending and -then back. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/io_err_stat.c | 7 +++---- - multipathd/main.c | 25 ++++++++++++++----------- - 2 files changed, 17 insertions(+), 15 deletions(-) - -diff --git a/libmultipath/io_err_stat.c b/libmultipath/io_err_stat.c -index bf78a236..abdd0b4f 100644 ---- a/libmultipath/io_err_stat.c -+++ b/libmultipath/io_err_stat.c -@@ -252,7 +252,7 @@ static int enqueue_io_err_stat_by_path(struct path *path) - vector_set_slot(io_err_pathvec, p); - pthread_mutex_unlock(&io_err_pathvec_lock); - -- io_err_stat_log(2, "%s: enqueue path %s to check", -+ io_err_stat_log(3, "%s: enqueue path %s to check", - path->mpp->alias, path->dev); - return 0; - -@@ -343,7 +343,7 @@ int need_io_err_check(struct path *pp) - if (uatomic_read(&io_err_thread_running) == 0) - return 0; - if (count_active_paths(pp->mpp) <= 0) { -- io_err_stat_log(2, "%s: recover path early", pp->dev); -+ io_err_stat_log(2, "%s: no paths. recovering early", pp->dev); - goto recover; - } - if (pp->io_err_pathfail_cnt != PATH_IO_ERR_WAITING_TO_CHECK) -@@ -361,8 +361,7 @@ int need_io_err_check(struct path *pp) - * Or else, return 1 to set path state to PATH_SHAKY - */ - if (r == 1) { -- io_err_stat_log(3, "%s: enqueue fails, to recover", -- pp->dev); -+ io_err_stat_log(2, "%s: enqueue failed. recovering early", pp->dev); - goto recover; - } else - pp->io_err_pathfail_cnt = PATH_IO_ERR_IN_CHECKING; -diff --git a/multipathd/main.c b/multipathd/main.c -index 92c45d44..99a89a69 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -2132,8 +2132,8 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) - pathinfo(pp, conf, 0); - pthread_cleanup_pop(1); - return 1; -- } else if ((newstate != PATH_UP && newstate != PATH_GHOST) && -- (pp->state == PATH_DELAYED)) { -+ } else if ((newstate != PATH_UP && newstate != PATH_GHOST && -+ newstate != PATH_PENDING) && (pp->state == PATH_DELAYED)) { - /* If path state become failed again cancel path delay state */ - pp->state = newstate; - /* -@@ -2200,8 +2200,9 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) - if ((newstate == PATH_UP || newstate == PATH_GHOST) && - (san_path_check_enabled(pp->mpp) || - marginal_path_check_enabled(pp->mpp))) { -- int was_marginal = pp->marginal; - if (should_skip_path(pp)) { -+ if (!pp->marginal && pp->state != PATH_DELAYED) -+ condlog(2, "%s: path is now marginal", pp->dev); - if (!marginal_pathgroups) { - if (marginal_path_check_enabled(pp->mpp)) - /* to reschedule as soon as possible, -@@ -2211,13 +2212,18 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) - pp->state = PATH_DELAYED; - return 1; - } -- if (!was_marginal) { -+ if (!pp->marginal) { - pp->marginal = 1; - marginal_changed = 1; - } -- } else if (marginal_pathgroups && was_marginal) { -- pp->marginal = 0; -- marginal_changed = 1; -+ } else { -+ if (pp->marginal || pp->state == PATH_DELAYED) -+ condlog(2, "%s: path is no longer marginal", -+ pp->dev); -+ if (marginal_pathgroups && pp->marginal) { -+ pp->marginal = 0; -+ marginal_changed = 1; -+ } - } - } - -@@ -2343,11 +2349,8 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) - */ - condlog(4, "path prio refresh"); - -- if (marginal_changed) { -- condlog(2, "%s: path is %s marginal", pp->dev, -- (pp->marginal)? "now" : "no longer"); -+ if (marginal_changed) - reload_and_sync_map(pp->mpp, vecs, 1); -- } - else if (update_prio(pp, new_path_up) && - (pp->mpp->pgpolicyfn == (pgpolicyfn *)group_by_prio) && - pp->mpp->pgfailback == -FAILBACK_IMMEDIATE) { diff --git a/0103-libmultipath-fix-NULL-dereference-in-find_path_by_de.patch b/0103-libmultipath-fix-NULL-dereference-in-find_path_by_de.patch deleted file mode 100644 index e115e58..0000000 --- a/0103-libmultipath-fix-NULL-dereference-in-find_path_by_de.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: lixiaokeng -Date: Sat, 23 Jan 2021 16:19:28 +0800 -Subject: [PATCH] libmultipath: fix NULL dereference in find_path_by_dev - -When I test the 0.8.5 code with iscsi login/out, multipathd command -and multipath command concurrently, there is a multipathd coredump. -The stack is shown: - -uxlsnrloop - ->cli_list_devices - ->show_devices - ->snprint_devices - ->find_path_by_dev - -The reason is that devname is NULL in snprint_devices, then it will -be dereference. Here we check dev in find_path_by_dev. - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/structs.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/structs.c b/libmultipath/structs.c -index 464596fc..a3f27fd6 100644 ---- a/libmultipath/structs.c -+++ b/libmultipath/structs.c -@@ -453,12 +453,12 @@ find_mp_by_str (const struct _vector *mpvec, const char * str) - } - - struct path * --find_path_by_dev (const struct _vector *pathvec, const char * dev) -+find_path_by_dev (const struct _vector *pathvec, const char *dev) - { - int i; - struct path * pp; - -- if (!pathvec) -+ if (!pathvec || !dev) - return NULL; - - vector_foreach_slot (pathvec, pp, i) diff --git a/0104-libmultipath-snprint_devices-avoid-NULL-dereference.patch b/0104-libmultipath-snprint_devices-avoid-NULL-dereference.patch deleted file mode 100644 index 4ddae1c..0000000 --- a/0104-libmultipath-snprint_devices-avoid-NULL-dereference.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 25 Jan 2021 16:12:10 +0100 -Subject: [PATCH] libmultipath: snprint_devices(): avoid NULL dereference - -All libudev functions may return NULL. Watch out for it. - -Fixes: d041258 ("libmultipath: snprint_devices(): use udev_enumerate" -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/print.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/libmultipath/print.c b/libmultipath/print.c -index 19de2c7c..8151e11e 100644 ---- a/libmultipath/print.c -+++ b/libmultipath/print.c -@@ -2055,8 +2055,16 @@ int snprint_devices(struct config *conf, char *buff, size_t len, - struct udev_device *u_dev; - - path = udev_list_entry_get_name(item); -+ if (!path) -+ continue; - u_dev = udev_device_new_from_syspath(udev, path); -+ if (!u_dev) -+ continue; - devname = udev_device_get_sysname(u_dev); -+ if (!devname) { -+ udev_device_unref(u_dev); -+ continue; -+ } - - fwd += snprintf(buff + fwd, len - fwd, " %s", devname); - if (fwd >= len) diff --git a/0105-libmpathpersist-fix-thread-safety-of-default-functio.patch b/0105-libmpathpersist-fix-thread-safety-of-default-functio.patch deleted file mode 100644 index e21e27c..0000000 --- a/0105-libmpathpersist-fix-thread-safety-of-default-functio.patch +++ /dev/null @@ -1,271 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 25 Jan 2021 23:31:04 -0600 -Subject: [PATCH] libmpathpersist: fix thread safety of default functions - -commit a839e39e ("libmpathpersist: factor out initialization and -teardown") made mpath_presistent_reserve_{in,out} use share variables -for curmp and pathvec. There are users of this library that call these -functions in a multi-threaded process, and this change causes their -application to crash. config and udev are also shared variables, but -libmpathpersist doesn't write to the config in -mpath_presistent_reserve_{in,out}, and looking into the libudev code, I -don't see any place where libmpathpersist uses the udev object in a way -that isn't thread-safe. - -This patch makes mpath_presistent_reserve_{in,out} go back to using -local variables for curmp and pathvec, so that multiple threads won't -be operating on these variables at the same time. - -Fixes: a839e39e ("libmpathpersist: factor out initialization and teardown") -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmpathpersist/mpath_persist.c | 116 +++++++++++++++++++++----------- - libmpathpersist/mpath_persist.h | 24 +++++-- - 2 files changed, 94 insertions(+), 46 deletions(-) - -diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c -index 08077936..5c95af20 100644 ---- a/libmpathpersist/mpath_persist.c -+++ b/libmpathpersist/mpath_persist.c -@@ -133,69 +133,57 @@ mpath_prin_activepath (struct multipath *mpp, int rq_servact, - return ret; - } - --int mpath_persistent_reserve_in (int fd, int rq_servact, -- struct prin_resp *resp, int noisy, int verbose) --{ -- int ret = mpath_persistent_reserve_init_vecs(verbose); -- -- if (ret != MPATH_PR_SUCCESS) -- return ret; -- ret = __mpath_persistent_reserve_in(fd, rq_servact, resp, noisy); -- mpath_persistent_reserve_free_vecs(); -- return ret; --} -- --int mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, -- unsigned int rq_type, struct prout_param_descriptor *paramp, int noisy, int verbose) --{ -- int ret = mpath_persistent_reserve_init_vecs(verbose); -- -- if (ret != MPATH_PR_SUCCESS) -- return ret; -- ret = __mpath_persistent_reserve_out(fd, rq_servact, rq_scope, rq_type, -- paramp, noisy); -- mpath_persistent_reserve_free_vecs(); -- return ret; --} -- - static vector curmp; - static vector pathvec; - --void mpath_persistent_reserve_free_vecs(void) -+static void __mpath_persistent_reserve_free_vecs(vector curmp, vector pathvec) - { - free_multipathvec(curmp, KEEP_PATHS); - free_pathvec(pathvec, FREE_PATHS); -+} -+ -+void mpath_persistent_reserve_free_vecs(void) -+{ -+ __mpath_persistent_reserve_free_vecs(curmp, pathvec); - curmp = pathvec = NULL; - } - --int mpath_persistent_reserve_init_vecs(int verbose) -+static int __mpath_persistent_reserve_init_vecs(vector *curmp_p, -+ vector *pathvec_p, int verbose) - { - libmp_verbosity = verbose; - -- if (curmp) -+ if (*curmp_p) - return MPATH_PR_SUCCESS; - /* - * allocate core vectors to store paths and multipaths - */ -- curmp = vector_alloc (); -- pathvec = vector_alloc (); -+ *curmp_p = vector_alloc (); -+ *pathvec_p = vector_alloc (); - -- if (!curmp || !pathvec){ -+ if (!*curmp_p || !*pathvec_p){ - condlog (0, "vector allocation failed."); - goto err; - } - -- if (dm_get_maps(curmp)) -+ if (dm_get_maps(*curmp_p)) - goto err; - - return MPATH_PR_SUCCESS; - - err: -- mpath_persistent_reserve_free_vecs(); -+ __mpath_persistent_reserve_free_vecs(*curmp_p, *pathvec_p); -+ *curmp_p = *pathvec_p = NULL; - return MPATH_PR_DMMP_ERROR; - } - --static int mpath_get_map(int fd, char **palias, struct multipath **pmpp) -+int mpath_persistent_reserve_init_vecs(int verbose) -+{ -+ return __mpath_persistent_reserve_init_vecs(&curmp, &pathvec, verbose); -+} -+ -+static int mpath_get_map(vector curmp, vector pathvec, int fd, char **palias, -+ struct multipath **pmpp) - { - int ret = MPATH_PR_DMMP_ERROR; - struct stat info; -@@ -255,13 +243,13 @@ out: - return ret; - } - --int __mpath_persistent_reserve_in (int fd, int rq_servact, -- struct prin_resp *resp, int noisy) -+static int do_mpath_persistent_reserve_in (vector curmp, vector pathvec, -+ int fd, int rq_servact, struct prin_resp *resp, int noisy) - { - struct multipath *mpp; - int ret; - -- ret = mpath_get_map(fd, NULL, &mpp); -+ ret = mpath_get_map(curmp, pathvec, fd, NULL, &mpp); - if (ret != MPATH_PR_SUCCESS) - return ret; - -@@ -270,8 +258,17 @@ int __mpath_persistent_reserve_in (int fd, int rq_servact, - return ret; - } - --int __mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, -- unsigned int rq_type, struct prout_param_descriptor *paramp, int noisy) -+ -+int __mpath_persistent_reserve_in (int fd, int rq_servact, -+ struct prin_resp *resp, int noisy) -+{ -+ return do_mpath_persistent_reserve_in(curmp, pathvec, fd, rq_servact, -+ resp, noisy); -+} -+ -+static int do_mpath_persistent_reserve_out(vector curmp, vector pathvec, int fd, -+ int rq_servact, int rq_scope, unsigned int rq_type, -+ struct prout_param_descriptor *paramp, int noisy) - { - struct multipath *mpp; - char *alias; -@@ -279,7 +276,7 @@ int __mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, - uint64_t prkey; - struct config *conf; - -- ret = mpath_get_map(fd, &alias, &mpp); -+ ret = mpath_get_map(curmp, pathvec, fd, &alias, &mpp); - if (ret != MPATH_PR_SUCCESS) - return ret; - -@@ -349,6 +346,45 @@ out1: - return ret; - } - -+ -+int __mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, -+ unsigned int rq_type, struct prout_param_descriptor *paramp, int noisy) -+{ -+ return do_mpath_persistent_reserve_out(curmp, pathvec, fd, rq_servact, -+ rq_scope, rq_type, paramp, -+ noisy); -+} -+ -+int mpath_persistent_reserve_in (int fd, int rq_servact, -+ struct prin_resp *resp, int noisy, int verbose) -+{ -+ vector curmp = NULL, pathvec; -+ int ret = __mpath_persistent_reserve_init_vecs(&curmp, &pathvec, -+ verbose); -+ -+ if (ret != MPATH_PR_SUCCESS) -+ return ret; -+ ret = do_mpath_persistent_reserve_in(curmp, pathvec, fd, rq_servact, -+ resp, noisy); -+ __mpath_persistent_reserve_free_vecs(curmp, pathvec); -+ return ret; -+} -+ -+int mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, -+ unsigned int rq_type, struct prout_param_descriptor *paramp, int noisy, int verbose) -+{ -+ vector curmp = NULL, pathvec; -+ int ret = __mpath_persistent_reserve_init_vecs(&curmp, &pathvec, -+ verbose); -+ -+ if (ret != MPATH_PR_SUCCESS) -+ return ret; -+ ret = do_mpath_persistent_reserve_out(curmp, pathvec, fd, rq_servact, -+ rq_scope, rq_type, paramp, noisy); -+ __mpath_persistent_reserve_free_vecs(curmp, pathvec); -+ return ret; -+} -+ - int - get_mpvec (vector curmp, vector pathvec, char * refwwid) - { -diff --git a/libmpathpersist/mpath_persist.h b/libmpathpersist/mpath_persist.h -index 5435eae4..9e9c0a82 100644 ---- a/libmpathpersist/mpath_persist.h -+++ b/libmpathpersist/mpath_persist.h -@@ -246,9 +246,13 @@ extern int mpath_persistent_reserve_in (int fd, int rq_servact, struct prin_resp - - /* - * DESCRIPTION : -- * This function is like mpath_persistent_reserve_in(), except that it doesn't call -- * mpath_persistent_reserve_init_vecs() and mpath_persistent_reserve_free_vecs() -- * before and after the actual PR call. -+ * This function is like mpath_persistent_reserve_in(), except that it -+ * requires mpath_persistent_reserve_init_vecs() to be called before the -+ * PR call to set up internal variables. These must later be cleanup up -+ * by calling mpath_persistent_reserve_free_vecs(). -+ * -+ * RESTRICTIONS: -+ * This function uses static internal variables, and is not thread-safe. - */ - extern int __mpath_persistent_reserve_in(int fd, int rq_servact, - struct prin_resp *resp, int noisy); -@@ -280,9 +284,13 @@ extern int mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, - int verbose); - /* - * DESCRIPTION : -- * This function is like mpath_persistent_reserve_out(), except that it doesn't call -- * mpath_persistent_reserve_init_vecs() and mpath_persistent_reserve_free_vecs() -- * before and after the actual PR call. -+ * This function is like mpath_persistent_reserve_out(), except that it -+ * requires mpath_persistent_reserve_init_vecs() to be called before the -+ * PR call to set up internal variables. These must later be cleanup up -+ * by calling mpath_persistent_reserve_free_vecs(). -+ * -+ * RESTRICTIONS: -+ * This function uses static internal variables, and is not thread-safe. - */ - extern int __mpath_persistent_reserve_out( int fd, int rq_servact, int rq_scope, - unsigned int rq_type, struct prout_param_descriptor *paramp, -@@ -296,6 +304,7 @@ extern int __mpath_persistent_reserve_out( int fd, int rq_servact, int rq_scope, - * @verbose: Set verbosity level. Input argument. value:0 to 3. 0->disabled, 3->Max verbose - * - * RESTRICTIONS: -+ * This function uses static internal variables, and is not thread-safe. - * - * RETURNS: MPATH_PR_SUCCESS if successful else returns any of the status specified - * above in RETURN_STATUS. -@@ -306,6 +315,9 @@ int mpath_persistent_reserve_init_vecs(int verbose); - * DESCRIPTION : - * This function frees data structures allocated by - * mpath_persistent_reserve_init_vecs(). -+ * -+ * RESTRICTIONS: -+ * This function uses static internal variables, and is not thread-safe. - */ - void mpath_persistent_reserve_free_vecs(void); - diff --git a/0106-Added-github-action-for-building.patch b/0106-Added-github-action-for-building.patch deleted file mode 100644 index 9622788..0000000 --- a/0106-Added-github-action-for-building.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 18 Dec 2020 21:38:43 +0100 -Subject: [PATCH] Added github action for building - -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/build-and-unittest.yaml | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - create mode 100644 .github/workflows/build-and-unittest.yaml - -diff --git a/.github/workflows/build-and-unittest.yaml b/.github/workflows/build-and-unittest.yaml -new file mode 100644 -index 00000000..2b13c65c ---- /dev/null -+++ b/.github/workflows/build-and-unittest.yaml -@@ -0,0 +1,17 @@ -+name: basic-build-and-ci -+on: [push] -+jobs: -+ build: -+ runs-on: ubuntu-latest -+ steps: -+ - uses: actions/checkout@v2 -+ - name: dependencies -+ run: > -+ sudo apt-get install --yes gcc -+ make perl-base pkg-config -+ libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev -+ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev -+ - name: build -+ run: make -O -j$(grep -c ^processor /proc/cpuinfo) -+ - name: test -+ run: make -O -j$(grep -c ^processor /proc/cpuinfo) test diff --git a/0107-github-workflow-use-zram-device-as-test-block-device.patch b/0107-github-workflow-use-zram-device-as-test-block-device.patch deleted file mode 100644 index 4a2d179..0000000 --- a/0107-github-workflow-use-zram-device-as-test-block-device.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 18 Dec 2020 22:18:20 +0100 -Subject: [PATCH] github workflow: use zram device as test block device - -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/build-and-unittest.yaml | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/.github/workflows/build-and-unittest.yaml b/.github/workflows/build-and-unittest.yaml -index 2b13c65c..ef55b8c1 100644 ---- a/.github/workflows/build-and-unittest.yaml -+++ b/.github/workflows/build-and-unittest.yaml -@@ -5,6 +5,14 @@ jobs: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 -+ - name: mpath -+ run: sudo modprobe dm_multipath -+ - name: zram -+ run: sudo modprobe zram num_devices=0 -+ - name: zram-device -+ run: echo ZRAM=$(sudo cat /sys/class/zram-control/hot_add) >> $GITHUB_ENV -+ - name: set-zram-size -+ run: echo 1G | sudo tee /sys/block/zram$ZRAM/disksize - - name: dependencies - run: > - sudo apt-get install --yes gcc -@@ -15,3 +23,7 @@ jobs: - run: make -O -j$(grep -c ^processor /proc/cpuinfo) - - name: test - run: make -O -j$(grep -c ^processor /proc/cpuinfo) test -+ - name: clean-nonroot-artifacts -+ run: rm -f tests/dmevents.out tests/directio.out -+ - name: root-test -+ run: sudo make DIO_TEST_DEV=/dev/zram$ZRAM test diff --git a/0108-github-workflow-use-explicit-Ubuntu-version.patch b/0108-github-workflow-use-explicit-Ubuntu-version.patch deleted file mode 100644 index f9b2336..0000000 --- a/0108-github-workflow-use-explicit-Ubuntu-version.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 18 Dec 2020 22:54:24 +0100 -Subject: [PATCH] github workflow: use explicit Ubuntu version - -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/build-and-unittest.yaml | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/.github/workflows/build-and-unittest.yaml b/.github/workflows/build-and-unittest.yaml -index ef55b8c1..577a14ac 100644 ---- a/.github/workflows/build-and-unittest.yaml -+++ b/.github/workflows/build-and-unittest.yaml -@@ -2,7 +2,7 @@ name: basic-build-and-ci - on: [push] - jobs: - build: -- runs-on: ubuntu-latest -+ runs-on: ubuntu-18.04 - steps: - - uses: actions/checkout@v2 - - name: mpath diff --git a/0109-github-workflow-add-valgrind-tests.patch b/0109-github-workflow-add-valgrind-tests.patch deleted file mode 100644 index fc5f15c..0000000 --- a/0109-github-workflow-add-valgrind-tests.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 18 Dec 2020 23:21:16 +0100 -Subject: [PATCH] github workflow: add valgrind tests - -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/build-and-unittest.yaml | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/.github/workflows/build-and-unittest.yaml b/.github/workflows/build-and-unittest.yaml -index 577a14ac..929f63a6 100644 ---- a/.github/workflows/build-and-unittest.yaml -+++ b/.github/workflows/build-and-unittest.yaml -@@ -16,13 +16,17 @@ jobs: - - name: dependencies - run: > - sudo apt-get install --yes gcc -- make perl-base pkg-config -+ make perl-base pkg-config valgrind - libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev - libudev-dev libjson-c-dev liburcu-dev libcmocka-dev - - name: build - run: make -O -j$(grep -c ^processor /proc/cpuinfo) - - name: test - run: make -O -j$(grep -c ^processor /proc/cpuinfo) test -+ - name: valgrind-test -+ run: make -O -j$(grep -c ^processor /proc/cpuinfo) valgrind-test -+ - name: valgrind-results -+ run: cat tests/*.vgr - - name: clean-nonroot-artifacts - run: rm -f tests/dmevents.out tests/directio.out - - name: root-test diff --git a/0110-github-workflow-run-apt-get-update.patch b/0110-github-workflow-run-apt-get-update.patch deleted file mode 100644 index f257ffc..0000000 --- a/0110-github-workflow-run-apt-get-update.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 18 Dec 2020 23:26:16 +0100 -Subject: [PATCH] github workflow: run apt-get update - -E: Failed to fetch http://azure.archive.ubuntu.com/ubuntu/pool/main/g/glibc/libc6-dbg_2.27-3ubuntu1.3_amd64.deb 404 Not Found [IP: 52.252.75.106 80] -E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing? -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/build-and-unittest.yaml | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/.github/workflows/build-and-unittest.yaml b/.github/workflows/build-and-unittest.yaml -index 929f63a6..389578be 100644 ---- a/.github/workflows/build-and-unittest.yaml -+++ b/.github/workflows/build-and-unittest.yaml -@@ -13,6 +13,8 @@ jobs: - run: echo ZRAM=$(sudo cat /sys/class/zram-control/hot_add) >> $GITHUB_ENV - - name: set-zram-size - run: echo 1G | sudo tee /sys/block/zram$ZRAM/disksize -+ - name: update -+ run: sudo apt-get update - - name: dependencies - run: > - sudo apt-get install --yes gcc diff --git a/0111-github-workflow-add-tests-with-gcc-10-and-clang.patch b/0111-github-workflow-add-tests-with-gcc-10-and-clang.patch deleted file mode 100644 index a328464..0000000 --- a/0111-github-workflow-add-tests-with-gcc-10-and-clang.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 18 Dec 2020 23:44:11 +0100 -Subject: [PATCH] github workflow: add tests with gcc 10 and clang - -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/build-and-unittest.yaml | 62 ++++++++++++++++++++++- - 1 file changed, 61 insertions(+), 1 deletion(-) - -diff --git a/.github/workflows/build-and-unittest.yaml b/.github/workflows/build-and-unittest.yaml -index 389578be..4173576f 100644 ---- a/.github/workflows/build-and-unittest.yaml -+++ b/.github/workflows/build-and-unittest.yaml -@@ -1,7 +1,7 @@ - name: basic-build-and-ci - on: [push] - jobs: -- build: -+ bionic: - runs-on: ubuntu-18.04 - steps: - - uses: actions/checkout@v2 -@@ -33,3 +33,63 @@ jobs: - run: rm -f tests/dmevents.out tests/directio.out - - name: root-test - run: sudo make DIO_TEST_DEV=/dev/zram$ZRAM test -+ focal-gcc10: -+ runs-on: ubuntu-20.04 -+ steps: -+ - uses: actions/checkout@v2 -+ - name: mpath -+ run: sudo modprobe dm_multipath -+ - name: brd -+ run: sudo modprobe brd rd_nr=1 rd_size=65536 -+ - name: update -+ run: sudo apt-get update -+ - name: dependencies -+ run: > -+ sudo apt-get install --yes gcc-10 -+ make perl-base pkg-config valgrind -+ libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev -+ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev -+ - name: set CC -+ run: echo CC=gcc-10 >> $GITHUB_ENV -+ - name: build -+ run: make -O -j$(grep -c ^processor /proc/cpuinfo) -+ - name: test -+ run: make -O -j$(grep -c ^processor /proc/cpuinfo) test -+ - name: valgrind-test -+ run: make -O -j$(grep -c ^processor /proc/cpuinfo) valgrind-test -+ - name: valgrind-results -+ run: cat tests/*.vgr -+ - name: clean-nonroot-artifacts -+ run: rm -f tests/dmevents.out tests/directio.out -+ - name: root-test -+ run: sudo make DIO_TEST_DEV=/dev/ram0 test -+ focal-clang10: -+ runs-on: ubuntu-20.04 -+ steps: -+ - uses: actions/checkout@v2 -+ - name: mpath -+ run: sudo modprobe dm_multipath -+ - name: brd -+ run: sudo modprobe brd rd_nr=1 rd_size=65536 -+ - name: update -+ run: sudo apt-get update -+ - name: dependencies -+ run: > -+ sudo apt-get install --yes clang -+ make perl-base pkg-config valgrind -+ libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev -+ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev -+ - name: set CC -+ run: echo CC=clang >> $GITHUB_ENV -+ - name: build -+ run: make -O -j$(grep -c ^processor /proc/cpuinfo) -+ - name: test -+ run: make -O -j$(grep -c ^processor /proc/cpuinfo) test -+ - name: valgrind-test -+ run: make -O -j$(grep -c ^processor /proc/cpuinfo) valgrind-test -+ - name: valgrind-results -+ run: cat tests/*.vgr -+ - name: clean-nonroot-artifacts -+ run: rm -f tests/dmevents.out tests/directio.out -+ - name: root-test -+ run: sudo make DIO_TEST_DEV=/dev/ram0 test diff --git a/0112-multipathd-Fix-multipathd-stopping-on-shutdown.patch b/0112-multipathd-Fix-multipathd-stopping-on-shutdown.patch deleted file mode 100644 index d18b363..0000000 --- a/0112-multipathd-Fix-multipathd-stopping-on-shutdown.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 18 Dec 2020 17:06:41 -0600 -Subject: [PATCH] multipathd: Fix multipathd stopping on shutdown - -According to man "systemd.special" - -"shutdown.target: ... Services that shall be terminated on system -shutdown shall add Conflicts= and Before= dependencies to this unit for -their service unit, which is implicitly done when -DefaultDependencies=yes is set (the default)." - -multipathd.service sets DefaultDependencies=no and includes the -Conflits= dependency, but not the Before= one. This can cause multipathd -to continue running past when it is supposed to during shutdown. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - multipathd/multipathd.service | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service -index ba24983e..7d547fa7 100644 ---- a/multipathd/multipathd.service -+++ b/multipathd/multipathd.service -@@ -2,7 +2,7 @@ - Description=Device-Mapper Multipath Device Controller - Wants=systemd-udev-trigger.service systemd-udev-settle.service - Before=iscsi.service iscsid.service lvm2-activation-early.service --Before=local-fs-pre.target blk-availability.service -+Before=local-fs-pre.target blk-availability.service shutdown.target - After=multipathd.socket systemd-udev-trigger.service systemd-udev-settle.service - DefaultDependencies=no - Conflicts=shutdown.target diff --git a/0113-libmultipath-use-3rd-digit-as-transport_id-for-expan.patch b/0113-libmultipath-use-3rd-digit-as-transport_id-for-expan.patch deleted file mode 100644 index a83d7bd..0000000 --- a/0113-libmultipath-use-3rd-digit-as-transport_id-for-expan.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 13 Nov 2020 22:34:41 +0100 -Subject: [PATCH] libmultipath: use 3rd digit as transport_id for expanders - -On SAS expanders, node id's have 3 digits. sysfs paths look like this: - -/sys/devices/pci0000:80/0000:80:02.0/0000:8b:00.0/0000:8c:09.0/0000:8f:00.0/host9/port-9:0/expander-9:0/port-9:0:13/expander-9:1/port-9:1:12/expander-9:2/port-9:2:4/end_device-9:2:4/target9:0:29/9:0:29:0/block/sdac - -In that case, we should use the last digit as transport id. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/discovery.c | 13 ++++++++++--- - 1 file changed, 10 insertions(+), 3 deletions(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index e818585a..6d74cc07 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -358,10 +358,17 @@ sysfs_get_tgt_nodename(struct path *pp, char *node) - if (value) { - tgtdev = udev_device_get_parent(parent); - while (tgtdev) { -+ char c; -+ - tgtname = udev_device_get_sysname(tgtdev); -- if (tgtname && sscanf(tgtname, "end_device-%d:%d", -- &host, &tgtid) == 2) -- break; -+ if (tgtname) { -+ if (sscanf(tgtname, "end_device-%d:%d:%d%c", -+ &host, &channel, &tgtid, &c) == 3) -+ break; -+ if (sscanf(tgtname, "end_device-%d:%d%c", -+ &host, &tgtid, &c) == 2) -+ break; -+ } - tgtdev = udev_device_get_parent(tgtdev); - tgtid = -1; - } diff --git a/0114-libmultipath-sysfs_set_nexus_loss_tmo-support-SAS-ex.patch b/0114-libmultipath-sysfs_set_nexus_loss_tmo-support-SAS-ex.patch deleted file mode 100644 index 1eccb08..0000000 --- a/0114-libmultipath-sysfs_set_nexus_loss_tmo-support-SAS-ex.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 13 Nov 2020 22:38:21 +0100 -Subject: [PATCH] libmultipath: sysfs_set_nexus_loss_tmo(): support SAS - expanders - -With SAS expanders, SAS node names have 3 digits. libmultipath -would fail to discover the sas_end_device matching a given SCSI -target in this case. Fix it. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/discovery.c | 24 +++++++++++++++++++----- - 1 file changed, 19 insertions(+), 5 deletions(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 6d74cc07..921025d4 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -789,14 +789,28 @@ sysfs_set_session_tmo(struct multipath *mpp, struct path *pp) - static void - sysfs_set_nexus_loss_tmo(struct multipath *mpp, struct path *pp) - { -- struct udev_device *sas_dev = NULL; -- char end_dev_id[64]; -+ struct udev_device *parent, *sas_dev = NULL; -+ const char *end_dev_id = NULL; - char value[11]; -+ static const char ed_str[] = "end_device-"; - -- if (mpp->dev_loss == DEV_LOSS_TMO_UNSET) -+ if (!pp->udev || mpp->dev_loss == DEV_LOSS_TMO_UNSET) - return; -- sprintf(end_dev_id, "end_device-%d:%d", -- pp->sg_id.host_no, pp->sg_id.transport_id); -+ -+ for (parent = udev_device_get_parent(pp->udev); -+ parent; -+ parent = udev_device_get_parent(parent)) { -+ const char *ed = udev_device_get_sysname(parent); -+ -+ if (!strncmp(ed, ed_str, sizeof(ed_str) - 1)) { -+ end_dev_id = ed; -+ break; -+ } -+ } -+ if (!end_dev_id) { -+ condlog(1, "%s: No SAS end device", pp->dev); -+ return; -+ } - sas_dev = udev_device_new_from_subsystem_sysname(udev, - "sas_end_device", end_dev_id); - if (!sas_dev) { diff --git a/0115-multipathd-add-code-to-initalize-unwinder.patch b/0115-multipathd-add-code-to-initalize-unwinder.patch deleted file mode 100644 index b2ccb84..0000000 --- a/0115-multipathd-add-code-to-initalize-unwinder.patch +++ /dev/null @@ -1,131 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 17 Dec 2020 16:50:06 +0100 -Subject: [PATCH] multipathd: add code to initalize unwinder - -glibc's implementation of pthread_cancel() loads symbols from -libgcc_s.so using dlopen() when pthread_cancel() is called -for the first time. This happens even with LD_BIND_NOW=1. -This may imply the need for file system access when a thread is -cancelled, which in the case of multipath-tools might be in a -dangerous situation where multipathd must avoid blocking. - -Call load_unwinder() during startup to make sure the dynamic -linker has all necessary symbols resolved early on. - -This implementation simply creates a dummy thread and cancels -it. This way all necessary symbols for thread cancellation -will be loaded, no matter what the C library needs to implement -cancellation. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipathd/Makefile | 2 +- - multipathd/init_unwinder.c | 34 ++++++++++++++++++++++++++++++++++ - multipathd/init_unwinder.h | 21 +++++++++++++++++++++ - multipathd/main.c | 2 ++ - 4 files changed, 58 insertions(+), 1 deletion(-) - create mode 100644 multipathd/init_unwinder.c - create mode 100644 multipathd/init_unwinder.h - -diff --git a/multipathd/Makefile b/multipathd/Makefile -index 632b82b1..d053c1ed 100644 ---- a/multipathd/Makefile -+++ b/multipathd/Makefile -@@ -30,7 +30,7 @@ ifeq ($(ENABLE_DMEVENTS_POLL),0) - endif - - OBJS = main.o pidfile.o uxlsnr.o uxclnt.o cli.o cli_handlers.o waiter.o \ -- dmevents.o -+ dmevents.o init_unwinder.o - - EXEC = multipathd - -diff --git a/multipathd/init_unwinder.c b/multipathd/init_unwinder.c -new file mode 100644 -index 00000000..14467f3d ---- /dev/null -+++ b/multipathd/init_unwinder.c -@@ -0,0 +1,34 @@ -+#include -+#include -+#include "init_unwinder.h" -+ -+static pthread_mutex_t dummy_mtx = PTHREAD_MUTEX_INITIALIZER; -+static pthread_cond_t dummy_cond = PTHREAD_COND_INITIALIZER; -+ -+static void *dummy_thread(void *arg __attribute__((unused))) -+{ -+ pthread_mutex_lock(&dummy_mtx); -+ pthread_cond_broadcast(&dummy_cond); -+ pthread_mutex_unlock(&dummy_mtx); -+ pause(); -+ return NULL; -+} -+ -+int init_unwinder(void) -+{ -+ pthread_t dummy; -+ int rc; -+ -+ pthread_mutex_lock(&dummy_mtx); -+ -+ rc = pthread_create(&dummy, NULL, dummy_thread, NULL); -+ if (rc != 0) { -+ pthread_mutex_unlock(&dummy_mtx); -+ return rc; -+ } -+ -+ pthread_cond_wait(&dummy_cond, &dummy_mtx); -+ pthread_mutex_unlock(&dummy_mtx); -+ -+ return pthread_cancel(dummy); -+} -diff --git a/multipathd/init_unwinder.h b/multipathd/init_unwinder.h -new file mode 100644 -index 00000000..ada09f82 ---- /dev/null -+++ b/multipathd/init_unwinder.h -@@ -0,0 +1,21 @@ -+#ifndef _INIT_UNWINDER_H -+#define _INIT_UNWINDER_H 1 -+ -+/* -+ * init_unwinder(): make sure unwinder symbols are loaded -+ * -+ * libc's implementation of pthread_cancel() loads symbols from -+ * libgcc_s.so using dlopen() when pthread_cancel() is called -+ * for the first time. This happens even with LD_BIND_NOW=1. -+ * This may imply the need for file system access when a thread is -+ * cancelled, which in the case of multipath-tools might be in a -+ * dangerous situation where multipathd must avoid blocking. -+ * -+ * Call load_unwinder() during startup to make sure the dynamic -+ * linker has all necessary symbols resolved early on. -+ * -+ * Return: 0 if successful, an error number otherwise. -+ */ -+int init_unwinder(void); -+ -+#endif -diff --git a/multipathd/main.c b/multipathd/main.c -index 99a89a69..6f851ae8 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -83,6 +83,7 @@ - #include "wwids.h" - #include "foreign.h" - #include "../third-party/valgrind/drd.h" -+#include "init_unwinder.h" - - #define FILE_NAME_SIZE 256 - #define CMDSIZE 160 -@@ -3041,6 +3042,7 @@ child (__attribute__((unused)) void *param) - enum daemon_status state; - int exit_code = 1; - -+ init_unwinder(); - mlockall(MCL_CURRENT | MCL_FUTURE); - signal_init(); - mp_rcu_data = setup_rcu(); diff --git a/0116-libmultipath-check-if-adopt_path-really-added-curren.patch b/0116-libmultipath-check-if-adopt_path-really-added-curren.patch deleted file mode 100644 index 195e9ed..0000000 --- a/0116-libmultipath-check-if-adopt_path-really-added-curren.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 2 Feb 2021 11:12:21 +0100 -Subject: [PATCH] libmultipath: check if adopt_path() really added current path - -The description of 2d32d6f ("libmultipath: adopt_paths(): don't bail out on -single path failure") said "we need to check after successful call to -adopt_paths() if that specific path had been actually added, and fail in the -caller otherwise". But the commit failed to actually implement this check. -Instead, it just checked if the path was member of the pathvec, which will -almost always be the case. - -Fix it by checking what actually needs to be checked, membership of the -path to be added in mpp->paths. - -Fixes: 2d32d6f ("libmultipath: adopt_paths(): don't bail out on single path failure") - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/structs_vec.c | 4 ++-- - multipathd/main.c | 4 ++-- - 2 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c -index f7f45f11..47b1d03e 100644 ---- a/libmultipath/structs_vec.c -+++ b/libmultipath/structs_vec.c -@@ -707,8 +707,8 @@ struct multipath *add_map_with_path(struct vectors *vecs, struct path *pp, - goto out; - mpp->size = pp->size; - -- if (adopt_paths(vecs->pathvec, mpp) || -- find_slot(vecs->pathvec, pp) == -1) -+ if (adopt_paths(vecs->pathvec, mpp) || pp->mpp != mpp || -+ find_slot(mpp->paths, pp) == -1) - goto out; - - if (add_vec) { -diff --git a/multipathd/main.c b/multipathd/main.c -index 6f851ae8..43d77688 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -1008,8 +1008,8 @@ rescan: - if (mpp) { - condlog(4,"%s: adopting all paths for path %s", - mpp->alias, pp->dev); -- if (adopt_paths(vecs->pathvec, mpp) || -- find_slot(vecs->pathvec, pp) == -1) -+ if (adopt_paths(vecs->pathvec, mpp) || pp->mpp != mpp || -+ find_slot(mpp->paths, pp) == -1) - goto fail; /* leave path added to pathvec */ - - verify_paths(mpp); diff --git a/0117-multipathd-ev_add_path-fail-if-add_map_with_path-fai.patch b/0117-multipathd-ev_add_path-fail-if-add_map_with_path-fai.patch deleted file mode 100644 index 1bff1e5..0000000 --- a/0117-multipathd-ev_add_path-fail-if-add_map_with_path-fai.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 1 Feb 2021 13:10:46 +0100 -Subject: [PATCH] multipathd: ev_add_path: fail if add_map_with_path() fails - -If start_waiter was set before and the "rescan" label was used, -we may try to set up an empty/invalid map. -Always fail if add_map_with_path() isn't successful. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 43d77688..425492a9 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -1028,7 +1028,7 @@ rescan: - */ - start_waiter = 1; - } -- if (!start_waiter) -+ else - goto fail; /* leave path added to pathvec */ - } - diff --git a/0118-libmultipath-check-return-value-of-udev_device_get_d.patch b/0118-libmultipath-check-return-value-of-udev_device_get_d.patch deleted file mode 100644 index 711e00f..0000000 --- a/0118-libmultipath-check-return-value-of-udev_device_get_d.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 2 Feb 2021 15:18:33 +0100 -Subject: [PATCH] libmultipath: check return value of udev_device_get_devnum() - -udev_device_get_devnum() may fail, in which case it returns -makedev(0, 0). - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/discovery.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 921025d4..15cf6413 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -1659,6 +1659,9 @@ common_sysfs_pathinfo (struct path * pp) - return PATHINFO_FAILED; - } - devt = udev_device_get_devnum(pp->udev); -+ if (major(devt) == 0 && minor(devt) == 0) -+ return PATHINFO_FAILED; -+ - snprintf(pp->dev_t, BLK_DEV_SIZE, "%d:%d", major(devt), minor(devt)); - - condlog(4, "%s: dev_t = %s", pp->dev, pp->dev_t); diff --git a/0119-pathinfo-call-filter_property-after-sysfs_pathinfo.patch b/0119-pathinfo-call-filter_property-after-sysfs_pathinfo.patch deleted file mode 100644 index 660ba85..0000000 --- a/0119-pathinfo-call-filter_property-after-sysfs_pathinfo.patch +++ /dev/null @@ -1,278 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 2 Feb 2021 17:07:37 +0100 -Subject: [PATCH] pathinfo: call filter_property() after sysfs_pathinfo() - -The of filter_property() depends on the value of pp->uid_attribute. -This may in turn depend on pp->hwe, which is initialized in -sysfs_pathinfo(). To obtain consistent results from pathinfo(), -make sure uid_attribute is correctly set before calling filter_property(). - -filter_property() is now called from pathinfo() with properly set -uid_attribute, thus we don't need to call it from is_path_valid() any more. - -Thes changes require modifications to the unit tests. The is_path_valid() -test now wouldn't need to test filter_property() any more, because -is_path_valid() calls filter_property() no more. But that doesn't feel -right. Instead, test_filter_property() is modified to test the behavior -with the filter_property() test called indirectly from pathinfo(). - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/discovery.c | 21 +++++++++- - libmultipath/valid.c | 4 -- - tests/Makefile | 2 +- - tests/test-lib.c | 5 ++- - tests/valid.c | 91 ++++++++++++++++++++++++++++++++++++---- - 5 files changed, 105 insertions(+), 18 deletions(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 15cf6413..febcd0ae 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -2247,9 +2247,17 @@ int pathinfo(struct path *pp, struct config *conf, int mask) - condlog(4, "%s: hidden", pp->dev); - return PATHINFO_SKIPPED; - } -- if (is_claimed_by_foreign(pp->udev) || -- filter_property(conf, pp->udev, 4, pp->uid_attribute) > 0) -+ -+ if (is_claimed_by_foreign(pp->udev)) - return PATHINFO_SKIPPED; -+ -+ /* -+ * uid_attribute is required for filter_property below, -+ * and needs access to pp->hwe. -+ */ -+ if (!(mask & DI_SYSFS) && !pp->uid_attribute && -+ VECTOR_SIZE(pp->hwe) == 0) -+ mask |= DI_SYSFS; - } - - if (strlen(pp->dev) != 0 && filter_devnode(conf->blist_devnode, -@@ -2287,6 +2295,15 @@ int pathinfo(struct path *pp, struct config *conf, int mask) - } - } - -+ if (pp->udev) { -+ /* uid_attribute is required for filter_property() */ -+ if (!pp->uid_attribute) -+ select_getuid(conf, pp); -+ -+ if (filter_property(conf, pp->udev, 4, pp->uid_attribute) > 0) -+ return PATHINFO_SKIPPED; -+ } -+ - if (mask & DI_BLACKLIST && mask & DI_SYSFS) { - if (filter_device(conf->blist_device, conf->elist_device, - pp->vendor_id, pp->product_id, pp->dev) > 0 || -diff --git a/libmultipath/valid.c b/libmultipath/valid.c -index 456b1f6e..a6aa9215 100644 ---- a/libmultipath/valid.c -+++ b/libmultipath/valid.c -@@ -89,10 +89,6 @@ is_path_valid(const char *name, struct config *conf, struct path *pp, - if (pp->wwid[0] == '\0') - return PATH_IS_NOT_VALID; - -- if (pp->udev && pp->uid_attribute && -- filter_property(conf, pp->udev, 3, pp->uid_attribute) > 0) -- return PATH_IS_NOT_VALID; -- - r = is_failed_wwid(pp->wwid); - if (r != WWID_IS_NOT_FAILED) { - if (r == WWID_IS_FAILED) -diff --git a/tests/Makefile b/tests/Makefile -index 50673fae..11ca1be5 100644 ---- a/tests/Makefile -+++ b/tests/Makefile -@@ -54,7 +54,7 @@ vpd-test_OBJDEPS := ../libmultipath/discovery.o - vpd-test_LIBDEPS := -ludev -lpthread -ldl - alias-test_TESTDEPS := test-log.o - alias-test_LIBDEPS := -lpthread -ldl --valid-test_OBJDEPS := ../libmultipath/valid.o -+valid-test_OBJDEPS := ../libmultipath/valid.o ../libmultipath/discovery.o - valid-test_LIBDEPS := -ludev -lpthread -ldl - devt-test_LIBDEPS := -ludev - mpathvalid-test_LIBDEPS := -ludev -lpthread -ldl -diff --git a/tests/test-lib.c b/tests/test-lib.c -index e7663f9a..960a7665 100644 ---- a/tests/test-lib.c -+++ b/tests/test-lib.c -@@ -257,6 +257,9 @@ void mock_pathinfo(int mask, const struct mocked_path *mp) - } else - will_return(__wrap_udev_device_get_sysattr_value, "0"); - -+ if (mask & DI_SYSFS) -+ mock_sysfs_pathinfo(mp); -+ - /* filter_property */ - will_return(__wrap_udev_device_get_sysname, mp->devnode); - if (mp->flags & BL_BY_PROPERTY) { -@@ -265,8 +268,6 @@ void mock_pathinfo(int mask, const struct mocked_path *mp) - } else - will_return(__wrap_udev_list_entry_get_name, - "SCSI_IDENT_LUN_NAA_EXT"); -- if (mask & DI_SYSFS) -- mock_sysfs_pathinfo(mp); - - if (mp->flags & BL_BY_DEVICE && - (mask & DI_BLACKLIST && mask & DI_SYSFS)) -diff --git a/tests/valid.c b/tests/valid.c -index 693c72c5..8ec803e8 100644 ---- a/tests/valid.c -+++ b/tests/valid.c -@@ -25,13 +25,18 @@ - #include - #include - #include -+#include -+ - #include "globals.c" - #include "util.h" - #include "discovery.h" - #include "wwids.h" - #include "blacklist.h" -+#include "foreign.h" - #include "valid.h" - -+#define PATHINFO_REAL 9999 -+ - int test_fd; - struct udev_device { - int unused; -@@ -78,12 +83,66 @@ struct udev_device *__wrap_udev_device_new_from_subsystem_sysname(struct udev *u - return NULL; - } - -+/* For the "hidden" check in pathinfo() */ -+const char *__wrap_udev_device_get_sysattr_value(struct udev_device *udev_device, -+ const char *sysattr) -+{ -+ check_expected(sysattr); -+ return mock_ptr_type(char *); -+} -+ -+/* For pathinfo() -> is_claimed_by_foreign() */ -+int __wrap_add_foreign(struct udev_device *udev_device) -+{ -+ return mock_type(int); -+} -+ -+/* called from pathinfo() */ -+int __wrap_filter_devnode(struct config *conf, const struct _vector *elist, -+ const char *vendor, const char * product, const char *dev) -+{ -+ return mock_type(int); -+} -+ -+/* called from pathinfo() */ -+int __wrap_filter_device(const struct _vector *blist, const struct _vector *elist, -+ const char *vendor, const char * product, const char *dev) -+{ -+ return mock_type(int); -+} -+ -+/* for common_sysfs_pathinfo() */ -+dev_t __wrap_udev_device_get_devnum(struct udev_device *ud) -+{ -+ return mock_type(dev_t); -+} -+ -+/* for common_sysfs_pathinfo() */ -+int __wrap_sysfs_get_size(struct path *pp, unsigned long long * size) -+{ -+ return mock_type(int); -+} -+ -+/* called in pathinfo() before filter_property() */ -+int __wrap_select_getuid(struct config *conf, struct path *pp) -+{ -+ pp->uid_attribute = mock_ptr_type(char *); -+ return 0; -+} -+ -+int __real_pathinfo(struct path *pp, struct config *conf, int mask); -+ - int __wrap_pathinfo(struct path *pp, struct config *conf, int mask) - { - int ret = mock_type(int); -+ - assert_string_equal(pp->dev, mock_ptr_type(char *)); - assert_int_equal(mask, DI_SYSFS | DI_WWID | DI_BLACKLIST); -- if (ret == PATHINFO_OK) { -+ if (ret == PATHINFO_REAL) { -+ /* for test_filter_property() */ -+ ret = __real_pathinfo(pp, conf, mask); -+ return ret; -+ } else if (ret == PATHINFO_OK) { - pp->uid_attribute = "ID_TEST"; - strlcpy(pp->wwid, mock_ptr_type(char *), WWID_SIZE); - } else -@@ -128,6 +187,7 @@ enum { - STAGE_IS_MULTIPATHED, - STAGE_CHECK_MULTIPATHD, - STAGE_GET_UDEV_DEVICE, -+ STAGE_PATHINFO_REAL, - STAGE_PATHINFO, - STAGE_FILTER_PROPERTY, - STAGE_IS_FAILED, -@@ -167,12 +227,25 @@ static void setup_passing(char *name, char *wwid, unsigned int check_multipathd, - name); - if (stage == STAGE_GET_UDEV_DEVICE) - return; -+ if (stage == STAGE_PATHINFO_REAL) { -+ /* special case for test_filter_property() */ -+ will_return(__wrap_pathinfo, PATHINFO_REAL); -+ will_return(__wrap_pathinfo, name); -+ expect_string(__wrap_udev_device_get_sysattr_value, -+ sysattr, "hidden"); -+ will_return(__wrap_udev_device_get_sysattr_value, NULL); -+ will_return(__wrap_add_foreign, FOREIGN_IGNORED); -+ will_return(__wrap_filter_devnode, MATCH_NOTHING); -+ will_return(__wrap_udev_device_get_devnum, makedev(259, 0)); -+ will_return(__wrap_sysfs_get_size, 0); -+ will_return(__wrap_select_getuid, "ID_TEST"); -+ return; -+ } - will_return(__wrap_pathinfo, PATHINFO_OK); - will_return(__wrap_pathinfo, name); - will_return(__wrap_pathinfo, wwid); - if (stage == STAGE_PATHINFO) - return; -- will_return(__wrap_filter_property, MATCH_PROPERTY_BLIST_EXCEPT); - if (stage == STAGE_FILTER_PROPERTY) - return; - will_return(__wrap_is_failed_wwid, WWID_IS_NOT_FAILED); -@@ -317,24 +390,24 @@ static void test_filter_property(void **state) - /* test blacklist property */ - memset(&pp, 0, sizeof(pp)); - conf.find_multipaths = FIND_MULTIPATHS_STRICT; -- setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_PATHINFO); -+ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_PATHINFO_REAL); - will_return(__wrap_filter_property, MATCH_PROPERTY_BLIST); - assert_int_equal(is_path_valid(name, &conf, &pp, false), - PATH_IS_NOT_VALID); - assert_ptr_equal(pp.udev, &test_udev); -- assert_string_equal(pp.wwid, wwid); -+ - /* test missing property */ - memset(&pp, 0, sizeof(pp)); -- setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_PATHINFO); -+ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_PATHINFO_REAL); - will_return(__wrap_filter_property, MATCH_PROPERTY_BLIST_MISSING); - assert_int_equal(is_path_valid(name, &conf, &pp, false), - PATH_IS_NOT_VALID); -- /* test MATCH_NOTHING fail on is_failed_wwid */ -+ -+ /* test MATCH_NOTHING fail on filter_device */ - memset(&pp, 0, sizeof(pp)); -- setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_PATHINFO); -+ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_PATHINFO_REAL); - will_return(__wrap_filter_property, MATCH_NOTHING); -- will_return(__wrap_is_failed_wwid, WWID_IS_FAILED); -- will_return(__wrap_is_failed_wwid, wwid); -+ will_return(__wrap_filter_device, MATCH_DEVICE_BLIST); - assert_int_equal(is_path_valid(name, &conf, &pp, false), - PATH_IS_NOT_VALID); - } diff --git a/0120-libmultipath-pathinfo-call-filter_property-only-with.patch b/0120-libmultipath-pathinfo-call-filter_property-only-with.patch deleted file mode 100644 index 62c930b..0000000 --- a/0120-libmultipath-pathinfo-call-filter_property-only-with.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 2 Feb 2021 19:55:28 +0100 -Subject: [PATCH] libmultipath: pathinfo: call filter_property only with - DI_BLACKLIST - -With the previous change to call filter_property() after sysfs_pathinfo(), -it can't happen any more that filter_property() is called from pathinfo -with uid_attribute not set. This may cause pathinfo() to return failure -in some cases where it should actually proceed (e.g. when called from -"multipath -m" -> get_refwwid(). Therefore, don't call filter_property() -any more unless DI_BLACKLIST is set. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/discovery.c | 16 ++++++---------- - tests/test-lib.c | 17 +++++++++-------- - 2 files changed, 15 insertions(+), 18 deletions(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index febcd0ae..9be94cd1 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -2255,8 +2255,8 @@ int pathinfo(struct path *pp, struct config *conf, int mask) - * uid_attribute is required for filter_property below, - * and needs access to pp->hwe. - */ -- if (!(mask & DI_SYSFS) && !pp->uid_attribute && -- VECTOR_SIZE(pp->hwe) == 0) -+ if (!(mask & DI_SYSFS) && (mask & DI_BLACKLIST) && -+ !pp->uid_attribute && VECTOR_SIZE(pp->hwe) == 0) - mask |= DI_SYSFS; - } - -@@ -2295,17 +2295,13 @@ int pathinfo(struct path *pp, struct config *conf, int mask) - } - } - -- if (pp->udev) { -+ if (mask & DI_BLACKLIST && mask & DI_SYSFS) { - /* uid_attribute is required for filter_property() */ -- if (!pp->uid_attribute) -+ if (pp->udev && !pp->uid_attribute) - select_getuid(conf, pp); - -- if (filter_property(conf, pp->udev, 4, pp->uid_attribute) > 0) -- return PATHINFO_SKIPPED; -- } -- -- if (mask & DI_BLACKLIST && mask & DI_SYSFS) { -- if (filter_device(conf->blist_device, conf->elist_device, -+ if (filter_property(conf, pp->udev, 4, pp->uid_attribute) > 0 || -+ filter_device(conf->blist_device, conf->elist_device, - pp->vendor_id, pp->product_id, pp->dev) > 0 || - filter_protocol(conf->blist_protocol, conf->elist_protocol, - pp) > 0) -diff --git a/tests/test-lib.c b/tests/test-lib.c -index 960a7665..f5542ed0 100644 ---- a/tests/test-lib.c -+++ b/tests/test-lib.c -@@ -260,14 +260,15 @@ void mock_pathinfo(int mask, const struct mocked_path *mp) - if (mask & DI_SYSFS) - mock_sysfs_pathinfo(mp); - -- /* filter_property */ -- will_return(__wrap_udev_device_get_sysname, mp->devnode); -- if (mp->flags & BL_BY_PROPERTY) { -- will_return(__wrap_udev_list_entry_get_name, "BAZ"); -- return; -- } else -- will_return(__wrap_udev_list_entry_get_name, -- "SCSI_IDENT_LUN_NAA_EXT"); -+ if (mask & DI_BLACKLIST) { -+ will_return(__wrap_udev_device_get_sysname, mp->devnode); -+ if (mp->flags & BL_BY_PROPERTY) { -+ will_return(__wrap_udev_list_entry_get_name, "BAZ"); -+ return; -+ } else -+ will_return(__wrap_udev_list_entry_get_name, -+ "SCSI_IDENT_LUN_NAA_EXT"); -+ } - - if (mp->flags & BL_BY_DEVICE && - (mask & DI_BLACKLIST && mask & DI_SYSFS)) diff --git a/0121-multipath-w-allow-removing-blacklisted-paths.patch b/0121-multipath-w-allow-removing-blacklisted-paths.patch deleted file mode 100644 index 6b3e4f7..0000000 --- a/0121-multipath-w-allow-removing-blacklisted-paths.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 2 Feb 2021 21:54:37 +0100 -Subject: [PATCH] multipath -w: allow removing blacklisted paths - -multipath should allow removing WWIDs of paths even if they -are blacklisted. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 3263bb01..598efe05 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -1441,7 +1441,7 @@ static int _get_refwwid(enum mpath_cmds cmd, const char *dev, - return ret; - } - } -- if (pp->udev && pp->uid_attribute && -+ if (flags & DI_BLACKLIST && - filter_property(conf, pp->udev, 3, pp->uid_attribute) > 0) - return PATHINFO_SKIPPED; - refwwid = pp->wwid; -@@ -1466,7 +1466,7 @@ static int _get_refwwid(enum mpath_cmds cmd, const char *dev, - refwwid = dev; - } - -- if (refwwid && strlen(refwwid) && -+ if (flags & DI_BLACKLIST && refwwid && strlen(refwwid) && - filter_wwid(conf->blist_wwid, conf->elist_wwid, refwwid, - NULL) > 0) - return PATHINFO_SKIPPED; diff --git a/0122-libmultipath-fix-use-after-free-in-uev_add_path.patch b/0122-libmultipath-fix-use-after-free-in-uev_add_path.patch deleted file mode 100644 index 921a0cc..0000000 --- a/0122-libmultipath-fix-use-after-free-in-uev_add_path.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 8 Feb 2021 23:19:26 -0600 -Subject: [PATCH] libmultipath: fix use-after-free in uev_add_path - -if ev_remove_path() returns success the path has very likely been -deleted. However, if pathinfo() returned something besides PATHINFO_OK, -but ev_remove_path() succeeded, uev_add_path() was still accessing the -the path afterwards, which would likely cause a use-after-free error. -Insted, uev_add_path() should only continue to access the path if -ev_remove_path() didn't succeed. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - multipathd/main.c | 15 +++++++-------- - 1 file changed, 7 insertions(+), 8 deletions(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 425492a9..19679848 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -890,13 +890,7 @@ uev_add_path (struct uevent *uev, struct vectors * vecs, int need_do_map) - */ - pp->mpp = prev_mpp; - ret = ev_remove_path(pp, vecs, true); -- if (r == PATHINFO_OK && !ret) -- /* -- * Path successfully freed, move on to -- * "new path" code path below -- */ -- pp = NULL; -- else { -+ if (ret != 0) { - /* - * Failure in ev_remove_path will keep - * path in pathvec in INIT_REMOVED state -@@ -907,7 +901,12 @@ uev_add_path (struct uevent *uev, struct vectors * vecs, int need_do_map) - dm_fail_path(pp->mpp->alias, pp->dev_t); - condlog(1, "%s: failed to re-add path still mapped in %s", - pp->dev, pp->mpp->alias); -- } -+ } else if (r == PATHINFO_OK) -+ /* -+ * Path successfully freed, move on to -+ * "new path" code path below -+ */ -+ pp = NULL; - } else if (r == PATHINFO_SKIPPED) { - condlog(3, "%s: remove blacklisted path", - uev->kernel); diff --git a/0123-multipath-tools-tests-fix-stringop-overflow-build-er.patch b/0123-multipath-tools-tests-fix-stringop-overflow-build-er.patch deleted file mode 100644 index bb199f5..0000000 --- a/0123-multipath-tools-tests-fix-stringop-overflow-build-er.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 10 Feb 2021 13:15:17 +0100 -Subject: [PATCH] multipath-tools tests: fix stringop-overflow build errors - with gcc 11 - -gcc-11 throws an error compiling alias.c and dmevents.c: - -In file included from ../libmultipath/checkers.h:4, - from ../libmultipath/prio.h:7, - from ../libmultipath/structs.h:8, - from dmevents.c:29: -../multipathd/dmevents.c: In function 'dmevent_loop': -../multipathd/dmevents.c:357:17: error: '__sigsetjmp' accessing 200 bytes in a region of size 72 [-Werror=stringop-overflow=] - 357 | pthread_cleanup_push(cleanup_lock, &waiter->vecs->lock); - | ^~~~~~~~~~~~~~~~~~~~ -../multipathd/dmevents.c:357:17: note: referencing argument 1 of type 'struct __jmp_buf_tag *' -/usr/include/pthread.h:734:12: note: in a call to function '__sigsetjmp' - 734 | extern int __sigsetjmp (struct __jmp_buf_tag *__env, int __savemask) __THROWNL; - | ^~~~~~~~~~~ - -The reason seems to be a mismatch between the __sigsetjmp() prototype -in and . The error is encountered iUntil this is fixed in the toolchain, -work around it by including before . - -Signed-off-by: Benjamin Marzinski ---- - tests/alias.c | 1 + - tests/dmevents.c | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/tests/alias.c b/tests/alias.c -index 0311faa6..5e0bfea3 100644 ---- a/tests/alias.c -+++ b/tests/alias.c -@@ -1,3 +1,4 @@ -+#include - #include - #include - #include -diff --git a/tests/dmevents.c b/tests/dmevents.c -index b7c5122b..29eaa6db 100644 ---- a/tests/dmevents.c -+++ b/tests/dmevents.c -@@ -16,6 +16,7 @@ - * - */ - -+#include - #include - #include - #include diff --git a/0124-libmultipath-cleanup-code-to-strip-wwid-trailing-spa.patch b/0124-libmultipath-cleanup-code-to-strip-wwid-trailing-spa.patch deleted file mode 100644 index 0d4a25e..0000000 --- a/0124-libmultipath-cleanup-code-to-strip-wwid-trailing-spa.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 24 Feb 2021 00:33:20 -0600 -Subject: [PATCH] libmultipath: cleanup code to strip wwid trailing spaces - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/discovery.c | 11 ++++------- - 1 file changed, 4 insertions(+), 7 deletions(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 9be94cd1..3a06f319 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -2152,11 +2152,11 @@ int - get_uid (struct path * pp, int path_state, struct udev_device *udev, - int allow_fallback) - { -- char *c; - const char *origin = "unknown"; - ssize_t len = 0; - struct config *conf; - int used_fallback = 0; -+ size_t i; - - if (!pp->uid_attribute && !pp->getuid) { - conf = get_multipath_config(); -@@ -2210,12 +2210,9 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev, - return 1; - } else { - /* Strip any trailing blanks */ -- c = strchr(pp->wwid, '\0'); -- c--; -- while (c && c >= pp->wwid && *c == ' ') { -- *c = '\0'; -- c--; -- } -+ for (i = strlen(pp->wwid); i > 0 && pp->wwid[i-1] == ' '; i--); -+ /* no-op */ -+ pp->wwid[i] = '\0'; - } - condlog((used_fallback)? 1 : 3, "%s: uid = %s (%s)", pp->dev, - *pp->wwid == '\0' ? "" : pp->wwid, origin); diff --git a/0125-libmultipath-cleanup-uid_attribute-checking-code.patch b/0125-libmultipath-cleanup-uid_attribute-checking-code.patch deleted file mode 100644 index 56e473d..0000000 --- a/0125-libmultipath-cleanup-uid_attribute-checking-code.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 24 Feb 2021 00:33:21 -0600 -Subject: [PATCH] libmultipath: cleanup uid_attribute checking code - -In get_uid(), if pp->getuid is NULL, multipath will check the -pp->uid_attribute to get the wwid. If pp->uid_attribute is NULL, -nothing will happen in that block of code, because both udev_available -and has_uid_fallback() are false if pp->uid_attribute is NULL. So -instead of multiple checks if pp->uid_attribute is NULL, just check once -for the code block. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/discovery.c | 17 ++++++++--------- - 1 file changed, 8 insertions(+), 9 deletions(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 3a06f319..40727fa3 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -2183,22 +2183,21 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev, - } else - len = strlen(pp->wwid); - origin = "callout"; -- } else { -- bool valid_uid_attr = pp->uid_attribute -- && *pp->uid_attribute; -- bool empty_uid_attr = pp->uid_attribute -- && !*pp->uid_attribute; -- bool udev_available = udev && valid_uid_attr; -+ } else if (pp->uid_attribute) { -+ /* if the uid_attribute is an empty string skip udev checking */ -+ bool check_uid_attr = udev && *pp->uid_attribute; - -- if (udev_available) { -+ if (check_uid_attr) { - len = get_udev_uid(pp, pp->uid_attribute, udev); - origin = "udev"; - if (len == 0) - condlog(1, "%s: empty udev uid", pp->dev); - } -- if ((!udev_available || (len <= 0 && allow_fallback)) -+ if ((!check_uid_attr || (len <= 0 && allow_fallback)) - && has_uid_fallback(pp)) { -- if (!udev || !empty_uid_attr) -+ /* if udev wasn't set or we failed in get_udev_uid() -+ * log at a higher priority */ -+ if (!udev || check_uid_attr) - used_fallback = 1; - len = uid_fallback(pp, path_state, &origin); - } diff --git a/0126-multipathd-add-recheck_wwid-option-to-verify-the-pat.patch b/0126-multipathd-add-recheck_wwid-option-to-verify-the-pat.patch deleted file mode 100644 index 27bc16c..0000000 --- a/0126-multipathd-add-recheck_wwid-option-to-verify-the-pat.patch +++ /dev/null @@ -1,453 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 24 Feb 2021 00:33:22 -0600 -Subject: [PATCH] multipathd: add recheck_wwid option to verify the path wwid - -There are cases where the wwid of a path changes due to LUN remapping -without triggering uevent for the changed path. Multipathd has no method -for trying to catch these cases, and corruption has resulted because of -it. - -In order to have a better chance at catching these cases, multipath now -has a recheck_wwid option. If this is set to "yes", when a failed path -has become active again, multipathd will recheck its wwid. If multipathd -notices that a path's wwid has changed, it will remove and re-add the -path, just like the existing wwid checking code for change events does. -In cases where the no uevent occurs, both the udev database entry and -sysfs will have the old wwid, so the only way to get a current wwid is -to ask the device directly. Currently multipath only has code to -directly get the wwid for scsi devices, so this option only effects scsi -devices, and they must be configured to be able to use the uid_fallback -methods. To make sure both the sysfs and udev database values are -updated, multipathd triggers a both a rescan of the device and a udev -add event. - -Co-developed-by: Chongyun Wu -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck Reviewed-by: Martin Wilck ---- - libmultipath/config.c | 2 + - libmultipath/config.h | 2 + - libmultipath/configure.c | 4 +- - libmultipath/configure.h | 2 + - libmultipath/defaults.h | 1 + - libmultipath/dict.c | 11 +++++ - libmultipath/discovery.c | 7 ++- - libmultipath/discovery.h | 1 + - libmultipath/libmultipath.version | 6 +++ - libmultipath/propsel.c | 21 +++++++++ - libmultipath/propsel.h | 1 + - libmultipath/structs.h | 7 +++ - multipath/multipath.conf.5 | 14 ++++++ - multipathd/cli_handlers.c | 9 ++++ - multipathd/main.c | 78 +++++++++++++++++++++++++++++++ - multipathd/main.h | 2 + - 16 files changed, 164 insertions(+), 4 deletions(-) - -diff --git a/libmultipath/config.c b/libmultipath/config.c -index be310159..30046a17 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -436,6 +436,7 @@ merge_hwe (struct hwentry * dst, struct hwentry * src) - merge_num(max_sectors_kb); - merge_num(ghost_delay); - merge_num(all_tg_pt); -+ merge_num(recheck_wwid); - merge_num(vpd_vendor_id); - merge_num(san_path_err_threshold); - merge_num(san_path_err_forget_rate); -@@ -867,6 +868,7 @@ int _init_config (const char *file, struct config *conf) - conf->remove_retries = 0; - conf->ghost_delay = DEFAULT_GHOST_DELAY; - conf->all_tg_pt = DEFAULT_ALL_TG_PT; -+ conf->recheck_wwid = DEFAULT_RECHECK_WWID; - /* - * preload default hwtable - */ -diff --git a/libmultipath/config.h b/libmultipath/config.h -index 9ce37f16..933fe0d1 100644 ---- a/libmultipath/config.h -+++ b/libmultipath/config.h -@@ -83,6 +83,7 @@ struct hwentry { - int ghost_delay; - int all_tg_pt; - int vpd_vendor_id; -+ int recheck_wwid; - char * bl_product; - }; - -@@ -187,6 +188,7 @@ struct config { - int marginal_pathgroups; - int skip_delegate; - unsigned int sequence_nr; -+ int recheck_wwid; - - char * multipath_dir; - char * selector; -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 598efe05..6ca1f4bb 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -527,8 +527,8 @@ get_udev_for_mpp(const struct multipath *mpp) - return udd; - } - --static void trigger_partitions_udev_change(struct udev_device *dev, -- const char *action, int len) -+void trigger_partitions_udev_change(struct udev_device *dev, -+ const char *action, int len) - { - struct udev_enumerate *part_enum; - struct udev_list_entry *item; -diff --git a/libmultipath/configure.h b/libmultipath/configure.h -index 6b23ccbb..70cf77a3 100644 ---- a/libmultipath/configure.h -+++ b/libmultipath/configure.h -@@ -58,3 +58,5 @@ int get_refwwid (enum mpath_cmds cmd, const char *dev, enum devtypes dev_type, - vector pathvec, char **wwid); - struct udev_device *get_udev_device(const char *dev, enum devtypes dev_type); - void trigger_paths_udev_change(struct multipath *mpp, bool is_mpath); -+void trigger_partitions_udev_change(struct udev_device *dev, const char *action, -+ int len); -diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h -index 947ba467..c27946c7 100644 ---- a/libmultipath/defaults.h -+++ b/libmultipath/defaults.h -@@ -53,6 +53,7 @@ - #define DEFAULT_FIND_MULTIPATHS_TIMEOUT -10 - #define DEFAULT_UNKNOWN_FIND_MULTIPATHS_TIMEOUT 1 - #define DEFAULT_ALL_TG_PT ALL_TG_PT_OFF -+#define DEFAULT_RECHECK_WWID RECHECK_WWID_OFF - /* Enable no foreign libraries by default */ - #define DEFAULT_ENABLE_FOREIGN "NONE" - -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index bab96146..dd08abf5 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -1401,6 +1401,14 @@ declare_hw_snprint(all_tg_pt, print_yes_no_undef) - declare_def_handler(marginal_pathgroups, set_yes_no) - declare_def_snprint(marginal_pathgroups, print_yes_no) - -+declare_def_handler(recheck_wwid, set_yes_no_undef) -+declare_def_snprint_defint(recheck_wwid, print_yes_no_undef, DEFAULT_RECHECK_WWID) -+declare_ovr_handler(recheck_wwid, set_yes_no_undef) -+declare_ovr_snprint(recheck_wwid, print_yes_no_undef) -+declare_hw_handler(recheck_wwid, set_yes_no_undef) -+declare_hw_snprint(recheck_wwid, print_yes_no_undef) -+ -+ - static int - def_uxsock_timeout_handler(struct config *conf, vector strvec) - { -@@ -1819,6 +1827,7 @@ init_keywords(vector keywords) - install_keyword("enable_foreign", &def_enable_foreign_handler, - &snprint_def_enable_foreign); - install_keyword("marginal_pathgroups", &def_marginal_pathgroups_handler, &snprint_def_marginal_pathgroups); -+ install_keyword("recheck_wwid", &def_recheck_wwid_handler, &snprint_def_recheck_wwid); - __deprecated install_keyword("default_selector", &def_selector_handler, NULL); - __deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL); - __deprecated install_keyword("default_uid_attribute", &def_uid_attribute_handler, NULL); -@@ -1908,6 +1917,7 @@ init_keywords(vector keywords) - 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_keyword("vpd_vendor", &hw_vpd_vendor_handler, &snprint_hw_vpd_vendor); -+ install_keyword("recheck_wwid", &hw_recheck_wwid_handler, &snprint_hw_recheck_wwid); - install_sublevel_end(); - - install_keyword_root("overrides", &overrides_handler); -@@ -1949,6 +1959,7 @@ init_keywords(vector keywords) - 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("recheck_wwid", &ovr_recheck_wwid_handler, &snprint_ovr_recheck_wwid); - - install_keyword_root("multipaths", &multipaths_handler); - install_keyword_multi("multipath", &multipath_handler, NULL); -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 40727fa3..f216a724 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -2127,7 +2127,7 @@ static ssize_t uid_fallback(struct path *pp, int path_state, - return len; - } - --static bool has_uid_fallback(struct path *pp) -+bool has_uid_fallback(struct path *pp) - { - /* - * Falling back to direct WWID determination is dangerous -@@ -2162,6 +2162,7 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev, - conf = get_multipath_config(); - pthread_cleanup_push(put_multipath_config, conf); - select_getuid(conf, pp); -+ select_recheck_wwid(conf, pp); - pthread_cleanup_pop(1); - } - -@@ -2293,8 +2294,10 @@ int pathinfo(struct path *pp, struct config *conf, int mask) - - if (mask & DI_BLACKLIST && mask & DI_SYSFS) { - /* uid_attribute is required for filter_property() */ -- if (pp->udev && !pp->uid_attribute) -+ if (pp->udev && !pp->uid_attribute) { - select_getuid(conf, pp); -+ select_recheck_wwid(conf, pp); -+ } - - if (filter_property(conf, pp->udev, 4, pp->uid_attribute) > 0 || - filter_device(conf->blist_device, conf->elist_device, -diff --git a/libmultipath/discovery.h b/libmultipath/discovery.h -index d3193daf..a5446b4d 100644 ---- a/libmultipath/discovery.h -+++ b/libmultipath/discovery.h -@@ -54,6 +54,7 @@ ssize_t sysfs_get_inquiry(struct udev_device *udev, - unsigned char *buff, size_t len); - int sysfs_get_asymmetric_access_state(struct path *pp, - char *buff, int buflen); -+bool has_uid_fallback(struct path *pp); - int get_uid(struct path * pp, int path_state, struct udev_device *udev, - int allow_fallback); - bool is_vpd_page_supported(int fd, int pg); -diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version -index 2228f4ec..e9b4608f 100644 ---- a/libmultipath/libmultipath.version -+++ b/libmultipath/libmultipath.version -@@ -280,3 +280,9 @@ LIBMULTIPATH_4.4.0 { - global: - get_next_string; - } LIBMULTIPATH_4.3.0; -+ -+LIBMULITIPATH_4.5.0 { -+global: -+ get_vpd_sgio; -+ trigger_partitions_udev_change; -+} LIBMULTIPATH_4.4.0; -diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c -index f771a830..b7b33791 100644 ---- a/libmultipath/propsel.c -+++ b/libmultipath/propsel.c -@@ -581,6 +581,27 @@ out: - return 0; - } - -+/* must be called after select_getuid */ -+int select_recheck_wwid(struct config *conf, struct path * pp) -+{ -+ const char *origin; -+ -+ pp_set_ovr(recheck_wwid); -+ pp_set_hwe(recheck_wwid); -+ pp_set_conf(recheck_wwid); -+ pp_set_default(recheck_wwid, DEFAULT_RECHECK_WWID); -+out: -+ if (pp->recheck_wwid == RECHECK_WWID_ON && -+ (pp->bus != SYSFS_BUS_SCSI || pp->getuid != NULL || -+ !has_uid_fallback(pp))) { -+ pp->recheck_wwid = RECHECK_WWID_OFF; -+ origin = "(setting: unsupported by device type/config)"; -+ } -+ condlog(3, "%s: recheck_wwid = %i %s", pp->dev, pp->recheck_wwid, -+ origin); -+ return 0; -+} -+ - void - detect_prio(struct config *conf, struct path * pp) - { -diff --git a/libmultipath/propsel.h b/libmultipath/propsel.h -index a68bacf0..72a7e33c 100644 ---- a/libmultipath/propsel.h -+++ b/libmultipath/propsel.h -@@ -7,6 +7,7 @@ int select_features (struct config *conf, struct multipath * mp); - int select_hwhandler (struct config *conf, struct multipath * mp); - int select_checker(struct config *conf, struct path *pp); - int select_getuid (struct config *conf, struct path * pp); -+int select_recheck_wwid(struct config *conf, struct path * pp); - int select_prio (struct config *conf, struct path * pp); - int select_find_multipaths_timeout(struct config *conf, struct path *pp); - int select_no_path_retry(struct config *conf, struct multipath *mp); -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index d6ff6762..c8447e56 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -242,6 +242,12 @@ enum eh_deadline_states { - EH_DEADLINE_ZERO = UOZ_ZERO, - }; - -+enum recheck_wwid_states { -+ RECHECK_WWID_UNDEF = YNU_UNDEF, -+ RECHECK_WWID_OFF = YNU_NO, -+ RECHECK_WWID_ON = YNU_YES, -+}; -+ - struct vpd_vendor_page { - int pg; - const char *name; -@@ -316,6 +322,7 @@ struct path { - int find_multipaths_timeout; - int marginal; - int vpd_vendor_id; -+ int recheck_wwid; - /* configlet pointers */ - vector hwe; - struct gen_path generic_path; -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 8ef3a747..37030765 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -1273,6 +1273,20 @@ The default is: \fB\(dqNONE\(dq\fR - .RE - . - . -+.TP -+.B recheck_wwid -+If set to \fIyes\fR, when a failed path is restored, its wwid is rechecked. If -+the wwid has changed, the path is removed from the current multipath device, -+and re-added as a new path. Multipathd will also recheck a path's wwid if it is -+manually re-added. This option only works for SCSI devices that are configured -+to use the default uid_attribute, \fIID_SERIAL\fR, or sysfs for getting their -+wwid. -+.RS -+.TP -+The default is \fBno\fR -+.RE -+. -+. - - . - .\" ---------------------------------------------------------------------------- -diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c -index 54635738..7f3e61f6 100644 ---- a/multipathd/cli_handlers.c -+++ b/multipathd/cli_handlers.c -@@ -715,6 +715,15 @@ cli_add_path (void * v, char ** reply, int * len, void * data) - pp = find_path_by_dev(vecs->pathvec, param); - if (pp && pp->initialized != INIT_REMOVED) { - condlog(2, "%s: path already in pathvec", param); -+ -+ if (pp->recheck_wwid == RECHECK_WWID_ON && -+ check_path_wwid_change(pp)) { -+ condlog(0, "%s: wwid changed. Removing device", -+ pp->dev); -+ handle_path_wwid_change(pp, vecs); -+ return 1; -+ } -+ - if (pp->mpp) - return 0; - } else if (pp) { -diff --git a/multipathd/main.c b/multipathd/main.c -index 19679848..637a53bf 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -823,6 +823,73 @@ ev_remove_map (char * devname, char * alias, int minor, struct vectors * vecs) - return flush_map(mpp, vecs, 0); - } - -+static void -+rescan_path(struct udev_device *parent) -+{ -+ while(parent) { -+ const char *subsys = udev_device_get_subsystem(parent); -+ if (subsys && !strncmp(subsys, "scsi", 4)) -+ break; -+ parent = udev_device_get_parent(parent); -+ } -+ if (parent) -+ sysfs_attr_set_value(parent, "rescan", "1", strlen("1")); -+} -+ -+void -+handle_path_wwid_change(struct path *pp, struct vectors *vecs) -+{ -+ struct udev_device *udd; -+ -+ if (!pp || !pp->udev) -+ return; -+ -+ udd = udev_device_ref(pp->udev); -+ if (ev_remove_path(pp, vecs, 1) != 0 && pp->mpp) { -+ pp->dmstate = PSTATE_FAILED; -+ dm_fail_path(pp->mpp->alias, pp->dev_t); -+ } -+ rescan_path(udd); -+ sysfs_attr_set_value(udd, "uevent", "add", strlen("add")); -+ trigger_partitions_udev_change(udd, "add", strlen("add")); -+ udev_device_unref(udd); -+} -+ -+bool -+check_path_wwid_change(struct path *pp) -+{ -+ char wwid[WWID_SIZE]; -+ int len = 0; -+ size_t i; -+ -+ if (!strlen(pp->wwid)) -+ return false; -+ -+ /* Get the real fresh device wwid by sgio. sysfs still has old -+ * data, so only get_vpd_sgio will work to get the new wwid */ -+ len = get_vpd_sgio(pp->fd, 0x83, 0, wwid, WWID_SIZE); -+ -+ if (len <= 0) { -+ condlog(2, "%s: failed to check wwid by sgio: len = %d", -+ pp->dev, len); -+ return false; -+ } -+ -+ /*Strip any trailing blanks */ -+ for (i = strlen(pp->wwid); i > 0 && pp->wwid[i-1] == ' '; i--); -+ /* no-op */ -+ pp->wwid[i] = '\0'; -+ condlog(4, "%s: Got wwid %s by sgio", pp->dev, wwid); -+ -+ if (strncmp(wwid, pp->wwid, WWID_SIZE)) { -+ condlog(0, "%s: wwid '%s' doesn't match wwid '%s' from device", -+ pp->dev, pp->wwid, wwid); -+ return true; -+ } -+ -+ return false; -+} -+ - static int - uev_add_path (struct uevent *uev, struct vectors * vecs, int need_do_map) - { -@@ -1296,6 +1363,7 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) - condlog(0, "%s: path wwid changed from '%s' to '%s'", - uev->kernel, wwid, pp->wwid); - ev_remove_path(pp, vecs, 1); -+ rescan_path(uev->udev); - needs_reinit = 1; - goto out; - } else { -@@ -2197,6 +2265,16 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) - return 0; - set_no_path_retry(pp->mpp); - -+ if (pp->recheck_wwid == RECHECK_WWID_ON && -+ (newstate == PATH_UP || newstate == PATH_GHOST) && -+ ((pp->state != PATH_UP && pp->state != PATH_GHOST) || -+ pp->dmstate == PSTATE_FAILED) && -+ check_path_wwid_change(pp)) { -+ condlog(0, "%s: path wwid change detected. Removing", pp->dev); -+ handle_path_wwid_change(pp, vecs); -+ return 0; -+ } -+ - if ((newstate == PATH_UP || newstate == PATH_GHOST) && - (san_path_check_enabled(pp->mpp) || - marginal_path_check_enabled(pp->mpp))) { -diff --git a/multipathd/main.h b/multipathd/main.h -index 5abbe97b..ddd953f9 100644 ---- a/multipathd/main.h -+++ b/multipathd/main.h -@@ -50,4 +50,6 @@ int update_multipath (struct vectors *vecs, char *mapname, int reset); - int reload_and_sync_map(struct multipath *mpp, struct vectors *vecs, - int refresh); - -+void handle_path_wwid_change(struct path *pp, struct vectors *vecs); -+bool check_path_wwid_change(struct path *pp); - #endif /* MAIN_H */ diff --git a/0127-libmultipath-check-if-user_friendly_name-is-in-use.patch b/0127-libmultipath-check-if-user_friendly_name-is-in-use.patch deleted file mode 100644 index 770dc90..0000000 --- a/0127-libmultipath-check-if-user_friendly_name-is-in-use.patch +++ /dev/null @@ -1,231 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 10 Mar 2021 15:15:14 -0600 -Subject: [PATCH] libmultipath: check if user_friendly_name is in use - -If there are multipath devices that have user_friendly_names but do not -have their bindings in the bindings_file, get_user_friendly_alias() can -currently give out those names again. This can result in an incorrect -entry in the bindings file, and a device that gets created with a WWID -alias instead of a user_friendly_name. This situation can happen after -the pivot root, if a multipath device is created in the initramfs. If -this device doesn't have a binding in the regular filesystem -bindings_file and a new multipath device is created before it can add -its binding, the new device can steal that user_friendly_name during -multipathd's initial configure. - -To solve this, get_user_friendly_alias() now calls lookup_binding() with -a new paramter, telling it to check if the id it found is already in use -by a diffent device. If so, lookup_binding() will continue to check open -ids, until it finds one that it not currently in use by a dm device. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/alias.c | 48 +++++++++++++++++++++++++++++++++++++++++--- - tests/alias.c | 22 ++++++++++---------- - 2 files changed, 56 insertions(+), 14 deletions(-) - -diff --git a/libmultipath/alias.c b/libmultipath/alias.c -index a7ba485a..02bc9d65 100644 ---- a/libmultipath/alias.c -+++ b/libmultipath/alias.c -@@ -21,6 +21,7 @@ - #include "config.h" - #include "util.h" - #include "errno.h" -+#include "devmapper.h" - - - /* -@@ -119,6 +120,28 @@ scan_devname(const char *alias, const char *prefix) - return n; - } - -+static int -+id_already_taken(int id, const char *prefix, const char *map_wwid) -+{ -+ char alias[LINE_MAX]; -+ -+ if (format_devname(alias, id, LINE_MAX, prefix) < 0) -+ return 0; -+ -+ if (dm_map_present(alias)) { -+ char wwid[WWID_SIZE]; -+ -+ /* If both the name and the wwid match, then it's fine.*/ -+ if (dm_get_uuid(alias, wwid, sizeof(wwid)) == 0 && -+ strncmp(map_wwid, wwid, sizeof(wwid)) == 0) -+ return 0; -+ condlog(3, "%s: alias '%s' already taken, but not in bindings file. reselecting alias", map_wwid, alias); -+ return 1; -+ } -+ return 0; -+} -+ -+ - /* - * Returns: 0 if matching entry in WWIDs file found - * -1 if an error occurs -@@ -128,7 +151,7 @@ scan_devname(const char *alias, const char *prefix) - */ - static int - lookup_binding(FILE *f, const char *map_wwid, char **map_alias, -- const char *prefix) -+ const char *prefix, int check_if_taken) - { - char buf[LINE_MAX]; - unsigned int line_nr = 0; -@@ -183,12 +206,31 @@ lookup_binding(FILE *f, const char *map_wwid, char **map_alias, - return 0; - } - } -+ if (!prefix && check_if_taken) -+ id = -1; - if (id >= smallest_bigger_id) { - if (biggest_id < INT_MAX) - id = biggest_id + 1; - else - id = -1; - } -+ if (id > 0 && check_if_taken) { -+ while(id_already_taken(id, prefix, map_wwid)) { -+ if (id == INT_MAX) { -+ id = -1; -+ break; -+ } -+ id++; -+ if (id == smallest_bigger_id) { -+ if (biggest_id == INT_MAX) { -+ id = -1; -+ break; -+ } -+ if (biggest_id >= smallest_bigger_id) -+ id = biggest_id + 1; -+ } -+ } -+ } - if (id < 0) { - condlog(0, "no more available user_friendly_names"); - return -1; -@@ -331,7 +373,7 @@ use_existing_alias (const char *wwid, const char *file, const char *alias_old, - goto out; - } - -- id = lookup_binding(f, wwid, &alias, NULL); -+ id = lookup_binding(f, wwid, &alias, NULL, 0); - if (alias) { - condlog(3, "Use existing binding [%s] for WWID [%s]", - alias, wwid); -@@ -388,7 +430,7 @@ get_user_friendly_alias(const char *wwid, const char *file, const char *prefix, - return NULL; - } - -- id = lookup_binding(f, wwid, &alias, prefix); -+ id = lookup_binding(f, wwid, &alias, prefix, 1); - if (id < 0) { - fclose(f); - return NULL; -diff --git a/tests/alias.c b/tests/alias.c -index 5e0bfea3..344aba73 100644 ---- a/tests/alias.c -+++ b/tests/alias.c -@@ -357,7 +357,7 @@ static void lb_empty(void **state) - - will_return(__wrap_fgets, NULL); - expect_condlog(3, "No matching wwid [WWID0] in bindings file.\n"); -- rc = lookup_binding(NULL, "WWID0", &alias, NULL); -+ rc = lookup_binding(NULL, "WWID0", &alias, NULL, 0); - assert_int_equal(rc, 1); - assert_ptr_equal(alias, NULL); - } -@@ -370,7 +370,7 @@ static void lb_match_a(void **state) - will_return(__wrap_fgets, "MPATHa WWID0\n"); - expect_condlog(3, "Found matching wwid [WWID0] in bindings file." - " Setting alias to MPATHa\n"); -- rc = lookup_binding(NULL, "WWID0", &alias, "MPATH"); -+ rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 0); - assert_int_equal(rc, 0); - assert_ptr_not_equal(alias, NULL); - assert_string_equal(alias, "MPATHa"); -@@ -385,7 +385,7 @@ static void lb_nomatch_a(void **state) - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, NULL); - expect_condlog(3, "No matching wwid [WWID1] in bindings file.\n"); -- rc = lookup_binding(NULL, "WWID1", &alias, "MPATH"); -+ rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 0); - assert_int_equal(rc, 2); - assert_ptr_equal(alias, NULL); - } -@@ -399,7 +399,7 @@ static void lb_match_c(void **state) - will_return(__wrap_fgets, "MPATHc WWID1\n"); - expect_condlog(3, "Found matching wwid [WWID1] in bindings file." - " Setting alias to MPATHc\n"); -- rc = lookup_binding(NULL, "WWID1", &alias, "MPATH"); -+ rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 0); - assert_int_equal(rc, 0); - assert_ptr_not_equal(alias, NULL); - assert_string_equal(alias, "MPATHc"); -@@ -415,7 +415,7 @@ static void lb_nomatch_a_c(void **state) - will_return(__wrap_fgets, "MPATHc WWID1\n"); - will_return(__wrap_fgets, NULL); - expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH"); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); - assert_int_equal(rc, 2); - assert_ptr_equal(alias, NULL); - } -@@ -429,7 +429,7 @@ static void lb_nomatch_c_a(void **state) - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, NULL); - expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH"); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); - assert_int_equal(rc, 2); - assert_ptr_equal(alias, NULL); - } -@@ -444,7 +444,7 @@ static void lb_nomatch_a_b(void **state) - will_return(__wrap_fgets, "MPATHb WWID1\n"); - will_return(__wrap_fgets, NULL); - expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH"); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); - assert_int_equal(rc, 3); - assert_ptr_equal(alias, NULL); - } -@@ -460,7 +460,7 @@ static void lb_nomatch_a_b_bad(void **state) - will_return(__wrap_fgets, NULL); - expect_condlog(3, "Ignoring malformed line 3 in bindings file\n"); - expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH"); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); - assert_int_equal(rc, 3); - assert_ptr_equal(alias, NULL); - } -@@ -475,7 +475,7 @@ static void lb_nomatch_b_a(void **state) - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, NULL); - expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH"); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); - assert_int_equal(rc, 27); - assert_ptr_equal(alias, NULL); - } -@@ -491,7 +491,7 @@ static void lb_nomatch_int_max(void **state) - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, NULL); - expect_condlog(0, "no more available user_friendly_names\n"); -- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH"); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); - assert_int_equal(rc, -1); - assert_ptr_equal(alias, NULL); - } -@@ -506,7 +506,7 @@ static void lb_nomatch_int_max_m1(void **state) - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, NULL); - expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH"); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); - assert_int_equal(rc, INT_MAX); - assert_ptr_equal(alias, NULL); - } diff --git a/0128-tests-add-tests-for-checking-if-alias-is-in-use.patch b/0128-tests-add-tests-for-checking-if-alias-is-in-use.patch deleted file mode 100644 index 9849282..0000000 --- a/0128-tests-add-tests-for-checking-if-alias-is-in-use.patch +++ /dev/null @@ -1,525 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 10 Mar 2021 15:15:15 -0600 -Subject: [PATCH] tests: add tests for checking if alias is in use - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - tests/alias.c | 409 +++++++++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 405 insertions(+), 4 deletions(-) - -diff --git a/tests/alias.c b/tests/alias.c -index 344aba73..ebe1209e 100644 ---- a/tests/alias.c -+++ b/tests/alias.c -@@ -62,6 +62,25 @@ int __wrap_ftruncate(int fd, off_t length) - return __set_errno(mock_type(int)); - } - -+int __wrap_dm_map_present(const char * str) -+{ -+ check_expected(str); -+ return mock_type(int); -+} -+ -+int __wrap_dm_get_uuid(const char *name, char *uuid, int uuid_len) -+{ -+ int ret; -+ -+ check_expected(name); -+ check_expected(uuid_len); -+ assert_non_null(uuid); -+ ret = mock_type(int); -+ if (ret == 0) -+ strcpy(uuid, mock_ptr_type(char *)); -+ return ret; -+} -+ - static void fd_mpatha(void **state) - { - char buf[32]; -@@ -350,6 +369,45 @@ static int test_scan_devname(void) - return cmocka_run_group_tests(tests, NULL, NULL); - } - -+static void mock_unused_alias(const char *alias) -+{ -+ expect_string(__wrap_dm_map_present, str, alias); -+ will_return(__wrap_dm_map_present, 0); -+} -+ -+static void mock_self_alias(const char *alias, const char *wwid) -+{ -+ expect_string(__wrap_dm_map_present, str, alias); -+ will_return(__wrap_dm_map_present, 1); -+ expect_string(__wrap_dm_get_uuid, name, alias); -+ expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); -+ will_return(__wrap_dm_get_uuid, 0); -+ will_return(__wrap_dm_get_uuid, wwid); -+} -+ -+#define USED_STR(alias_str, wwid_str) wwid_str ": alias '" alias_str "' already taken, but not in bindings file. reselecting alias\n" -+ -+static void mock_failed_alias(const char *alias, char *msg) -+{ -+ expect_string(__wrap_dm_map_present, str, alias); -+ will_return(__wrap_dm_map_present, 1); -+ expect_string(__wrap_dm_get_uuid, name, alias); -+ expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); -+ will_return(__wrap_dm_get_uuid, 1); -+ expect_condlog(3, msg); -+} -+ -+static void mock_used_alias(const char *alias, char *msg) -+{ -+ expect_string(__wrap_dm_map_present, str, alias); -+ will_return(__wrap_dm_map_present, 1); -+ expect_string(__wrap_dm_get_uuid, name, alias); -+ expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); -+ will_return(__wrap_dm_get_uuid, 0); -+ will_return(__wrap_dm_get_uuid, "WWID_USED"); -+ expect_condlog(3, msg); -+} -+ - static void lb_empty(void **state) - { - int rc; -@@ -362,6 +420,65 @@ static void lb_empty(void **state) - assert_ptr_equal(alias, NULL); - } - -+static void lb_empty_unused(void **state) -+{ -+ int rc; -+ char *alias; -+ -+ will_return(__wrap_fgets, NULL); -+ mock_unused_alias("MPATHa"); -+ expect_condlog(3, "No matching wwid [WWID0] in bindings file.\n"); -+ rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); -+ assert_int_equal(rc, 1); -+ assert_ptr_equal(alias, NULL); -+ free(alias); -+} -+ -+static void lb_empty_failed(void **state) -+{ -+ int rc; -+ char *alias; -+ -+ will_return(__wrap_fgets, NULL); -+ mock_failed_alias("MPATHa", USED_STR("MPATHa", "WWID0")); -+ mock_unused_alias("MPATHb"); -+ expect_condlog(3, "No matching wwid [WWID0] in bindings file.\n"); -+ rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); -+ assert_int_equal(rc, 2); -+ assert_ptr_equal(alias, NULL); -+ free(alias); -+} -+ -+static void lb_empty_1_used(void **state) -+{ -+ int rc; -+ char *alias; -+ -+ will_return(__wrap_fgets, NULL); -+ mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); -+ mock_unused_alias("MPATHb"); -+ expect_condlog(3, "No matching wwid [WWID0] in bindings file.\n"); -+ rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); -+ assert_int_equal(rc, 2); -+ assert_ptr_equal(alias, NULL); -+ free(alias); -+} -+ -+static void lb_empty_1_used_self(void **state) -+{ -+ int rc; -+ char *alias; -+ -+ will_return(__wrap_fgets, NULL); -+ mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); -+ mock_self_alias("MPATHb", "WWID0"); -+ expect_condlog(3, "No matching wwid [WWID0] in bindings file.\n"); -+ rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); -+ assert_int_equal(rc, 2); -+ assert_ptr_equal(alias, NULL); -+ free(alias); -+} -+ - static void lb_match_a(void **state) - { - int rc; -@@ -390,7 +507,52 @@ static void lb_nomatch_a(void **state) - assert_ptr_equal(alias, NULL); - } - --static void lb_match_c(void **state) -+static void lb_nomatch_a_bad_check(void **state) -+{ -+ int rc; -+ char *alias; -+ -+ will_return(__wrap_fgets, "MPATHa WWID0\n"); -+ will_return(__wrap_fgets, NULL); -+ expect_condlog(0, "no more available user_friendly_names\n"); -+ rc = lookup_binding(NULL, "WWID1", &alias, NULL, 1); -+ assert_int_equal(rc, -1); -+ assert_ptr_equal(alias, NULL); -+} -+ -+static void lb_nomatch_a_unused(void **state) -+{ -+ int rc; -+ char *alias; -+ -+ will_return(__wrap_fgets, "MPATHa WWID0\n"); -+ will_return(__wrap_fgets, NULL); -+ mock_unused_alias("MPATHb"); -+ expect_condlog(3, "No matching wwid [WWID1] in bindings file.\n"); -+ rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1); -+ assert_int_equal(rc, 2); -+ assert_ptr_equal(alias, NULL); -+} -+ -+static void lb_nomatch_a_3_used_failed_self(void **state) -+{ -+ int rc; -+ char *alias; -+ -+ will_return(__wrap_fgets, "MPATHa WWID0\n"); -+ will_return(__wrap_fgets, NULL); -+ mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID1")); -+ mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID1")); -+ mock_used_alias("MPATHd", USED_STR("MPATHd", "WWID1")); -+ mock_failed_alias("MPATHe", USED_STR("MPATHe", "WWID1")); -+ mock_self_alias("MPATHf", "WWID1"); -+ expect_condlog(3, "No matching wwid [WWID1] in bindings file.\n"); -+ rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1); -+ assert_int_equal(rc, 6); -+ assert_ptr_equal(alias, NULL); -+} -+ -+static void do_lb_match_c(void **state, int check_if_taken) - { - int rc; - char *alias; -@@ -399,13 +561,23 @@ static void lb_match_c(void **state) - will_return(__wrap_fgets, "MPATHc WWID1\n"); - expect_condlog(3, "Found matching wwid [WWID1] in bindings file." - " Setting alias to MPATHc\n"); -- rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 0); -+ rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", check_if_taken); - assert_int_equal(rc, 0); - assert_ptr_not_equal(alias, NULL); - assert_string_equal(alias, "MPATHc"); - free(alias); - } - -+static void lb_match_c(void **state) -+{ -+ do_lb_match_c(state, 0); -+} -+ -+static void lb_match_c_check(void **state) -+{ -+ do_lb_match_c(state, 1); -+} -+ - static void lb_nomatch_a_c(void **state) - { - int rc; -@@ -420,6 +592,72 @@ static void lb_nomatch_a_c(void **state) - assert_ptr_equal(alias, NULL); - } - -+static void lb_nomatch_a_d_unused(void **state) -+{ -+ int rc; -+ char *alias; -+ -+ will_return(__wrap_fgets, "MPATHa WWID0\n"); -+ will_return(__wrap_fgets, "MPATHd WWID1\n"); -+ will_return(__wrap_fgets, NULL); -+ mock_unused_alias("MPATHb"); -+ expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -+ assert_int_equal(rc, 2); -+ assert_ptr_equal(alias, NULL); -+} -+ -+static void lb_nomatch_a_d_1_used(void **state) -+{ -+ int rc; -+ char *alias; -+ -+ will_return(__wrap_fgets, "MPATHa WWID0\n"); -+ will_return(__wrap_fgets, "MPATHd WWID1\n"); -+ will_return(__wrap_fgets, NULL); -+ mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2")); -+ mock_unused_alias("MPATHc"); -+ expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -+ assert_int_equal(rc, 3); -+ assert_ptr_equal(alias, NULL); -+} -+ -+static void lb_nomatch_a_d_2_used(void **state) -+{ -+ int rc; -+ char *alias; -+ -+ will_return(__wrap_fgets, "MPATHa WWID0\n"); -+ will_return(__wrap_fgets, "MPATHd WWID1\n"); -+ will_return(__wrap_fgets, NULL); -+ mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2")); -+ mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID2")); -+ mock_unused_alias("MPATHe"); -+ expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -+ assert_int_equal(rc, 5); -+ assert_ptr_equal(alias, NULL); -+} -+ -+static void lb_nomatch_a_d_3_used(void **state) -+{ -+ int rc; -+ char *alias; -+ -+ will_return(__wrap_fgets, "MPATHa WWID0\n"); -+ will_return(__wrap_fgets, "MPATHd WWID1\n"); -+ will_return(__wrap_fgets, NULL); -+ mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2")); -+ mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID2")); -+ mock_used_alias("MPATHe", USED_STR("MPATHe", "WWID2")); -+ mock_unused_alias("MPATHf"); -+ expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -+ assert_int_equal(rc, 6); -+ assert_ptr_equal(alias, NULL); -+} -+ - static void lb_nomatch_c_a(void **state) - { - int rc; -@@ -434,6 +672,39 @@ static void lb_nomatch_c_a(void **state) - assert_ptr_equal(alias, NULL); - } - -+static void lb_nomatch_d_a_unused(void **state) -+{ -+ int rc; -+ char *alias; -+ -+ will_return(__wrap_fgets, "MPATHc WWID1\n"); -+ will_return(__wrap_fgets, "MPATHa WWID0\n"); -+ will_return(__wrap_fgets, "MPATHd WWID0\n"); -+ will_return(__wrap_fgets, NULL); -+ mock_unused_alias("MPATHb"); -+ expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -+ assert_int_equal(rc, 2); -+ assert_ptr_equal(alias, NULL); -+} -+ -+static void lb_nomatch_d_a_1_used(void **state) -+{ -+ int rc; -+ char *alias; -+ -+ will_return(__wrap_fgets, "MPATHc WWID1\n"); -+ will_return(__wrap_fgets, "MPATHa WWID0\n"); -+ will_return(__wrap_fgets, "MPATHd WWID0\n"); -+ will_return(__wrap_fgets, NULL); -+ mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2")); -+ mock_unused_alias("MPATHe"); -+ expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -+ assert_int_equal(rc, 5); -+ assert_ptr_equal(alias, NULL); -+} -+ - static void lb_nomatch_a_b(void **state) - { - int rc; -@@ -465,6 +736,23 @@ static void lb_nomatch_a_b_bad(void **state) - assert_ptr_equal(alias, NULL); - } - -+static void lb_nomatch_a_b_bad_self(void **state) -+{ -+ int rc; -+ char *alias; -+ -+ will_return(__wrap_fgets, "MPATHa WWID0\n"); -+ will_return(__wrap_fgets, "MPATHz WWID26\n"); -+ will_return(__wrap_fgets, "MPATHb\n"); -+ will_return(__wrap_fgets, NULL); -+ expect_condlog(3, "Ignoring malformed line 3 in bindings file\n"); -+ mock_self_alias("MPATHc", "WWID2"); -+ expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -+ assert_int_equal(rc, 3); -+ assert_ptr_equal(alias, NULL); -+} -+ - static void lb_nomatch_b_a(void **state) - { - int rc; -@@ -480,8 +768,27 @@ static void lb_nomatch_b_a(void **state) - assert_ptr_equal(alias, NULL); - } - -+static void lb_nomatch_b_a_3_used(void **state) -+{ -+ int rc; -+ char *alias; -+ -+ will_return(__wrap_fgets, "MPATHb WWID1\n"); -+ will_return(__wrap_fgets, "MPATHz WWID26\n"); -+ will_return(__wrap_fgets, "MPATHa WWID0\n"); -+ will_return(__wrap_fgets, NULL); -+ mock_used_alias("MPATHaa", USED_STR("MPATHaa", "WWID2")); -+ mock_used_alias("MPATHab", USED_STR("MPATHab", "WWID2")); -+ mock_used_alias("MPATHac", USED_STR("MPATHac", "WWID2")); -+ mock_unused_alias("MPATHad"); -+ expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -+ assert_int_equal(rc, 30); -+ assert_ptr_equal(alias, NULL); -+} -+ - #ifdef MPATH_ID_INT_MAX --static void lb_nomatch_int_max(void **state) -+static void do_lb_nomatch_int_max(void **state, int check_if_taken) - { - int rc; - char *alias; -@@ -491,7 +798,32 @@ static void lb_nomatch_int_max(void **state) - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, NULL); - expect_condlog(0, "no more available user_friendly_names\n"); -- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", check_if_taken); -+ assert_int_equal(rc, -1); -+ assert_ptr_equal(alias, NULL); -+} -+ -+static void lb_nomatch_int_max(void **state) -+{ -+ do_lb_nomatch_int_max(state, 0); -+} -+ -+static void lb_nomatch_int_max_check(void **state) -+{ -+ do_lb_nomatch_int_max(state, 1); -+} -+ -+static void lb_nomatch_int_max_used(void **state) -+{ -+ int rc; -+ char *alias; -+ -+ will_return(__wrap_fgets, "MPATHb WWID1\n"); -+ will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n"); -+ will_return(__wrap_fgets, NULL); -+ mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID2")); -+ expect_condlog(0, "no more available user_friendly_names\n"); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, -1); - assert_ptr_equal(alias, NULL); - } -@@ -510,23 +842,92 @@ static void lb_nomatch_int_max_m1(void **state) - assert_int_equal(rc, INT_MAX); - assert_ptr_equal(alias, NULL); - } -+ -+static void lb_nomatch_int_max_m1_used(void **state) -+{ -+ int rc; -+ char *alias; -+ -+ will_return(__wrap_fgets, "MPATHb WWID1\n"); -+ will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"); -+ will_return(__wrap_fgets, "MPATHa WWID0\n"); -+ will_return(__wrap_fgets, NULL); -+ mock_used_alias("MPATH" MPATH_ID_INT_MAX, USED_STR("MPATH" MPATH_ID_INT_MAX, "WWID2")); -+ expect_condlog(0, "no more available user_friendly_names\n"); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -+ assert_int_equal(rc, -1); -+ assert_ptr_equal(alias, NULL); -+} -+ -+static void lb_nomatch_int_max_m1_1_used(void **state) -+{ -+ int rc; -+ char *alias; -+ -+ will_return(__wrap_fgets, "MPATHb WWID1\n"); -+ will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"); -+ will_return(__wrap_fgets, NULL); -+ mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID2")); -+ mock_unused_alias("MPATH" MPATH_ID_INT_MAX); -+ expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -+ assert_int_equal(rc, INT_MAX); -+ assert_ptr_equal(alias, NULL); -+} -+ -+static void lb_nomatch_int_max_m1_2_used(void **state) -+{ -+ int rc; -+ char *alias; -+ -+ will_return(__wrap_fgets, "MPATHb WWID1\n"); -+ will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"); -+ will_return(__wrap_fgets, NULL); -+ mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID2")); -+ mock_used_alias("MPATH" MPATH_ID_INT_MAX, USED_STR("MPATH" MPATH_ID_INT_MAX, "WWID2")); -+ expect_condlog(0, "no more available user_friendly_names\n"); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -+ assert_int_equal(rc, -1); -+ assert_ptr_equal(alias, NULL); -+} - #endif - - static int test_lookup_binding(void) - { - const struct CMUnitTest tests[] = { - cmocka_unit_test(lb_empty), -+ cmocka_unit_test(lb_empty_unused), -+ cmocka_unit_test(lb_empty_failed), -+ cmocka_unit_test(lb_empty_1_used), -+ cmocka_unit_test(lb_empty_1_used_self), - cmocka_unit_test(lb_match_a), - cmocka_unit_test(lb_nomatch_a), -+ cmocka_unit_test(lb_nomatch_a_bad_check), -+ cmocka_unit_test(lb_nomatch_a_unused), -+ cmocka_unit_test(lb_nomatch_a_3_used_failed_self), - cmocka_unit_test(lb_match_c), -+ cmocka_unit_test(lb_match_c_check), - cmocka_unit_test(lb_nomatch_a_c), -+ cmocka_unit_test(lb_nomatch_a_d_unused), -+ cmocka_unit_test(lb_nomatch_a_d_1_used), -+ cmocka_unit_test(lb_nomatch_a_d_2_used), -+ cmocka_unit_test(lb_nomatch_a_d_3_used), - cmocka_unit_test(lb_nomatch_c_a), -+ cmocka_unit_test(lb_nomatch_d_a_unused), -+ cmocka_unit_test(lb_nomatch_d_a_1_used), - cmocka_unit_test(lb_nomatch_a_b), - cmocka_unit_test(lb_nomatch_a_b_bad), -+ cmocka_unit_test(lb_nomatch_a_b_bad_self), - cmocka_unit_test(lb_nomatch_b_a), -+ cmocka_unit_test(lb_nomatch_b_a_3_used), - #ifdef MPATH_ID_INT_MAX - cmocka_unit_test(lb_nomatch_int_max), -+ cmocka_unit_test(lb_nomatch_int_max_check), -+ cmocka_unit_test(lb_nomatch_int_max_used), - cmocka_unit_test(lb_nomatch_int_max_m1), -+ cmocka_unit_test(lb_nomatch_int_max_m1_used), -+ cmocka_unit_test(lb_nomatch_int_max_m1_1_used), -+ cmocka_unit_test(lb_nomatch_int_max_m1_2_used), - #endif - }; - diff --git a/0129-multipath-tools-add-DellEMC-PowerStore-to-hardware-t.patch b/0129-multipath-tools-add-DellEMC-PowerStore-to-hardware-t.patch deleted file mode 100644 index 596527f..0000000 --- a/0129-multipath-tools-add-DellEMC-PowerStore-to-hardware-t.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Sat, 6 Mar 2021 03:54:15 +0100 -Subject: [PATCH] multipath-tools: add DellEMC/PowerStore to hardware table - -Info from: https://www.delltechnologies.com/en-us/collaterals/unauth/technical-guides-support-information/products/storage-2/docu5128.pdf - -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/hwtable.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index 921aadc5..58fa7387 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -388,6 +388,17 @@ static struct hwentry default_hw[] = { - .product = "^EMC PowerMax_", - .pgpolicy = MULTIBUS, - }, -+ { -+ /* PowerStore */ -+ .vendor = "DellEMC", -+ .product = "PowerStore", -+ .pgpolicy = GROUP_BY_PRIO, -+ .prio_name = PRIO_ALUA, -+ .hwhandler = "1 alua", -+ .pgfailback = -FAILBACK_IMMEDIATE, -+ .no_path_retry = 3, -+ .fast_io_fail = 15, -+ }, - /* - * Fujitsu - */ diff --git a/0130-multipath-tools-delete-a-space-in-multipath.conf.5-t.patch b/0130-multipath-tools-delete-a-space-in-multipath.conf.5-t.patch deleted file mode 100644 index c8c8d1e..0000000 --- a/0130-multipath-tools-delete-a-space-in-multipath.conf.5-t.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Sat, 6 Mar 2021 16:39:59 +0100 -Subject: [PATCH] multipath-tools: delete a space in multipath.conf.5 to be - consistent - -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - multipath/multipath.conf.5 | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 37030765..73977b97 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -1095,7 +1095,7 @@ for the configured time, and is declared healthy, it will be returned to its - normal pathgroup. See "Shaky paths detection" below for more information. - .RS - .TP --The default is: \fBno\fR -+The default is: \fBno\fR - .RE - . - . diff --git a/0131-multipath-tools-tests-allow-control-of-test-verbosit.patch b/0131-multipath-tools-tests-allow-control-of-test-verbosit.patch deleted file mode 100644 index 50da56b..0000000 --- a/0131-multipath-tools-tests-allow-control-of-test-verbosit.patch +++ /dev/null @@ -1,253 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 11 Feb 2021 22:52:39 +0100 -Subject: [PATCH] multipath-tools tests: allow control of test verbosity - -Use common code to control verbosity during unit tests runs. -The environment variable MPATHTEST_VERBOSITY is honored by most -tests, except those that need to parse the log messages or have -other special needs. - -Also, get rid of the now obsolete global variables logsink and -udev, as these are now defined in libmultipath. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - tests/README.md | 5 +++++ - tests/alias.c | 2 +- - tests/blacklist.c | 2 +- - tests/devt.c | 1 + - tests/directio.c | 2 +- - tests/dmevents.c | 1 + - tests/globals.c | 27 +++++++++++++++++++++------ - tests/hwtable.c | 2 ++ - tests/parser.c | 1 + - tests/pgpolicy.c | 1 + - tests/uevent.c | 1 + - tests/unaligned.c | 1 + - tests/util.c | 1 + - tests/valid.c | 2 ++ - tests/vpd.c | 1 + - 15 files changed, 41 insertions(+), 9 deletions(-) - -diff --git a/tests/README.md b/tests/README.md -index 6e7ad405..47c0f0b2 100644 ---- a/tests/README.md -+++ b/tests/README.md -@@ -13,6 +13,11 @@ If valgrind detects a bad memory access or leak, the test will fail. The - output of the test run, including valgrind output, is stored as - `.vgr`. - -+## Controlling verbosity for unit tests -+ -+Some test programs use the environment variable `MPATHTEST_VERBOSITY` to -+control the log level during test execution. -+ - ## Notes on individual tests - - ### Tests that require root permissions -diff --git a/tests/alias.c b/tests/alias.c -index ebe1209e..7e7c1878 100644 ---- a/tests/alias.c -+++ b/tests/alias.c -@@ -1137,7 +1137,7 @@ static int test_allocate_binding(void) - int main(void) - { - int ret = 0; -- libmp_verbosity = conf.verbosity; -+ init_test_verbosity(3); - - ret += test_format_devname(); - ret += test_scan_devname(); -diff --git a/tests/blacklist.c b/tests/blacklist.c -index 0b42e255..882aa3a1 100644 ---- a/tests/blacklist.c -+++ b/tests/blacklist.c -@@ -153,7 +153,7 @@ static int setup(void **state) - store_ble(blist_property_wwn_inv, "!ID_WWN", ORIGIN_CONFIG)) - return -1; - -- libmp_verbosity = conf.verbosity = 4; -+ init_test_verbosity(4); - return 0; - } - -diff --git a/tests/devt.c b/tests/devt.c -index fd4d74a3..2b728516 100644 ---- a/tests/devt.c -+++ b/tests/devt.c -@@ -187,6 +187,7 @@ int main(void) - { - int ret = 0; - -+ init_test_verbosity(-1); - ret += devt2devname_tests(); - return ret; - } -diff --git a/tests/directio.c b/tests/directio.c -index 98954099..9f7d3883 100644 ---- a/tests/directio.c -+++ b/tests/directio.c -@@ -770,7 +770,7 @@ int main(void) - { - int ret = 0; - -- conf.verbosity = 2; -+ init_test_verbosity(2); - ret += test_directio(); - return ret; - } -diff --git a/tests/dmevents.c b/tests/dmevents.c -index 29eaa6db..204cf1d9 100644 ---- a/tests/dmevents.c -+++ b/tests/dmevents.c -@@ -925,6 +925,7 @@ int main(void) - { - int ret = 0; - -+ init_test_verbosity(-1); - ret += test_dmevents(); - return ret; - } -diff --git a/tests/globals.c b/tests/globals.c -index fc0c07ad..36319ed3 100644 ---- a/tests/globals.c -+++ b/tests/globals.c -@@ -1,13 +1,12 @@ -+#include -+#include -+ -+#include "defaults.h" - #include "structs.h" - #include "config.h" - #include "debug.h" - --/* Required globals */ --struct udev *udev; --int logsink = LOGSINK_STDERR_WITHOUT_TIME; --struct config conf = { -- .verbosity = 4, --}; -+struct config conf; - - struct config *get_multipath_config(void) - { -@@ -16,3 +15,19 @@ struct config *get_multipath_config(void) - - void put_multipath_config(void *arg) - {} -+ -+static __attribute__((unused)) void init_test_verbosity(int test_verbosity) -+{ -+ char *verb = getenv("MPATHTEST_VERBOSITY"); -+ -+ libmp_verbosity = test_verbosity >= 0 ? test_verbosity : -+ DEFAULT_VERBOSITY; -+ if (verb && *verb) { -+ char *c; -+ int vb; -+ -+ vb = strtoul(verb, &c, 10); -+ if (!*c && vb >= 0 && vb <= 5) -+ libmp_verbosity = vb; -+ } -+} -diff --git a/tests/hwtable.c b/tests/hwtable.c -index 4dd0873b..6f5766f7 100644 ---- a/tests/hwtable.c -+++ b/tests/hwtable.c -@@ -1778,6 +1778,8 @@ int main(void) - { - int ret = 0; - -+ /* We can't use init_test_verbosity in this test */ -+ libmp_verbosity = VERBOSITY; - ret += test_hwtable(); - return ret; - } -diff --git a/tests/parser.c b/tests/parser.c -index 5772391e..cf96d81f 100644 ---- a/tests/parser.c -+++ b/tests/parser.c -@@ -511,6 +511,7 @@ int main(void) - { - int ret = 0; - -+ init_test_verbosity(-1); - ret += test_config_parser(); - return ret; - } -diff --git a/tests/pgpolicy.c b/tests/pgpolicy.c -index 3f61b123..57ad3381 100644 ---- a/tests/pgpolicy.c -+++ b/tests/pgpolicy.c -@@ -1031,6 +1031,7 @@ int main(void) - { - int ret = 0; - -+ init_test_verbosity(-1); - ret += test_pgpolicies(); - return ret; - } -diff --git a/tests/uevent.c b/tests/uevent.c -index 9ffcd2df..648ff268 100644 ---- a/tests/uevent.c -+++ b/tests/uevent.c -@@ -322,6 +322,7 @@ int main(void) - { - int ret = 0; - -+ init_test_verbosity(-1); - ret += test_uevent_get_XXX(); - return ret; - } -diff --git a/tests/unaligned.c b/tests/unaligned.c -index 7ece1de8..e43b64d4 100644 ---- a/tests/unaligned.c -+++ b/tests/unaligned.c -@@ -91,6 +91,7 @@ int main(void) - { - int ret = 0; - -+ init_test_verbosity(-1); - ret += test_unaligned(); - return ret; - } -diff --git a/tests/util.c b/tests/util.c -index c3c49b60..9affb0e1 100644 ---- a/tests/util.c -+++ b/tests/util.c -@@ -946,6 +946,7 @@ int main(void) - { - int ret = 0; - -+ init_test_verbosity(-1); - ret += test_basenamecpy(); - ret += test_bitmasks(); - ret += test_strlcpy(); -diff --git a/tests/valid.c b/tests/valid.c -index 8ec803e8..e7393a1c 100644 ---- a/tests/valid.c -+++ b/tests/valid.c -@@ -554,6 +554,8 @@ int test_valid(void) - int main(void) - { - int ret = 0; -+ -+ init_test_verbosity(-1); - ret += test_valid(); - return ret; - } -diff --git a/tests/vpd.c b/tests/vpd.c -index e2ec65e9..8e730d37 100644 ---- a/tests/vpd.c -+++ b/tests/vpd.c -@@ -799,6 +799,7 @@ int main(void) - { - int ret = 0; - -+ init_test_verbosity(-1); - ret += test_vpd(); - return ret; - } diff --git a/0132-multipath-tools-devt-test-avoid-failure-when-run-in-.patch b/0132-multipath-tools-devt-test-avoid-failure-when-run-in-.patch deleted file mode 100644 index 35ea98d..0000000 --- a/0132-multipath-tools-devt-test-avoid-failure-when-run-in-.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 11 Feb 2021 22:54:58 +0100 -Subject: [PATCH] multipath-tools: devt test: avoid failure when run in - containers - -/sys/dev/block is usually unavailable containers, causing libudev -calls to fail. Skip the respective tests. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - tests/devt.c | 18 ++++++++++++++++++ - 1 file changed, 18 insertions(+) - -diff --git a/tests/devt.c b/tests/devt.c -index 2b728516..02f2e8f3 100644 ---- a/tests/devt.c -+++ b/tests/devt.c -@@ -11,11 +11,25 @@ - #include - #include - #include -+#include -+#include -+#include - #include "util.h" - #include "debug.h" - - #include "globals.c" - -+static bool sys_dev_block_exists(void) -+{ -+ int fd; -+ bool rc; -+ -+ fd = open("/sys/dev/block", O_RDONLY|O_DIRECTORY); -+ rc = (fd != -1); -+ close(fd); -+ return rc; -+} -+ - static int get_one_devt(char *devt, size_t len) - { - struct udev_enumerate *enm; -@@ -71,6 +85,8 @@ static void test_devt2devname_devt_good(void **state) - { - char dummy[BLK_DEV_SIZE]; - -+ if (!sys_dev_block_exists()) -+ skip(); - assert_int_equal(devt2devname(dummy, sizeof(dummy), *state), 0); - } - -@@ -137,6 +153,8 @@ static void test_devt2devname_real(void **state) - struct udev_list_entry *first, *item; - unsigned int i = 0; - -+ if (!sys_dev_block_exists()) -+ skip(); - enm = udev_enumerate_new(udev); - assert_non_null(enm); - r = udev_enumerate_add_match_subsystem(enm, "block"); diff --git a/0133-multipath-tools-fix-compilation-errors-on-32-bit-mus.patch b/0133-multipath-tools-fix-compilation-errors-on-32-bit-mus.patch deleted file mode 100644 index 36a7607..0000000 --- a/0133-multipath-tools-fix-compilation-errors-on-32-bit-mus.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 12 Feb 2021 00:38:44 +0100 -Subject: [PATCH] multipath-tools: fix compilation errors on 32-bit musl - -gcc on alpine Linux/i386 throws errors because the "tv_sec" element -of struct timespec is a time_t, which is a "long long" in that -environment. In general, time_t is signed. As we only use CLOCK_MONOTONIC, -which starts at boot time, a cast to long should be no problem, even -in 32bit environments. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/main.c | 2 +- - multipathd/main.c | 16 ++++++++-------- - multipathd/uxlsnr.c | 4 ++-- - 3 files changed, 11 insertions(+), 11 deletions(-) - -diff --git a/multipath/main.c b/multipath/main.c -index 9ac42869..3f97582b 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -417,7 +417,7 @@ static int print_cmd_valid(int k, const vector pathvec, - 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); -+ (long)until.tv_sec, until.tv_nsec/1000); - else if (wait == FIND_MULTIPATHS_WAIT_DONE) - printf("FIND_MULTIPATHS_WAIT_UNTIL=\"0\"\n"); - printf("DM_MULTIPATH_DEVICE_PATH=\"%d\"\n", -diff --git a/multipathd/main.c b/multipathd/main.c -index 637a53bf..e0797ccd 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -2486,8 +2486,8 @@ checkerloop (void *ap) - get_monotonic_time(&start_time); - if (start_time.tv_sec && last_time.tv_sec) { - timespecsub(&start_time, &last_time, &diff_time); -- condlog(4, "tick (%lu.%06lu secs)", -- diff_time.tv_sec, diff_time.tv_nsec / 1000); -+ condlog(4, "tick (%ld.%06lu secs)", -+ (long)diff_time.tv_sec, diff_time.tv_nsec / 1000); - last_time = start_time; - ticks = diff_time.tv_sec; - } else { -@@ -2548,18 +2548,18 @@ checkerloop (void *ap) - if (num_paths) { - unsigned int max_checkint; - -- condlog(4, "checked %d path%s in %lu.%06lu secs", -+ condlog(4, "checked %d path%s in %ld.%06lu secs", - num_paths, num_paths > 1 ? "s" : "", -- diff_time.tv_sec, -+ (long)diff_time.tv_sec, - diff_time.tv_nsec / 1000); - conf = get_multipath_config(); - max_checkint = conf->max_checkint; - put_multipath_config(conf); - if (diff_time.tv_sec > (time_t)max_checkint) - condlog(1, "path checkers took longer " -- "than %lu seconds, consider " -+ "than %ld seconds, consider " - "increasing max_polling_interval", -- diff_time.tv_sec); -+ (long)diff_time.tv_sec); - } - } - -@@ -2585,8 +2585,8 @@ checkerloop (void *ap) - } else - diff_time.tv_sec = 1; - -- condlog(3, "waiting for %lu.%06lu secs", -- diff_time.tv_sec, -+ condlog(3, "waiting for %ld.%06lu secs", -+ (long)diff_time.tv_sec, - diff_time.tv_nsec / 1000); - if (nanosleep(&diff_time, NULL) != 0) { - condlog(3, "nanosleep failed with error %d", -diff --git a/multipathd/uxlsnr.c b/multipathd/uxlsnr.c -index cd462b6d..dbee0d6f 100644 ---- a/multipathd/uxlsnr.c -+++ b/multipathd/uxlsnr.c -@@ -154,8 +154,8 @@ static void check_timeout(struct timespec start_time, char *inbuf, - diff_time.tv_nsec / (1000 * 1000); - if (msecs > timeout) - condlog(2, "cli cmd '%s' timeout reached " -- "after %lu.%06lu secs", inbuf, -- diff_time.tv_sec, diff_time.tv_nsec / 1000); -+ "after %ld.%06lu secs", inbuf, -+ (long)diff_time.tv_sec, diff_time.tv_nsec / 1000); - } - } - diff --git a/0134-libmultipath-fix-compilation-error-with-gcc-10-on-i3.patch b/0134-libmultipath-fix-compilation-error-with-gcc-10-on-i3.patch deleted file mode 100644 index dff5288..0000000 --- a/0134-libmultipath-fix-compilation-error-with-gcc-10-on-i3.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 12 Feb 2021 00:41:55 +0100 -Subject: [PATCH] libmultipath: fix compilation error with gcc 10 on i386 - -gcc complained about a possible negative value of "nr" in the -memcpy() call. I consider that a false positive, but it's easily -fixed. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/sysfs.c | 29 ++++++++++++++--------------- - 1 file changed, 14 insertions(+), 15 deletions(-) - -diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c -index 5390de62..7a2af1ea 100644 ---- a/libmultipath/sysfs.c -+++ b/libmultipath/sysfs.c -@@ -344,24 +344,23 @@ bool sysfs_is_multipathed(struct path *pp, bool set_wwid) - pthread_cleanup_push(close_fd, (void *)fd); - nr = read(fd, uuid, sizeof(uuid)); - if (nr > (int)UUID_PREFIX_LEN && -- !memcmp(uuid, UUID_PREFIX, UUID_PREFIX_LEN)) -+ !memcmp(uuid, UUID_PREFIX, UUID_PREFIX_LEN)) { - found = true; -- else if (nr < 0) { -+ if (set_wwid) { -+ nr -= UUID_PREFIX_LEN; -+ memcpy(pp->wwid, uuid + UUID_PREFIX_LEN, nr); -+ if (nr == WWID_SIZE) { -+ condlog(4, "%s: overflow while reading from %s", -+ __func__, pathbuf); -+ pp->wwid[0] = '\0'; -+ } else { -+ pp->wwid[nr] = '\0'; -+ strchop(pp->wwid); -+ } -+ } -+ } else if (nr < 0) - condlog(1, "%s: error reading from %s: %m", - __func__, pathbuf); -- } -- if (found && set_wwid) { -- nr -= UUID_PREFIX_LEN; -- memcpy(pp->wwid, uuid + UUID_PREFIX_LEN, nr); -- if (nr == WWID_SIZE) { -- condlog(4, "%s: overflow while reading from %s", -- __func__, pathbuf); -- pp->wwid[0] = '\0'; -- } else { -- pp->wwid[nr] = '\0'; -- strchop(pp->wwid); -- } -- } - - pthread_cleanup_pop(1); - } diff --git a/0135-kpartx-free-loop-device-after-listing-partitions.patch b/0135-kpartx-free-loop-device-after-listing-partitions.patch deleted file mode 100644 index 566bee4..0000000 --- a/0135-kpartx-free-loop-device-after-listing-partitions.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 24 Feb 2021 00:05:13 -0600 -Subject: [PATCH] kpartx: free loop device after listing partitions - -If "kpartx -l" is run on a file that doesn't already have a loop device -associated with it, it will create a loop device to run the command. -Starting with da59d15c6 ("Fix loopback file with kpartx -av"), it will -not free the loop device when exitting. This is because it checks if the -the file it stat()ed is a regular file, before freeing the loop device. -However, after da59d15c6, stat() is rerun on the loop device itself, so -the check fails. There is no need to check this, if loopcreated is -true, then the file will be a kpartx created loop device, and should be -freed. - -Also, keep kpartx from printing that the loop device has been removed -at normal verbosity. - -Fixes: da59d15c6 ("Fix loopback file with kpartx -av") -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - kpartx/kpartx.c | 9 +++++---- - 1 file changed, 5 insertions(+), 4 deletions(-) - -diff --git a/kpartx/kpartx.c b/kpartx/kpartx.c -index 6a7933fa..8ff116b8 100644 ---- a/kpartx/kpartx.c -+++ b/kpartx/kpartx.c -@@ -424,7 +424,7 @@ main(int argc, char **argv){ - fprintf(stderr, "can't del loop : %s\n", - loopdev); - r = 1; -- } else -+ } else if (verbose) - fprintf(stderr, "loop deleted : %s\n", loopdev); - } - goto end; -@@ -668,16 +668,17 @@ main(int argc, char **argv){ - if (n > 0) - break; - } -- if (what == LIST && loopcreated && S_ISREG (buf.st_mode)) { -+ if (what == LIST && loopcreated) { - if (fd != -1) - close(fd); - if (del_loop(device)) { - if (verbose) -- printf("can't del loop : %s\n", -+ fprintf(stderr, "can't del loop : %s\n", - device); - exit(1); - } -- printf("loop deleted : %s\n", device); -+ if (verbose) -+ fprintf(stderr, "loop deleted : %s\n", device); - } - - end: diff --git a/0136-libmultipath-merge-update_multipath_table-and-update.patch b/0136-libmultipath-merge-update_multipath_table-and-update.patch deleted file mode 100644 index 482f122..0000000 --- a/0136-libmultipath-merge-update_multipath_table-and-update.patch +++ /dev/null @@ -1,229 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 17 Mar 2021 17:18:22 +0100 -Subject: [PATCH] libmultipath: merge update_multipath_table() and - update_multipath_status() - -Since 378cb66 ("multipath: use update_pathvec_from_dm()"), -we remove paths and even pathgroups from multipathd's data structures -in update_multipath_table() if these paths are found to be non-existent. -But update_multipath_status() is called afterwards, and it -uses the kernel's mapping of pathgroups and paths, which won't match -any more if any members had been removed. disassemble_status() returns -an error if the number of path groups doesn't match, causing the -entire structure setup to fail. And because disassemble_status() -doesn't check the dev_t against the corresponding values in multipathd's -data structures, it may assign wrong DM state to paths. - -Fix this by calling disassemble_status() before making any changes to -the data structure in update_pathvec_from_dm(). This can be easily -done, because every call to update_multipath_status() is preceded -by a call to update_multipath_table() anyway, and vice versa. So -we simply merge the two functions into one. This actually simplifies -the code for all callers. - -As we remove a symbol, the major library version must be bumped. - -Fixes: 378cb66 ("multipath: use update_pathvec_from_dm()") -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmpathpersist/mpath_persist.c | 1 - - libmultipath/libmultipath.version | 30 ++++++++---------------- - libmultipath/structs_vec.c | 38 ++++++++----------------------- - multipath/main.c | 6 ++--- - multipathd/main.c | 5 +--- - 5 files changed, 21 insertions(+), 59 deletions(-) - -diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c -index 5c95af20..190e9707 100644 ---- a/libmpathpersist/mpath_persist.c -+++ b/libmpathpersist/mpath_persist.c -@@ -408,7 +408,6 @@ get_mpvec (vector curmp, vector pathvec, char * refwwid) - continue; - - if (update_multipath_table(mpp, pathvec, DI_CHECKER) != DMP_OK || -- update_multipath_status(mpp) != DMP_OK || - update_mpp_paths(mpp, pathvec)) { - condlog(1, "error parsing map %s", mpp->wwid); - remove_map(mpp, pathvec, curmp, PURGE_VEC); -diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version -index e9b4608f..0cff3111 100644 ---- a/libmultipath/libmultipath.version -+++ b/libmultipath/libmultipath.version -@@ -31,7 +31,7 @@ - * The new version inherits the previous ones. - */ - --LIBMULTIPATH_4.0.0 { -+LIBMULTIPATH_5.0.0 { - global: - /* symbols referenced by multipath and multipathd */ - add_foreign; -@@ -198,7 +198,6 @@ global: - uevent_is_mpath; - uevent_listen; - update_mpp_paths; -- update_multipath_status; - update_multipath_strings; - update_multipath_table; - update_pathvec_from_dm; -@@ -256,33 +255,22 @@ global: - libmultipath_init; - libmultipath_exit; - --local: -- *; --}; -- --LIBMULTIPATH_4.1.0 { --global: -+ /* added in 4.1.0 */ - libmp_verbosity; --} LIBMULTIPATH_4.0.0; - --LIBMULTIPATH_4.2.0 { --global: -+ /* added in 4.2.0 */ - dm_prereq; - skip_libmp_dm_init; --} LIBMULTIPATH_4.1.0; - --LIBMULTIPATH_4.3.0 { --global: -+ /* added in 4.3.0 */ - start_checker_thread; --} LIBMULTIPATH_4.2.0; - --LIBMULTIPATH_4.4.0 { --global: -+ /* added in 4.4.0 */ - get_next_string; --} LIBMULTIPATH_4.3.0; - --LIBMULITIPATH_4.5.0 { --global: -+ /* added in 4.5.0 */ - get_vpd_sgio; - trigger_partitions_udev_change; --} LIBMULTIPATH_4.4.0; -+local: -+ *; -+}; -diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c -index 47b1d03e..d242c06b 100644 ---- a/libmultipath/structs_vec.c -+++ b/libmultipath/structs_vec.c -@@ -423,44 +423,27 @@ update_multipath_table (struct multipath *mpp, vector pathvec, int flags) - - r = dm_get_map(mpp->alias, &mpp->size, params); - if (r != DMP_OK) { -- condlog(3, "%s: %s", mpp->alias, (r == DMP_ERR)? "error getting table" : "map not present"); -+ condlog(2, "%s: %s", mpp->alias, (r == DMP_ERR)? "error getting table" : "map not present"); - return r; - } - - if (disassemble_map(pathvec, params, mpp)) { -- condlog(3, "%s: cannot disassemble map", mpp->alias); -+ condlog(2, "%s: cannot disassemble map", mpp->alias); - return DMP_ERR; - } - -+ *params = '\0'; -+ if (dm_get_status(mpp->alias, params) != DMP_OK) -+ condlog(2, "%s: %s", mpp->alias, (r == DMP_ERR)? "error getting status" : "map not present"); -+ else if (disassemble_status(params, mpp)) -+ condlog(2, "%s: cannot disassemble status", mpp->alias); -+ - /* FIXME: we should deal with the return value here */ - update_pathvec_from_dm(pathvec, mpp, flags); - - return DMP_OK; - } - --int --update_multipath_status (struct multipath *mpp) --{ -- int r = DMP_ERR; -- char status[PARAMS_SIZE] = {0}; -- -- if (!mpp) -- return r; -- -- r = dm_get_status(mpp->alias, status); -- if (r != DMP_OK) { -- condlog(3, "%s: %s", mpp->alias, (r == DMP_ERR)? "error getting status" : "map not present"); -- return r; -- } -- -- if (disassemble_status(status, mpp)) { -- condlog(3, "%s: cannot disassemble status", mpp->alias); -- return DMP_ERR; -- } -- -- return DMP_OK; --} -- - static struct path *find_devt_in_pathgroups(const struct multipath *mpp, - const char *dev_t) - { -@@ -538,11 +521,8 @@ update_multipath_strings(struct multipath *mpp, vector pathvec) - r = update_multipath_table(mpp, pathvec, 0); - if (r != DMP_OK) - return r; -- sync_paths(mpp, pathvec); - -- r = update_multipath_status(mpp); -- if (r != DMP_OK) -- return r; -+ sync_paths(mpp, pathvec); - - vector_foreach_slot(mpp->pg, pgp, i) - if (pgp->paths) -diff --git a/multipath/main.c b/multipath/main.c -index 3f97582b..ef89c7cf 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -196,8 +196,7 @@ get_dm_mpvec (enum mpath_cmds cmd, vector curmp, vector pathvec, char * refwwid) - continue; - } - -- if (update_multipath_table(mpp, pathvec, flags) != DMP_OK || -- update_multipath_status(mpp) != DMP_OK) { -+ if (update_multipath_table(mpp, pathvec, flags) != DMP_OK) { - condlog(1, "error parsing map %s", mpp->wwid); - remove_map(mpp, pathvec, curmp, PURGE_VEC); - i--; -@@ -263,8 +262,7 @@ static int check_usable_paths(struct config *conf, - if (mpp == NULL) - goto free; - -- if (update_multipath_table(mpp, pathvec, 0) != DMP_OK || -- update_multipath_status(mpp) != DMP_OK) -+ if (update_multipath_table(mpp, pathvec, 0) != DMP_OK) - goto free; - - vector_foreach_slot (mpp->pg, pg, i) { -diff --git a/multipathd/main.c b/multipathd/main.c -index e0797ccd..154a4eef 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -559,8 +559,6 @@ add_map_without_path (struct vectors *vecs, const char *alias) - - if (update_multipath_table(mpp, vecs->pathvec, 0) != DMP_OK) - goto out; -- if (update_multipath_status(mpp) != DMP_OK) -- goto out; - - if (!vector_alloc_slot(vecs->mpvec)) - goto out; -@@ -1469,8 +1467,7 @@ map_discovery (struct vectors * vecs) - return 1; - - vector_foreach_slot (vecs->mpvec, mpp, i) -- if (update_multipath_table(mpp, vecs->pathvec, 0) != DMP_OK || -- update_multipath_status(mpp) != DMP_OK) { -+ if (update_multipath_table(mpp, vecs->pathvec, 0) != DMP_OK) { - remove_map(mpp, vecs->pathvec, vecs->mpvec, PURGE_VEC); - i--; - } diff --git a/0137-11-dm-mpath.rules-run-multipath-U-with-v1.patch b/0137-11-dm-mpath.rules-run-multipath-U-with-v1.patch deleted file mode 100644 index eb50696..0000000 --- a/0137-11-dm-mpath.rules-run-multipath-U-with-v1.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 17 Mar 2021 17:30:54 +0100 -Subject: [PATCH] 11-dm-mpath.rules: run "multipath -U" with -v1 - -In cases where some path devices are temporarily unavailable (e.g. failover), -high amounts of error messages such as these are seen: - -Feb 27 08:02:03 ictm1608s02h1 multipath[1420]: get_udev_device: failed to look up 65:224 with type 1 -Feb 27 08:02:03 ictm1608s02h1 multipath[1420]: 3600a098000aada210000f1625de51ed9: discarding non-existing path 65:224 - -This is because every invocation of "multipath -U" prints these messages -at the default log level (-v2). In the case of "multipath -U", these -messages aren't important, and in failover situations, "multipath -U" is -run pretty often, spamming the log with many similar messages. - -Generally reducing the log level of these messages would be wrong, -because they are important for multipathd's operation, to verify that -multipathd does the right thing when discovering a discrepancy between the dm -state and the devices present in the system. Therefore, just decrease the -verbosity with which we invoke "multipath -U" in the udev rules. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/11-dm-mpath.rules | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/multipath/11-dm-mpath.rules b/multipath/11-dm-mpath.rules -index cd522e8c..d191ae8d 100644 ---- a/multipath/11-dm-mpath.rules -+++ b/multipath/11-dm-mpath.rules -@@ -32,7 +32,7 @@ ACTION=="add", ENV{.MPATH_DEVICE_READY_OLD}=="1", GOTO="paths_ok" - - # Check the map state directly with multipath -U. - # This doesn't attempt I/O on the device. --PROGRAM=="$env{MPATH_SBIN_PATH}/multipath -U %k", GOTO="paths_ok" -+PROGRAM=="$env{MPATH_SBIN_PATH}/multipath -U -v1 %k", GOTO="paths_ok" - ENV{MPATH_DEVICE_READY}="0", GOTO="mpath_action" - LABEL="paths_ok" - diff --git a/0138-multipath-tools-tests-check-if-sys-dev-block-is-non-.patch b/0138-multipath-tools-tests-check-if-sys-dev-block-is-non-.patch deleted file mode 100644 index 534ebba..0000000 --- a/0138-multipath-tools-tests-check-if-sys-dev-block-is-non-.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 18 Mar 2021 09:50:55 +0100 -Subject: [PATCH] multipath-tools tests: check if /sys/dev/block is non-empty - -Since f131e31 ("multipath-tools: devt test: avoid failure when run in -containers"), we check the existence of /sys/dev/block before running -the devt test. It turns out that on recent releases of podman (3.0.1), -this check is insufficient, because /sys/dev/block exists now in -containers, albeit empty. So we need to check for actual entries -in the directory. - -Fixes: f131e31 ("multipath-tools: devt test: avoid failure when run in containers") - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - tests/devt.c | 22 +++++++++++++++++----- - 1 file changed, 17 insertions(+), 5 deletions(-) - -diff --git a/tests/devt.c b/tests/devt.c -index 02f2e8f3..d971302c 100644 ---- a/tests/devt.c -+++ b/tests/devt.c -@@ -13,7 +13,9 @@ - #include - #include - #include -+#include - #include -+#include - #include "util.h" - #include "debug.h" - -@@ -21,12 +23,22 @@ - - static bool sys_dev_block_exists(void) - { -- int fd; -- bool rc; -+ DIR *dir; -+ bool rc = false; - -- fd = open("/sys/dev/block", O_RDONLY|O_DIRECTORY); -- rc = (fd != -1); -- close(fd); -+ dir = opendir("/sys/dev/block"); -+ if (dir != NULL) { -+ struct dirent *de; -+ -+ while((de = readdir(dir)) != NULL) { -+ if (strcmp(de->d_name, ".") && -+ strcmp(de->d_name, "..")) { -+ rc = true; -+ break; -+ } -+ } -+ } -+ closedir(dir); - return rc; - } - diff --git a/0139-multipathd-reduce-log-levels-in-cli_add_map.patch b/0139-multipathd-reduce-log-levels-in-cli_add_map.patch deleted file mode 100644 index 85823f0..0000000 --- a/0139-multipathd-reduce-log-levels-in-cli_add_map.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 19 Mar 2021 09:50:46 +0100 -Subject: [PATCH] multipathd: reduce log levels in cli_add_map() - -Normally "add map" will be used to add a map which doesn't exist -yet. Thus not finding this map in the first place is not a problem -indicator and should be logged at level 3 only. - -Signed-off-by: Benjamin Marzinski ---- - multipathd/cli_handlers.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c -index 7f3e61f6..1de6ad8e 100644 ---- a/multipathd/cli_handlers.c -+++ b/multipathd/cli_handlers.c -@@ -852,14 +852,15 @@ cli_add_map (void * v, char ** reply, int * len, void * data) - } - do { - if (dm_get_major_minor(param, &major, &minor) < 0) -- condlog(2, "%s: not a device mapper table", param); -+ condlog(count ? 2 : 3, -+ "%s: not a device mapper table", param); - else { - sprintf(dev_path, "dm-%d", minor); - alias = dm_mapname(major, minor); - } - /*if there is no mapname found, we first create the device*/ - if (!alias && !count) { -- condlog(2, "%s: mapname not found for %d:%d", -+ condlog(3, "%s: mapname not found for %d:%d", - param, major, minor); - get_refwwid(CMD_NONE, param, DEV_DEVMAP, - vecs->pathvec, &refwwid); diff --git a/0140-multipath-tools-fix-format-in-multipath.conf.5-to-be.patch b/0140-multipath-tools-fix-format-in-multipath.conf.5-to-be.patch deleted file mode 100644 index 71c4413..0000000 --- a/0140-multipath-tools-fix-format-in-multipath.conf.5-to-be.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Fri, 19 Mar 2021 17:18:56 +0100 -Subject: [PATCH] multipath-tools: fix format in multipath.conf.5 to be - consistent - -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - multipath/multipath.conf.5 | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 73977b97..2aa0f526 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -1283,7 +1283,7 @@ to use the default uid_attribute, \fIID_SERIAL\fR, or sysfs for getting their - wwid. - .RS - .TP --The default is \fBno\fR -+The default is: \fBno\fR - .RE - . - . diff --git a/0141-multipath-tools-use-same-format-for-default-values-i.patch b/0141-multipath-tools-use-same-format-for-default-values-i.patch deleted file mode 100644 index 1fc374b..0000000 --- a/0141-multipath-tools-use-same-format-for-default-values-i.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Sat, 20 Mar 2021 03:13:07 +0100 -Subject: [PATCH] multipath-tools: use same format for default values in - multipath.conf.5 - -For max_sectors_kb, replace "device dependent" with its sysfs path. -And use as wildcard for device in paths. - -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - multipath/multipath.conf.5 | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 2aa0f526..064e4826 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -647,7 +647,7 @@ does not respond to the checker command after \fIchecker_timeout\fR - seconds have elapsed, it is considered down. - .RS - .TP --The default is: in \fB/sys/block/sd/device/timeout\fR -+The default is: in \fB/sys/block//device/timeout\fR - .RE - . - . -@@ -1242,7 +1242,7 @@ Sets the max_sectors_kb device parameter on all path devices and the multipath - device to the specified value. - .RS - .TP --The default is: \fB\fR -+The default is: in \fB/sys/block//queue/max_sectors_kb\fR - .RE - . - . diff --git a/0142-multipathd-fix-NULL-dereference-in-check_path.patch b/0142-multipathd-fix-NULL-dereference-in-check_path.patch deleted file mode 100644 index 3e7e86f..0000000 --- a/0142-multipathd-fix-NULL-dereference-in-check_path.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: lixiaokeng -Date: Tue, 23 Mar 2021 19:50:02 +0800 -Subject: [PATCH] multipathd fix NULL dereference in check_path - -When iscsi login/logout and multipath command are executed -concurrently, there is a coredump. - -The reason is: -check_path - ->update_multipath_strings - ->sync_paths - ->orphan_path //pp->mpp is set to NULL - ->update_multipath_status - ->dm_get_status //return DMP_NOT_FOUND - ->condlog //pp->mpp->alias, NULL dereference - -Here we don't dereference pp-> mpp if it is NULL. - -Signed-off-by: Lixiaokeng -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 154a4eef..1df69096 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -2250,7 +2250,7 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) - if (ret == DMP_NOT_FOUND) { - /* multipath device missing. Likely removed */ - condlog(1, "%s: multipath device '%s' not found", -- pp->dev, pp->mpp->alias); -+ pp->dev, pp->mpp ? pp->mpp->alias : ""); - return 0; - } else - condlog(1, "%s: Couldn't synchronize with kernel state", diff --git a/0143-libmultipath-avoid-infinite-loop-with-bad-vpd-page-8.patch b/0143-libmultipath-avoid-infinite-loop-with-bad-vpd-page-8.patch deleted file mode 100644 index d4a4dd0..0000000 --- a/0143-libmultipath-avoid-infinite-loop-with-bad-vpd-page-8.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 24 Mar 2021 14:15:02 -0500 -Subject: [PATCH] libmultipath: avoid infinite loop with bad vpd page 83 - identifier - -If a device with a scsi name identifier has an unknown prefix, -parse_vpd_pg83() needs to advance to the next identifier, instead of -simply trying the same one again in an infinite loop. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/discovery.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index f216a724..5727f7a6 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -1157,7 +1157,7 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, - if (memcmp(d + 4, "eui.", 4) && - memcmp(d + 4, "naa.", 4) && - memcmp(d + 4, "iqn.", 4)) -- continue; -+ break; - if (prio < 4) { - prio = 4; - vpd = d; diff --git a/0144-libmultipath-fix-priorities-in-parse_vpd_pg83.patch b/0144-libmultipath-fix-priorities-in-parse_vpd_pg83.patch deleted file mode 100644 index dbd28e9..0000000 --- a/0144-libmultipath-fix-priorities-in-parse_vpd_pg83.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 24 Mar 2021 14:48:07 -0500 -Subject: [PATCH] libmultipath: fix priorities in parse_vpd_pg83 - -The priorities for the EUI-64 (0x02) and NAME (0x08) scsi identifiers in -parse_vpd_pg83() don't match their priorities in 55-scsi-sg3_id.rules. -Switch them so that they match. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/discovery.c | 16 ++++++++-------- - 1 file changed, 8 insertions(+), 8 deletions(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 5727f7a6..f8044141 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -1152,19 +1152,19 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, - vpd = d; - } - break; -- case 0x8: -- /* SCSI Name: Prio 4 */ -- if (memcmp(d + 4, "eui.", 4) && -- memcmp(d + 4, "naa.", 4) && -- memcmp(d + 4, "iqn.", 4)) -- break; -+ case 0x2: -+ /* EUI-64: Prio 4 */ - if (prio < 4) { - prio = 4; - vpd = d; - } - break; -- case 0x2: -- /* EUI-64: Prio 3 */ -+ case 0x8: -+ /* SCSI Name: Prio 3 */ -+ if (memcmp(d + 4, "eui.", 4) && -+ memcmp(d + 4, "naa.", 4) && -+ memcmp(d + 4, "iqn.", 4)) -+ break; - if (prio < 3) { - prio = 3; - vpd = d; diff --git a/0145-multipathd-improve-getting-parent-udevice-in-rescan_.patch b/0145-multipathd-improve-getting-parent-udevice-in-rescan_.patch deleted file mode 100644 index a3ceeab..0000000 --- a/0145-multipathd-improve-getting-parent-udevice-in-rescan_.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 24 Mar 2021 21:48:15 -0500 -Subject: [PATCH] multipathd: improve getting parent udevice in rescan_path - -Instead of looping through parents and checking, just call -udev_device_get_parent_with_subsystem_devtype() to get the -right one. - -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 14 +++++--------- - 1 file changed, 5 insertions(+), 9 deletions(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 1df69096..bc747d0e 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -822,16 +822,12 @@ ev_remove_map (char * devname, char * alias, int minor, struct vectors * vecs) - } - - static void --rescan_path(struct udev_device *parent) -+rescan_path(struct udev_device *ud) - { -- while(parent) { -- const char *subsys = udev_device_get_subsystem(parent); -- if (subsys && !strncmp(subsys, "scsi", 4)) -- break; -- parent = udev_device_get_parent(parent); -- } -- if (parent) -- sysfs_attr_set_value(parent, "rescan", "1", strlen("1")); -+ ud = udev_device_get_parent_with_subsystem_devtype(ud, "scsi", -+ "scsi_device"); -+ if (ud) -+ sysfs_attr_set_value(ud, "rescan", "1", strlen("1")); - } - - void diff --git a/0146-multipathd-don-t-trigger-uevent-for-partitions-on-ww.patch b/0146-multipathd-don-t-trigger-uevent-for-partitions-on-ww.patch deleted file mode 100644 index 160adc2..0000000 --- a/0146-multipathd-don-t-trigger-uevent-for-partitions-on-ww.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 24 Mar 2021 23:24:08 -0500 -Subject: [PATCH] multipathd: don't trigger uevent for partitions on wwid - change - -If the wwid changed, the device is no longer the same, so sending add -events to the devices partitions doesn't make any sense. - -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index bc747d0e..3579bad7 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -845,7 +845,6 @@ handle_path_wwid_change(struct path *pp, struct vectors *vecs) - } - rescan_path(udd); - sysfs_attr_set_value(udd, "uevent", "add", strlen("add")); -- trigger_partitions_udev_change(udd, "add", strlen("add")); - udev_device_unref(udd); - } - diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index b8e18d7..c770b71 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,171 +1,25 @@ Name: device-mapper-multipath -Version: 0.8.5 -Release: 6%{?dist} +Version: 0.8.6 +Release: 1%{?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 -L https://github.com/opensvc/multipath-tools/archive/0.8.5.tar.gz -o multipath-tools-0.8.5.tgz -Source0: multipath-tools-0.8.5.tgz +# curl -L https://github.com/opensvc/multipath-tools/archive/0.8.6.tar.gz -o multipath-tools-0.8.6.tgz +Source0: multipath-tools-0.8.6.tgz Source1: multipath.conf -Patch0001: 0001-Change-the-multipath.conf-manpage-uxsock_timeout-def.patch -Patch0002: 0002-libmultipath-find_mpe-don-t-match-with-empty-WWID.patch -Patch0003: 0003-libmultipath-copy-mpp-hwe-from-pp-hwe.patch -Patch0004: 0004-libmultipath-dm_map_present_by_uuid-fix-dm_task_crea.patch -Patch0005: 0005-libdmmp-tests-fix-compilation.patch -Patch0006: 0006-libmultipath-prio-constify-some-function-parameters.patch -Patch0007: 0007-libmultipath-checkers-prio-allow-non-lazy-.so-loadin.patch -Patch0008: 0008-multipath-tools-Makefiles-separate-rules-for-.so-and.patch -Patch0009: 0009-libmultipath-create-separate-.so-for-unit-tests.patch -Patch0010: 0010-libmultipath-add-linker-version-script.patch -Patch0011: 0011-libmpathpersist-add-linker-version-script.patch -Patch0012: 0012-libmpathcmd-add-linker-version-script.patch -Patch0013: 0013-libmpathpersist-initialize-mpp-hwe-in-get_mpvec.patch -Patch0014: 0014-multipathd-allow-shutdown-during-configure.patch -Patch0015: 0015-multipathd-avoid-sending-READY-1-to-systemd-on-early.patch -Patch0016: 0016-multipathd-send-STOPPING-1-to-systemd-on-shutdown.patch -Patch0017: 0017-multipathd-send-RELOADING-1-to-systemd-on-DAEMON_CON.patch -Patch0018: 0018-multipathd-use-volatile-qualifier-for-running_state.patch -Patch0019: 0019-multipathd-generalize-and-fix-wait_for_state_change_.patch -Patch0020: 0020-multipathd-set_config_state-avoid-code-duplication.patch -Patch0021: 0021-multipathd-cancel-threads-early-during-shutdown.patch -Patch0022: 0022-multipath-tools-don-t-call-dm_lib_release-any-more.patch -Patch0023: 0023-libmultipath-devmapper-refactor-libdm-version-determ.patch -Patch0024: 0024-libmultipath-protect-racy-libdevmapper-calls-with-a-.patch -Patch0025: 0025-libmultipath-constify-file-argument-in-config-parser.patch -Patch0026: 0026-libmultipath-provide-defaults-for-get-put-_multipath.patch -Patch0027: 0027-libmpathpersist-allow-using-libmultipath-get-put-_mu.patch -Patch0028: 0028-multipath-use-get_put-_multipath_config-from-libmult.patch -Patch0029: 0029-mpathpersist-use-get-put-_multipath_config-from-libm.patch -Patch0030: 0030-libmultipath-add-udev-and-logsink-symbols.patch -Patch0031: 0031-multipath-remove-logsink-and-udev.patch -Patch0032: 0032-libmpathpersist-call-libmultipath_-init-exit.patch -Patch0033: 0033-mpathpersist-remove-logsink-and-udev.patch -Patch0034: 0034-multipathd-remove-logsink-and-udev.patch -Patch0035: 0035-multipath-tools-add-Vexata-by-StorCentric-VX-arrays.patch -Patch0036: 0036-multipath-tools-Violin-and-Nexsan-were-bought-by-Sto.patch -Patch0037: 0037-libmultipath-fix-memory-leaks-in-coalesce_paths.patch -Patch0038: 0038-multipath-tools-replace-hidden-tab-by-space-in-hwtab.patch -Patch0039: 0039-multipathd-uxlsnr-avoid-deadlock-on-exit.patch -Patch0040: 0040-multipathd-Fix-liburcu-memory-leak.patch -Patch0041: 0041-multipathd-move-handling-of-io_err_stat_attr-into-li.patch -Patch0042: 0042-multipathd-move-vecs-desctruction-into-cleanup-funct.patch -Patch0043: 0043-multipathd-make-some-globals-static.patch -Patch0044: 0044-multipathd-move-threads-destruction-into-separate-fu.patch -Patch0045: 0045-multipathd-move-conf-destruction-into-separate-funct.patch -Patch0046: 0046-multipathd-move-pid-destruction-into-separate-functi.patch -Patch0047: 0047-multipathd-close-pidfile-on-exit.patch -Patch0048: 0048-multipathd-add-helper-for-systemd-notification-at-ex.patch -Patch0049: 0049-multipathd-child-call-cleanups-in-failure-case-too.patch -Patch0050: 0050-multipathd-unwatch_all_dmevents-check-if-waiter-is-i.patch -Patch0051: 0051-multipathd-print-error-message-if-config-can-t-be-lo.patch -Patch0052: 0052-libmultipath-add-libmp_dm_exit.patch -Patch0053: 0053-multipathd-fixup-libdm-deinitialization.patch -Patch0054: 0054-libmultipath-log_thread_stop-check-if-logarea-is-ini.patch -Patch0055: 0055-multipathd-add-cleanup_child-exit-handler.patch -Patch0056: 0056-libmultipath-fix-log_thread-startup-and-teardown.patch -Patch0057: 0057-multipathd-move-cleanup_-prio-checkers-foreign-to-li.patch -Patch0058: 0058-multipath-use-atexit-for-cleanup-handlers.patch -Patch0059: 0059-mpathpersist-use-atexit-for-cleanup-handlers.patch -Patch0060: 0060-multipath-fix-leak-in-check_path_valid.patch -Patch0061: 0061-multipath-tools-mpath-tools.supp-file-with-valgrind-.patch -Patch0062: 0062-libmultipath-use-libmp_verbosity-to-track-verbosity.patch -Patch0063: 0063-libmultipath-introduce-symbolic-values-for-logsink.patch -Patch0064: 0064-libmultipath-simplify-dlog.patch -Patch0065: 0065-multipathd-common-code-for-k-and-command-args.patch -Patch0066: 0066-multipathd-sanitize-uxsock_listen.patch -Patch0067: 0067-libmultipath-fix-race-between-log_safe-and-log_threa.patch -Patch0068: 0068-multipath-add-libmpathvalid-library.patch -Patch0069: 0069-multipath-tools-tests-and-unit-tests-for-libmpathval.patch -Patch0070: 0070-libmultipath-add-uid-failback-for-dasd-devices.patch -Patch0071: 0071-libmultipath-change-log-level-for-null-uid_attribute.patch -Patch0072: 0072-libmultipath-move-fast_io_fail-defines-to-structs.h.patch -Patch0073: 0073-libmultipath-add-eh_deadline-multipath.conf-paramete.patch -Patch0074: 0074-multipathd-remove-redundant-vector_free-int-configur.patch -Patch0075: 0075-libmultipath-factor-out-code-to-get-vpd-page-data.patch -Patch0076: 0076-libmultipath-limit-reading-0xc9-vpd-page.patch -Patch0077: 0077-libmultipath-move-logq_lock-handling-to-log.c.patch -Patch0078: 0078-libmultipath-protect-logarea-with-logq_lock.patch -Patch0079: 0079-libmultipath-prevent-DSO-unloading-with-astray-check.patch -Patch0080: 0080-libmultipath-force-map-reload-if-udev-incomplete.patch -Patch0081: 0081-multipath-tools-avoid-access-to-etc-localtime.patch -Patch0082: 0082-multipath-tools-make-sure-plugin-DSOs-use-symbol-ver.patch -Patch0083: 0083-libmultipath.version-add-missing-symbol.patch -Patch0084: 0084-multipath-tools-tests-unversioned-.so-for-valgrind-t.patch -Patch0085: 0085-multipath-tools-unit-tests-fix-memory-leaks-in-mpath.patch -Patch0086: 0086-mpathpersist-Fix-Register-and-Ignore-with-0x00-SARK.patch -Patch0087: 0087-mpathpersist-update-prkeys-file-on-changing-registra.patch -Patch0088: 0088-libmultipath-warn-about-missing-braces-at-end-of-mul.patch -Patch0089: 0089-libmultipath-ignore-multipaths-sections-without-wwid.patch -Patch0090: 0090-libmultipath-fix-format-warning-with-clang.patch -Patch0091: 0091-libmultipath-check-for-null-wwid-before-strcmp.patch -Patch0092: 0092-multipath.conf.5-Improve-checker_timeout-description.patch -Patch0093: 0093-multipathd-fix-path-checkint-not-changed-when-path-s.patch -Patch0094: 0094-libmultipath-select_action-skip-is_mpp_known_to_udev.patch -Patch0095: 0095-libmultipath-coalesce_paths-stop-triggering-spurious.patch -Patch0096: 0096-Revert-multipathd-uev_trigger-handle-incomplete-ADD-.patch -Patch0097: 0097-libmultipath-make-find_err_path_by_dev-static.patch -Patch0098: 0098-multipathd-avoid-io_err_stat-crash-during-shutdown.patch -Patch0099: 0099-multipathd-avoid-io_err_stat-ABBA-deadlock.patch -Patch0100: 0100-multipathd-use-get_monotonic_time-in-io_err_stat-cod.patch -Patch0101: 0101-multipathd-combine-free_io_err_stat_path-and-destroy.patch -Patch0102: 0102-multipathd-cleanup-logging-for-marginal-paths.patch -Patch0103: 0103-libmultipath-fix-NULL-dereference-in-find_path_by_de.patch -Patch0104: 0104-libmultipath-snprint_devices-avoid-NULL-dereference.patch -Patch0105: 0105-libmpathpersist-fix-thread-safety-of-default-functio.patch -Patch0106: 0106-Added-github-action-for-building.patch -Patch0107: 0107-github-workflow-use-zram-device-as-test-block-device.patch -Patch0108: 0108-github-workflow-use-explicit-Ubuntu-version.patch -Patch0109: 0109-github-workflow-add-valgrind-tests.patch -Patch0110: 0110-github-workflow-run-apt-get-update.patch -Patch0111: 0111-github-workflow-add-tests-with-gcc-10-and-clang.patch -Patch0112: 0112-multipathd-Fix-multipathd-stopping-on-shutdown.patch -Patch0113: 0113-libmultipath-use-3rd-digit-as-transport_id-for-expan.patch -Patch0114: 0114-libmultipath-sysfs_set_nexus_loss_tmo-support-SAS-ex.patch -Patch0115: 0115-multipathd-add-code-to-initalize-unwinder.patch -Patch0116: 0116-libmultipath-check-if-adopt_path-really-added-curren.patch -Patch0117: 0117-multipathd-ev_add_path-fail-if-add_map_with_path-fai.patch -Patch0118: 0118-libmultipath-check-return-value-of-udev_device_get_d.patch -Patch0119: 0119-pathinfo-call-filter_property-after-sysfs_pathinfo.patch -Patch0120: 0120-libmultipath-pathinfo-call-filter_property-only-with.patch -Patch0121: 0121-multipath-w-allow-removing-blacklisted-paths.patch -Patch0122: 0122-libmultipath-fix-use-after-free-in-uev_add_path.patch -Patch0123: 0123-multipath-tools-tests-fix-stringop-overflow-build-er.patch -Patch0124: 0124-libmultipath-cleanup-code-to-strip-wwid-trailing-spa.patch -Patch0125: 0125-libmultipath-cleanup-uid_attribute-checking-code.patch -Patch0126: 0126-multipathd-add-recheck_wwid-option-to-verify-the-pat.patch -Patch0127: 0127-libmultipath-check-if-user_friendly_name-is-in-use.patch -Patch0128: 0128-tests-add-tests-for-checking-if-alias-is-in-use.patch -Patch0129: 0129-multipath-tools-add-DellEMC-PowerStore-to-hardware-t.patch -Patch0130: 0130-multipath-tools-delete-a-space-in-multipath.conf.5-t.patch -Patch0131: 0131-multipath-tools-tests-allow-control-of-test-verbosit.patch -Patch0132: 0132-multipath-tools-devt-test-avoid-failure-when-run-in-.patch -Patch0133: 0133-multipath-tools-fix-compilation-errors-on-32-bit-mus.patch -Patch0134: 0134-libmultipath-fix-compilation-error-with-gcc-10-on-i3.patch -Patch0135: 0135-kpartx-free-loop-device-after-listing-partitions.patch -Patch0136: 0136-libmultipath-merge-update_multipath_table-and-update.patch -Patch0137: 0137-11-dm-mpath.rules-run-multipath-U-with-v1.patch -Patch0138: 0138-multipath-tools-tests-check-if-sys-dev-block-is-non-.patch -Patch0139: 0139-multipathd-reduce-log-levels-in-cli_add_map.patch -Patch0140: 0140-multipath-tools-fix-format-in-multipath.conf.5-to-be.patch -Patch0141: 0141-multipath-tools-use-same-format-for-default-values-i.patch -Patch0142: 0142-multipathd-fix-NULL-dereference-in-check_path.patch -Patch0143: 0143-libmultipath-avoid-infinite-loop-with-bad-vpd-page-8.patch -Patch0144: 0144-libmultipath-fix-priorities-in-parse_vpd_pg83.patch -Patch0145: 0145-multipathd-improve-getting-parent-udevice-in-rescan_.patch -Patch0146: 0146-multipathd-don-t-trigger-uevent-for-partitions-on-ww.patch -Patch0147: 0147-RH-fixup-udev-rules-for-redhat.patch -Patch0148: 0148-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0149: 0149-RH-don-t-start-without-a-config-file.patch -Patch0150: 0150-RH-Fix-nvme-function-missing-argument.patch -Patch0151: 0151-RH-use-rpm-optflags-if-present.patch -Patch0152: 0152-RH-add-mpathconf.patch -Patch0153: 0153-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0154: 0154-RH-reset-default-find_mutipaths-value-to-off.patch -Patch0155: 0155-RH-attempt-to-get-ANA-info-via-sysfs-first.patch -Patch0156: 0156-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +Patch0001: 0001-RH-fixup-udev-rules-for-redhat.patch +Patch0002: 0002-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0003: 0003-RH-don-t-start-without-a-config-file.patch +Patch0004: 0004-RH-Fix-nvme-function-missing-argument.patch +Patch0005: 0005-RH-use-rpm-optflags-if-present.patch +Patch0006: 0006-RH-add-mpathconf.patch +Patch0007: 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0008: 0008-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0009: 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0010: 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -249,7 +103,7 @@ This package contains the files needed to develop applications that use device-mapper-multipath's libdmmp C API library %prep -%autosetup -n multipath-tools-0.8.5 -p1 +%autosetup -n multipath-tools-0.8.6 -p1 cp %{SOURCE1} . %build @@ -363,6 +217,13 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Mon Apr 5 2021 Benjamin Marzinski - 0.8.6-1 +- Update Source to upstream version 0.8.6 + * Previous patches 0001-0146 are included in the commit +- Rename files + * Previous patches 0147-0156 are now patches 0001-0010 +- sync tests with RHEL repository + * Fri Mar 26 2021 Benjamin Marzinski - 0.8.5-6 - Change patch format to remove Git version * Patches 0001-0122 only have the patch format modified diff --git a/sources b/sources index cf508e4..13188ae 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (multipath-tools-0.8.5.tgz) = 3b65f89621203304cdc0d074124627132f0a600c347f2eec03372463737493e3a7da38813d375c1f7d6fe2e55a7d4f7494574f74412534832f217954ba34c293 +SHA512 (multipath-tools-0.8.6.tgz) = 82e5b7307e599ba6b059679c3987a442fb5be4885f0a27c260a99a07cb336b88d48e314b4ec951944e0200e4731522d8da043d98fa566857ecc6d100791c0e38 SHA512 (multipath.conf) = 71953dce5a68adcf60a942305f5a66023e6f4c4baf53b1bfdb4edf65ed5b8e03db804363c36d1dcfd85591f4766f52b515269904c53b84d7b076da0b80b09942 diff --git a/tests/alias_clash/LICENSE b/tests/alias_clash/LICENSE new file mode 100644 index 0000000..10926e8 --- /dev/null +++ b/tests/alias_clash/LICENSE @@ -0,0 +1,675 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 3 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 . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. + diff --git a/tests/alias_clash/PURPOSE b/tests/alias_clash/PURPOSE new file mode 100644 index 0000000..ba496c4 --- /dev/null +++ b/tests/alias_clash/PURPOSE @@ -0,0 +1,20 @@ +verify that multipath doesn't try to assign new devices in-use user_friendly +aliases. + +steps: +1. setup config file and remove existing bindings file +2. create scsi_debug devices +3. start multipathd to create devices and bindings file +4. look at path device ordering in multipathd output +5. stop multipathd and remove devices +6. blacklist the devices which were multipathed early in the config file +7. remove the bindings file +8. restart multipathd to create devices, where the later devices grab the + earlier user_friendly_names +9. stop multipathd +10. remove blacklists from the config file and remove bindings file +11. restart multipathd +12. Verify that all devices are there, the previously existing devices + still have the same alias, and all the devices match the bindings file +13. reconfigure multipathd +14. Verify that all devices are still there and still match. diff --git a/tests/alias_clash/main.sh b/tests/alias_clash/main.sh new file mode 100755 index 0000000..6e3b23c --- /dev/null +++ b/tests/alias_clash/main.sh @@ -0,0 +1,122 @@ +#!/bin/bash + +# Copyright (c) 2021 Red Hat, Inc. +# +# 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 3 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 . + +# Author: Benjamin Marzinski + +source ../include/ec.sh || exit 200 +tlog "running $0" + +cleanup () +{ + trun "multipathd disablequeueing maps" + sleep 5 + trun "multipath -DF" + trun "service multipathd stop" + sleep 5 + trun "udevadm settle" + trun "modprobe -r scsi_debug" +} + +assert () +{ + local cmd="$*" + _trun_ "$cmd" 0 + if test $? -eq 0; then + tpass_ "$cmd" ; + else + tfail_ "$cmd" ; + cleanup ; + tend ; + fi +} + +tlog "running $0" + +rpm -q device-mapper-multipath || dnf install -y device-mapper-multipath + +# cleanup existing devices and restart +cleanup +trun "rm -f /etc/multipath.conf" +trun "rm -f /etc/multipath.conf.bak" +trun "rm -r /etc/multipath/bindings" +trun "mpathconf --enable --with_module y --with_multipathd n --find_multipaths n" +sed -i '/^blacklist[[:space:]]*{/ a\ + device {\n vendor ".*"\n product ".*"\n } +' /etc/multipath.conf +if grep -qw blacklist_exceptions /etc/multipath.conf ; then + sed -i '/^blacklist_exceptions[[:space:]]*{/ a\ + device {\n vendor Linux\n product scsi_debug\n } +' /etc/multipath.conf +else + cat << _EOF_ >> /etc/multipath.conf +blacklist_exceptions { + device { + vendor Linux + product scsi_debug + } +} +_EOF_ +fi +trun "modprobe scsi_debug num_tgts=20 vpd_use_hostno=0" +sleep 5 +trun "service multipathd start" +sleep 5 +pathcount=`multipathd show paths raw format %w | wc -l` +assert "[[ $pathcount -eq 20 ]]" +wwids=`multipathd show paths raw format " wwid %w" | sed '11,$d'` +wwids="${wwids//$'\n'/\\n}" +trun "multipath -DF" +trun "service multipathd stop" +sleep 5 +tnot "pidof multipathd" +tok "cp /etc/multipath.conf /etc/mulitpath.conf.bak" +sed -i '/^blacklist[[:space:]]*{/ a\ +'"$wwids"' +' /etc/multipath.conf +tok "rm -f /etc/multipath/bindings" +trun "service multipathd start" +sleep 5 +mapcount=`multipathd show maps raw format %w | wc -l` +assert "[[ $mapcount -eq 10 ]]" +orig_maps=`multipathd show maps raw format "%n %w"` +trun "service multipathd stop" +sleep 5 +tnot "pidof multipathd" +tok "mv -f /etc/mulitpath.conf.bak /etc/multipath.conf" +tok "rm -f /etc/multipath/bindings" +trun "service multipathd start" +sleep 5 +mapcount=`multipathd show maps raw format %w | wc -l` +assert "[[ $mapcount -eq 20 ]]" +new_maps=`multipathd show maps raw format "%n %w" | sort` +tlog "Checking if devices have been renamed" +while IFS= read -r line; do + echo "$new_maps" | grep "$line" + assert "[[ $? -eq 0 ]]" +done <<< "$orig_maps" +bindings=`cat /etc/multipath/bindings | sed '/^#.*$/d' | sort` +tlog "Checking if devices match bindings" +assert "[[ \"$new_maps\" = \"$bindings\" ]]" +trun "service multipathd reload" +sleep 5 +mapcount=`multipathd show maps raw format %w | wc -l` +assert "[[ $mapcount -eq 20 ]]" +reload_maps=`multipathd show maps raw format "%n %w" | sort` +tlog "Checking if devices change on reconfigure" +assert "[[ \"$new_maps\" = \"$reload_maps\" ]]" +cleanup +tend diff --git a/tests/find_multipaths/main.sh b/tests/find_multipaths/main.sh index ed51e10..a39af79 100755 --- a/tests/find_multipaths/main.sh +++ b/tests/find_multipaths/main.sh @@ -20,54 +20,79 @@ #set -x source ../include/ec.sh || exit 200 +cleanup () +{ + trun "multipathd disablequeueing maps" + trun "service multipathd stop" + sleep 5 + trun "udevadm settle" + trun "multipath -F" + sleep 5 + trun "modprobe -r scsi_debug" +} + tlog "running $0" # which not set find_multipaths yes, so multipath always create a multipath device for single device # so stop service and reconfig with --find_multipaths y, and reload/start the service again. -trun "service multipathd stop" rpm -q device-mapper-multipath || yum install -y device-mapper-multipath # test with find_multipath=y, will not multipath for the single device; reload/start the service to enable the config -trun "mpathconf --enable --user_friendly_names y --find_multipaths y --with_multipathd y" -trun "service multipathd status" -# use scsi_debug to simulate a drive -trun "multipath -F" -terr "modprobe -r scsi_debug" +cleanup +trun "rm -f /etc/multipath.conf" +trun "mpathconf --enable --user_friendly_names y --find_multipaths y --with_multipathd n" +sed -i '/^blacklist[[:space:]]*{/ a\ + device {\n vendor ".*"\n product ".*"\n } +' /etc/multipath.conf +if grep -qw blacklist_exceptions /etc/multipath.conf ; then + sed -i '/^blacklist_exceptions[[:space:]]*{/ a\ + device {\n vendor Linux\n product scsi_debug\n } +' /etc/multipath.conf +else + cat << _EOF_ >> /etc/multipath.conf +blacklist_exceptions { + device { + vendor Linux + product scsi_debug + } +} +_EOF_ +fi +trun "service multipathd start" trun "modprobe scsi_debug" -sleep 3 +sleep 5 trun "multipath -W" cat /etc/multipath/wwids trun "multipath" disk_path=$(get_scsi_debug_devices) disk_node=$(basename $disk_path) mpath_name=$(get_mpath_disk_by_scsi_device $disk_node) -tok '[[ -z $mpath_name ]]' +tok '[[ $mpath_name = "[orphan]" ]]' # test with find_multipath=n, will multipath for the single device -trun "mpathconf --enable --user_friendly_names y --find_multipaths n --with_multipathd y" +trun "mpathconf --user_friendly_names y --find_multipaths n --with_multipathd y" sleep 5 -trun "multipath" mpath_name=$(get_mpath_disk_by_scsi_device $disk_node) tok "is_mpath $mpath_name" # flush new created path -sleep 3 trun "multipath -F" -sleep 3 +sleep 1 # test with find_multipath=y, A path has the same WWID as a multipath device that was previously created -trun "mpathconf --enable --user_friendly_names y --find_multipaths y --with_multipathd y" +trun "mpathconf --user_friendly_names y --find_multipaths y --with_multipathd y" sleep 5 -trun "multipath" mpath_name=$(get_mpath_disk_by_scsi_device $disk_node) tok "is_mpath $mpath_name" +trun "multipath -F" +sleep 1 # Clear wwid, test with find_multipath=y, will not multipath for the single device trun "multipath -W" -trun "mpathconf --disable --with_multipathd y" +trun "service multipathd reload" sleep 5 mpath_name=$(get_mpath_disk_by_scsi_device $disk_node) -tok '[[ -z $mpath_name ]]' +tok '[[ $mpath_name = "[orphan]" ]]' trun "multipath -F" sleep 5 @@ -81,14 +106,7 @@ disk_node=$(basename $disk_paths) mpath_name=$(get_mpath_disk_by_scsi_device $disk_node) tok "is_mpath $mpath_name" -sleep 10 - -trun "multipath -F" -sleep 5 -trun "modprobe -r scsi_debug" -# remove the scsi_debug wwid -trun "service multipathd stop" -sleep 3 +cleanup trun "multipath -W" cat /etc/multipath/wwids tend diff --git a/tests/include/mpath.sh b/tests/include/mpath.sh index 806225e..b894c27 100644 --- a/tests/include/mpath.sh +++ b/tests/include/mpath.sh @@ -78,8 +78,7 @@ get_mpath_disk_by_scsi_device() { # multipathd_running || texit "multipathd is not running" local disk=$1 - wwid=$(get_wwid_of_disk $disk) - local mpath=$(multipathd show maps format %w,%n | grep "^$wwid\s*," \ + local mpath=$(multipathd show paths raw format "%d,%m" | grep "^$disk\s*," \ | awk -F, '{ print $2 }' | sed 's/\s//g') echo $mpath } diff --git a/tests/multipath_conf_syntax/main.sh b/tests/multipath_conf_syntax/main.sh index f29109d..331d65e 100755 --- a/tests/multipath_conf_syntax/main.sh +++ b/tests/multipath_conf_syntax/main.sh @@ -17,96 +17,129 @@ # Author: Lin Li +source ../include/ec.sh || exit 200 +tlog "running $0" -# Include Beaker environment -. /usr/bin/rhts-environment.sh || exit 1 -. /usr/share/beakerlib/beakerlib.sh || exit 1 +cleanup () +{ + trun "multipathd disablequeueing maps" + sleep 5 + trun "multipath -F" + trun "service multipathd stop" + sleep 5 + trun "udevadm settle" + trun "modprobe -r scsi_debug" +} -PACKAGE="device-mapper-multipath" +assert () +{ + local cmd="$*" + _trun_ "$cmd" 0 + if test $? -eq 0; then + tpass_ "$cmd" ; + else + tfail_ "$cmd" ; + cleanup ; + tend ; + fi +} -rlJournalStart - rlPhaseStartSetup - rlAssertRpm $PACKAGE - rlRun "multipath -F; sleep 5" - rlRun "modprobe -r scsi_debug" 0 "Remove if scsi_debug load before" - rlRun "rm -f /etc/multipath.conf" - rlRun "mpathconf --enable --with_module y --with_multipathd y --find_multipaths n" 0 "Set up multipath" - rlServiceStart multipathd - rlRun "cp /etc/multipath.conf /etc/multipath.conf.bak" 0 "Backup /etc/multipath.conf first" - rlPhaseEnd +rpm -q device-mapper-multipath || yum install -y device-mapper-multipath - rlPhaseStartTest - rlRun "modprobe scsi_debug" - sleep 5 - rlLogInfo "`multipath -ll`" - wwid=`multipathd show maps format %w | grep -v uuid` - # test missing closing quote on alias - cat << _EOF_ >> /etc/multipath.conf -multipaths { - multipath { - wwid "$wwid" - alias "mypath - } +# cleanup existing devices and restart +cleanup +trun "rm -f /etc/multipath.conf" +trun "mpathconf --enable --with_module y --with_multipathd n --find_multipaths n" +sed -i '/^blacklist[[:space:]]*{/ a\ + device {\n vendor ".*"\n product ".*"\n } +' /etc/multipath.conf +if grep -qw blacklist_exceptions /etc/multipath.conf ; then + sed -i '/^blacklist_exceptions[[:space:]]*{/ a\ + device {\n vendor Linux\n product scsi_debug\n } +' /etc/multipath.conf +else + cat << _EOF_ >> /etc/multipath.conf +blacklist_exceptions { + device { + vendor Linux + product scsi_debug + } } _EOF_ - rlRun "multipath 2>&1 | grep 'missing closing quotes on line'" 0 "test missing closing quote on alias" - rlRun "multipath -r" - rlRun "multipath -ll |grep mypath" 0 "check if mpath rename to mypath successfully" +fi - # test no value for alias - rlRun "sed -i 's/alias.*$/alias/g' /etc/multipath.conf" - rlRun "multipath 2>&1 | grep \"missing value for option 'alias' on line\"" 0 "test no value for alias" - rlRun "multipath -r" - rlRun "multipath -ll |grep mpath*" 0 "check if mpath rename to mpath* from mypath successfully" +trun "cp /etc/multipath.conf /etc/multipath.conf.bak" +trun "service multipathd stop" +trun "service multipathd start" - # test missing starting quote on alias - rlRun "sed -i 's/alias.*$/alias mypath\"/g' /etc/multipath.conf" - rlRun "multipath 2>&1 |grep 'ignoring extra data starting with'" 0 "test missing starting quote on alias" - rlRun "multipath -r" - rlRun "multipath -ll |grep mypath" 0 "check if mpath rename to mypath successfully" +trun "modprobe scsi_debug" +sleep 5 +trun "multipath -ll" +pathcount=`multipathd show maps format %w | grep -v uuid | wc -l` +assert "[[ $pathcount -eq 1 ]]" +wwid=`multipathd show maps format %w | grep -v uuid` - # test wrong quote on alias - rlRun "sed -i 's/alias.*$/alias /g' /etc/multipath.conf" - rlRun "multipath 2>&1 | grep config" 1 "no warning" - rlRun "multipath -r" - rlRun "multipath -ll |grep ''" 0 "check if mpath rename to successfully" +# test missing closing quote on alias +cat << _EOF_ >> /etc/multipath.conf +multipaths { + multipath { + wwid "$wwid" + alias "mypath + } +} +_EOF_ +tok "multipath 2>&1 | grep 'missing closing quotes on line'" +trun "multipath -r" +tok "multipath -ll | grep mypath" - # test value has a space - rlRun "sed -i 's/alias.*$/alias mypath test/g' /etc/multipath.conf" - rlRun "multipath 2>&1 |grep 'ignoring extra data starting with'" 0 "test value has a space" - rlRun "multipath -r" - rlRun "multipath -ll |grep mypath" 0 "check if mpath rename to mypath successfully" +# test no value for alias +trun "sed -i 's/alias.*$/alias/g' /etc/multipath.conf" +multipath +tok "multipath 2>&1 | grep \"missing value for option 'alias' on line\"" +trun "multipath -r" +tok "multipath -ll | grep mpath" - # test wrong alias keyword - rlRun "sed -i 's/alias.*$/alia mypath/g' /etc/multipath.conf" - rlRun "multipath 2>&1 |grep 'invalid keyword: alia'" 0 "invalid keyword: alia" - rlRun "multipath -r" - rlRun "multipath -ll |grep mpath*" 0 "check if mpath rename to mpath* from mypath successfully" - rlRun "sed -i 's/alia.*$/alias mypath/g' /etc/multipath.conf" +# test missing starting quote on alias +trun "sed -i 's/alias.*$/alias mypath\"/g' /etc/multipath.conf" +tok "multipath 2>&1 |grep 'ignoring extra data starting with'" +trun "multipath -r" +tok "multipath -ll | grep mypath" - # test no space between the section name and the open bracket that followed it - # fix issue about if a section doesn't have a space between the section name and the open bracket, that section isn't read in. - rlRun "sed -i 's/multipaths.*/multipaths{/g' /etc/multipath.conf" - rlRun "multipath 2>&1 | grep config" 1 "no warning" - rlRun "multipath -r" - rlRun "multipath -ll |grep mypath" 0 "check if mpath rename to mypath successfully" +# test wrong quote on alias +trun "sed -i 's/alias.*$/alias /g' /etc/multipath.conf" +tnot "multipath 2>&1 | grep config" +trun "multipath -r" +tok "multipath -ll | grep ''" - # test wrong section keywords - rlRun "sed -i 's/multipaths.*/ultipaths {/g' /etc/multipath.conf" - rlRun "multipath 2>&1 | grep 'invalid keyword: ultipaths'" 0 "test wrong multipaths section keyword" - rlRun "sed -i 's/defaults.*/efaults {/g' /etc/multipath.conf" - rlRun "multipath 2>&1 | grep 'invalid keyword: efaults'" 0 "test wrong defaults section keyword" - rlRun "sed -i 's/blacklist {/lacklist {/g' /etc/multipath.conf" - rlRun "multipath 2>&1 | grep 'invalid keyword: lacklist'" 0 "test wrong blacklist section keyword" +# test value has a space +trun "sed -i 's/alias.*$/alias mypath test/g' /etc/multipath.conf" +tok "multipath 2>&1 |grep 'ignoring extra data starting with'" +trun "multipath -r" +tok "multipath -ll | grep mypath" - rlPhaseEnd +# test wrong alias keyword +trun "sed -i 's/alias.*$/alia mypath/g' /etc/multipath.conf" +tok "multipath 2>&1 | grep 'invalid keyword: alia'" +trun "multipath -r" +tok "multipath -ll | grep mpath" +trun "sed -i 's/alia.*$/alias mypath/g' /etc/multipath.conf" - rlPhaseStartCleanup - rlRun "udevadm settle" - rlRun "multipath -F" 0 "Flush all unused multipath device maps" - rlServiceStop multipathd - rlRun "modprobe -r scsi_debug" 0 "Remove scsi_debug" - rlRun "cp -f /etc/multipath.conf.bak /etc/multipath.conf" 0 "Recovery /etc/multipath.conf" - rlPhaseEnd -rlJournalPrintText -rlJournalEnd +# test no space between the section name and the open bracket that followed it +# fix issue about if a section doesn't have a space between the section name +# and the open bracket, that section isn't read in. +trun "sed -i 's/multipaths.*/multipaths{/g' /etc/multipath.conf" +tnot "multipath 2>&1 | grep config" +trun "multipath -r" +tok "multipath -ll |grep mypath" + +# test wrong section keywords +trun "sed -i 's/multipaths.*/ultipaths {/g' /etc/multipath.conf" +tok "multipath 2>&1 | grep 'invalid keyword: ultipaths'" +trun "sed -i 's/defaults.*/efaults {/g' /etc/multipath.conf" +tok "multipath 2>&1 | grep 'invalid keyword: efaults'" +trun "sed -i 's/blacklist {/lacklist {/g' /etc/multipath.conf" +tok "multipath 2>&1 | grep 'invalid keyword: lacklist'" +trun "mv /etc/multipath.conf.bak /etc/multipath.conf" + +cleanup +tend diff --git a/tests/restate_module/main.sh b/tests/restate_module/main.sh index 6d5b0c5..7f3279d 100755 --- a/tests/restate_module/main.sh +++ b/tests/restate_module/main.sh @@ -93,4 +93,5 @@ path_state=`multipathd show paths raw format "%d %t %T %o" | grep ${pathname} | tlog "Checking state of ${pathname}" assert "[[ $path_state -eq 1 ]]" +cleanup tend diff --git a/tests/tests.yml b/tests/tests.yml index 4c396d2..15f26d2 100644 --- a/tests/tests.yml +++ b/tests/tests.yml @@ -27,15 +27,17 @@ - bindings: run: ./main.sh timeout: 15m - required_packages: - - device-mapper-multipath - - perl - - - role: standard-test-beakerlib - tags: - - classic - tests: + - restate_module: + run: ./main.sh + timeout: 15m + - find_multipaths: + run: ./main.sh + timeout: 15m - multipath_conf_syntax: + run: ./main.sh + timeout: 15m + - alias_clash: + run: ./main.sh timeout: 15m required_packages: - device-mapper-multipath From db52ccc87f5d3e351c227302aafaf5e220a1b7b6 Mon Sep 17 00:00:00 2001 From: Cole Robinson Date: Wed, 23 Jun 2021 12:15:13 -0400 Subject: [PATCH 18/67] Rebuild for userspace-rcu soname bump Signed-off-by: Cole Robinson --- device-mapper-multipath.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index c770b71..a1940f8 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.8.6 -Release: 1%{?dist} +Release: 1%{?dist}.1 Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -217,6 +217,9 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Wed Jun 23 2021 Cole Robinson - 0.8.6-1.fc35.1 +- Rebuild for userspace-rcu soname bump + * Mon Apr 5 2021 Benjamin Marzinski - 0.8.6-1 - Update Source to upstream version 0.8.6 * Previous patches 0001-0146 are included in the commit From c64a48b95f7e2e6601fd6472b753770a384a9f9b Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 1 Jul 2021 15:23:09 -0500 Subject: [PATCH 19/67] device-mapper-multipath-0.8.6-2 Pull in latest upstream post-tag commits * Patches 0001-0015 are from https://github.com/openSUSE/multipath-tools/tree/queue and are already queued for upstream Rename files * Previous patches 0001-0010 and now patches 0016-0025 --- ...-memory-leak-in-checker_cleanup_thre.patch | 32 ++ ...x-compilation-issue-with-liburcu-0.8.patch | 85 +++++ ...-fail-to-remove-path-once-the-map-is.patch | 70 ++++ ...e-duplicate-orphan_paths-in-flush_ma.patch | 27 ++ ...-ev_remove_path-return-code-handling.patch | 226 ++++++++++++ ...-multipath-free-vectors-in-configure.patch | 47 +++ ...ak-memory-when-getblock-returns-NULL.patch | 28 ++ ...-rescan_path-on-wwid-change-in-uev_u.patch | 28 ++ ...andlers-cleanup-setting-reply-length.patch | 82 +++++ ...ipathd-cli_getprkey-fix-return-value.patch | 53 +++ ...path-tools-enable-Wformat-overflow-2.patch | 64 ++++ ...LD_BUILD_TIMESTAMP-when-building-man.patch | 347 ++++++++++++++++++ ...add-info-about-HPE-Alletra-6000-and-.patch | 52 +++ ...multipathd-don-t-start-in-containers.patch | 32 ++ ...fix-build-without-LIBDM_API_DEFERRED.patch | 59 +++ ... 0016-RH-fixup-udev-rules-for-redhat.patch | 2 +- ...property-blacklist-exception-builtin.patch | 0 ...RH-don-t-start-without-a-config-file.patch | 2 +- ...H-Fix-nvme-function-missing-argument.patch | 0 ... 0020-RH-use-rpm-optflags-if-present.patch | 11 +- ...hconf.patch => 0021-RH-add-mpathconf.patch | 0 ...om-kernel-cmdline-mpath.wwids-with-A.patch | 12 +- ...-default-find_mutipaths-value-to-off.patch | 0 ...empt-to-get-ANA-info-via-sysfs-first.patch | 0 ...-parse_vpd_pg83-match-scsi_id-output.patch | 2 +- device-mapper-multipath.spec | 45 ++- 26 files changed, 1281 insertions(+), 25 deletions(-) create mode 100644 0001-libmultipath-fix-memory-leak-in-checker_cleanup_thre.patch create mode 100644 0002-multipathd-fix-compilation-issue-with-liburcu-0.8.patch create mode 100644 0003-multipathd-don-t-fail-to-remove-path-once-the-map-is.patch create mode 100644 0004-multipathd-remove-duplicate-orphan_paths-in-flush_ma.patch create mode 100644 0005-multipathd-fix-ev_remove_path-return-code-handling.patch create mode 100644 0006-multipath-free-vectors-in-configure.patch create mode 100644 0007-kpartx-Don-t-leak-memory-when-getblock-returns-NULL.patch create mode 100644 0008-multipathd-don-t-rescan_path-on-wwid-change-in-uev_u.patch create mode 100644 0009-multipathd-cli_handlers-cleanup-setting-reply-length.patch create mode 100644 0010-multipathd-cli_getprkey-fix-return-value.patch create mode 100644 0011-multipath-tools-enable-Wformat-overflow-2.patch create mode 100644 0012-libdmmp-use-KBUILD_BUILD_TIMESTAMP-when-building-man.patch create mode 100644 0013-multipath-tools-add-info-about-HPE-Alletra-6000-and-.patch create mode 100644 0014-multipathd-don-t-start-in-containers.patch create mode 100644 0015-libmultipath-fix-build-without-LIBDM_API_DEFERRED.patch rename 0001-RH-fixup-udev-rules-for-redhat.patch => 0016-RH-fixup-udev-rules-for-redhat.patch (98%) rename 0002-RH-Remove-the-property-blacklist-exception-builtin.patch => 0017-RH-Remove-the-property-blacklist-exception-builtin.patch (100%) rename 0003-RH-don-t-start-without-a-config-file.patch => 0018-RH-don-t-start-without-a-config-file.patch (99%) rename 0004-RH-Fix-nvme-function-missing-argument.patch => 0019-RH-Fix-nvme-function-missing-argument.patch (100%) rename 0005-RH-use-rpm-optflags-if-present.patch => 0020-RH-use-rpm-optflags-if-present.patch (85%) rename 0006-RH-add-mpathconf.patch => 0021-RH-add-mpathconf.patch (100%) rename 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch => 0022-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch (95%) rename 0008-RH-reset-default-find_mutipaths-value-to-off.patch => 0023-RH-reset-default-find_mutipaths-value-to-off.patch (100%) rename 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch => 0024-RH-attempt-to-get-ANA-info-via-sysfs-first.patch (100%) rename 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch => 0025-RH-make-parse_vpd_pg83-match-scsi_id-output.patch (97%) diff --git a/0001-libmultipath-fix-memory-leak-in-checker_cleanup_thre.patch b/0001-libmultipath-fix-memory-leak-in-checker_cleanup_thre.patch new file mode 100644 index 0000000..5e389f3 --- /dev/null +++ b/0001-libmultipath-fix-memory-leak-in-checker_cleanup_thre.patch @@ -0,0 +1,32 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: lixiaokeng +Date: Fri, 9 Apr 2021 15:15:05 +0800 +Subject: [PATCH] libmultipath: fix memory leak in checker_cleanup_thread + +If checker_cleanup_thread is called after cleanup_checkers, +the checker_class will not be freed. + +Here, we use free_checker_class instead of checker_class_unref +in checker_cleanup_thread. + +Signed-off-by: Lixiaokeng +Reviewed-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/checkers.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmultipath/checkers.c b/libmultipath/checkers.c +index 2dd9915d..8039c2bf 100644 +--- a/libmultipath/checkers.c ++++ b/libmultipath/checkers.c +@@ -368,7 +368,7 @@ static void checker_cleanup_thread(void *arg) + { + struct checker_class *cls = arg; + +- (void)checker_class_unref(cls); ++ free_checker_class(cls); + rcu_unregister_thread(); + } + diff --git a/0002-multipathd-fix-compilation-issue-with-liburcu-0.8.patch b/0002-multipathd-fix-compilation-issue-with-liburcu-0.8.patch new file mode 100644 index 0000000..a9c4af4 --- /dev/null +++ b/0002-multipathd-fix-compilation-issue-with-liburcu-0.8.patch @@ -0,0 +1,85 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 12 May 2021 23:06:51 +0200 +Subject: [PATCH] multipathd: fix compilation issue with liburcu < 0.8 + +To avoid race conditions with pending RCU callbacks on exit, it's +necessary to call rcu_barrier() in cleanup_rcu() (see +https://lists.lttng.org/pipermail/lttng-dev/2021-May/029958.html and +follow-ups). + +rcu_barrier() is only available in User-space RCU v0.8 and newer. +Fix it by reverting 5d0dae6 ("multipathd: Fix liburcu memory leak") +if an older version of liburcu is detected. + +Fixes: 5d0dae6 ("multipathd: Fix liburcu memory leak") +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipathd/Makefile | 2 ++ + multipathd/main.c | 17 +++++++++++++++-- + 2 files changed, 17 insertions(+), 2 deletions(-) + +diff --git a/multipathd/Makefile b/multipathd/Makefile +index d053c1ed..393b6cbb 100644 +--- a/multipathd/Makefile ++++ b/multipathd/Makefile +@@ -16,6 +16,8 @@ LDFLAGS += $(BIN_LDFLAGS) + LIBDEPS += -L$(multipathdir) -lmultipath -L$(mpathpersistdir) -lmpathpersist \ + -L$(mpathcmddir) -lmpathcmd -ludev -ldl -lurcu -lpthread \ + -ldevmapper -lreadline ++CFLAGS += $(shell $(PKGCONFIG) --modversion liburcu 2>/dev/null | \ ++ awk -F. '{ printf("-DURCU_VERSION=0x%06x", 256 * ( 256 * $$1 + $$2) + $$3); }') + + ifdef SYSTEMD + CFLAGS += -DUSE_SYSTEMD=$(SYSTEMD) +diff --git a/multipathd/main.c b/multipathd/main.c +index 102946bf..c34fd9c8 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -3031,6 +3031,10 @@ static void cleanup_threads(void) + pthread_attr_destroy(&waiter_attr); + } + ++#ifndef URCU_VERSION ++# define URCU_VERSION 0 ++#endif ++#if (URCU_VERSION >= 0x000800) + /* + * Use a non-default call_rcu_data for child(). + * +@@ -3040,6 +3044,9 @@ static void cleanup_threads(void) + * can't be joined with pthread_join(), leaving a memory leak. + * + * Therefore we create our own, which can be destroyed and joined. ++ * The cleanup handler needs to call rcu_barrier(), which is only ++ * available in user-space RCU v0.8 and newer. See ++ * https://lists.lttng.org/pipermail/lttng-dev/2021-May/029958.html + */ + static struct call_rcu_data *setup_rcu(void) + { +@@ -3072,6 +3079,7 @@ static void cleanup_rcu(void) + } + rcu_unregister_thread(); + } ++#endif /* URCU_VERSION */ + + static void cleanup_child(void) + { +@@ -3116,9 +3124,14 @@ child (__attribute__((unused)) void *param) + init_unwinder(); + mlockall(MCL_CURRENT | MCL_FUTURE); + signal_init(); ++#if (URCU_VERSION >= 0x000800) + mp_rcu_data = setup_rcu(); +- +- if (atexit(cleanup_rcu) || atexit(cleanup_child)) ++ if (atexit(cleanup_rcu)) ++ fprintf(stderr, "failed to register RCU cleanup handler\n"); ++#else ++ rcu_init(); ++#endif ++ if (atexit(cleanup_child)) + fprintf(stderr, "failed to register cleanup handlers\n"); + + setup_thread_attr(&misc_attr, 64 * 1024, 0); diff --git a/0003-multipathd-don-t-fail-to-remove-path-once-the-map-is.patch b/0003-multipathd-don-t-fail-to-remove-path-once-the-map-is.patch new file mode 100644 index 0000000..89d027a --- /dev/null +++ b/0003-multipathd-don-t-fail-to-remove-path-once-the-map-is.patch @@ -0,0 +1,70 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 17 May 2021 11:29:54 -0500 +Subject: [PATCH] multipathd: don't fail to remove path once the map is removed + +In ev_remove_path(), if update_mpp_paths() fails, we delete the entire +map. However, since update_mpp_paths() happens before we call +set_path_removed(), pp->initialized isn't set to INIT_REMOVED, so +remove_map_and_stop_waiter() doesn't remove the path when in removes the +map. But with the map removed, there's nothing to keep us from removing +the path. + +Call set_path_removed() before update_mpp_paths() to avoid the odd case +of ev_remove_path() removing the map but not the path. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/structs_vec.c | 4 ++-- + multipathd/main.c | 13 ++++++++----- + 2 files changed, 10 insertions(+), 7 deletions(-) + +diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c +index d242c06b..75390198 100644 +--- a/libmultipath/structs_vec.c ++++ b/libmultipath/structs_vec.c +@@ -45,8 +45,8 @@ int update_mpp_paths(struct multipath *mpp, vector pathvec) + + /* + * Avoid adding removed paths to the map again +- * when we reload it. Such paths may exist if +- * domap fails in ev_remove_path(). ++ * when we reload it. Such paths may exist in ++ * ev_remove_paths() or if it returns failure. + */ + pp1 = find_path_by_devt(pathvec, pp->dev_t); + if (pp1 && pp->initialized != INIT_REMOVED && +diff --git a/multipathd/main.c b/multipathd/main.c +index c34fd9c8..2062bc10 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -1199,6 +1199,13 @@ ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map) + * avoid referring to the map of an orphaned path + */ + if ((mpp = pp->mpp)) { ++ /* ++ * Mark the path as removed. In case of success, we ++ * will delete it for good. Otherwise, it will be deleted ++ * later, unless all attempts to reload this map fail. ++ */ ++ set_path_removed(pp); ++ + /* + * transform the mp->pg vector of vectors of paths + * into a mp->params string to feed the device-mapper +@@ -1210,13 +1217,9 @@ ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map) + } + + /* +- * Mark the path as removed. In case of success, we +- * will delete it for good. Otherwise, it will be deleted +- * later, unless all attempts to reload this map fail. +- * Note: we have to explicitly remove pp from mpp->paths, ++ * we have to explicitly remove pp from mpp->paths, + * update_mpp_paths() doesn't do that. + */ +- set_path_removed(pp); + i = find_slot(mpp->paths, pp); + if (i != -1) + vector_del_slot(mpp->paths, i); diff --git a/0004-multipathd-remove-duplicate-orphan_paths-in-flush_ma.patch b/0004-multipathd-remove-duplicate-orphan_paths-in-flush_ma.patch new file mode 100644 index 0000000..636a18c --- /dev/null +++ b/0004-multipathd-remove-duplicate-orphan_paths-in-flush_ma.patch @@ -0,0 +1,27 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 17 May 2021 11:29:55 -0500 +Subject: [PATCH] multipathd: remove duplicate orphan_paths in flush_map + +remove_map_and_stop_waiter() already calls orphan_paths() so flush_map() +doesn't need to call orphan_paths() before calling +remove_map_and_stop_waiter(). + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + multipathd/main.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 2062bc10..266d6b44 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -660,7 +660,6 @@ flush_map(struct multipath * mpp, struct vectors * vecs, int nopaths) + else + condlog(2, "%s: map flushed", mpp->alias); + +- orphan_paths(vecs->pathvec, mpp, "map flushed"); + remove_map_and_stop_waiter(mpp, vecs); + + return 0; diff --git a/0005-multipathd-fix-ev_remove_path-return-code-handling.patch b/0005-multipathd-fix-ev_remove_path-return-code-handling.patch new file mode 100644 index 0000000..74bf879 --- /dev/null +++ b/0005-multipathd-fix-ev_remove_path-return-code-handling.patch @@ -0,0 +1,226 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 17 May 2021 11:29:56 -0500 +Subject: [PATCH] multipathd: fix ev_remove_path return code handling + +When ev_remove_path() returned success, callers assumed that the path +(and possibly the map) had been removed. When ev_remove_path() returned +failure, callers assumed that the path had not been removed. However, +the path could be removed on both success or failure. This could cause +callers to dereference the path after it was removed. + +To deal with this, make ev_remove_path() return a different symbolic +value for each outcome, and make the callers react appropriately for +the different values. Found by coverity. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + multipathd/cli_handlers.c | 24 +++++++++++++++++++++-- + multipathd/main.c | 41 ++++++++++++++++++++------------------- + multipathd/main.h | 14 +++++++++++++ + 3 files changed, 57 insertions(+), 22 deletions(-) + +diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c +index 1de6ad8e..6765fcf0 100644 +--- a/multipathd/cli_handlers.c ++++ b/multipathd/cli_handlers.c +@@ -752,7 +752,8 @@ cli_add_path (void * v, char ** reply, int * len, void * data) + /* Have the checker reinstate this path asap */ + pp->tick = 1; + return 0; +- } else if (!ev_remove_path(pp, vecs, true)) ++ } else if (ev_remove_path(pp, vecs, true) & ++ REMOVE_PATH_SUCCESS) + /* Path removed in ev_remove_path() */ + pp = NULL; + else { +@@ -813,6 +814,7 @@ cli_del_path (void * v, char ** reply, int * len, void * data) + struct vectors * vecs = (struct vectors *)data; + char * param = get_keyparam(v, PATH); + struct path *pp; ++ int ret; + + param = convert_dev(param, 1); + condlog(2, "%s: remove path (operator)", param); +@@ -821,7 +823,25 @@ cli_del_path (void * v, char ** reply, int * len, void * data) + condlog(0, "%s: path already removed", param); + return 1; + } +- return ev_remove_path(pp, vecs, 1); ++ ret = ev_remove_path(pp, vecs, 1); ++ if (ret == REMOVE_PATH_DELAY) { ++ *reply = strdup("delayed\n"); ++ if (*reply) ++ *len = strlen(*reply) + 1; ++ else { ++ *len = 0; ++ ret = REMOVE_PATH_FAILURE; ++ } ++ } else if (ret == REMOVE_PATH_MAP_ERROR) { ++ *reply = strdup("map reload error. removed\n"); ++ if (*reply) ++ *len = strlen(*reply) + 1; ++ else { ++ *len = 0; ++ ret = REMOVE_PATH_FAILURE; ++ } ++ } ++ return (ret == REMOVE_PATH_FAILURE); + } + + int +diff --git a/multipathd/main.c b/multipathd/main.c +index 266d6b44..26a4e44e 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -838,7 +838,7 @@ handle_path_wwid_change(struct path *pp, struct vectors *vecs) + return; + + udd = udev_device_ref(pp->udev); +- if (ev_remove_path(pp, vecs, 1) != 0 && pp->mpp) { ++ if (!(ev_remove_path(pp, vecs, 1) & REMOVE_PATH_SUCCESS) && pp->mpp) { + pp->dmstate = PSTATE_FAILED; + dm_fail_path(pp->mpp->alias, pp->dev_t); + } +@@ -948,8 +948,8 @@ uev_add_path (struct uevent *uev, struct vectors * vecs, int need_do_map) + * Make another attempt to remove the path + */ + pp->mpp = prev_mpp; +- ret = ev_remove_path(pp, vecs, true); +- if (ret != 0) { ++ if (!(ev_remove_path(pp, vecs, true) & ++ REMOVE_PATH_SUCCESS)) { + /* + * Failure in ev_remove_path will keep + * path in pathvec in INIT_REMOVED state +@@ -960,6 +960,7 @@ uev_add_path (struct uevent *uev, struct vectors * vecs, int need_do_map) + dm_fail_path(pp->mpp->alias, pp->dev_t); + condlog(1, "%s: failed to re-add path still mapped in %s", + pp->dev, pp->mpp->alias); ++ ret = 1; + } else if (r == PATHINFO_OK) + /* + * Path successfully freed, move on to +@@ -1167,7 +1168,6 @@ static int + uev_remove_path (struct uevent *uev, struct vectors * vecs, int need_do_map) + { + struct path *pp; +- int ret; + + condlog(3, "%s: remove path (uevent)", uev->kernel); + delete_foreign(uev->udev); +@@ -1177,21 +1177,18 @@ uev_remove_path (struct uevent *uev, struct vectors * vecs, int need_do_map) + pthread_testcancel(); + pp = find_path_by_dev(vecs->pathvec, uev->kernel); + if (pp) +- ret = ev_remove_path(pp, vecs, need_do_map); ++ ev_remove_path(pp, vecs, need_do_map); + lock_cleanup_pop(vecs->lock); +- if (!pp) { +- /* Not an error; path might have been purged earlier */ ++ if (!pp) /* Not an error; path might have been purged earlier */ + condlog(0, "%s: path already removed", uev->kernel); +- return 0; +- } +- return ret; ++ return 0; + } + + int + ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map) + { + struct multipath * mpp; +- int i, retval = 0; ++ int i, retval = REMOVE_PATH_SUCCESS; + char params[PARAMS_SIZE] = {0}; + + /* +@@ -1245,7 +1242,6 @@ ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map) + condlog(2, "%s: removed map after" + " removing all paths", + alias); +- retval = 0; + /* flush_map() has freed the path */ + goto out; + } +@@ -1262,11 +1258,14 @@ ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map) + + if (mpp->wait_for_udev) { + mpp->wait_for_udev = 2; ++ retval = REMOVE_PATH_DELAY; + goto out; + } + +- if (!need_do_map) ++ if (!need_do_map) { ++ retval = REMOVE_PATH_DELAY; + goto out; ++ } + /* + * reload the map + */ +@@ -1275,7 +1274,7 @@ ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map) + condlog(0, "%s: failed in domap for " + "removal of path %s", + mpp->alias, pp->dev); +- retval = 1; ++ retval = REMOVE_PATH_FAILURE; + } else { + /* + * update our state from kernel +@@ -1283,12 +1282,12 @@ ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map) + char devt[BLK_DEV_SIZE]; + + strlcpy(devt, pp->dev_t, sizeof(devt)); ++ ++ /* setup_multipath will free the path ++ * regardless of whether it succeeds or ++ * fails */ + if (setup_multipath(vecs, mpp)) +- return 1; +- /* +- * Successful map reload without this path: +- * sync_map_state() will free it. +- */ ++ return REMOVE_PATH_MAP_ERROR; + sync_map_state(mpp); + + condlog(2, "%s: path removed from map %s", +@@ -1304,8 +1303,10 @@ out: + return retval; + + fail: ++ condlog(0, "%s: error removing path. removing map %s", pp->dev, ++ mpp->alias); + remove_map_and_stop_waiter(mpp, vecs); +- return 1; ++ return REMOVE_PATH_MAP_ERROR; + } + + static int +diff --git a/multipathd/main.h b/multipathd/main.h +index ddd953f9..bc1f938f 100644 +--- a/multipathd/main.h ++++ b/multipathd/main.h +@@ -13,6 +13,20 @@ enum daemon_status { + DAEMON_STATUS_SIZE, + }; + ++enum remove_path_result { ++ REMOVE_PATH_FAILURE = 0x0, /* path could not be removed. It is still ++ * part of the kernel map, but its state ++ * is set to INIT_REMOVED, and it will be ++ * removed at the next possible occassion */ ++ REMOVE_PATH_SUCCESS = 0x1, /* path was removed */ ++ REMOVE_PATH_DELAY = 0x2, /* path is set to be removed later. it ++ * currently still exists and is part of the ++ * kernel map */ ++ REMOVE_PATH_MAP_ERROR = 0x5, /* map was removed because of error. value ++ * includes REMOVE_PATH_SUCCESS bit ++ * because the path was also removed */ ++}; ++ + struct prout_param_descriptor; + struct prin_resp; + diff --git a/0006-multipath-free-vectors-in-configure.patch b/0006-multipath-free-vectors-in-configure.patch new file mode 100644 index 0000000..9c8a08e --- /dev/null +++ b/0006-multipath-free-vectors-in-configure.patch @@ -0,0 +1,47 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 17 May 2021 11:29:57 -0500 +Subject: [PATCH] multipath: free vectors in configure + +configure() can retry multiple times, each time reallocing a maps and +paths vector, and leaking the previous ones. Fix this by always freeing +the vectors before configure() exits. Found by coverity. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + multipath/main.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/multipath/main.c b/multipath/main.c +index ef89c7cf..8fc0e15f 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -466,7 +466,6 @@ configure (struct config *conf, enum mpath_cmds cmd, + */ + curmp = vector_alloc(); + pathvec = vector_alloc(); +- atexit(cleanup_vecs); + + if (!curmp || !pathvec) { + condlog(0, "can not allocate memory"); +@@ -578,6 +577,11 @@ out: + if (refwwid) + FREE(refwwid); + ++ free_multipathvec(curmp, KEEP_PATHS); ++ vecs.mpvec = NULL; ++ free_pathvec(pathvec, FREE_PATHS); ++ vecs.pathvec = NULL; ++ + return r; + } + +@@ -823,6 +827,7 @@ main (int argc, char *argv[]) + conf = get_multipath_config(); + conf->retrigger_tries = 0; + conf->force_sync = 1; ++ atexit(cleanup_vecs); + while ((arg = getopt(argc, argv, ":adDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { + switch(arg) { + case 1: printf("optarg : %s\n",optarg); diff --git a/0007-kpartx-Don-t-leak-memory-when-getblock-returns-NULL.patch b/0007-kpartx-Don-t-leak-memory-when-getblock-returns-NULL.patch new file mode 100644 index 0000000..3cf456a --- /dev/null +++ b/0007-kpartx-Don-t-leak-memory-when-getblock-returns-NULL.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 17 May 2021 11:29:58 -0500 +Subject: [PATCH] kpartx: Don't leak memory when getblock returns NULL + +If a new block was allocated, but couldn't be filled, getblock will +discard it. When it does so, it needs to free the block to avoid leaking +memory. Found by coverity. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + kpartx/kpartx.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/kpartx/kpartx.c b/kpartx/kpartx.c +index 8ff116b8..7bc64543 100644 +--- a/kpartx/kpartx.c ++++ b/kpartx/kpartx.c +@@ -766,6 +766,8 @@ getblock (int fd, unsigned int blknr) { + if (read(fd, bp->block, secsz) != secsz) { + fprintf(stderr, "read error, sector %d\n", secnr); + blockhead = bp->next; ++ free(bp->block); ++ free(bp); + return NULL; + } + diff --git a/0008-multipathd-don-t-rescan_path-on-wwid-change-in-uev_u.patch b/0008-multipathd-don-t-rescan_path-on-wwid-change-in-uev_u.patch new file mode 100644 index 0000000..384ccb0 --- /dev/null +++ b/0008-multipathd-don-t-rescan_path-on-wwid-change-in-uev_u.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 17 May 2021 11:29:59 -0500 +Subject: [PATCH] multipathd: don't rescan_path on wwid change in + uev_update_path + +If get_uid() is returning a different wwid in uev_update_path(), then +the uid_attribute must have already gotten updated, which was the +purpose behind calling rescan_path() in the first place. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + multipathd/main.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 26a4e44e..2251e02c 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -1359,7 +1359,6 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) + condlog(0, "%s: path wwid changed from '%s' to '%s'", + uev->kernel, wwid, pp->wwid); + ev_remove_path(pp, vecs, 1); +- rescan_path(uev->udev); + needs_reinit = 1; + goto out; + } else { diff --git a/0009-multipathd-cli_handlers-cleanup-setting-reply-length.patch b/0009-multipathd-cli_handlers-cleanup-setting-reply-length.patch new file mode 100644 index 0000000..3099df6 --- /dev/null +++ b/0009-multipathd-cli_handlers-cleanup-setting-reply-length.patch @@ -0,0 +1,82 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 17 May 2021 22:37:34 +0200 +Subject: [PATCH] multipathd: cli_handlers: cleanup setting reply length + +Create a macro for setting the reply length for string literals +correctly, and use it where necessary. + +In cli_del_path(), don't change the function's return code +if just the buffer allocation for the reply failed. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipathd/cli_handlers.c | 33 ++++++++++++--------------------- + 1 file changed, 12 insertions(+), 21 deletions(-) + +diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c +index 6765fcf0..96064944 100644 +--- a/multipathd/cli_handlers.c ++++ b/multipathd/cli_handlers.c +@@ -32,6 +32,12 @@ + #include "foreign.h" + #include "cli_handlers.h" + ++#define SET_REPLY_AND_LEN(__rep, __len, string_literal) \ ++ do { \ ++ *(__rep) = strdup(string_literal); \ ++ *(__len) = *(__rep) ? sizeof(string_literal) : 0; \ ++ } while (0) ++ + int + show_paths (char ** r, int * len, struct vectors * vecs, char * style, + int pretty) +@@ -802,8 +808,7 @@ cli_add_path (void * v, char ** reply, int * len, void * data) + } + return ev_add_path(pp, vecs, 1); + blacklisted: +- *reply = strdup("blacklisted\n"); +- *len = strlen(*reply) + 1; ++ SET_REPLY_AND_LEN(reply, len, "blacklisted\n"); + condlog(2, "%s: path blacklisted", param); + return 0; + } +@@ -824,23 +829,10 @@ cli_del_path (void * v, char ** reply, int * len, void * data) + return 1; + } + ret = ev_remove_path(pp, vecs, 1); +- if (ret == REMOVE_PATH_DELAY) { +- *reply = strdup("delayed\n"); +- if (*reply) +- *len = strlen(*reply) + 1; +- else { +- *len = 0; +- ret = REMOVE_PATH_FAILURE; +- } +- } else if (ret == REMOVE_PATH_MAP_ERROR) { +- *reply = strdup("map reload error. removed\n"); +- if (*reply) +- *len = strlen(*reply) + 1; +- else { +- *len = 0; +- ret = REMOVE_PATH_FAILURE; +- } +- } ++ if (ret == REMOVE_PATH_DELAY) ++ SET_REPLY_AND_LEN(reply, len, "delayed\n"); ++ else if (ret == REMOVE_PATH_MAP_ERROR) ++ SET_REPLY_AND_LEN(reply, len, "map reload error. removed\n"); + return (ret == REMOVE_PATH_FAILURE); + } + +@@ -865,8 +857,7 @@ cli_add_map (void * v, char ** reply, int * len, void * data) + invalid = 1; + pthread_cleanup_pop(1); + if (invalid) { +- *reply = strdup("blacklisted\n"); +- *len = strlen(*reply) + 1; ++ SET_REPLY_AND_LEN(reply, len, "blacklisted\n"); + condlog(2, "%s: map blacklisted", param); + return 1; + } diff --git a/0010-multipathd-cli_getprkey-fix-return-value.patch b/0010-multipathd-cli_getprkey-fix-return-value.patch new file mode 100644 index 0000000..841190b --- /dev/null +++ b/0010-multipathd-cli_getprkey-fix-return-value.patch @@ -0,0 +1,53 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 17 May 2021 22:45:05 +0200 +Subject: [PATCH] multipathd: cli_getprkey(): fix return value + +By setting (*reply)[19] = '\0', we always truncated a possible +":aptpl" suffix. Fix it, and use the return value of snprintf() +as length. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipathd/cli_handlers.c | 17 ++++++++--------- + 1 file changed, 8 insertions(+), 9 deletions(-) + +diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c +index 96064944..59d44b45 100644 +--- a/multipathd/cli_handlers.c ++++ b/multipathd/cli_handlers.c +@@ -1540,7 +1540,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 = ""; ++ uint64_t key; + + mapname = convert_dev(mapname, 0); + condlog(3, "%s: get persistent reservation key (operator)", mapname); +@@ -1553,17 +1553,16 @@ cli_getprkey(void * v, char ** reply, int * len, void * data) + if (!*reply) + return 1; + +- if (!get_be64(mpp->reservation_key)) { ++ key = get_be64(mpp->reservation_key); ++ if (!key) { + sprintf(*reply, "none\n"); +- *len = strlen(*reply) + 1; ++ *len = sizeof("none\n"); + return 0; + } +- if (mpp->sa_flags & MPATH_F_APTPL_MASK) +- flagstr = ":aptpl"; +- snprintf(*reply, 26, "0x%" PRIx64 "%s\n", +- get_be64(mpp->reservation_key), flagstr); +- (*reply)[19] = '\0'; +- *len = strlen(*reply) + 1; ++ ++ /* This snprintf() can't overflow - PRIx64 needs max 16 chars */ ++ *len = snprintf(*reply, 26, "0x%" PRIx64 "%s\n", key, ++ mpp->sa_flags & MPATH_F_APTPL_MASK ? ":aptpl" : "") + 1; + return 0; + } + diff --git a/0011-multipath-tools-enable-Wformat-overflow-2.patch b/0011-multipath-tools-enable-Wformat-overflow-2.patch new file mode 100644 index 0000000..ab6f670 --- /dev/null +++ b/0011-multipath-tools-enable-Wformat-overflow-2.patch @@ -0,0 +1,64 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 17 May 2021 22:43:02 +0200 +Subject: [PATCH] multipath-tools: enable -Wformat-overflow=2 + +Allow the compiler to catch possible format string overflows. +Two were found by gcc 10. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 3 ++- + libmultipath/discovery.c | 2 +- + libmultipath/print.c | 4 ++-- + 3 files changed, 5 insertions(+), 4 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index f1e23131..91100a20 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -95,9 +95,10 @@ TEST_CC_OPTION = $(shell \ + STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector) + ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers,) + WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered -Wno-error=clobbered,) ++WFORMATOVERFLOW := $(call TEST_CC_OPTION,-Wformat-overflow=2,) + + OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 +-WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 -Werror=implicit-int \ ++WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int \ + -Werror=implicit-function-declaration -Werror=format-security \ + $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) + CPPFLAGS := -Wp,-D_FORTIFY_SOURCE=2 +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index ec99a7aa..bfe2f56c 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -635,7 +635,7 @@ sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp) + { + struct udev_device *rport_dev = NULL; + char value[16], *eptr; +- char rport_id[32]; ++ char rport_id[42]; + unsigned int tmo; + int ret; + +diff --git a/libmultipath/print.c b/libmultipath/print.c +index 8151e11e..3c69bf48 100644 +--- a/libmultipath/print.c ++++ b/libmultipath/print.c +@@ -1,4 +1,4 @@ +-/* ++ /* + * Copyright (c) 2005 Christophe Varoqui + */ + #include +@@ -594,7 +594,7 @@ int + snprint_tgt_wwpn (char * buff, size_t len, const struct path * pp) + { + struct udev_device *rport_dev = NULL; +- char rport_id[32]; ++ char rport_id[42]; + const char *value = NULL; + int ret; + diff --git a/0012-libdmmp-use-KBUILD_BUILD_TIMESTAMP-when-building-man.patch b/0012-libdmmp-use-KBUILD_BUILD_TIMESTAMP-when-building-man.patch new file mode 100644 index 0000000..af81882 --- /dev/null +++ b/0012-libdmmp-use-KBUILD_BUILD_TIMESTAMP-when-building-man.patch @@ -0,0 +1,347 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 17 May 2021 23:12:10 +0200 +Subject: [PATCH] libdmmp: use KBUILD_BUILD_TIMESTAMP when building man pages + +Use the latest commit timestamp of the "libdmmp.h" file as +the timestamp for the man pages. This should avoid spurious rebuilds +of the documentation. + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libdmmp/Makefile | 2 ++ + libdmmp/docs/man/dmmp_context_free.3 | 2 +- + libdmmp/docs/man/dmmp_context_log_func_set.3 | 2 +- + libdmmp/docs/man/dmmp_context_log_priority_get.3 | 2 +- + libdmmp/docs/man/dmmp_context_log_priority_set.3 | 2 +- + libdmmp/docs/man/dmmp_context_new.3 | 2 +- + libdmmp/docs/man/dmmp_context_timeout_get.3 | 2 +- + libdmmp/docs/man/dmmp_context_timeout_set.3 | 2 +- + libdmmp/docs/man/dmmp_context_userdata_get.3 | 2 +- + libdmmp/docs/man/dmmp_context_userdata_set.3 | 2 +- + libdmmp/docs/man/dmmp_flush_mpath.3 | 2 +- + libdmmp/docs/man/dmmp_last_error_msg.3 | 2 +- + libdmmp/docs/man/dmmp_log_priority_str.3 | 2 +- + libdmmp/docs/man/dmmp_mpath_array_free.3 | 2 +- + libdmmp/docs/man/dmmp_mpath_array_get.3 | 2 +- + libdmmp/docs/man/dmmp_mpath_kdev_name_get.3 | 2 +- + libdmmp/docs/man/dmmp_mpath_name_get.3 | 2 +- + libdmmp/docs/man/dmmp_mpath_wwid_get.3 | 2 +- + libdmmp/docs/man/dmmp_path_array_get.3 | 2 +- + libdmmp/docs/man/dmmp_path_blk_name_get.3 | 2 +- + libdmmp/docs/man/dmmp_path_group_array_get.3 | 2 +- + libdmmp/docs/man/dmmp_path_group_id_get.3 | 2 +- + libdmmp/docs/man/dmmp_path_group_priority_get.3 | 2 +- + libdmmp/docs/man/dmmp_path_group_selector_get.3 | 2 +- + libdmmp/docs/man/dmmp_path_group_status_get.3 | 2 +- + libdmmp/docs/man/dmmp_path_group_status_str.3 | 2 +- + libdmmp/docs/man/dmmp_path_status_get.3 | 2 +- + libdmmp/docs/man/dmmp_path_status_str.3 | 2 +- + libdmmp/docs/man/dmmp_reconfig.3 | 2 +- + libdmmp/docs/man/dmmp_strerror.3 | 2 +- + 30 files changed, 31 insertions(+), 29 deletions(-) + +diff --git a/libdmmp/Makefile b/libdmmp/Makefile +index 764a0bc5..79b92fb2 100644 +--- a/libdmmp/Makefile ++++ b/libdmmp/Makefile +@@ -76,6 +76,8 @@ docs/man/%.3.gz: docs/man/%.3 + docs/man/dmmp_strerror.3: $(HEADERS) + TEMPFILE=$(shell mktemp); \ + cat $^ | perl docs/doc-preclean.pl >$$TEMPFILE; \ ++ LC_ALL=C \ ++ KBUILD_BUILD_TIMESTAMP=`git log -n1 --pretty=%cd --date=iso -- $^` \ + perl docs/kernel-doc -man $$TEMPFILE | \ + perl docs/split-man.pl docs/man; \ + rm -f $$TEMPFILE +diff --git a/libdmmp/docs/man/dmmp_context_free.3 b/libdmmp/docs/man/dmmp_context_free.3 +index 0d26f42c..7c109e13 100644 +--- a/libdmmp/docs/man/dmmp_context_free.3 ++++ b/libdmmp/docs/man/dmmp_context_free.3 +@@ -1,4 +1,4 @@ +-.TH "dmmp_context_free" 3 "dmmp_context_free" "March 2021" "Device Mapper Multipath API - libdmmp Manual" ++.TH "dmmp_context_free" 3 "dmmp_context_free" "March 2018" "Device Mapper Multipath API - libdmmp Manual" + .SH NAME + dmmp_context_free \- Release the memory of struct dmmp_context. + .SH SYNOPSIS +diff --git a/libdmmp/docs/man/dmmp_context_log_func_set.3 b/libdmmp/docs/man/dmmp_context_log_func_set.3 +index 986793db..be311ecf 100644 +--- a/libdmmp/docs/man/dmmp_context_log_func_set.3 ++++ b/libdmmp/docs/man/dmmp_context_log_func_set.3 +@@ -1,4 +1,4 @@ +-.TH "dmmp_context_log_func_set" 3 "dmmp_context_log_func_set" "March 2021" "Device Mapper Multipath API - libdmmp Manual" ++.TH "dmmp_context_log_func_set" 3 "dmmp_context_log_func_set" "March 2018" "Device Mapper Multipath API - libdmmp Manual" + .SH NAME + dmmp_context_log_func_set \- Set log handler function. + .SH SYNOPSIS +diff --git a/libdmmp/docs/man/dmmp_context_log_priority_get.3 b/libdmmp/docs/man/dmmp_context_log_priority_get.3 +index 9a273a28..be383013 100644 +--- a/libdmmp/docs/man/dmmp_context_log_priority_get.3 ++++ b/libdmmp/docs/man/dmmp_context_log_priority_get.3 +@@ -1,4 +1,4 @@ +-.TH "dmmp_context_log_priority_get" 3 "dmmp_context_log_priority_get" "March 2021" "Device Mapper Multipath API - libdmmp Manual" ++.TH "dmmp_context_log_priority_get" 3 "dmmp_context_log_priority_get" "March 2018" "Device Mapper Multipath API - libdmmp Manual" + .SH NAME + dmmp_context_log_priority_get \- Get log priority. + .SH SYNOPSIS +diff --git a/libdmmp/docs/man/dmmp_context_log_priority_set.3 b/libdmmp/docs/man/dmmp_context_log_priority_set.3 +index 469c5a49..79e4d2e8 100644 +--- a/libdmmp/docs/man/dmmp_context_log_priority_set.3 ++++ b/libdmmp/docs/man/dmmp_context_log_priority_set.3 +@@ -1,4 +1,4 @@ +-.TH "dmmp_context_log_priority_set" 3 "dmmp_context_log_priority_set" "March 2021" "Device Mapper Multipath API - libdmmp Manual" ++.TH "dmmp_context_log_priority_set" 3 "dmmp_context_log_priority_set" "March 2018" "Device Mapper Multipath API - libdmmp Manual" + .SH NAME + dmmp_context_log_priority_set \- Set log priority. + .SH SYNOPSIS +diff --git a/libdmmp/docs/man/dmmp_context_new.3 b/libdmmp/docs/man/dmmp_context_new.3 +index 0eaeb00d..12505f91 100644 +--- a/libdmmp/docs/man/dmmp_context_new.3 ++++ b/libdmmp/docs/man/dmmp_context_new.3 +@@ -1,4 +1,4 @@ +-.TH "dmmp_context_new" 3 "dmmp_context_new" "March 2021" "Device Mapper Multipath API - libdmmp Manual" ++.TH "dmmp_context_new" 3 "dmmp_context_new" "March 2018" "Device Mapper Multipath API - libdmmp Manual" + .SH NAME + dmmp_context_new \- Create struct dmmp_context. + .SH SYNOPSIS +diff --git a/libdmmp/docs/man/dmmp_context_timeout_get.3 b/libdmmp/docs/man/dmmp_context_timeout_get.3 +index 1df27936..2ed825d5 100644 +--- a/libdmmp/docs/man/dmmp_context_timeout_get.3 ++++ b/libdmmp/docs/man/dmmp_context_timeout_get.3 +@@ -1,4 +1,4 @@ +-.TH "dmmp_context_timeout_get" 3 "dmmp_context_timeout_get" "March 2021" "Device Mapper Multipath API - libdmmp Manual" ++.TH "dmmp_context_timeout_get" 3 "dmmp_context_timeout_get" "March 2018" "Device Mapper Multipath API - libdmmp Manual" + .SH NAME + dmmp_context_timeout_get \- Get IPC timeout. + .SH SYNOPSIS +diff --git a/libdmmp/docs/man/dmmp_context_timeout_set.3 b/libdmmp/docs/man/dmmp_context_timeout_set.3 +index f3d77092..16bc9d99 100644 +--- a/libdmmp/docs/man/dmmp_context_timeout_set.3 ++++ b/libdmmp/docs/man/dmmp_context_timeout_set.3 +@@ -1,4 +1,4 @@ +-.TH "dmmp_context_timeout_set" 3 "dmmp_context_timeout_set" "March 2021" "Device Mapper Multipath API - libdmmp Manual" ++.TH "dmmp_context_timeout_set" 3 "dmmp_context_timeout_set" "March 2018" "Device Mapper Multipath API - libdmmp Manual" + .SH NAME + dmmp_context_timeout_set \- Set IPC timeout. + .SH SYNOPSIS +diff --git a/libdmmp/docs/man/dmmp_context_userdata_get.3 b/libdmmp/docs/man/dmmp_context_userdata_get.3 +index fb713d50..eff446c6 100644 +--- a/libdmmp/docs/man/dmmp_context_userdata_get.3 ++++ b/libdmmp/docs/man/dmmp_context_userdata_get.3 +@@ -1,4 +1,4 @@ +-.TH "dmmp_context_userdata_get" 3 "dmmp_context_userdata_get" "March 2021" "Device Mapper Multipath API - libdmmp Manual" ++.TH "dmmp_context_userdata_get" 3 "dmmp_context_userdata_get" "March 2018" "Device Mapper Multipath API - libdmmp Manual" + .SH NAME + dmmp_context_userdata_get \- Get user data pointer. + .SH SYNOPSIS +diff --git a/libdmmp/docs/man/dmmp_context_userdata_set.3 b/libdmmp/docs/man/dmmp_context_userdata_set.3 +index c5bf63f3..d7be869f 100644 +--- a/libdmmp/docs/man/dmmp_context_userdata_set.3 ++++ b/libdmmp/docs/man/dmmp_context_userdata_set.3 +@@ -1,4 +1,4 @@ +-.TH "dmmp_context_userdata_set" 3 "dmmp_context_userdata_set" "March 2021" "Device Mapper Multipath API - libdmmp Manual" ++.TH "dmmp_context_userdata_set" 3 "dmmp_context_userdata_set" "March 2018" "Device Mapper Multipath API - libdmmp Manual" + .SH NAME + dmmp_context_userdata_set \- Set user data pointer. + .SH SYNOPSIS +diff --git a/libdmmp/docs/man/dmmp_flush_mpath.3 b/libdmmp/docs/man/dmmp_flush_mpath.3 +index cdfd5266..359607ed 100644 +--- a/libdmmp/docs/man/dmmp_flush_mpath.3 ++++ b/libdmmp/docs/man/dmmp_flush_mpath.3 +@@ -1,4 +1,4 @@ +-.TH "dmmp_flush_mpath" 3 "dmmp_flush_mpath" "March 2021" "Device Mapper Multipath API - libdmmp Manual" ++.TH "dmmp_flush_mpath" 3 "dmmp_flush_mpath" "March 2018" "Device Mapper Multipath API - libdmmp Manual" + .SH NAME + dmmp_flush_mpath \- Flush specified multipath device map if unused. + .SH SYNOPSIS +diff --git a/libdmmp/docs/man/dmmp_last_error_msg.3 b/libdmmp/docs/man/dmmp_last_error_msg.3 +index 20acbc6a..378c55a5 100644 +--- a/libdmmp/docs/man/dmmp_last_error_msg.3 ++++ b/libdmmp/docs/man/dmmp_last_error_msg.3 +@@ -1,4 +1,4 @@ +-.TH "dmmp_last_error_msg" 3 "dmmp_last_error_msg" "March 2021" "Device Mapper Multipath API - libdmmp Manual" ++.TH "dmmp_last_error_msg" 3 "dmmp_last_error_msg" "March 2018" "Device Mapper Multipath API - libdmmp Manual" + .SH NAME + dmmp_last_error_msg \- Retrieves the last error message. + .SH SYNOPSIS +diff --git a/libdmmp/docs/man/dmmp_log_priority_str.3 b/libdmmp/docs/man/dmmp_log_priority_str.3 +index 3b5f8284..b2761602 100644 +--- a/libdmmp/docs/man/dmmp_log_priority_str.3 ++++ b/libdmmp/docs/man/dmmp_log_priority_str.3 +@@ -1,4 +1,4 @@ +-.TH "dmmp_log_priority_str" 3 "dmmp_log_priority_str" "March 2021" "Device Mapper Multipath API - libdmmp Manual" ++.TH "dmmp_log_priority_str" 3 "dmmp_log_priority_str" "March 2018" "Device Mapper Multipath API - libdmmp Manual" + .SH NAME + dmmp_log_priority_str \- Convert log priority to string. + .SH SYNOPSIS +diff --git a/libdmmp/docs/man/dmmp_mpath_array_free.3 b/libdmmp/docs/man/dmmp_mpath_array_free.3 +index 8c294e0d..0514a66f 100644 +--- a/libdmmp/docs/man/dmmp_mpath_array_free.3 ++++ b/libdmmp/docs/man/dmmp_mpath_array_free.3 +@@ -1,4 +1,4 @@ +-.TH "dmmp_mpath_array_free" 3 "dmmp_mpath_array_free" "March 2021" "Device Mapper Multipath API - libdmmp Manual" ++.TH "dmmp_mpath_array_free" 3 "dmmp_mpath_array_free" "March 2018" "Device Mapper Multipath API - libdmmp Manual" + .SH NAME + dmmp_mpath_array_free \- Free 'struct dmmp_mpath' pointer array. + .SH SYNOPSIS +diff --git a/libdmmp/docs/man/dmmp_mpath_array_get.3 b/libdmmp/docs/man/dmmp_mpath_array_get.3 +index e211db42..8b0e5b53 100644 +--- a/libdmmp/docs/man/dmmp_mpath_array_get.3 ++++ b/libdmmp/docs/man/dmmp_mpath_array_get.3 +@@ -1,4 +1,4 @@ +-.TH "dmmp_mpath_array_get" 3 "dmmp_mpath_array_get" "March 2021" "Device Mapper Multipath API - libdmmp Manual" ++.TH "dmmp_mpath_array_get" 3 "dmmp_mpath_array_get" "March 2018" "Device Mapper Multipath API - libdmmp Manual" + .SH NAME + dmmp_mpath_array_get \- Query all existing multipath devices. + .SH SYNOPSIS +diff --git a/libdmmp/docs/man/dmmp_mpath_kdev_name_get.3 b/libdmmp/docs/man/dmmp_mpath_kdev_name_get.3 +index e802fe6d..ddead551 100644 +--- a/libdmmp/docs/man/dmmp_mpath_kdev_name_get.3 ++++ b/libdmmp/docs/man/dmmp_mpath_kdev_name_get.3 +@@ -1,4 +1,4 @@ +-.TH "dmmp_mpath_kdev_name_get" 3 "dmmp_mpath_kdev_name_get" "March 2021" "Device Mapper Multipath API - libdmmp Manual" ++.TH "dmmp_mpath_kdev_name_get" 3 "dmmp_mpath_kdev_name_get" "March 2018" "Device Mapper Multipath API - libdmmp Manual" + .SH NAME + dmmp_mpath_kdev_name_get \- Retrieve kernel DEVNAME of certain mpath. + .SH SYNOPSIS +diff --git a/libdmmp/docs/man/dmmp_mpath_name_get.3 b/libdmmp/docs/man/dmmp_mpath_name_get.3 +index d70579e5..2b0027e5 100644 +--- a/libdmmp/docs/man/dmmp_mpath_name_get.3 ++++ b/libdmmp/docs/man/dmmp_mpath_name_get.3 +@@ -1,4 +1,4 @@ +-.TH "dmmp_mpath_name_get" 3 "dmmp_mpath_name_get" "March 2021" "Device Mapper Multipath API - libdmmp Manual" ++.TH "dmmp_mpath_name_get" 3 "dmmp_mpath_name_get" "March 2018" "Device Mapper Multipath API - libdmmp Manual" + .SH NAME + dmmp_mpath_name_get \- Retrieve name(alias) of certain mpath. + .SH SYNOPSIS +diff --git a/libdmmp/docs/man/dmmp_mpath_wwid_get.3 b/libdmmp/docs/man/dmmp_mpath_wwid_get.3 +index 3d060e92..b8e9e7d8 100644 +--- a/libdmmp/docs/man/dmmp_mpath_wwid_get.3 ++++ b/libdmmp/docs/man/dmmp_mpath_wwid_get.3 +@@ -1,4 +1,4 @@ +-.TH "dmmp_mpath_wwid_get" 3 "dmmp_mpath_wwid_get" "March 2021" "Device Mapper Multipath API - libdmmp Manual" ++.TH "dmmp_mpath_wwid_get" 3 "dmmp_mpath_wwid_get" "March 2018" "Device Mapper Multipath API - libdmmp Manual" + .SH NAME + dmmp_mpath_wwid_get \- Retrieve WWID of certain mpath. + .SH SYNOPSIS +diff --git a/libdmmp/docs/man/dmmp_path_array_get.3 b/libdmmp/docs/man/dmmp_path_array_get.3 +index 53340b3d..21f486be 100644 +--- a/libdmmp/docs/man/dmmp_path_array_get.3 ++++ b/libdmmp/docs/man/dmmp_path_array_get.3 +@@ -1,4 +1,4 @@ +-.TH "dmmp_path_array_get" 3 "dmmp_path_array_get" "March 2021" "Device Mapper Multipath API - libdmmp Manual" ++.TH "dmmp_path_array_get" 3 "dmmp_path_array_get" "March 2018" "Device Mapper Multipath API - libdmmp Manual" + .SH NAME + dmmp_path_array_get \- Retrieve path pointer array. + .SH SYNOPSIS +diff --git a/libdmmp/docs/man/dmmp_path_blk_name_get.3 b/libdmmp/docs/man/dmmp_path_blk_name_get.3 +index da5f9f03..5938f0e7 100644 +--- a/libdmmp/docs/man/dmmp_path_blk_name_get.3 ++++ b/libdmmp/docs/man/dmmp_path_blk_name_get.3 +@@ -1,4 +1,4 @@ +-.TH "dmmp_path_blk_name_get" 3 "dmmp_path_blk_name_get" "March 2021" "Device Mapper Multipath API - libdmmp Manual" ++.TH "dmmp_path_blk_name_get" 3 "dmmp_path_blk_name_get" "March 2018" "Device Mapper Multipath API - libdmmp Manual" + .SH NAME + dmmp_path_blk_name_get \- Retrieve block name. + .SH SYNOPSIS +diff --git a/libdmmp/docs/man/dmmp_path_group_array_get.3 b/libdmmp/docs/man/dmmp_path_group_array_get.3 +index 6eee4a2b..ca3187cb 100644 +--- a/libdmmp/docs/man/dmmp_path_group_array_get.3 ++++ b/libdmmp/docs/man/dmmp_path_group_array_get.3 +@@ -1,4 +1,4 @@ +-.TH "dmmp_path_group_array_get" 3 "dmmp_path_group_array_get" "March 2021" "Device Mapper Multipath API - libdmmp Manual" ++.TH "dmmp_path_group_array_get" 3 "dmmp_path_group_array_get" "March 2018" "Device Mapper Multipath API - libdmmp Manual" + .SH NAME + dmmp_path_group_array_get \- Retrieve path groups pointer array. + .SH SYNOPSIS +diff --git a/libdmmp/docs/man/dmmp_path_group_id_get.3 b/libdmmp/docs/man/dmmp_path_group_id_get.3 +index 4f07b536..a84f31f0 100644 +--- a/libdmmp/docs/man/dmmp_path_group_id_get.3 ++++ b/libdmmp/docs/man/dmmp_path_group_id_get.3 +@@ -1,4 +1,4 @@ +-.TH "dmmp_path_group_id_get" 3 "dmmp_path_group_id_get" "March 2021" "Device Mapper Multipath API - libdmmp Manual" ++.TH "dmmp_path_group_id_get" 3 "dmmp_path_group_id_get" "March 2018" "Device Mapper Multipath API - libdmmp Manual" + .SH NAME + dmmp_path_group_id_get \- Retrieve path group ID. + .SH SYNOPSIS +diff --git a/libdmmp/docs/man/dmmp_path_group_priority_get.3 b/libdmmp/docs/man/dmmp_path_group_priority_get.3 +index a48b2704..1cda8af3 100644 +--- a/libdmmp/docs/man/dmmp_path_group_priority_get.3 ++++ b/libdmmp/docs/man/dmmp_path_group_priority_get.3 +@@ -1,4 +1,4 @@ +-.TH "dmmp_path_group_priority_get" 3 "dmmp_path_group_priority_get" "March 2021" "Device Mapper Multipath API - libdmmp Manual" ++.TH "dmmp_path_group_priority_get" 3 "dmmp_path_group_priority_get" "March 2018" "Device Mapper Multipath API - libdmmp Manual" + .SH NAME + dmmp_path_group_priority_get \- Retrieve path group priority. + .SH SYNOPSIS +diff --git a/libdmmp/docs/man/dmmp_path_group_selector_get.3 b/libdmmp/docs/man/dmmp_path_group_selector_get.3 +index 407b3f41..f55477bb 100644 +--- a/libdmmp/docs/man/dmmp_path_group_selector_get.3 ++++ b/libdmmp/docs/man/dmmp_path_group_selector_get.3 +@@ -1,4 +1,4 @@ +-.TH "dmmp_path_group_selector_get" 3 "dmmp_path_group_selector_get" "March 2021" "Device Mapper Multipath API - libdmmp Manual" ++.TH "dmmp_path_group_selector_get" 3 "dmmp_path_group_selector_get" "March 2018" "Device Mapper Multipath API - libdmmp Manual" + .SH NAME + dmmp_path_group_selector_get \- Retrieve path group selector. + .SH SYNOPSIS +diff --git a/libdmmp/docs/man/dmmp_path_group_status_get.3 b/libdmmp/docs/man/dmmp_path_group_status_get.3 +index a81aeb3a..53e68b8e 100644 +--- a/libdmmp/docs/man/dmmp_path_group_status_get.3 ++++ b/libdmmp/docs/man/dmmp_path_group_status_get.3 +@@ -1,4 +1,4 @@ +-.TH "dmmp_path_group_status_get" 3 "dmmp_path_group_status_get" "March 2021" "Device Mapper Multipath API - libdmmp Manual" ++.TH "dmmp_path_group_status_get" 3 "dmmp_path_group_status_get" "March 2018" "Device Mapper Multipath API - libdmmp Manual" + .SH NAME + dmmp_path_group_status_get \- Retrieve path group status. + .SH SYNOPSIS +diff --git a/libdmmp/docs/man/dmmp_path_group_status_str.3 b/libdmmp/docs/man/dmmp_path_group_status_str.3 +index e4a9f74b..98f877a4 100644 +--- a/libdmmp/docs/man/dmmp_path_group_status_str.3 ++++ b/libdmmp/docs/man/dmmp_path_group_status_str.3 +@@ -1,4 +1,4 @@ +-.TH "dmmp_path_group_status_str" 3 "dmmp_path_group_status_str" "March 2021" "Device Mapper Multipath API - libdmmp Manual" ++.TH "dmmp_path_group_status_str" 3 "dmmp_path_group_status_str" "March 2018" "Device Mapper Multipath API - libdmmp Manual" + .SH NAME + dmmp_path_group_status_str \- Convert path group status to string. + .SH SYNOPSIS +diff --git a/libdmmp/docs/man/dmmp_path_status_get.3 b/libdmmp/docs/man/dmmp_path_status_get.3 +index 025cfee5..baa4437d 100644 +--- a/libdmmp/docs/man/dmmp_path_status_get.3 ++++ b/libdmmp/docs/man/dmmp_path_status_get.3 +@@ -1,4 +1,4 @@ +-.TH "dmmp_path_status_get" 3 "dmmp_path_status_get" "March 2021" "Device Mapper Multipath API - libdmmp Manual" ++.TH "dmmp_path_status_get" 3 "dmmp_path_status_get" "March 2018" "Device Mapper Multipath API - libdmmp Manual" + .SH NAME + dmmp_path_status_get \- Retrieve the path status. + .SH SYNOPSIS +diff --git a/libdmmp/docs/man/dmmp_path_status_str.3 b/libdmmp/docs/man/dmmp_path_status_str.3 +index 3944d399..425e472a 100644 +--- a/libdmmp/docs/man/dmmp_path_status_str.3 ++++ b/libdmmp/docs/man/dmmp_path_status_str.3 +@@ -1,4 +1,4 @@ +-.TH "dmmp_path_status_str" 3 "dmmp_path_status_str" "March 2021" "Device Mapper Multipath API - libdmmp Manual" ++.TH "dmmp_path_status_str" 3 "dmmp_path_status_str" "March 2018" "Device Mapper Multipath API - libdmmp Manual" + .SH NAME + dmmp_path_status_str \- Convert path status to string. + .SH SYNOPSIS +diff --git a/libdmmp/docs/man/dmmp_reconfig.3 b/libdmmp/docs/man/dmmp_reconfig.3 +index a743e308..36bd5041 100644 +--- a/libdmmp/docs/man/dmmp_reconfig.3 ++++ b/libdmmp/docs/man/dmmp_reconfig.3 +@@ -1,4 +1,4 @@ +-.TH "dmmp_reconfig" 3 "dmmp_reconfig" "March 2021" "Device Mapper Multipath API - libdmmp Manual" ++.TH "dmmp_reconfig" 3 "dmmp_reconfig" "March 2018" "Device Mapper Multipath API - libdmmp Manual" + .SH NAME + dmmp_reconfig \- Instruct multipathd daemon to do reconfiguration. + .SH SYNOPSIS +diff --git a/libdmmp/docs/man/dmmp_strerror.3 b/libdmmp/docs/man/dmmp_strerror.3 +index 4d753d36..3acd9c9d 100644 +--- a/libdmmp/docs/man/dmmp_strerror.3 ++++ b/libdmmp/docs/man/dmmp_strerror.3 +@@ -1,4 +1,4 @@ +-.TH "dmmp_strerror" 3 "dmmp_strerror" "March 2021" "Device Mapper Multipath API - libdmmp Manual" ++.TH "dmmp_strerror" 3 "dmmp_strerror" "March 2018" "Device Mapper Multipath API - libdmmp Manual" + .SH NAME + dmmp_strerror \- Convert error code to string. + .SH SYNOPSIS diff --git a/0013-multipath-tools-add-info-about-HPE-Alletra-6000-and-.patch b/0013-multipath-tools-add-info-about-HPE-Alletra-6000-and-.patch new file mode 100644 index 0000000..551ba59 --- /dev/null +++ b/0013-multipath-tools-add-info-about-HPE-Alletra-6000-and-.patch @@ -0,0 +1,52 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Sat, 5 Jun 2021 01:01:45 +0200 +Subject: [PATCH] multipath-tools: add info about HPE Alletra 6000 and 9000 + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + README.alua | 2 +- + libmultipath/hwtable.c | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/README.alua b/README.alua +index b15eb487..5d2b1c64 100644 +--- a/README.alua ++++ b/README.alua +@@ -6,7 +6,7 @@ To enable ALUA, the following options should be changed: + - EMC CLARiiON/VNX: + "Failover Mode" should be changed to "4" or "Active-Active mode(ALUA)-failover mode 4" + +-- HPE 3PAR: ++- HPE 3PAR, Primera, and Alletra 9000: + "Host:" should be changed to "Generic-ALUA Persona 2 (UARepLun, SESLun, ALUA)". + + - Promise VTrak/Vess: +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index 58fa7387..e884d8c7 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -107,7 +107,7 @@ static struct hwentry default_hw[] = { + * HPE + */ + { +- /* 3PAR / Primera */ ++ /* 3PAR / Primera / Alletra 9000 */ + .vendor = "3PARdata", + .product = "VV", + .pgpolicy = GROUP_BY_PRIO, +@@ -225,7 +225,7 @@ static struct hwentry default_hw[] = { + .prio_name = PRIO_ALUA, + }, + { +- /* Nimble Storage */ ++ /* Nimble Storage / HPE Alletra 6000 */ + .vendor = "Nimble", + .product = "Server", + .hwhandler = "1 alua", diff --git a/0014-multipathd-don-t-start-in-containers.patch b/0014-multipathd-don-t-start-in-containers.patch new file mode 100644 index 0000000..79fcaf5 --- /dev/null +++ b/0014-multipathd-don-t-start-in-containers.patch @@ -0,0 +1,32 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Utkarsh Gupta +Date: Mon, 7 Jun 2021 20:08:24 +0530 +Subject: [PATCH] multipathd: don't start in containers + +Do not attempt to start multipath-tools in containers, +should switch for on-demand udev/socket based +activation in the future. + +Originally reported as: +https://bugs.launchpad.net/ubuntu/+source/multipath-tools/+bug/1823093 + +Author: Dimitri John Ledkov +Co-Author: Utkarsh Gupta +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + multipathd/multipathd.service | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service +index 7d547fa7..0b2ac814 100644 +--- a/multipathd/multipathd.service ++++ b/multipathd/multipathd.service +@@ -8,6 +8,7 @@ DefaultDependencies=no + Conflicts=shutdown.target + ConditionKernelCommandLine=!nompath + ConditionKernelCommandLine=!multipath=off ++ConditionVirtualization=!container + + [Service] + Type=notify diff --git a/0015-libmultipath-fix-build-without-LIBDM_API_DEFERRED.patch b/0015-libmultipath-fix-build-without-LIBDM_API_DEFERRED.patch new file mode 100644 index 0000000..77068c0 --- /dev/null +++ b/0015-libmultipath-fix-build-without-LIBDM_API_DEFERRED.patch @@ -0,0 +1,59 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 20 May 2021 21:26:01 +0200 +Subject: [PATCH] libmultipath: fix build without LIBDM_API_DEFERRED + +Build fails on distributions that don't support DM_DEFERRED_REMOVE +(libdevmapper < 1.02.89). Fix it. + +Resolves: https://github.com/opensvc/multipath-tools/issues/7 +Tested-by: Paul Menzel +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/devmapper.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index 095cbc0c..47a6d60e 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -49,6 +49,9 @@ static int dm_conf_verbosity; + + #ifdef LIBDM_API_DEFERRED + static int dm_cancel_remove_partmaps(const char * mapname); ++#define __DR_UNUSED__ /* empty */ ++#else ++#define __DR_UNUSED__ __attribute__((unused)) + #endif + + static int do_foreach_partmaps(const char * mapname, +@@ -384,7 +387,8 @@ libmp_dm_task_create(int task) + #define do_deferred(x) ((x) == DEFERRED_REMOVE_ON || (x) == DEFERRED_REMOVE_IN_PROGRESS) + + static int +-dm_simplecmd (int task, const char *name, int no_flush, int need_sync, uint16_t udev_flags, int deferred_remove) { ++dm_simplecmd (int task, const char *name, int no_flush, int need_sync, ++ uint16_t udev_flags, int deferred_remove __DR_UNUSED__) { + int r = 0; + int udev_wait_flag = ((need_sync || udev_flags) && + (task == DM_DEVICE_RESUME || +@@ -1122,7 +1126,8 @@ dm_flush_map_nopaths(const char * mapname, int deferred_remove) + #else + + int +-dm_flush_map_nopaths(const char * mapname, int deferred_remove) ++dm_flush_map_nopaths(const char * mapname, ++ int deferred_remove __attribute__((unused))) + { + return _dm_flush_map(mapname, 1, 0, 0, 0); + } +@@ -1573,7 +1578,7 @@ dm_cancel_deferred_remove (struct multipath *mpp) + #else + + int +-dm_cancel_deferred_remove (struct multipath *mpp) ++dm_cancel_deferred_remove (struct multipath *mpp __attribute__((unused))) + { + return 0; + } diff --git a/0001-RH-fixup-udev-rules-for-redhat.patch b/0016-RH-fixup-udev-rules-for-redhat.patch similarity index 98% rename from 0001-RH-fixup-udev-rules-for-redhat.patch rename to 0016-RH-fixup-udev-rules-for-redhat.patch index e84f9e0..66c702a 100644 --- a/0001-RH-fixup-udev-rules-for-redhat.patch +++ b/0016-RH-fixup-udev-rules-for-redhat.patch @@ -15,7 +15,7 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index f1e23131..c593fd3b 100644 +index 91100a20..6c3714eb 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -55,7 +55,7 @@ endif diff --git a/0002-RH-Remove-the-property-blacklist-exception-builtin.patch b/0017-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 100% rename from 0002-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0017-RH-Remove-the-property-blacklist-exception-builtin.patch diff --git a/0003-RH-don-t-start-without-a-config-file.patch b/0018-RH-don-t-start-without-a-config-file.patch similarity index 99% rename from 0003-RH-don-t-start-without-a-config-file.patch rename to 0018-RH-don-t-start-without-a-config-file.patch index 1d5c693..5290d9e 100644 --- a/0003-RH-don-t-start-without-a-config-file.patch +++ b/0018-RH-don-t-start-without-a-config-file.patch @@ -81,7 +81,7 @@ index 048a838d..8bd47a80 100644 . .\" ---------------------------------------------------------------------------- diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service -index 7d547fa7..af592057 100644 +index 0b2ac814..6d57c7e8 100644 --- a/multipathd/multipathd.service +++ b/multipathd/multipathd.service @@ -4,6 +4,7 @@ Wants=systemd-udev-trigger.service systemd-udev-settle.service diff --git a/0004-RH-Fix-nvme-function-missing-argument.patch b/0019-RH-Fix-nvme-function-missing-argument.patch similarity index 100% rename from 0004-RH-Fix-nvme-function-missing-argument.patch rename to 0019-RH-Fix-nvme-function-missing-argument.patch diff --git a/0005-RH-use-rpm-optflags-if-present.patch b/0020-RH-use-rpm-optflags-if-present.patch similarity index 85% rename from 0005-RH-use-rpm-optflags-if-present.patch rename to 0020-RH-use-rpm-optflags-if-present.patch index debec54..ca542d3 100644 --- a/0005-RH-use-rpm-optflags-if-present.patch +++ b/0020-RH-use-rpm-optflags-if-present.patch @@ -13,19 +13,20 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index c593fd3b..87fb39f2 100644 +index 6c3714eb..db35feb6 100644 --- a/Makefile.inc +++ b/Makefile.inc -@@ -92,15 +92,27 @@ TEST_CC_OPTION = $(shell \ +@@ -92,16 +92,28 @@ TEST_CC_OPTION = $(shell \ echo "$(2)"; \ fi) -STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector) ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers,) WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered -Wno-error=clobbered,) + WFORMATOVERFLOW := $(call TEST_CC_OPTION,-Wformat-overflow=2,) -OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 --WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 -Werror=implicit-int \ +-WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int \ +ifndef RPM_OPT_FLAGS + STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector) + OPTFLAGS := -O2 -g -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions \ @@ -40,7 +41,7 @@ index c593fd3b..87fb39f2 100644 +else + OPTFLAGS := $(RPM_OPT_FLAGS) --param=ssp-buffer-size=4 +endif -+WARNFLAGS := -Werror -Wextra -Wformat=2 -Werror=implicit-int \ ++WARNFLAGS := -Werror -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int \ -Werror=implicit-function-declaration -Werror=format-security \ - $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) -CPPFLAGS := -Wp,-D_FORTIFY_SOURCE=2 @@ -49,7 +50,7 @@ index c593fd3b..87fb39f2 100644 CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ -DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" \ -MMD -MP -@@ -138,4 +150,4 @@ check_file = $(shell \ +@@ -139,4 +151,4 @@ check_file = $(shell \ %.o: %.c @echo building $@ because of $? diff --git a/0006-RH-add-mpathconf.patch b/0021-RH-add-mpathconf.patch similarity index 100% rename from 0006-RH-add-mpathconf.patch rename to 0021-RH-add-mpathconf.patch diff --git a/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0022-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 95% rename from 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0022-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch index 557669b..e842947 100644 --- a/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +++ b/0022-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch @@ -20,7 +20,7 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/multipath/main.c b/multipath/main.c -index ef89c7cf..f618550d 100644 +index 8fc0e15f..9fe53dcd 100644 --- a/multipath/main.c +++ b/multipath/main.c @@ -122,7 +122,7 @@ usage (char * progname) @@ -92,16 +92,16 @@ index ef89c7cf..f618550d 100644 static int configure (struct config *conf, enum mpath_cmds cmd, enum devtypes dev_type, char *devpath) -@@ -823,7 +869,7 @@ main (int argc, char *argv[]) - conf = get_multipath_config(); +@@ -828,7 +874,7 @@ main (int argc, char *argv[]) conf->retrigger_tries = 0; conf->force_sync = 1; + atexit(cleanup_vecs); - while ((arg = getopt(argc, argv, ":adDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { + while ((arg = getopt(argc, argv, ":aAdDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { switch(arg) { case 1: printf("optarg : %s\n",optarg); break; -@@ -900,6 +946,10 @@ main (int argc, char *argv[]) +@@ -905,6 +951,10 @@ main (int argc, char *argv[]) case 'T': cmd = CMD_DUMP_CONFIG; break; @@ -138,10 +138,10 @@ index 5b29a5d9..0478f4e7 100644 Remove the WWID for the specified device from the WWIDs file. . diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service -index af592057..bc8fa07a 100644 +index 6d57c7e8..dfc1e962 100644 --- a/multipathd/multipathd.service +++ b/multipathd/multipathd.service -@@ -15,6 +15,7 @@ Type=notify +@@ -16,6 +16,7 @@ Type=notify NotifyAccess=main LimitCORE=infinity ExecStartPre=-/sbin/modprobe -a scsi_dh_alua scsi_dh_emc scsi_dh_rdac dm-multipath diff --git a/0008-RH-reset-default-find_mutipaths-value-to-off.patch b/0023-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 100% rename from 0008-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0023-RH-reset-default-find_mutipaths-value-to-off.patch diff --git a/0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0024-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 100% rename from 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0024-RH-attempt-to-get-ANA-info-via-sysfs-first.patch diff --git a/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch b/0025-RH-make-parse_vpd_pg83-match-scsi_id-output.patch similarity index 97% rename from 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch rename to 0025-RH-make-parse_vpd_pg83-match-scsi_id-output.patch index 0ab20c5..5ae95ee 100644 --- a/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +++ b/0025-RH-make-parse_vpd_pg83-match-scsi_id-output.patch @@ -13,7 +13,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index ec99a7aa..2704270e 100644 +index bfe2f56c..4bb7ba2f 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c @@ -1135,12 +1135,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index a1940f8..5662b4d 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.8.6 -Release: 1%{?dist}.1 +Release: 2%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -10,16 +10,31 @@ URL: http://christophe.varoqui.free.fr/ # curl -L https://github.com/opensvc/multipath-tools/archive/0.8.6.tar.gz -o multipath-tools-0.8.6.tgz Source0: multipath-tools-0.8.6.tgz Source1: multipath.conf -Patch0001: 0001-RH-fixup-udev-rules-for-redhat.patch -Patch0002: 0002-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0003: 0003-RH-don-t-start-without-a-config-file.patch -Patch0004: 0004-RH-Fix-nvme-function-missing-argument.patch -Patch0005: 0005-RH-use-rpm-optflags-if-present.patch -Patch0006: 0006-RH-add-mpathconf.patch -Patch0007: 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0008: 0008-RH-reset-default-find_mutipaths-value-to-off.patch -Patch0009: 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch -Patch0010: 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +Patch0001: 0001-libmultipath-fix-memory-leak-in-checker_cleanup_thre.patch +Patch0002: 0002-multipathd-fix-compilation-issue-with-liburcu-0.8.patch +Patch0003: 0003-multipathd-don-t-fail-to-remove-path-once-the-map-is.patch +Patch0004: 0004-multipathd-remove-duplicate-orphan_paths-in-flush_ma.patch +Patch0005: 0005-multipathd-fix-ev_remove_path-return-code-handling.patch +Patch0006: 0006-multipath-free-vectors-in-configure.patch +Patch0007: 0007-kpartx-Don-t-leak-memory-when-getblock-returns-NULL.patch +Patch0008: 0008-multipathd-don-t-rescan_path-on-wwid-change-in-uev_u.patch +Patch0009: 0009-multipathd-cli_handlers-cleanup-setting-reply-length.patch +Patch0010: 0010-multipathd-cli_getprkey-fix-return-value.patch +Patch0011: 0011-multipath-tools-enable-Wformat-overflow-2.patch +Patch0012: 0012-libdmmp-use-KBUILD_BUILD_TIMESTAMP-when-building-man.patch +Patch0013: 0013-multipath-tools-add-info-about-HPE-Alletra-6000-and-.patch +Patch0014: 0014-multipathd-don-t-start-in-containers.patch +Patch0015: 0015-libmultipath-fix-build-without-LIBDM_API_DEFERRED.patch +Patch0016: 0016-RH-fixup-udev-rules-for-redhat.patch +Patch0017: 0017-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0018: 0018-RH-don-t-start-without-a-config-file.patch +Patch0019: 0019-RH-Fix-nvme-function-missing-argument.patch +Patch0020: 0020-RH-use-rpm-optflags-if-present.patch +Patch0021: 0021-RH-add-mpathconf.patch +Patch0022: 0022-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0023: 0023-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0024: 0024-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0025: 0025-RH-make-parse_vpd_pg83-match-scsi_id-output.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -217,6 +232,14 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Thu Jul 1 2021 Benjamin Marzinski - 0.8.6-2 +- Pull in latest upstream post-tag commits + * Patches 0001-0015 are from + https://github.com/openSUSE/multipath-tools/tree/queue and are + already queued for upstream +- Rename files + * Previous patches 0001-0010 and now patches 0016-0025 + * Wed Jun 23 2021 Cole Robinson - 0.8.6-1.fc35.1 - Rebuild for userspace-rcu soname bump From a5c63c957bb638d7988c42acbfbb283cf0b9800d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= Date: Sat, 10 Jul 2021 11:52:26 +0200 Subject: [PATCH 20/67] Rebuild for versioned symbols in json-c --- device-mapper-multipath.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 5662b4d..72528fd 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.8.6 -Release: 2%{?dist} +Release: 3%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -232,6 +232,9 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Sat Jul 10 2021 Björn Esser - 0.8.6-3 +- Rebuild for versioned symbols in json-c + * Thu Jul 1 2021 Benjamin Marzinski - 0.8.6-2 - Pull in latest upstream post-tag commits * Patches 0001-0015 are from From 51c88e7181d048b8ab906f269ba1709d2ff1b417 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 21 Jul 2021 20:41:13 +0000 Subject: [PATCH 21/67] - Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- device-mapper-multipath.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 72528fd..bed8ed3 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.8.6 -Release: 3%{?dist} +Release: 4%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -232,6 +232,9 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Wed Jul 21 2021 Fedora Release Engineering - 0.8.6-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild + * Sat Jul 10 2021 Björn Esser - 0.8.6-3 - Rebuild for versioned symbols in json-c From 2d373b68200b07a5b9ce1297d41e4884c02c0737 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Fri, 30 Jul 2021 13:07:22 -0500 Subject: [PATCH 22/67] device-mapper-multipath-0.8.6-5 Update to the head of the upstream staging branch plus redhat patches * Patches 0016-0018 are from the upstream staging branch * Patches 0019-0024 have been submitted upstream Rename files * Previous patches 0016-0025 are now patches 0024-0033 --- ...multipath-use-uint64_t-for-sg_id.lun.patch | 128 ++++++++++++++++++ ...-Remove-trailing-leading-whitespaces.patch | 115 ++++++++++++++++ ...make-HUAWEI-XSG1-config-work-with-al.patch | 63 +++++++++ ...-fix-typo-in-ghost_delay-description.patch | 23 ++++ ...l-commands-when-no-usable-paths-exis.patch | 41 ++++++ ...warning-if-multipathd-is-not-running.patch | 119 ++++++++++++++++ ...move-unneeded-code-in-coalesce_paths.patch | 81 +++++++++++ ...-deal-with-dynamic-PTHREAD_STACK_MIN.patch | 31 +++++ ... 0024-RH-fixup-udev-rules-for-redhat.patch | 2 +- ...property-blacklist-exception-builtin.patch | 2 +- ...RH-don-t-start-without-a-config-file.patch | 0 ...H-Fix-nvme-function-missing-argument.patch | 0 ... 0028-RH-use-rpm-optflags-if-present.patch | 4 +- ...hconf.patch => 0029-RH-add-mpathconf.patch | 78 ++++++----- ...om-kernel-cmdline-mpath.wwids-with-A.patch | 10 +- ...-default-find_mutipaths-value-to-off.patch | 0 ...empt-to-get-ANA-info-via-sysfs-first.patch | 0 ...-parse_vpd_pg83-match-scsi_id-output.patch | 2 +- device-mapper-multipath.spec | 37 +++-- 19 files changed, 679 insertions(+), 57 deletions(-) create mode 100644 0016-libmultipath-use-uint64_t-for-sg_id.lun.patch create mode 100644 0017-multipath-tools-Remove-trailing-leading-whitespaces.patch create mode 100644 0018-multipath-tools-make-HUAWEI-XSG1-config-work-with-al.patch create mode 100644 0019-multipath.conf-fix-typo-in-ghost_delay-description.patch create mode 100644 0020-mpathpersist-fail-commands-when-no-usable-paths-exis.patch create mode 100644 0021-multipath-print-warning-if-multipathd-is-not-running.patch create mode 100644 0022-libmultipath-remove-unneeded-code-in-coalesce_paths.patch create mode 100644 0023-libmultipath-deal-with-dynamic-PTHREAD_STACK_MIN.patch rename 0016-RH-fixup-udev-rules-for-redhat.patch => 0024-RH-fixup-udev-rules-for-redhat.patch (98%) rename 0017-RH-Remove-the-property-blacklist-exception-builtin.patch => 0025-RH-Remove-the-property-blacklist-exception-builtin.patch (99%) rename 0018-RH-don-t-start-without-a-config-file.patch => 0026-RH-don-t-start-without-a-config-file.patch (100%) rename 0019-RH-Fix-nvme-function-missing-argument.patch => 0027-RH-Fix-nvme-function-missing-argument.patch (100%) rename 0020-RH-use-rpm-optflags-if-present.patch => 0028-RH-use-rpm-optflags-if-present.patch (97%) rename 0021-RH-add-mpathconf.patch => 0029-RH-add-mpathconf.patch (89%) rename 0022-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch => 0030-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch (95%) rename 0023-RH-reset-default-find_mutipaths-value-to-off.patch => 0031-RH-reset-default-find_mutipaths-value-to-off.patch (100%) rename 0024-RH-attempt-to-get-ANA-info-via-sysfs-first.patch => 0032-RH-attempt-to-get-ANA-info-via-sysfs-first.patch (100%) rename 0025-RH-make-parse_vpd_pg83-match-scsi_id-output.patch => 0033-RH-make-parse_vpd_pg83-match-scsi_id-output.patch (97%) diff --git a/0016-libmultipath-use-uint64_t-for-sg_id.lun.patch b/0016-libmultipath-use-uint64_t-for-sg_id.lun.patch new file mode 100644 index 0000000..500700c --- /dev/null +++ b/0016-libmultipath-use-uint64_t-for-sg_id.lun.patch @@ -0,0 +1,128 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 30 Jun 2021 21:51:53 +0200 +Subject: [PATCH] libmultipath: use uint64_t for sg_id.lun + +SCSI LUNs are 64bit unsigned integers, and have been exposed as such by +the kernel for years. Storage using the full 8 bytes is fortunately rare. +Still, we should handle this properly. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/discovery.c | 10 +++++----- + libmultipath/print.c | 2 +- + libmultipath/prioritizers/weightedpath.c | 2 +- + libmultipath/structs.c | 2 +- + libmultipath/structs.h | 4 +++- + 5 files changed, 11 insertions(+), 9 deletions(-) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index bfe2f56c..e9f5703c 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -1427,7 +1427,7 @@ scsi_sysfs_pathinfo (struct path *pp, const struct _vector *hwtable) + attr_path = udev_device_get_sysname(parent); + if (!attr_path) + break; +- if (sscanf(attr_path, "%i:%i:%i:%i", ++ if (sscanf(attr_path, "%i:%i:%i:%" SCNu64, + &pp->sg_id.host_no, + &pp->sg_id.channel, + &pp->sg_id.scsi_id, +@@ -1462,7 +1462,7 @@ scsi_sysfs_pathinfo (struct path *pp, const struct _vector *hwtable) + /* + * host / bus / target / lun + */ +- condlog(3, "%s: h:b:t:l = %i:%i:%i:%i", ++ condlog(3, "%s: h:b:t:l = %i:%i:%i:%" PRIu64, + pp->dev, + pp->sg_id.host_no, + pp->sg_id.channel, +@@ -1577,7 +1577,7 @@ ccw_sysfs_pathinfo (struct path *pp, const struct _vector *hwtable) + &pp->sg_id.host_no, + &pp->sg_id.channel, + &pp->sg_id.scsi_id) == 3) { +- condlog(3, "%s: h:b:t:l = %i:%i:%i:%i", ++ condlog(3, "%s: h:b:t:l = %i:%i:%i:%" PRIu64, + pp->dev, + pp->sg_id.host_no, + pp->sg_id.channel, +@@ -1636,7 +1636,7 @@ cciss_sysfs_pathinfo (struct path *pp, const struct _vector *hwtable) + */ + pp->sg_id.lun = 0; + pp->sg_id.channel = 0; +- condlog(3, "%s: h:b:t:l = %i:%i:%i:%i", ++ condlog(3, "%s: h:b:t:l = %i:%i:%i:%" PRIu64, + pp->dev, + pp->sg_id.host_no, + pp->sg_id.channel, +@@ -1815,7 +1815,7 @@ scsi_ioctl_pathinfo (struct path * pp, int mask) + attr_path = udev_device_get_sysname(parent); + if (!attr_path) + break; +- if (sscanf(attr_path, "%i:%i:%i:%i", ++ if (sscanf(attr_path, "%i:%i:%i:%" SCNu64, + &pp->sg_id.host_no, + &pp->sg_id.channel, + &pp->sg_id.scsi_id, +diff --git a/libmultipath/print.c b/libmultipath/print.c +index 3c69bf48..29ce499d 100644 +--- a/libmultipath/print.c ++++ b/libmultipath/print.c +@@ -392,7 +392,7 @@ snprint_hcil (char * buff, size_t len, const struct path * pp) + if (!pp || pp->sg_id.host_no < 0) + return snprintf(buff, len, "#:#:#:#"); + +- return snprintf(buff, len, "%i:%i:%i:%i", ++ return snprintf(buff, len, "%i:%i:%i:%" PRIu64, + pp->sg_id.host_no, + pp->sg_id.channel, + pp->sg_id.scsi_id, +diff --git a/libmultipath/prioritizers/weightedpath.c b/libmultipath/prioritizers/weightedpath.c +index 916970df..650088b4 100644 +--- a/libmultipath/prioritizers/weightedpath.c ++++ b/libmultipath/prioritizers/weightedpath.c +@@ -101,7 +101,7 @@ int prio_path_weight(struct path *pp, char *prio_args) + } + + if (!strcmp(regex, HBTL)) { +- sprintf(path, "%d:%d:%d:%d", pp->sg_id.host_no, ++ sprintf(path, "%d:%d:%d:%" PRIu64, pp->sg_id.host_no, + pp->sg_id.channel, pp->sg_id.scsi_id, pp->sg_id.lun); + } else if (!strcmp(regex, DEV_NAME)) { + strcpy(path, pp->dev); +diff --git a/libmultipath/structs.c b/libmultipath/structs.c +index 8751fc2b..6e5a1038 100644 +--- a/libmultipath/structs.c ++++ b/libmultipath/structs.c +@@ -96,7 +96,7 @@ alloc_path (void) + pp->sg_id.host_no = -1; + pp->sg_id.channel = -1; + pp->sg_id.scsi_id = -1; +- pp->sg_id.lun = -1; ++ pp->sg_id.lun = SCSI_INVALID_LUN; + pp->sg_id.proto_id = SCSI_PROTOCOL_UNSPEC; + pp->fd = -1; + pp->tpgs = TPGS_UNDEF; +diff --git a/libmultipath/structs.h b/libmultipath/structs.h +index c8447e56..c52bcee1 100644 +--- a/libmultipath/structs.h ++++ b/libmultipath/structs.h +@@ -178,6 +178,8 @@ enum scsi_protocol { + SCSI_PROTOCOL_UNSPEC = 0xf, /* No specific protocol */ + }; + ++#define SCSI_INVALID_LUN ~0ULL ++ + enum no_undef_states { + NU_NO = -1, + NU_UNDEF = 0, +@@ -258,7 +260,7 @@ struct sg_id { + int host_no; + int channel; + int scsi_id; +- int lun; ++ uint64_t lun; + short h_cmd_per_lun; + short d_queue_depth; + enum scsi_protocol proto_id; diff --git a/0017-multipath-tools-Remove-trailing-leading-whitespaces.patch b/0017-multipath-tools-Remove-trailing-leading-whitespaces.patch new file mode 100644 index 0000000..7c403a9 --- /dev/null +++ b/0017-multipath-tools-Remove-trailing-leading-whitespaces.patch @@ -0,0 +1,115 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Sat, 22 May 2021 21:17:36 +0200 +Subject: [PATCH] multipath-tools: Remove trailing/leading whitespaces + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Martin Wilck " +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 2 +- + libmultipath/configure.c | 2 +- + libmultipath/devmapper.c | 4 ++-- + libmultipath/sysfs.c | 2 +- + multipath/multipath.8 | 2 +- + multipathd/cli_handlers.c | 2 +- + multipathd/main.c | 2 +- + 7 files changed, 8 insertions(+), 8 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 91100a20..d0ec9b44 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -101,7 +101,7 @@ OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 + WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int \ + -Werror=implicit-function-declaration -Werror=format-security \ + $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) +-CPPFLAGS := -Wp,-D_FORTIFY_SOURCE=2 ++CPPFLAGS := -Wp,-D_FORTIFY_SOURCE=2 + CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ + -DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" \ + -MMD -MP +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index 6ca1f4bb..a6ae3359 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -397,7 +397,7 @@ int setup_map(struct multipath *mpp, char *params, int params_size, + start_io_err_stat_thread(vecs); + + n_paths = VECTOR_SIZE(mpp->paths); +- /* ++ /* + * assign paths to path groups -- start with no groups and all paths + * in mpp->paths + */ +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index 47a6d60e..945e625b 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -602,8 +602,8 @@ int dm_addmap_reload(struct multipath *mpp, char *params, int flush) + return r; + + /* If the resume failed, dm will leave the device suspended, and +- * drop the new table, so doing a second resume will try using +- * the original table */ ++ * drop the new table, so doing a second resume will try using ++ * the original table */ + if (dm_is_suspended(mpp->alias)) + dm_simplecmd(DM_DEVICE_RESUME, mpp->alias, !flush, 1, + udev_flags, 0); +diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c +index 7a2af1ea..9ff145f2 100644 +--- a/libmultipath/sysfs.c ++++ b/libmultipath/sysfs.c +@@ -358,7 +358,7 @@ bool sysfs_is_multipathed(struct path *pp, bool set_wwid) + strchop(pp->wwid); + } + } +- } else if (nr < 0) ++ } else if (nr < 0) + condlog(1, "%s: error reading from %s: %m", + __func__, pathbuf); + +diff --git a/multipath/multipath.8 b/multipath/multipath.8 +index 5b29a5d9..17df59f5 100644 +--- a/multipath/multipath.8 ++++ b/multipath/multipath.8 +@@ -225,7 +225,7 @@ Dry run, do not create or update devmaps. + .TP + .B \-e + Enable all foreign libraries. This overrides the +-.I enable_foreign ++.I enable_foreign + option from \fBmultipath.conf(5)\fR. + . + .TP +diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c +index 59d44b45..d70e1dbc 100644 +--- a/multipathd/cli_handlers.c ++++ b/multipathd/cli_handlers.c +@@ -1215,7 +1215,7 @@ cli_reconfigure(void * v, char ** reply, int * len, void * data) + + condlog(2, "reconfigure (operator)"); + +- rc = set_config_state(DAEMON_CONFIGURE); ++ rc = set_config_state(DAEMON_CONFIGURE); + if (rc == ETIMEDOUT) { + condlog(2, "timeout starting reconfiguration"); + return 1; +diff --git a/multipathd/main.c b/multipathd/main.c +index 2251e02c..bdd629e7 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -2014,7 +2014,7 @@ static int check_path_reinstate_state(struct path * pp) { + + /* If path became failed again or continue failed, should reset + * path san_path_err_forget_rate and path dis_reinstate_time to +- * start a new stable check. ++ * start a new stable check. + */ + if ((pp->state != PATH_UP) && (pp->state != PATH_GHOST) && + (pp->state != PATH_DELAYED)) { diff --git a/0018-multipath-tools-make-HUAWEI-XSG1-config-work-with-al.patch b/0018-multipath-tools-make-HUAWEI-XSG1-config-work-with-al.patch new file mode 100644 index 0000000..614039e --- /dev/null +++ b/0018-multipath-tools-make-HUAWEI-XSG1-config-work-with-al.patch @@ -0,0 +1,63 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Mon, 5 Apr 2021 00:12:58 +0200 +Subject: [PATCH] multipath-tools: make HUAWEI/XSG1 config work with alua and + multibus + +And add recommended no_path_retry and pgfailback values. + +Info from: +- RHEL https://download.huawei.com/edownload/e/download.do?actionFlag=download&nid=EDOC1100113070&partNo=6001&mid=SUPE_DOC&_t=1612885511000 +- SLES https://download.huawei.com/edownload/e/download.do?actionFlag=download&nid=EDOC1100117892&partNo=6001&mid=SUPE_DOC&_t=1612885538000 + +- without HyperMetro: +vendor "HUAWEI" +product "XSG1" +path_grouping_policy multibus +no_path_retry 15 + +- with HyperMetro: +vendor "HUAWEI" +product "XSG1" +path_grouping_policy group_by_prio +prio alua +failback immediate +no_path_retry 15 + +ALUA is only used with HyperMetro(cluster of two arrays). + +Suggested-by: Martin Wilck +Cc: Zhouweigang (Jack) +Cc: Zou Ming +Cc: Benjamin Marzinski +Cc: Martin Wilck +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Martin Wilck " +Signed-off-by: Benjamin Marzinski +--- + libmultipath/hwtable.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index e884d8c7..2a896440 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -1078,11 +1078,14 @@ static struct hwentry default_hw[] = { + * Huawei + */ + { +- /* OceanStor V3 */ ++ /* OceanStor V3-V6 */ ++ // This config works with multibus and ALUA ++ // ALUA is required by HyperMetro + .vendor = "HUAWEI", + .product = "XSG1", + .pgpolicy = GROUP_BY_PRIO, +- .prio_name = PRIO_ALUA, ++ .pgfailback = -FAILBACK_IMMEDIATE, ++ .no_path_retry = 15, + }, + /* + * Kove diff --git a/0019-multipath.conf-fix-typo-in-ghost_delay-description.patch b/0019-multipath.conf-fix-typo-in-ghost_delay-description.patch new file mode 100644 index 0000000..03dcb3f --- /dev/null +++ b/0019-multipath.conf-fix-typo-in-ghost_delay-description.patch @@ -0,0 +1,23 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 15 Jul 2021 14:46:49 -0500 +Subject: [PATCH] multipath.conf: fix typo in ghost_delay description + +Signed-off-by: Benjamin Marzinski +--- + multipath/multipath.conf.5 | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 +index 064e4826..d6b8c7f6 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5 +@@ -1251,7 +1251,7 @@ The default is: in \fB/sys/block//queue/max_sectors_kb\fR + Sets the number of seconds that multipath will wait after creating a device + with only ghost paths before marking it ready for use in systemd. This gives + the active paths time to appear before the multipath runs the hardware handler +-to switch the ghost paths to active ones. Setting this to \fI0\fR or \fIon\fR ++to switch the ghost paths to active ones. Setting this to \fI0\fR or \fIno\fR + makes multipath immediately mark a device with only ghost paths as ready. + .RS + .TP diff --git a/0020-mpathpersist-fail-commands-when-no-usable-paths-exis.patch b/0020-mpathpersist-fail-commands-when-no-usable-paths-exis.patch new file mode 100644 index 0000000..32f4f60 --- /dev/null +++ b/0020-mpathpersist-fail-commands-when-no-usable-paths-exis.patch @@ -0,0 +1,41 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 15 Jul 2021 17:09:05 -0500 +Subject: [PATCH] mpathpersist: fail commands when no usable paths exist + +"mpathpersist -oCK " will return success if it +is run on devices with no usable paths, but nothing is actually done. +The -L command will fail, but it should give up sooner, and with a more +helpful error message. + +Signed-off-by: Benjamin Marzinski +--- + libmpathpersist/mpath_persist.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c +index 190e9707..26710e79 100644 +--- a/libmpathpersist/mpath_persist.c ++++ b/libmpathpersist/mpath_persist.c +@@ -604,7 +604,8 @@ int mpath_prout_common(struct multipath *mpp,int rq_servact, int rq_scope, + return ret ; + } + } +- return MPATH_PR_SUCCESS; ++ condlog (0, "%s: no path available", mpp->wwid); ++ return MPATH_PR_DMMP_ERROR; + } + + int send_prout_activepath(char * dev, int rq_servact, int rq_scope, +@@ -663,6 +664,11 @@ int mpath_prout_rel(struct multipath *mpp,int rq_servact, int rq_scope, + + active_pathcount = count_active_paths(mpp); + ++ if (active_pathcount == 0) { ++ condlog (0, "%s: no path available", mpp->wwid); ++ return MPATH_PR_DMMP_ERROR; ++ } ++ + struct threadinfo thread[active_pathcount]; + memset(thread, 0, sizeof(thread)); + for (i = 0; i < active_pathcount; i++){ diff --git a/0021-multipath-print-warning-if-multipathd-is-not-running.patch b/0021-multipath-print-warning-if-multipathd-is-not-running.patch new file mode 100644 index 0000000..d303392 --- /dev/null +++ b/0021-multipath-print-warning-if-multipathd-is-not-running.patch @@ -0,0 +1,119 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Fri, 16 Jul 2021 12:39:17 -0500 +Subject: [PATCH] multipath: print warning if multipathd is not running. + +If multipath notices that multipath devices exist or were created, and +multipathd is not running, it now prints a warning message, so users are +notified of the issue. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/configure.c | 13 +++++++++++-- + libmultipath/configure.h | 1 + + libmultipath/libmultipath.version | 5 +++++ + multipath/main.c | 5 +++++ + 4 files changed, 22 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index a6ae3359..eb76fbc4 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -1083,7 +1083,8 @@ deadmap (struct multipath * mpp) + return 1; /* dead */ + } + +-int check_daemon(void) ++extern int ++check_daemon(void) + { + int fd; + char *reply; +@@ -1138,6 +1139,8 @@ int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid, + struct config *conf; + int allow_queueing; + struct bitfield *size_mismatch_seen; ++ bool map_processed = false; ++ bool no_daemon = false; + + /* ignore refwwid if it's empty */ + if (refwwid && !strlen(refwwid)) +@@ -1288,7 +1291,9 @@ int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid, + conf = get_multipath_config(); + allow_queueing = conf->allow_queueing; + put_multipath_config(conf); +- if (!is_daemon && !allow_queueing && !check_daemon()) { ++ if (!is_daemon && !allow_queueing && ++ (no_daemon || !check_daemon())) { ++ no_daemon = true; + if (mpp->no_path_retry != NO_PATH_RETRY_UNDEF && + mpp->no_path_retry != NO_PATH_RETRY_FAIL) + condlog(3, "%s: multipathd not running, unset " +@@ -1311,6 +1316,7 @@ int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid, + else + remove_map(mpp, vecs->pathvec, vecs->mpvec, + KEEP_VEC); ++ map_processed = true; + } + /* + * Flush maps with only dead paths (ie not in sysfs) +@@ -1336,6 +1342,9 @@ int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid, + condlog(2, "%s: remove (dead)", alias); + } + } ++ if (map_processed && !is_daemon && (no_daemon || !check_daemon())) ++ condlog(2, "multipath devices exist, but multipathd service is not running"); ++ + ret = CP_OK; + out: + free(size_mismatch_seen); +diff --git a/libmultipath/configure.h b/libmultipath/configure.h +index 70cf77a3..741066b3 100644 +--- a/libmultipath/configure.h ++++ b/libmultipath/configure.h +@@ -60,3 +60,4 @@ struct udev_device *get_udev_device(const char *dev, enum devtypes dev_type); + void trigger_paths_udev_change(struct multipath *mpp, bool is_mpath); + void trigger_partitions_udev_change(struct udev_device *dev, const char *action, + int len); ++int check_daemon(void); +diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version +index 0cff3111..d8be5fd2 100644 +--- a/libmultipath/libmultipath.version ++++ b/libmultipath/libmultipath.version +@@ -274,3 +274,8 @@ global: + local: + *; + }; ++ ++LIBMULTIPATH_5.1.0 { ++global: ++ check_daemon; ++} LIBMULTIPATH_5.0.0; +diff --git a/multipath/main.c b/multipath/main.c +index 8fc0e15f..33377147 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -180,6 +180,7 @@ get_dm_mpvec (enum mpath_cmds cmd, vector curmp, vector pathvec, char * refwwid) + int i; + struct multipath * mpp; + int flags = (cmd == CMD_LIST_SHORT ? DI_NOIO : DI_ALL); ++ bool maps_present = false; + + if (dm_get_maps(curmp)) + return 1; +@@ -212,11 +213,15 @@ get_dm_mpvec (enum mpath_cmds cmd, vector curmp, vector pathvec, char * refwwid) + + if (cmd == CMD_CREATE) + reinstate_paths(mpp); ++ ++ maps_present = true; + } + + if (cmd == CMD_LIST_SHORT || cmd == CMD_LIST_LONG) + print_foreign_topology(libmp_verbosity); + ++ if (maps_present && !check_daemon()) ++ condlog(2, "multipath devices exist, but multipathd service is not running"); + return 0; + } + diff --git a/0022-libmultipath-remove-unneeded-code-in-coalesce_paths.patch b/0022-libmultipath-remove-unneeded-code-in-coalesce_paths.patch new file mode 100644 index 0000000..a4913d3 --- /dev/null +++ b/0022-libmultipath-remove-unneeded-code-in-coalesce_paths.patch @@ -0,0 +1,81 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Fri, 16 Jul 2021 17:58:14 -0500 +Subject: [PATCH] libmultipath: remove unneeded code in coalesce_paths + +The code at the end of coalesce_paths() removes a multipath device that +was just created/reloaded, if none of its path devices have pp->dev set. +This code is very old, and no longer has any actual effect. Multipath +devices no longer get placed in pathvec without having pp->dev set. Even +if they could, there's no point in creating/reloading the device and +then immediately removing it. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/configure.c | 46 ---------------------------------------- + 1 file changed, 46 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index eb76fbc4..df6ba725 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -1061,28 +1061,6 @@ int domap(struct multipath *mpp, char *params, int is_daemon) + return DOMAP_FAIL; + } + +-static int +-deadmap (struct multipath * mpp) +-{ +- int i, j; +- struct pathgroup * pgp; +- struct path * pp; +- +- if (!mpp->pg) +- return 1; +- +- vector_foreach_slot (mpp->pg, pgp, i) { +- if (!pgp->paths) +- continue; +- +- vector_foreach_slot (pgp->paths, pp, j) +- if (strlen(pp->dev)) +- return 0; /* alive */ +- } +- +- return 1; /* dead */ +-} +- + extern int + check_daemon(void) + { +@@ -1318,30 +1296,6 @@ int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid, + KEEP_VEC); + map_processed = true; + } +- /* +- * Flush maps with only dead paths (ie not in sysfs) +- * Keep maps with only failed paths +- */ +- if (mpvec) { +- vector_foreach_slot (newmp, mpp, i) { +- char alias[WWID_SIZE]; +- +- if (!deadmap(mpp)) +- continue; +- +- strlcpy(alias, mpp->alias, WWID_SIZE); +- +- vector_del_slot(newmp, i); +- i--; +- remove_map(mpp, vecs->pathvec, vecs->mpvec, KEEP_VEC); +- +- if (dm_flush_map(alias)) +- condlog(2, "%s: remove failed (dead)", +- alias); +- else +- condlog(2, "%s: remove (dead)", alias); +- } +- } + if (map_processed && !is_daemon && (no_daemon || !check_daemon())) + condlog(2, "multipath devices exist, but multipathd service is not running"); + diff --git a/0023-libmultipath-deal-with-dynamic-PTHREAD_STACK_MIN.patch b/0023-libmultipath-deal-with-dynamic-PTHREAD_STACK_MIN.patch new file mode 100644 index 0000000..11d8b4e --- /dev/null +++ b/0023-libmultipath-deal-with-dynamic-PTHREAD_STACK_MIN.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 29 Jul 2021 13:16:57 -0500 +Subject: [PATCH] libmultipath: deal with dynamic PTHREAD_STACK_MIN + +Starting in glibc-2.34 (commit 5d98a7da), PTHREAD_STACK_MIN is defined +as sysconf(_SC_THREAD_STACK_MIN) if _GNU_SOURCE is defined. sysconf() +returns a long and can, at least in theory, return -1. This change +causes compilation to fail in setup_thread_attr() due to a comparision +with different signedness, since stacksize is a size_t. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/util.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/util.c b/libmultipath/util.c +index 0e37f3ff..17f8fcc6 100644 +--- a/libmultipath/util.c ++++ b/libmultipath/util.c +@@ -223,8 +223,8 @@ setup_thread_attr(pthread_attr_t *attr, size_t stacksize, int detached) + + ret = pthread_attr_init(attr); + assert(ret == 0); +- if (stacksize < PTHREAD_STACK_MIN) +- stacksize = PTHREAD_STACK_MIN; ++ if (PTHREAD_STACK_MIN > 0 && stacksize < (size_t)PTHREAD_STACK_MIN) ++ stacksize = (size_t)PTHREAD_STACK_MIN; + ret = pthread_attr_setstacksize(attr, stacksize); + assert(ret == 0); + if (detached) { diff --git a/0016-RH-fixup-udev-rules-for-redhat.patch b/0024-RH-fixup-udev-rules-for-redhat.patch similarity index 98% rename from 0016-RH-fixup-udev-rules-for-redhat.patch rename to 0024-RH-fixup-udev-rules-for-redhat.patch index 66c702a..df4455e 100644 --- a/0016-RH-fixup-udev-rules-for-redhat.patch +++ b/0024-RH-fixup-udev-rules-for-redhat.patch @@ -15,7 +15,7 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 91100a20..6c3714eb 100644 +index d0ec9b44..2a75dc9c 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -55,7 +55,7 @@ endif diff --git a/0017-RH-Remove-the-property-blacklist-exception-builtin.patch b/0025-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 99% rename from 0017-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0025-RH-Remove-the-property-blacklist-exception-builtin.patch index dcb1491..53ee89b 100644 --- a/0017-RH-Remove-the-property-blacklist-exception-builtin.patch +++ b/0025-RH-Remove-the-property-blacklist-exception-builtin.patch @@ -43,7 +43,7 @@ index 6c6a5979..785f5ee9 100644 udev_device_get_properties_list_entry(udev)) { diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 064e4826..0d2bce09 100644 +index d6b8c7f6..689d09aa 100644 --- a/multipath/multipath.conf.5 +++ b/multipath/multipath.conf.5 @@ -1347,9 +1347,14 @@ keywords. Both are regular expressions. For a full description of these keywords diff --git a/0018-RH-don-t-start-without-a-config-file.patch b/0026-RH-don-t-start-without-a-config-file.patch similarity index 100% rename from 0018-RH-don-t-start-without-a-config-file.patch rename to 0026-RH-don-t-start-without-a-config-file.patch diff --git a/0019-RH-Fix-nvme-function-missing-argument.patch b/0027-RH-Fix-nvme-function-missing-argument.patch similarity index 100% rename from 0019-RH-Fix-nvme-function-missing-argument.patch rename to 0027-RH-Fix-nvme-function-missing-argument.patch diff --git a/0020-RH-use-rpm-optflags-if-present.patch b/0028-RH-use-rpm-optflags-if-present.patch similarity index 97% rename from 0020-RH-use-rpm-optflags-if-present.patch rename to 0028-RH-use-rpm-optflags-if-present.patch index ca542d3..303ad0d 100644 --- a/0020-RH-use-rpm-optflags-if-present.patch +++ b/0028-RH-use-rpm-optflags-if-present.patch @@ -13,7 +13,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 6c3714eb..db35feb6 100644 +index 2a75dc9c..db35feb6 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -92,16 +92,28 @@ TEST_CC_OPTION = $(shell \ @@ -44,7 +44,7 @@ index 6c3714eb..db35feb6 100644 +WARNFLAGS := -Werror -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int \ -Werror=implicit-function-declaration -Werror=format-security \ - $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) --CPPFLAGS := -Wp,-D_FORTIFY_SOURCE=2 +-CPPFLAGS := -Wp,-D_FORTIFY_SOURCE=2 + $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) \ + -Wstrict-prototypes CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ diff --git a/0021-RH-add-mpathconf.patch b/0029-RH-add-mpathconf.patch similarity index 89% rename from 0021-RH-add-mpathconf.patch rename to 0029-RH-add-mpathconf.patch index d262f55..7fb97f6 100644 --- a/0021-RH-add-mpathconf.patch +++ b/0029-RH-add-mpathconf.patch @@ -14,9 +14,9 @@ Signed-off-by: Benjamin Marzinski --- libmultipath/config.c | 2 + multipath/Makefile | 5 + - multipath/mpathconf | 555 ++++++++++++++++++++++++++++++++++++++++++ + multipath/mpathconf | 561 ++++++++++++++++++++++++++++++++++++++++++ multipath/mpathconf.8 | 135 ++++++++++ - 4 files changed, 697 insertions(+) + 4 files changed, 703 insertions(+) create mode 100644 multipath/mpathconf create mode 100644 multipath/mpathconf.8 @@ -69,10 +69,10 @@ index b9bbb3cf..e720c7f6 100644 $(RM) core *.o $(EXEC) *.gz diff --git a/multipath/mpathconf b/multipath/mpathconf new file mode 100644 -index 00000000..2f4f3eaf +index 00000000..039b3e47 --- /dev/null +++ b/multipath/mpathconf -@@ -0,0 +1,555 @@ +@@ -0,0 +1,561 @@ +#!/bin/bash +# +# Copyright (C) 2010 Red Hat, Inc. All rights reserved. @@ -315,7 +315,7 @@ index 00000000..2f4f3eaf + echo "--enable_foreign must be either 'y' or 'n'" + exit 1 + fi -+ if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" -a -z "$PROPERTY" ]; then ++ if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" -a -z "$PROPERTY" -a -z "$FOREIGN" ]; then + SHOW_STATUS=1 + fi + if [ -n "$MODULE" ] && [ "$MODULE" != "y" -a "$MODULE" != "n" ]; then @@ -390,46 +390,50 @@ index 00000000..2f4f3eaf +fi + +if [ "$HAVE_BLACKLIST" = "1" ]; then -+ if sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*devnode \"\.\?\*\"" ; then ++ if sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*devnode[[:space:]][[:space:]]*\"\.\?\*\"" ; then + HAVE_DISABLE=1 -+ elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*devnode \"\.\?\*\"" ; then ++ elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*devnode[[:space:]][[:space:]]*\"\.\?\*\"" ; then + HAVE_DISABLE=0 + fi +fi + +if [ "$HAVE_BLACKLIST" = "1" ]; then -+ if sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*wwid \"\.\?\*\"" ; then ++ if sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*wwid[[:space:]][[:space:]]*\"\.\?\*\"" ; then + HAVE_WWID_DISABLE=1 -+ elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*wwid \"\.\?\*\"" ; then ++ elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*wwid[[:space:]][[:space:]]*\"\.\?\*\"" ; then + HAVE_WWID_DISABLE=0 + fi +fi + +if [ "$HAVE_DEFAULTS" = "1" ]; then -+ HAVE_FIND=`sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | sed -n 's/^[[:blank:]]*find_multipaths[[:blank:]]*\([^[:blank:]]*\).*$/\1/p' | sed -n 1p` ++ HAVE_FIND=`sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | sed -n 's/^[[:blank:]]*find_multipaths[[:blank:]][[:blank:]]*\([^[:blank:]]*\).*$/\1/p' | sed -n 1p` + if [ "$HAVE_FIND" = "1" ]; then + HAVE_FIND="yes" + elif [ "$HAVE_FIND" = "0" ]; then + HAVE_FIND="no" + fi -+ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]]*\(yes\|1\)" ; then ++ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]][[:space:]]*\(yes\|1\)" ; then + HAVE_FRIENDLY=1 -+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]]*\(no\|0\)" ; then ++ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]][[:space:]]*\(no\|0\)" ; then + HAVE_FRIENDLY=0 + fi + if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*enable_foreign" ; then + HAVE_FOREIGN=0 -+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]]*\"\^\$\"" ; then ++ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]][[:space:]]*\"\.\*\"" ; then + HAVE_FOREIGN=1 -+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign" ; then ++ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]][[:space:]]*\"\^\$\"" ; then + HAVE_FOREIGN=2 ++ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]][[:space:]]*\"NONE\"" ; then ++ HAVE_FOREIGN=2 ++ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign" ; then ++ HAVE_FOREIGN=3 + fi +fi + +if [ "$HAVE_EXCEPTIONS" = "1" ]; then -+ if sed -n '/^blacklist_exceptions[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"" ; then ++ if sed -n '/^blacklist_exceptions[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*property[[:space:]][[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"" ; then + HAVE_PROPERTY=1 -+ elif sed -n '/^blacklist_exceptions[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"" ; then ++ elif sed -n '/^blacklist_exceptions[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*property[[:space:]][[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"" ; then + HAVE_PROPERTY=0 + fi +fi @@ -456,8 +460,10 @@ index 00000000..2f4f3eaf + echo "default property blacklist is enabled" + fi + if [ -z "$HAVE_FOREIGN" -o "$HAVE_FOREIGN" = 0 ]; then -+ echo "enable_foreign is not set (all foreign multipath devices will be shown)" ++ echo "enable_foreign is not set (no foreign multipath devices will be shown)" + elif [ "$HAVE_FOREIGN" = 1 ]; then ++ echo "enable_foreign is set (all foreign multipath devices will be shown)" ++ elif [ "$HAVE_FOREIGN" = 2 ]; then + echo "enable_foreign is set (no foreign multipath devices will be shown)" + else + echo "enable_foreign is set (foreign multipath devices may not be shown)" @@ -502,14 +508,14 @@ index 00000000..2f4f3eaf + +if [ "$ENABLE" = 2 ]; then + if [ "$HAVE_DISABLE" = 1 ]; then -+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*devnode \"\.\?\*\"/# devnode ".*"/' $TMPFILE ++ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*devnode[[:space:]][[:space:]]*\"\.\?\*\"/# devnode ".*"/' $TMPFILE + fi + if [ -z "$HAVE_WWID_DISABLE" ]; then + sed -i '/^blacklist[[:space:]]*{/ a\ + wwid ".*" +' $TMPFILE + elif [ "$HAVE_WWID_DISABLE" = 0 ]; then -+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*wwid \"\.\?\*\"/ wwid ".*"/' $TMPFILE ++ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*wwid[[:space:]][[:space:]]*\"\.\?\*\"/ wwid ".*"/' $TMPFILE + fi + if [ "$HAVE_EXCEPTIONS" = 1 ]; then + sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ {/^[[:space:]]*wwid/ d}' $TMPFILE @@ -523,7 +529,7 @@ index 00000000..2f4f3eaf + add_blacklist_exceptions +elif [ "$ENABLE" = 1 ]; then + if [ "$HAVE_DISABLE" = 1 ]; then -+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*devnode \"\.\?\*\"/# devnode ".*"/' $TMPFILE ++ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*devnode[[:space:]][[:space:]]*\"\.\?\*\"/# devnode ".*"/' $TMPFILE + fi +elif [ "$ENABLE" = 0 ]; then + if [ -z "$HAVE_DISABLE" ]; then @@ -531,7 +537,7 @@ index 00000000..2f4f3eaf + devnode ".*" +' $TMPFILE + elif [ "$HAVE_DISABLE" = 0 ]; then -+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*devnode \"\.\?\*\"/ devnode ".*"/' $TMPFILE ++ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*devnode[[:space:]][[:space:]]*\"\.\?\*\"/ devnode ".*"/' $TMPFILE + fi +fi + @@ -542,14 +548,14 @@ index 00000000..2f4f3eaf +' $TMPFILE + CHANGED_CONFIG=1 + elif [ "$FIND" != "$HAVE_FIND" ]; then -+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:blank:]]*find_multipaths[[:blank:]]*[^[:blank:]]*/ find_multipaths '"$FIND"'/' $TMPFILE ++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:blank:]]*find_multipaths[[:blank:]][[:blank:]]*[^[:blank:]]*/ find_multipaths '"$FIND"'/' $TMPFILE + CHANGED_CONFIG=1 + fi +fi + +if [ "$FRIENDLY" = "n" ]; then + if [ "$HAVE_FRIENDLY" = 1 ]; then -+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*user_friendly_names[[:space:]]*\(yes\|1\)/ user_friendly_names no/' $TMPFILE ++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*user_friendly_names[[:space:]][[:space:]]*\(yes\|1\)/ user_friendly_names no/' $TMPFILE + CHANGED_CONFIG=1 + fi +elif [ "$FRIENDLY" = "y" ]; then @@ -559,14 +565,14 @@ index 00000000..2f4f3eaf +' $TMPFILE + CHANGED_CONFIG=1 + elif [ "$HAVE_FRIENDLY" = 0 ]; then -+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*user_friendly_names[[:space:]]*\(no\|0\)/ user_friendly_names yes/' $TMPFILE ++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*user_friendly_names[[:space:]][[:space:]]*\(no\|0\)/ user_friendly_names yes/' $TMPFILE + CHANGED_CONFIG=1 + fi +fi + +if [ "$PROPERTY" = "n" ]; then + if [ "$HAVE_PROPERTY" = 1 ]; then -+ sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/# property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE ++ sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*property[[:space:]][[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/# property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE + CHANGED_CONFIG=1 + fi +elif [ "$PROPERTY" = "y" ]; then @@ -576,24 +582,24 @@ index 00000000..2f4f3eaf +' $TMPFILE + CHANGED_CONFIG=1 + elif [ "$HAVE_PROPERTY" = 0 ]; then -+ sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/ property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE ++ sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*property[[:space:]][[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/ property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE + CHANGED_CONFIG=1 + fi +fi + -+if [ "$FOREIGN" = "y" ]; then -+ if [ "$HAVE_FOREIGN" = 1 -o "$HAVE_FOREIGN" = 2 ]; then ++if [ "$FOREIGN" = "n" ]; then ++ if [ "$HAVE_FOREIGN" = 1 -o "$HAVE_FOREIGN" = 3 ]; then + sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*enable_foreign/# enable_foreign/' $TMPFILE + CHANGED_CONFIG=1 + fi -+elif [ "$FOREIGN" = "n" ]; then ++elif [ "$FOREIGN" = "y" ]; then + if [ -z "$HAVE_FOREIGN" ]; then + sed -i '/^defaults[[:space:]]*{/ a\ -+ enable_foreign "^$" ++ enable_foreign ".*" +' $TMPFILE + CHANGED_CONFIG=1 -+ elif [ "$HAVE_FOREIGN" = 0 -o "$HAVE_FOREIGN" = 2 ]; then -+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*#\?[[:space:]]*enable_foreign.*$/ enable_foreign "^$"/' $TMPFILE ++ elif [ "$HAVE_FOREIGN" = 0 -o "$HAVE_FOREIGN" = 2 -o "$HAVE_FOREIGN" = 3 ]; then ++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*#\?[[:space:]]*enable_foreign.*$/ enable_foreign ".*"/' $TMPFILE + CHANGED_CONFIG=1 + fi +fi @@ -630,7 +636,7 @@ index 00000000..2f4f3eaf +fi diff --git a/multipath/mpathconf.8 b/multipath/mpathconf.8 new file mode 100644 -index 00000000..83515eb4 +index 00000000..a14d831e --- /dev/null +++ b/multipath/mpathconf.8 @@ -0,0 +1,135 @@ @@ -730,11 +736,11 @@ index 00000000..83515eb4 +present. This command can be used along with any other command. +.TP +.B --enable_foreign\fP { \fBy\fP | \fBn\fP } -+If set to \fBn\fP, this adds the line -+.B enable_foreign "^$" ++If set to \fBy\fP, this adds the line ++.B enable_foreign ".*" +to the +.B /etc/multipath.conf -+defaults section. if set to \fBy\fP, this removes the line, if present. This ++defaults section. if set to \fBn\fP, this removes the line, if present. This +command can be used along with any other command. +.TP +.B --outfile \fB\fP diff --git a/0022-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0030-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 95% rename from 0022-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0030-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch index e842947..d20115a 100644 --- a/0022-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +++ b/0030-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch @@ -20,7 +20,7 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/multipath/main.c b/multipath/main.c -index 8fc0e15f..9fe53dcd 100644 +index 33377147..85e4481d 100644 --- a/multipath/main.c +++ b/multipath/main.c @@ -122,7 +122,7 @@ usage (char * progname) @@ -41,7 +41,7 @@ index 8fc0e15f..9fe53dcd 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" -@@ -450,6 +452,50 @@ static void cleanup_vecs(void) +@@ -455,6 +457,50 @@ static void cleanup_vecs(void) free_pathvec(vecs.pathvec, FREE_PATHS); } @@ -92,7 +92,7 @@ index 8fc0e15f..9fe53dcd 100644 static int configure (struct config *conf, enum mpath_cmds cmd, enum devtypes dev_type, char *devpath) -@@ -828,7 +874,7 @@ main (int argc, char *argv[]) +@@ -833,7 +879,7 @@ main (int argc, char *argv[]) conf->retrigger_tries = 0; conf->force_sync = 1; atexit(cleanup_vecs); @@ -101,7 +101,7 @@ index 8fc0e15f..9fe53dcd 100644 switch(arg) { case 1: printf("optarg : %s\n",optarg); break; -@@ -905,6 +951,10 @@ main (int argc, char *argv[]) +@@ -910,6 +956,10 @@ main (int argc, char *argv[]) case 'T': cmd = CMD_DUMP_CONFIG; break; @@ -113,7 +113,7 @@ index 8fc0e15f..9fe53dcd 100644 usage(argv[0]); exit(RTVL_OK); diff --git a/multipath/multipath.8 b/multipath/multipath.8 -index 5b29a5d9..0478f4e7 100644 +index 17df59f5..5ca75359 100644 --- a/multipath/multipath.8 +++ b/multipath/multipath.8 @@ -63,7 +63,7 @@ multipath \- Device mapper target autoconfig. diff --git a/0023-RH-reset-default-find_mutipaths-value-to-off.patch b/0031-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 100% rename from 0023-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0031-RH-reset-default-find_mutipaths-value-to-off.patch diff --git a/0024-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0032-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 100% rename from 0024-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0032-RH-attempt-to-get-ANA-info-via-sysfs-first.patch diff --git a/0025-RH-make-parse_vpd_pg83-match-scsi_id-output.patch b/0033-RH-make-parse_vpd_pg83-match-scsi_id-output.patch similarity index 97% rename from 0025-RH-make-parse_vpd_pg83-match-scsi_id-output.patch rename to 0033-RH-make-parse_vpd_pg83-match-scsi_id-output.patch index 5ae95ee..e16060d 100644 --- a/0025-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +++ b/0033-RH-make-parse_vpd_pg83-match-scsi_id-output.patch @@ -13,7 +13,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index bfe2f56c..4bb7ba2f 100644 +index e9f5703c..7c1bcdf0 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c @@ -1135,12 +1135,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index bed8ed3..d81bbba 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.8.6 -Release: 4%{?dist} +Release: 5%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -25,16 +25,24 @@ Patch0012: 0012-libdmmp-use-KBUILD_BUILD_TIMESTAMP-when-building-man.patch Patch0013: 0013-multipath-tools-add-info-about-HPE-Alletra-6000-and-.patch Patch0014: 0014-multipathd-don-t-start-in-containers.patch Patch0015: 0015-libmultipath-fix-build-without-LIBDM_API_DEFERRED.patch -Patch0016: 0016-RH-fixup-udev-rules-for-redhat.patch -Patch0017: 0017-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0018: 0018-RH-don-t-start-without-a-config-file.patch -Patch0019: 0019-RH-Fix-nvme-function-missing-argument.patch -Patch0020: 0020-RH-use-rpm-optflags-if-present.patch -Patch0021: 0021-RH-add-mpathconf.patch -Patch0022: 0022-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0023: 0023-RH-reset-default-find_mutipaths-value-to-off.patch -Patch0024: 0024-RH-attempt-to-get-ANA-info-via-sysfs-first.patch -Patch0025: 0025-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +Patch0016: 0016-libmultipath-use-uint64_t-for-sg_id.lun.patch +Patch0017: 0017-multipath-tools-Remove-trailing-leading-whitespaces.patch +Patch0018: 0018-multipath-tools-make-HUAWEI-XSG1-config-work-with-al.patch +Patch0019: 0019-multipath.conf-fix-typo-in-ghost_delay-description.patch +Patch0020: 0020-mpathpersist-fail-commands-when-no-usable-paths-exis.patch +Patch0021: 0021-multipath-print-warning-if-multipathd-is-not-running.patch +Patch0022: 0022-libmultipath-remove-unneeded-code-in-coalesce_paths.patch +Patch0023: 0023-libmultipath-deal-with-dynamic-PTHREAD_STACK_MIN.patch +Patch0024: 0024-RH-fixup-udev-rules-for-redhat.patch +Patch0025: 0025-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0026: 0026-RH-don-t-start-without-a-config-file.patch +Patch0027: 0027-RH-Fix-nvme-function-missing-argument.patch +Patch0028: 0028-RH-use-rpm-optflags-if-present.patch +Patch0029: 0029-RH-add-mpathconf.patch +Patch0030: 0030-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0031: 0031-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0032: 0032-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0033: 0033-RH-make-parse_vpd_pg83-match-scsi_id-output.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -232,6 +240,13 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Fri Jul 30 2021 Benjamin Marzinski - 0.8.6-5 +- Update to the head of the upstream staging branch plus redhat patches + * Patches 0016-0018 are from the upstream staging branch + * Patches 0019-0024 have been submitted upstream +- Rename files + * Previous patches 0016-0025 are now patches 0024-0033 + * Wed Jul 21 2021 Fedora Release Engineering - 0.8.6-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild From a4b79a10d40513a82a55e70f15cefea0e2921ebd Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Wed, 6 Oct 2021 18:14:26 -0500 Subject: [PATCH 23/67] device-mapper-multipath-0.8.7-1 Update source to upstream version 0.8.7 * Previous patches 0001-0023 are included in the commit. Add patches from upstream staging branch * Patches 0001-0010 are from the upstream staging branch Rename redhat patches * Previous patches 0024-0033 are now patches 0011-0020 --- .gitignore | 1 + ...-memory-leak-in-checker_cleanup_thre.patch | 32 -- ...add-info-about-IO-affinity-path-sele.patch | 45 +++ ...x-compilation-issue-with-liburcu-0.8.patch | 85 ----- ...issing-persistent-reseravtion-for-ac.patch | 52 +++ ...minor-fixes-to-multipath.conf.5-man-.patch | 48 +++ ...-fail-to-remove-path-once-the-map-is.patch | 70 ---- ...make-IBM-XIV-config-work-with-alua-a.patch | 39 ++ ...e-duplicate-orphan_paths-in-flush_ma.patch | 27 -- ...-ev_remove_path-return-code-handling.patch | 226 ------------ ...t-add-missing-conditions-from-servic.patch | 32 ++ ...-multipath-free-vectors-in-configure.patch | 47 --- ...make-IBM-2107900-DS8000-config-work-.patch | 40 ++ ...ak-memory-when-getblock-returns-NULL.patch | 28 -- ...make-EMC-SYMMETRIX-config-work-with-.patch | 35 ++ ...make-EMC-Invista-config-work-with-al.patch | 37 ++ ...-rescan_path-on-wwid-change-in-uev_u.patch | 28 -- ...make-COMPELNT-Compellent-Vol-config-.patch | 35 ++ ...andlers-cleanup-setting-reply-length.patch | 82 ----- ...h-tools-remove-Compellent-maintainer.patch | 35 ++ ...ipathd-cli_getprkey-fix-return-value.patch | 53 --- ... 0011-RH-fixup-udev-rules-for-redhat.patch | 0 ...path-tools-enable-Wformat-overflow-2.patch | 64 ---- ...property-blacklist-exception-builtin.patch | 12 +- ...LD_BUILD_TIMESTAMP-when-building-man.patch | 347 ------------------ ...RH-don-t-start-without-a-config-file.patch | 0 ...add-info-about-HPE-Alletra-6000-and-.patch | 52 --- ...H-Fix-nvme-function-missing-argument.patch | 0 ...multipathd-don-t-start-in-containers.patch | 32 -- ... 0015-RH-use-rpm-optflags-if-present.patch | 0 ...fix-build-without-LIBDM_API_DEFERRED.patch | 59 --- ...hconf.patch => 0016-RH-add-mpathconf.patch | 0 ...multipath-use-uint64_t-for-sg_id.lun.patch | 128 ------- ...om-kernel-cmdline-mpath.wwids-with-A.patch | 8 +- ...-Remove-trailing-leading-whitespaces.patch | 115 ------ ...-default-find_mutipaths-value-to-off.patch | 0 ...make-HUAWEI-XSG1-config-work-with-al.patch | 63 ---- ...empt-to-get-ANA-info-via-sysfs-first.patch | 0 ...-fix-typo-in-ghost_delay-description.patch | 23 -- ...-parse_vpd_pg83-match-scsi_id-output.patch | 6 +- ...l-commands-when-no-usable-paths-exis.patch | 41 --- ...warning-if-multipathd-is-not-running.patch | 119 ------ ...move-unneeded-code-in-coalesce_paths.patch | 81 ---- ...-deal-with-dynamic-PTHREAD_STACK_MIN.patch | 31 -- device-mapper-multipath.spec | 71 ++-- sources | 2 +- 46 files changed, 446 insertions(+), 1885 deletions(-) delete mode 100644 0001-libmultipath-fix-memory-leak-in-checker_cleanup_thre.patch create mode 100644 0001-multipath-tools-add-info-about-IO-affinity-path-sele.patch delete mode 100644 0002-multipathd-fix-compilation-issue-with-liburcu-0.8.patch create mode 100644 0002-multipathd-fix-missing-persistent-reseravtion-for-ac.patch create mode 100644 0003-multipath-tools-minor-fixes-to-multipath.conf.5-man-.patch delete mode 100644 0003-multipathd-don-t-fail-to-remove-path-once-the-map-is.patch create mode 100644 0004-multipath-tools-make-IBM-XIV-config-work-with-alua-a.patch delete mode 100644 0004-multipathd-remove-duplicate-orphan_paths-in-flush_ma.patch delete mode 100644 0005-multipathd-fix-ev_remove_path-return-code-handling.patch create mode 100644 0005-multipathd.socket-add-missing-conditions-from-servic.patch delete mode 100644 0006-multipath-free-vectors-in-configure.patch create mode 100644 0006-multipath-tools-make-IBM-2107900-DS8000-config-work-.patch delete mode 100644 0007-kpartx-Don-t-leak-memory-when-getblock-returns-NULL.patch create mode 100644 0007-multipath-tools-make-EMC-SYMMETRIX-config-work-with-.patch create mode 100644 0008-multipath-tools-make-EMC-Invista-config-work-with-al.patch delete mode 100644 0008-multipathd-don-t-rescan_path-on-wwid-change-in-uev_u.patch create mode 100644 0009-multipath-tools-make-COMPELNT-Compellent-Vol-config-.patch delete mode 100644 0009-multipathd-cli_handlers-cleanup-setting-reply-length.patch create mode 100644 0010-multipath-tools-remove-Compellent-maintainer.patch delete mode 100644 0010-multipathd-cli_getprkey-fix-return-value.patch rename 0024-RH-fixup-udev-rules-for-redhat.patch => 0011-RH-fixup-udev-rules-for-redhat.patch (100%) delete mode 100644 0011-multipath-tools-enable-Wformat-overflow-2.patch rename 0025-RH-Remove-the-property-blacklist-exception-builtin.patch => 0012-RH-Remove-the-property-blacklist-exception-builtin.patch (92%) delete mode 100644 0012-libdmmp-use-KBUILD_BUILD_TIMESTAMP-when-building-man.patch rename 0026-RH-don-t-start-without-a-config-file.patch => 0013-RH-don-t-start-without-a-config-file.patch (100%) delete mode 100644 0013-multipath-tools-add-info-about-HPE-Alletra-6000-and-.patch rename 0027-RH-Fix-nvme-function-missing-argument.patch => 0014-RH-Fix-nvme-function-missing-argument.patch (100%) delete mode 100644 0014-multipathd-don-t-start-in-containers.patch rename 0028-RH-use-rpm-optflags-if-present.patch => 0015-RH-use-rpm-optflags-if-present.patch (100%) delete mode 100644 0015-libmultipath-fix-build-without-LIBDM_API_DEFERRED.patch rename 0029-RH-add-mpathconf.patch => 0016-RH-add-mpathconf.patch (100%) delete mode 100644 0016-libmultipath-use-uint64_t-for-sg_id.lun.patch rename 0030-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch => 0017-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch (96%) delete mode 100644 0017-multipath-tools-Remove-trailing-leading-whitespaces.patch rename 0031-RH-reset-default-find_mutipaths-value-to-off.patch => 0018-RH-reset-default-find_mutipaths-value-to-off.patch (100%) delete mode 100644 0018-multipath-tools-make-HUAWEI-XSG1-config-work-with-al.patch rename 0032-RH-attempt-to-get-ANA-info-via-sysfs-first.patch => 0019-RH-attempt-to-get-ANA-info-via-sysfs-first.patch (100%) delete mode 100644 0019-multipath.conf-fix-typo-in-ghost_delay-description.patch rename 0033-RH-make-parse_vpd_pg83-match-scsi_id-output.patch => 0020-RH-make-parse_vpd_pg83-match-scsi_id-output.patch (89%) delete mode 100644 0020-mpathpersist-fail-commands-when-no-usable-paths-exis.patch delete mode 100644 0021-multipath-print-warning-if-multipathd-is-not-running.patch delete mode 100644 0022-libmultipath-remove-unneeded-code-in-coalesce_paths.patch delete mode 100644 0023-libmultipath-deal-with-dynamic-PTHREAD_STACK_MIN.patch diff --git a/.gitignore b/.gitignore index 7ac9519..03e544c 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,4 @@ multipath-tools-091027.tar.gz /multipath-tools-0.8.4.tgz /multipath-tools-0.8.5.tgz /multipath-tools-0.8.6.tgz +/multipath-tools-0.8.7.tgz diff --git a/0001-libmultipath-fix-memory-leak-in-checker_cleanup_thre.patch b/0001-libmultipath-fix-memory-leak-in-checker_cleanup_thre.patch deleted file mode 100644 index 5e389f3..0000000 --- a/0001-libmultipath-fix-memory-leak-in-checker_cleanup_thre.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: lixiaokeng -Date: Fri, 9 Apr 2021 15:15:05 +0800 -Subject: [PATCH] libmultipath: fix memory leak in checker_cleanup_thread - -If checker_cleanup_thread is called after cleanup_checkers, -the checker_class will not be freed. - -Here, we use free_checker_class instead of checker_class_unref -in checker_cleanup_thread. - -Signed-off-by: Lixiaokeng -Reviewed-by: Benjamin Marzinski -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/checkers.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/checkers.c b/libmultipath/checkers.c -index 2dd9915d..8039c2bf 100644 ---- a/libmultipath/checkers.c -+++ b/libmultipath/checkers.c -@@ -368,7 +368,7 @@ static void checker_cleanup_thread(void *arg) - { - struct checker_class *cls = arg; - -- (void)checker_class_unref(cls); -+ free_checker_class(cls); - rcu_unregister_thread(); - } - diff --git a/0001-multipath-tools-add-info-about-IO-affinity-path-sele.patch b/0001-multipath-tools-add-info-about-IO-affinity-path-sele.patch new file mode 100644 index 0000000..559d5a5 --- /dev/null +++ b/0001-multipath-tools-add-info-about-IO-affinity-path-sele.patch @@ -0,0 +1,45 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Wed, 8 Sep 2021 22:33:54 +0200 +Subject: [PATCH] multipath-tools: add info about IO affinity path selector to + manpage + +Added in 5.11: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e4d2e82b2300b03f66b3ca8417590c86e661fab1 + +Cc: Mike Christie +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + multipath/multipath.conf.5 | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 +index d6b8c7f6..42a15ffd 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5 +@@ -6,7 +6,7 @@ + .\" + .\" ---------------------------------------------------------------------------- + . +-.TH MULTIPATH.CONF 5 2018-05-21 Linux ++.TH MULTIPATH.CONF 5 2021-09-08 Linux + . + . + .\" ---------------------------------------------------------------------------- +@@ -210,6 +210,10 @@ of outstanding I/O to the path and its relative throughput. + estimation of future service time based on the history of previous I/O submitted + to each path. + .TP ++.I "io-affinity 0" ++(Since 5.11 kernel) Choose the path for the next bunch of I/O based on a CPU to ++path mapping the user passes in and what CPU we are executing on. ++.TP + The default is: \fBservice-time 0\fR + .RE + . diff --git a/0002-multipathd-fix-compilation-issue-with-liburcu-0.8.patch b/0002-multipathd-fix-compilation-issue-with-liburcu-0.8.patch deleted file mode 100644 index a9c4af4..0000000 --- a/0002-multipathd-fix-compilation-issue-with-liburcu-0.8.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 12 May 2021 23:06:51 +0200 -Subject: [PATCH] multipathd: fix compilation issue with liburcu < 0.8 - -To avoid race conditions with pending RCU callbacks on exit, it's -necessary to call rcu_barrier() in cleanup_rcu() (see -https://lists.lttng.org/pipermail/lttng-dev/2021-May/029958.html and -follow-ups). - -rcu_barrier() is only available in User-space RCU v0.8 and newer. -Fix it by reverting 5d0dae6 ("multipathd: Fix liburcu memory leak") -if an older version of liburcu is detected. - -Fixes: 5d0dae6 ("multipathd: Fix liburcu memory leak") -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipathd/Makefile | 2 ++ - multipathd/main.c | 17 +++++++++++++++-- - 2 files changed, 17 insertions(+), 2 deletions(-) - -diff --git a/multipathd/Makefile b/multipathd/Makefile -index d053c1ed..393b6cbb 100644 ---- a/multipathd/Makefile -+++ b/multipathd/Makefile -@@ -16,6 +16,8 @@ LDFLAGS += $(BIN_LDFLAGS) - LIBDEPS += -L$(multipathdir) -lmultipath -L$(mpathpersistdir) -lmpathpersist \ - -L$(mpathcmddir) -lmpathcmd -ludev -ldl -lurcu -lpthread \ - -ldevmapper -lreadline -+CFLAGS += $(shell $(PKGCONFIG) --modversion liburcu 2>/dev/null | \ -+ awk -F. '{ printf("-DURCU_VERSION=0x%06x", 256 * ( 256 * $$1 + $$2) + $$3); }') - - ifdef SYSTEMD - CFLAGS += -DUSE_SYSTEMD=$(SYSTEMD) -diff --git a/multipathd/main.c b/multipathd/main.c -index 102946bf..c34fd9c8 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -3031,6 +3031,10 @@ static void cleanup_threads(void) - pthread_attr_destroy(&waiter_attr); - } - -+#ifndef URCU_VERSION -+# define URCU_VERSION 0 -+#endif -+#if (URCU_VERSION >= 0x000800) - /* - * Use a non-default call_rcu_data for child(). - * -@@ -3040,6 +3044,9 @@ static void cleanup_threads(void) - * can't be joined with pthread_join(), leaving a memory leak. - * - * Therefore we create our own, which can be destroyed and joined. -+ * The cleanup handler needs to call rcu_barrier(), which is only -+ * available in user-space RCU v0.8 and newer. See -+ * https://lists.lttng.org/pipermail/lttng-dev/2021-May/029958.html - */ - static struct call_rcu_data *setup_rcu(void) - { -@@ -3072,6 +3079,7 @@ static void cleanup_rcu(void) - } - rcu_unregister_thread(); - } -+#endif /* URCU_VERSION */ - - static void cleanup_child(void) - { -@@ -3116,9 +3124,14 @@ child (__attribute__((unused)) void *param) - init_unwinder(); - mlockall(MCL_CURRENT | MCL_FUTURE); - signal_init(); -+#if (URCU_VERSION >= 0x000800) - mp_rcu_data = setup_rcu(); -- -- if (atexit(cleanup_rcu) || atexit(cleanup_child)) -+ if (atexit(cleanup_rcu)) -+ fprintf(stderr, "failed to register RCU cleanup handler\n"); -+#else -+ rcu_init(); -+#endif -+ if (atexit(cleanup_child)) - fprintf(stderr, "failed to register cleanup handlers\n"); - - setup_thread_attr(&misc_attr, 64 * 1024, 0); diff --git a/0002-multipathd-fix-missing-persistent-reseravtion-for-ac.patch b/0002-multipathd-fix-missing-persistent-reseravtion-for-ac.patch new file mode 100644 index 0000000..5312160 --- /dev/null +++ b/0002-multipathd-fix-missing-persistent-reseravtion-for-ac.patch @@ -0,0 +1,52 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: lixiaokeng +Date: Mon, 13 Sep 2021 10:43:14 +0800 +Subject: [PATCH] multipathd: fix missing persistent reseravtion for active + path + +There are two paths(sucu as sda and adb) for one LUN. The two +paths log in, but before the two uevents have been processed +(for example there are many uevent), users use multipathd add +path /dev/sda to cause mpatha and use mpathpersist -o -I to +register prkey for mpatha. The add map uevent is after add path +uevent, the the uevent(add sdb) will delay and missing persistent +reseravtion check. + +Here, we add persistent reseravtion check in update_map() which +is called ev_add_map(). + +Signed-off-by: Lixiaokeng +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 3aff241d..1defeaf1 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -490,6 +490,8 @@ update_map (struct multipath *mpp, struct vectors *vecs, int new_map) + { + int retries = 3; + char *params __attribute__((cleanup(cleanup_charp))) = NULL; ++ struct path *pp; ++ int i; + + retry: + condlog(4, "%s: updating new map", mpp->alias); +@@ -502,6 +504,15 @@ retry: + verify_paths(mpp); + mpp->action = ACT_RELOAD; + ++ if (mpp->prflag) { ++ vector_foreach_slot(mpp->paths, pp, i) { ++ if ((pp->state == PATH_UP) || (pp->state == PATH_GHOST)) { ++ /* persistent reseravtion check*/ ++ mpath_pr_event_handle(pp); ++ } ++ } ++ } ++ + if (setup_map(mpp, ¶ms, vecs)) { + condlog(0, "%s: failed to setup new map in update", mpp->alias); + retries = -1; diff --git a/0003-multipath-tools-minor-fixes-to-multipath.conf.5-man-.patch b/0003-multipath-tools-minor-fixes-to-multipath.conf.5-man-.patch new file mode 100644 index 0000000..ddad7b0 --- /dev/null +++ b/0003-multipath-tools-minor-fixes-to-multipath.conf.5-man-.patch @@ -0,0 +1,48 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Thu, 16 Sep 2021 00:44:49 +0200 +Subject: [PATCH] multipath-tools: minor fixes to multipath.conf.5 man page + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Signed-off-by: Benjamin Marzinski +--- + multipath/multipath.conf.5 | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 +index 42a15ffd..c74129bd 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5 +@@ -1,9 +1,9 @@ + .\" ---------------------------------------------------------------------------- +-.\" Update the date below if you make any significant change. + .\" Make sure there are no errors with: + .\" groff -z -wall -b -e -t multipath/multipath.conf.5 + .\" man --warnings -E UTF-8 -l -Tutf8 -Z multipath/multipath.conf.5 >/dev/null + .\" ++.\" Update the date below if you make any significant change. + .\" ---------------------------------------------------------------------------- + . + .TH MULTIPATH.CONF 5 2021-09-08 Linux +@@ -189,7 +189,7 @@ The default is: \fB\fR + .TP + .B path_selector + The default path selector algorithm to use; they are offered by the +-kernel multipath target. There are three selector algorithms: ++kernel multipath target: + .RS + .TP 12 + .I "round-robin 0" +@@ -206,7 +206,7 @@ of outstanding I/O to the path. + of outstanding I/O to the path and its relative throughput. + .TP + .I "historical-service-time 0" +-(Since 5.8 kernel) Choose the path for the next bunch of IOs based on the ++(Since 5.8 kernel) Choose the path for the next bunch of I/O based on the + estimation of future service time based on the history of previous I/O submitted + to each path. + .TP diff --git a/0003-multipathd-don-t-fail-to-remove-path-once-the-map-is.patch b/0003-multipathd-don-t-fail-to-remove-path-once-the-map-is.patch deleted file mode 100644 index 89d027a..0000000 --- a/0003-multipathd-don-t-fail-to-remove-path-once-the-map-is.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 17 May 2021 11:29:54 -0500 -Subject: [PATCH] multipathd: don't fail to remove path once the map is removed - -In ev_remove_path(), if update_mpp_paths() fails, we delete the entire -map. However, since update_mpp_paths() happens before we call -set_path_removed(), pp->initialized isn't set to INIT_REMOVED, so -remove_map_and_stop_waiter() doesn't remove the path when in removes the -map. But with the map removed, there's nothing to keep us from removing -the path. - -Call set_path_removed() before update_mpp_paths() to avoid the odd case -of ev_remove_path() removing the map but not the path. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/structs_vec.c | 4 ++-- - multipathd/main.c | 13 ++++++++----- - 2 files changed, 10 insertions(+), 7 deletions(-) - -diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c -index d242c06b..75390198 100644 ---- a/libmultipath/structs_vec.c -+++ b/libmultipath/structs_vec.c -@@ -45,8 +45,8 @@ int update_mpp_paths(struct multipath *mpp, vector pathvec) - - /* - * Avoid adding removed paths to the map again -- * when we reload it. Such paths may exist if -- * domap fails in ev_remove_path(). -+ * when we reload it. Such paths may exist in -+ * ev_remove_paths() or if it returns failure. - */ - pp1 = find_path_by_devt(pathvec, pp->dev_t); - if (pp1 && pp->initialized != INIT_REMOVED && -diff --git a/multipathd/main.c b/multipathd/main.c -index c34fd9c8..2062bc10 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -1199,6 +1199,13 @@ ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map) - * avoid referring to the map of an orphaned path - */ - if ((mpp = pp->mpp)) { -+ /* -+ * Mark the path as removed. In case of success, we -+ * will delete it for good. Otherwise, it will be deleted -+ * later, unless all attempts to reload this map fail. -+ */ -+ set_path_removed(pp); -+ - /* - * transform the mp->pg vector of vectors of paths - * into a mp->params string to feed the device-mapper -@@ -1210,13 +1217,9 @@ ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map) - } - - /* -- * Mark the path as removed. In case of success, we -- * will delete it for good. Otherwise, it will be deleted -- * later, unless all attempts to reload this map fail. -- * Note: we have to explicitly remove pp from mpp->paths, -+ * we have to explicitly remove pp from mpp->paths, - * update_mpp_paths() doesn't do that. - */ -- set_path_removed(pp); - i = find_slot(mpp->paths, pp); - if (i != -1) - vector_del_slot(mpp->paths, i); diff --git a/0004-multipath-tools-make-IBM-XIV-config-work-with-alua-a.patch b/0004-multipath-tools-make-IBM-XIV-config-work-with-alua-a.patch new file mode 100644 index 0000000..da06d58 --- /dev/null +++ b/0004-multipath-tools-make-IBM-XIV-config-work-with-alua-a.patch @@ -0,0 +1,39 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Sat, 25 Sep 2021 00:27:36 +0200 +Subject: [PATCH] multipath-tools: make IBM/XIV config work with alua and + multibus + +And add recommended pgfailback value. + +ALUA is supported since XIV_Gen2 and microcode 10.2.1 +(All ports across all controllers in single Target Port Group) + +https://www.ibm.com/support/pages/ibm-flashsystem%C2%AE-a9000-and-a9000r-hyperswap-solution-deployment-linux%C2%AE-ibm-z-systems%C2%AE +https://www.google.com/search?q=%222810XIV%22+%22path_grouping_policy%22+site%3Aibm.com + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/hwtable.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index 0caac0da..72f81c60 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -712,7 +712,8 @@ static struct hwentry default_hw[] = { + .vendor = "(XIV|IBM)", + .product = "(NEXTRA|2810XIV)", + .no_path_retry = NO_PATH_RETRY_QUEUE, +- .pgpolicy = MULTIBUS, ++ .pgpolicy = GROUP_BY_PRIO, ++ .pgfailback = 15, + }, + { + /* TMS RamSan / FlashSystem 710/720/810/820/840/900 */ diff --git a/0004-multipathd-remove-duplicate-orphan_paths-in-flush_ma.patch b/0004-multipathd-remove-duplicate-orphan_paths-in-flush_ma.patch deleted file mode 100644 index 636a18c..0000000 --- a/0004-multipathd-remove-duplicate-orphan_paths-in-flush_ma.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 17 May 2021 11:29:55 -0500 -Subject: [PATCH] multipathd: remove duplicate orphan_paths in flush_map - -remove_map_and_stop_waiter() already calls orphan_paths() so flush_map() -doesn't need to call orphan_paths() before calling -remove_map_and_stop_waiter(). - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - multipathd/main.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 2062bc10..266d6b44 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -660,7 +660,6 @@ flush_map(struct multipath * mpp, struct vectors * vecs, int nopaths) - else - condlog(2, "%s: map flushed", mpp->alias); - -- orphan_paths(vecs->pathvec, mpp, "map flushed"); - remove_map_and_stop_waiter(mpp, vecs); - - return 0; diff --git a/0005-multipathd-fix-ev_remove_path-return-code-handling.patch b/0005-multipathd-fix-ev_remove_path-return-code-handling.patch deleted file mode 100644 index 74bf879..0000000 --- a/0005-multipathd-fix-ev_remove_path-return-code-handling.patch +++ /dev/null @@ -1,226 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 17 May 2021 11:29:56 -0500 -Subject: [PATCH] multipathd: fix ev_remove_path return code handling - -When ev_remove_path() returned success, callers assumed that the path -(and possibly the map) had been removed. When ev_remove_path() returned -failure, callers assumed that the path had not been removed. However, -the path could be removed on both success or failure. This could cause -callers to dereference the path after it was removed. - -To deal with this, make ev_remove_path() return a different symbolic -value for each outcome, and make the callers react appropriately for -the different values. Found by coverity. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - multipathd/cli_handlers.c | 24 +++++++++++++++++++++-- - multipathd/main.c | 41 ++++++++++++++++++++------------------- - multipathd/main.h | 14 +++++++++++++ - 3 files changed, 57 insertions(+), 22 deletions(-) - -diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c -index 1de6ad8e..6765fcf0 100644 ---- a/multipathd/cli_handlers.c -+++ b/multipathd/cli_handlers.c -@@ -752,7 +752,8 @@ cli_add_path (void * v, char ** reply, int * len, void * data) - /* Have the checker reinstate this path asap */ - pp->tick = 1; - return 0; -- } else if (!ev_remove_path(pp, vecs, true)) -+ } else if (ev_remove_path(pp, vecs, true) & -+ REMOVE_PATH_SUCCESS) - /* Path removed in ev_remove_path() */ - pp = NULL; - else { -@@ -813,6 +814,7 @@ cli_del_path (void * v, char ** reply, int * len, void * data) - struct vectors * vecs = (struct vectors *)data; - char * param = get_keyparam(v, PATH); - struct path *pp; -+ int ret; - - param = convert_dev(param, 1); - condlog(2, "%s: remove path (operator)", param); -@@ -821,7 +823,25 @@ cli_del_path (void * v, char ** reply, int * len, void * data) - condlog(0, "%s: path already removed", param); - return 1; - } -- return ev_remove_path(pp, vecs, 1); -+ ret = ev_remove_path(pp, vecs, 1); -+ if (ret == REMOVE_PATH_DELAY) { -+ *reply = strdup("delayed\n"); -+ if (*reply) -+ *len = strlen(*reply) + 1; -+ else { -+ *len = 0; -+ ret = REMOVE_PATH_FAILURE; -+ } -+ } else if (ret == REMOVE_PATH_MAP_ERROR) { -+ *reply = strdup("map reload error. removed\n"); -+ if (*reply) -+ *len = strlen(*reply) + 1; -+ else { -+ *len = 0; -+ ret = REMOVE_PATH_FAILURE; -+ } -+ } -+ return (ret == REMOVE_PATH_FAILURE); - } - - int -diff --git a/multipathd/main.c b/multipathd/main.c -index 266d6b44..26a4e44e 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -838,7 +838,7 @@ handle_path_wwid_change(struct path *pp, struct vectors *vecs) - return; - - udd = udev_device_ref(pp->udev); -- if (ev_remove_path(pp, vecs, 1) != 0 && pp->mpp) { -+ if (!(ev_remove_path(pp, vecs, 1) & REMOVE_PATH_SUCCESS) && pp->mpp) { - pp->dmstate = PSTATE_FAILED; - dm_fail_path(pp->mpp->alias, pp->dev_t); - } -@@ -948,8 +948,8 @@ uev_add_path (struct uevent *uev, struct vectors * vecs, int need_do_map) - * Make another attempt to remove the path - */ - pp->mpp = prev_mpp; -- ret = ev_remove_path(pp, vecs, true); -- if (ret != 0) { -+ if (!(ev_remove_path(pp, vecs, true) & -+ REMOVE_PATH_SUCCESS)) { - /* - * Failure in ev_remove_path will keep - * path in pathvec in INIT_REMOVED state -@@ -960,6 +960,7 @@ uev_add_path (struct uevent *uev, struct vectors * vecs, int need_do_map) - dm_fail_path(pp->mpp->alias, pp->dev_t); - condlog(1, "%s: failed to re-add path still mapped in %s", - pp->dev, pp->mpp->alias); -+ ret = 1; - } else if (r == PATHINFO_OK) - /* - * Path successfully freed, move on to -@@ -1167,7 +1168,6 @@ static int - uev_remove_path (struct uevent *uev, struct vectors * vecs, int need_do_map) - { - struct path *pp; -- int ret; - - condlog(3, "%s: remove path (uevent)", uev->kernel); - delete_foreign(uev->udev); -@@ -1177,21 +1177,18 @@ uev_remove_path (struct uevent *uev, struct vectors * vecs, int need_do_map) - pthread_testcancel(); - pp = find_path_by_dev(vecs->pathvec, uev->kernel); - if (pp) -- ret = ev_remove_path(pp, vecs, need_do_map); -+ ev_remove_path(pp, vecs, need_do_map); - lock_cleanup_pop(vecs->lock); -- if (!pp) { -- /* Not an error; path might have been purged earlier */ -+ if (!pp) /* Not an error; path might have been purged earlier */ - condlog(0, "%s: path already removed", uev->kernel); -- return 0; -- } -- return ret; -+ return 0; - } - - int - ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map) - { - struct multipath * mpp; -- int i, retval = 0; -+ int i, retval = REMOVE_PATH_SUCCESS; - char params[PARAMS_SIZE] = {0}; - - /* -@@ -1245,7 +1242,6 @@ ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map) - condlog(2, "%s: removed map after" - " removing all paths", - alias); -- retval = 0; - /* flush_map() has freed the path */ - goto out; - } -@@ -1262,11 +1258,14 @@ ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map) - - if (mpp->wait_for_udev) { - mpp->wait_for_udev = 2; -+ retval = REMOVE_PATH_DELAY; - goto out; - } - -- if (!need_do_map) -+ if (!need_do_map) { -+ retval = REMOVE_PATH_DELAY; - goto out; -+ } - /* - * reload the map - */ -@@ -1275,7 +1274,7 @@ ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map) - condlog(0, "%s: failed in domap for " - "removal of path %s", - mpp->alias, pp->dev); -- retval = 1; -+ retval = REMOVE_PATH_FAILURE; - } else { - /* - * update our state from kernel -@@ -1283,12 +1282,12 @@ ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map) - char devt[BLK_DEV_SIZE]; - - strlcpy(devt, pp->dev_t, sizeof(devt)); -+ -+ /* setup_multipath will free the path -+ * regardless of whether it succeeds or -+ * fails */ - if (setup_multipath(vecs, mpp)) -- return 1; -- /* -- * Successful map reload without this path: -- * sync_map_state() will free it. -- */ -+ return REMOVE_PATH_MAP_ERROR; - sync_map_state(mpp); - - condlog(2, "%s: path removed from map %s", -@@ -1304,8 +1303,10 @@ out: - return retval; - - fail: -+ condlog(0, "%s: error removing path. removing map %s", pp->dev, -+ mpp->alias); - remove_map_and_stop_waiter(mpp, vecs); -- return 1; -+ return REMOVE_PATH_MAP_ERROR; - } - - static int -diff --git a/multipathd/main.h b/multipathd/main.h -index ddd953f9..bc1f938f 100644 ---- a/multipathd/main.h -+++ b/multipathd/main.h -@@ -13,6 +13,20 @@ enum daemon_status { - DAEMON_STATUS_SIZE, - }; - -+enum remove_path_result { -+ REMOVE_PATH_FAILURE = 0x0, /* path could not be removed. It is still -+ * part of the kernel map, but its state -+ * is set to INIT_REMOVED, and it will be -+ * removed at the next possible occassion */ -+ REMOVE_PATH_SUCCESS = 0x1, /* path was removed */ -+ REMOVE_PATH_DELAY = 0x2, /* path is set to be removed later. it -+ * currently still exists and is part of the -+ * kernel map */ -+ REMOVE_PATH_MAP_ERROR = 0x5, /* map was removed because of error. value -+ * includes REMOVE_PATH_SUCCESS bit -+ * because the path was also removed */ -+}; -+ - struct prout_param_descriptor; - struct prin_resp; - diff --git a/0005-multipathd.socket-add-missing-conditions-from-servic.patch b/0005-multipathd.socket-add-missing-conditions-from-servic.patch new file mode 100644 index 0000000..e6b34a2 --- /dev/null +++ b/0005-multipathd.socket-add-missing-conditions-from-servic.patch @@ -0,0 +1,32 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Luca BRUNO +Date: Fri, 24 Sep 2021 09:34:01 +0000 +Subject: [PATCH] multipathd.socket: add missing conditions from service unit + +This aligns 'multipathd' socket and service units, by adding the +start conditions that are set on the service but not on the socket. +It should help avoiding situations where the socket unit ends up +marked as failed after hitting its retry-limit. + +Fixes: https://github.com/opensvc/multipath-tools/issues/15 +Signed-off-by: Luca BRUNO +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + multipathd/multipathd.socket | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/multipathd/multipathd.socket b/multipathd/multipathd.socket +index 0ed4a1f7..c777e5e3 100644 +--- a/multipathd/multipathd.socket ++++ b/multipathd/multipathd.socket +@@ -1,6 +1,9 @@ + [Unit] + Description=multipathd control socket + DefaultDependencies=no ++ConditionKernelCommandLine=!nompath ++ConditionKernelCommandLine=!multipath=off ++ConditionVirtualization=!container + Before=sockets.target + + [Socket] diff --git a/0006-multipath-free-vectors-in-configure.patch b/0006-multipath-free-vectors-in-configure.patch deleted file mode 100644 index 9c8a08e..0000000 --- a/0006-multipath-free-vectors-in-configure.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 17 May 2021 11:29:57 -0500 -Subject: [PATCH] multipath: free vectors in configure - -configure() can retry multiple times, each time reallocing a maps and -paths vector, and leaking the previous ones. Fix this by always freeing -the vectors before configure() exits. Found by coverity. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - multipath/main.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/multipath/main.c b/multipath/main.c -index ef89c7cf..8fc0e15f 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -466,7 +466,6 @@ configure (struct config *conf, enum mpath_cmds cmd, - */ - curmp = vector_alloc(); - pathvec = vector_alloc(); -- atexit(cleanup_vecs); - - if (!curmp || !pathvec) { - condlog(0, "can not allocate memory"); -@@ -578,6 +577,11 @@ out: - if (refwwid) - FREE(refwwid); - -+ free_multipathvec(curmp, KEEP_PATHS); -+ vecs.mpvec = NULL; -+ free_pathvec(pathvec, FREE_PATHS); -+ vecs.pathvec = NULL; -+ - return r; - } - -@@ -823,6 +827,7 @@ main (int argc, char *argv[]) - conf = get_multipath_config(); - conf->retrigger_tries = 0; - conf->force_sync = 1; -+ atexit(cleanup_vecs); - while ((arg = getopt(argc, argv, ":adDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { - switch(arg) { - case 1: printf("optarg : %s\n",optarg); diff --git a/0006-multipath-tools-make-IBM-2107900-DS8000-config-work-.patch b/0006-multipath-tools-make-IBM-2107900-DS8000-config-work-.patch new file mode 100644 index 0000000..97cc8ef --- /dev/null +++ b/0006-multipath-tools-make-IBM-2107900-DS8000-config-work-.patch @@ -0,0 +1,40 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Tue, 28 Sep 2021 18:52:10 +0200 +Subject: [PATCH] multipath-tools: make IBM/2107900 (DS8000) config work with + alua and multibus + +ALUA is supported since the beginning: +https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/scsi/device_handler/scsi_dh_alua.c?id=057ea7c9683c3d684128cced796f03c179ecf1c2#n683 + +... the DS8000 is an Asymmetric Logical Unit Access (ALUA) capable storage array, +pag#160(144): https://www.redbooks.ibm.com/redbooks/pdfs/sg248887.pdf + +kernel log: +https://marc.info/?l=linux-scsi&m=156407413807511&q=mbox + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/hwtable.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index 72f81c60..f115c4f9 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -656,7 +656,8 @@ static struct hwentry default_hw[] = { + .vendor = "IBM", + .product = "^2107900", + .no_path_retry = NO_PATH_RETRY_QUEUE, +- .pgpolicy = MULTIBUS, ++ .pgpolicy = GROUP_BY_PRIO, ++ .pgfailback = -FAILBACK_IMMEDIATE, + }, + { + // Storwize V5000 and V7000 lines / SAN Volume Controller (SVC) / Flex System V7000 / diff --git a/0007-kpartx-Don-t-leak-memory-when-getblock-returns-NULL.patch b/0007-kpartx-Don-t-leak-memory-when-getblock-returns-NULL.patch deleted file mode 100644 index 3cf456a..0000000 --- a/0007-kpartx-Don-t-leak-memory-when-getblock-returns-NULL.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 17 May 2021 11:29:58 -0500 -Subject: [PATCH] kpartx: Don't leak memory when getblock returns NULL - -If a new block was allocated, but couldn't be filled, getblock will -discard it. When it does so, it needs to free the block to avoid leaking -memory. Found by coverity. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - kpartx/kpartx.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/kpartx/kpartx.c b/kpartx/kpartx.c -index 8ff116b8..7bc64543 100644 ---- a/kpartx/kpartx.c -+++ b/kpartx/kpartx.c -@@ -766,6 +766,8 @@ getblock (int fd, unsigned int blknr) { - if (read(fd, bp->block, secsz) != secsz) { - fprintf(stderr, "read error, sector %d\n", secnr); - blockhead = bp->next; -+ free(bp->block); -+ free(bp); - return NULL; - } - diff --git a/0007-multipath-tools-make-EMC-SYMMETRIX-config-work-with-.patch b/0007-multipath-tools-make-EMC-SYMMETRIX-config-work-with-.patch new file mode 100644 index 0000000..201232a --- /dev/null +++ b/0007-multipath-tools-make-EMC-SYMMETRIX-config-work-with-.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Tue, 28 Sep 2021 19:20:59 +0200 +Subject: [PATCH] multipath-tools: make EMC/SYMMETRIX config work with alua and + multibus + +ALUA is supported since VMAX3 and HYPERMAX OS 5977.811.784, pag#113: +https://www.delltechnologies.com/en-us/collaterals/unauth/technical-guides-support-information/products/storage-2/docu5128.pdf + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/hwtable.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index f115c4f9..7095aaf1 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -329,8 +329,9 @@ static struct hwentry default_hw[] = { + /* Symmetrix / DMX / VMAX / PowerMax */ + .vendor = "EMC", + .product = "SYMMETRIX", +- .pgpolicy = MULTIBUS, ++ .pgpolicy = GROUP_BY_PRIO, + .no_path_retry = 6, ++ .pgfailback = -FAILBACK_IMMEDIATE, + }, + { + /* DGC CLARiiON CX/AX / VNX and Unity */ diff --git a/0008-multipath-tools-make-EMC-Invista-config-work-with-al.patch b/0008-multipath-tools-make-EMC-Invista-config-work-with-al.patch new file mode 100644 index 0000000..723f023 --- /dev/null +++ b/0008-multipath-tools-make-EMC-Invista-config-work-with-al.patch @@ -0,0 +1,37 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Tue, 28 Sep 2021 19:31:21 +0200 +Subject: [PATCH] multipath-tools: make EMC/Invista config work with alua and + multibus + +Optimal Path Management (OPM) was introduced with VPLEX 5.5 to improve VPLEX +performance. OPM uses the ALUA mechanism to spread the I/O load across VPLEX directors +while gaining cache locality, pag #187: +https://www.delltechnologies.com/en-us/collaterals/unauth/technical-guides-support-information/products/storage-2/docu5128.pdf + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/hwtable.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index 7095aaf1..4e8b52ff 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -350,8 +350,9 @@ static struct hwentry default_hw[] = { + .vendor = "EMC", + .product = "Invista", + .bl_product = "LUNZ", +- .pgpolicy = MULTIBUS, ++ .pgpolicy = GROUP_BY_PRIO, + .no_path_retry = 5, ++ .pgfailback = -FAILBACK_IMMEDIATE, + }, + { + /* XtremIO */ diff --git a/0008-multipathd-don-t-rescan_path-on-wwid-change-in-uev_u.patch b/0008-multipathd-don-t-rescan_path-on-wwid-change-in-uev_u.patch deleted file mode 100644 index 384ccb0..0000000 --- a/0008-multipathd-don-t-rescan_path-on-wwid-change-in-uev_u.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 17 May 2021 11:29:59 -0500 -Subject: [PATCH] multipathd: don't rescan_path on wwid change in - uev_update_path - -If get_uid() is returning a different wwid in uev_update_path(), then -the uid_attribute must have already gotten updated, which was the -purpose behind calling rescan_path() in the first place. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - multipathd/main.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 26a4e44e..2251e02c 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -1359,7 +1359,6 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) - condlog(0, "%s: path wwid changed from '%s' to '%s'", - uev->kernel, wwid, pp->wwid); - ev_remove_path(pp, vecs, 1); -- rescan_path(uev->udev); - needs_reinit = 1; - goto out; - } else { diff --git a/0009-multipath-tools-make-COMPELNT-Compellent-Vol-config-.patch b/0009-multipath-tools-make-COMPELNT-Compellent-Vol-config-.patch new file mode 100644 index 0000000..e2a93ee --- /dev/null +++ b/0009-multipath-tools-make-COMPELNT-Compellent-Vol-config-.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Tue, 28 Sep 2021 22:15:56 +0200 +Subject: [PATCH] multipath-tools: make "COMPELNT/Compellent Vol" config work + with alua and multibus + +ALUA is needed by SAS arrays, pag#124: +https://downloads.dell.com/manuals/all-products/esuprt_solutions_int/esuprt_solutions_int_solutions_resources/general-solution-resources_white-papers2_en-us.pdf + +Cc: Sean McGinnis +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/hwtable.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index 4e8b52ff..7fc5bc04 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -368,7 +368,8 @@ static struct hwentry default_hw[] = { + */ + .vendor = "COMPELNT", + .product = "Compellent Vol", +- .pgpolicy = MULTIBUS, ++ .pgpolicy = GROUP_BY_PRIO, ++ .pgfailback = -FAILBACK_IMMEDIATE, + .no_path_retry = NO_PATH_RETRY_QUEUE, + }, + { diff --git a/0009-multipathd-cli_handlers-cleanup-setting-reply-length.patch b/0009-multipathd-cli_handlers-cleanup-setting-reply-length.patch deleted file mode 100644 index 3099df6..0000000 --- a/0009-multipathd-cli_handlers-cleanup-setting-reply-length.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 17 May 2021 22:37:34 +0200 -Subject: [PATCH] multipathd: cli_handlers: cleanup setting reply length - -Create a macro for setting the reply length for string literals -correctly, and use it where necessary. - -In cli_del_path(), don't change the function's return code -if just the buffer allocation for the reply failed. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipathd/cli_handlers.c | 33 ++++++++++++--------------------- - 1 file changed, 12 insertions(+), 21 deletions(-) - -diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c -index 6765fcf0..96064944 100644 ---- a/multipathd/cli_handlers.c -+++ b/multipathd/cli_handlers.c -@@ -32,6 +32,12 @@ - #include "foreign.h" - #include "cli_handlers.h" - -+#define SET_REPLY_AND_LEN(__rep, __len, string_literal) \ -+ do { \ -+ *(__rep) = strdup(string_literal); \ -+ *(__len) = *(__rep) ? sizeof(string_literal) : 0; \ -+ } while (0) -+ - int - show_paths (char ** r, int * len, struct vectors * vecs, char * style, - int pretty) -@@ -802,8 +808,7 @@ cli_add_path (void * v, char ** reply, int * len, void * data) - } - return ev_add_path(pp, vecs, 1); - blacklisted: -- *reply = strdup("blacklisted\n"); -- *len = strlen(*reply) + 1; -+ SET_REPLY_AND_LEN(reply, len, "blacklisted\n"); - condlog(2, "%s: path blacklisted", param); - return 0; - } -@@ -824,23 +829,10 @@ cli_del_path (void * v, char ** reply, int * len, void * data) - return 1; - } - ret = ev_remove_path(pp, vecs, 1); -- if (ret == REMOVE_PATH_DELAY) { -- *reply = strdup("delayed\n"); -- if (*reply) -- *len = strlen(*reply) + 1; -- else { -- *len = 0; -- ret = REMOVE_PATH_FAILURE; -- } -- } else if (ret == REMOVE_PATH_MAP_ERROR) { -- *reply = strdup("map reload error. removed\n"); -- if (*reply) -- *len = strlen(*reply) + 1; -- else { -- *len = 0; -- ret = REMOVE_PATH_FAILURE; -- } -- } -+ if (ret == REMOVE_PATH_DELAY) -+ SET_REPLY_AND_LEN(reply, len, "delayed\n"); -+ else if (ret == REMOVE_PATH_MAP_ERROR) -+ SET_REPLY_AND_LEN(reply, len, "map reload error. removed\n"); - return (ret == REMOVE_PATH_FAILURE); - } - -@@ -865,8 +857,7 @@ cli_add_map (void * v, char ** reply, int * len, void * data) - invalid = 1; - pthread_cleanup_pop(1); - if (invalid) { -- *reply = strdup("blacklisted\n"); -- *len = strlen(*reply) + 1; -+ SET_REPLY_AND_LEN(reply, len, "blacklisted\n"); - condlog(2, "%s: map blacklisted", param); - return 1; - } diff --git a/0010-multipath-tools-remove-Compellent-maintainer.patch b/0010-multipath-tools-remove-Compellent-maintainer.patch new file mode 100644 index 0000000..f8e9cc0 --- /dev/null +++ b/0010-multipath-tools-remove-Compellent-maintainer.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Tue, 28 Sep 2021 22:39:17 +0200 +Subject: [PATCH] multipath-tools: remove Compellent maintainer + +e-mail was bounced: 550 5.1.1 User Unknown + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/hwtable.c | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index 7fc5bc04..763982cd 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -361,11 +361,7 @@ static struct hwentry default_hw[] = { + .pgpolicy = MULTIBUS, + }, + { +- /* +- * SC Series, formerly Compellent +- * +- * Maintainer: Sean McGinnis +- */ ++ /* SC Series, formerly Compellent */ + .vendor = "COMPELNT", + .product = "Compellent Vol", + .pgpolicy = GROUP_BY_PRIO, diff --git a/0010-multipathd-cli_getprkey-fix-return-value.patch b/0010-multipathd-cli_getprkey-fix-return-value.patch deleted file mode 100644 index 841190b..0000000 --- a/0010-multipathd-cli_getprkey-fix-return-value.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 17 May 2021 22:45:05 +0200 -Subject: [PATCH] multipathd: cli_getprkey(): fix return value - -By setting (*reply)[19] = '\0', we always truncated a possible -":aptpl" suffix. Fix it, and use the return value of snprintf() -as length. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipathd/cli_handlers.c | 17 ++++++++--------- - 1 file changed, 8 insertions(+), 9 deletions(-) - -diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c -index 96064944..59d44b45 100644 ---- a/multipathd/cli_handlers.c -+++ b/multipathd/cli_handlers.c -@@ -1540,7 +1540,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 = ""; -+ uint64_t key; - - mapname = convert_dev(mapname, 0); - condlog(3, "%s: get persistent reservation key (operator)", mapname); -@@ -1553,17 +1553,16 @@ cli_getprkey(void * v, char ** reply, int * len, void * data) - if (!*reply) - return 1; - -- if (!get_be64(mpp->reservation_key)) { -+ key = get_be64(mpp->reservation_key); -+ if (!key) { - sprintf(*reply, "none\n"); -- *len = strlen(*reply) + 1; -+ *len = sizeof("none\n"); - return 0; - } -- if (mpp->sa_flags & MPATH_F_APTPL_MASK) -- flagstr = ":aptpl"; -- snprintf(*reply, 26, "0x%" PRIx64 "%s\n", -- get_be64(mpp->reservation_key), flagstr); -- (*reply)[19] = '\0'; -- *len = strlen(*reply) + 1; -+ -+ /* This snprintf() can't overflow - PRIx64 needs max 16 chars */ -+ *len = snprintf(*reply, 26, "0x%" PRIx64 "%s\n", key, -+ mpp->sa_flags & MPATH_F_APTPL_MASK ? ":aptpl" : "") + 1; - return 0; - } - diff --git a/0024-RH-fixup-udev-rules-for-redhat.patch b/0011-RH-fixup-udev-rules-for-redhat.patch similarity index 100% rename from 0024-RH-fixup-udev-rules-for-redhat.patch rename to 0011-RH-fixup-udev-rules-for-redhat.patch diff --git a/0011-multipath-tools-enable-Wformat-overflow-2.patch b/0011-multipath-tools-enable-Wformat-overflow-2.patch deleted file mode 100644 index ab6f670..0000000 --- a/0011-multipath-tools-enable-Wformat-overflow-2.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 17 May 2021 22:43:02 +0200 -Subject: [PATCH] multipath-tools: enable -Wformat-overflow=2 - -Allow the compiler to catch possible format string overflows. -Two were found by gcc 10. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 3 ++- - libmultipath/discovery.c | 2 +- - libmultipath/print.c | 4 ++-- - 3 files changed, 5 insertions(+), 4 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index f1e23131..91100a20 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -95,9 +95,10 @@ TEST_CC_OPTION = $(shell \ - STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector) - ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers,) - WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered -Wno-error=clobbered,) -+WFORMATOVERFLOW := $(call TEST_CC_OPTION,-Wformat-overflow=2,) - - OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 --WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 -Werror=implicit-int \ -+WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int \ - -Werror=implicit-function-declaration -Werror=format-security \ - $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) - CPPFLAGS := -Wp,-D_FORTIFY_SOURCE=2 -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index ec99a7aa..bfe2f56c 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -635,7 +635,7 @@ sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp) - { - struct udev_device *rport_dev = NULL; - char value[16], *eptr; -- char rport_id[32]; -+ char rport_id[42]; - unsigned int tmo; - int ret; - -diff --git a/libmultipath/print.c b/libmultipath/print.c -index 8151e11e..3c69bf48 100644 ---- a/libmultipath/print.c -+++ b/libmultipath/print.c -@@ -1,4 +1,4 @@ --/* -+ /* - * Copyright (c) 2005 Christophe Varoqui - */ - #include -@@ -594,7 +594,7 @@ int - snprint_tgt_wwpn (char * buff, size_t len, const struct path * pp) - { - struct udev_device *rport_dev = NULL; -- char rport_id[32]; -+ char rport_id[42]; - const char *value = NULL; - int ret; - diff --git a/0025-RH-Remove-the-property-blacklist-exception-builtin.patch b/0012-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 92% rename from 0025-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0012-RH-Remove-the-property-blacklist-exception-builtin.patch index 53ee89b..c1cdc10 100644 --- a/0025-RH-Remove-the-property-blacklist-exception-builtin.patch +++ b/0012-RH-Remove-the-property-blacklist-exception-builtin.patch @@ -19,10 +19,10 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c -index 6c6a5979..785f5ee9 100644 +index 4e315c97..1e463ef6 100644 --- a/libmultipath/blacklist.c +++ b/libmultipath/blacklist.c -@@ -201,9 +201,6 @@ setup_default_blist (struct config * conf) +@@ -202,9 +202,6 @@ setup_default_blist (struct config * conf) if (store_ble(conf->blist_devnode, "!^(sd[a-z]|dasd[a-z]|nvme[0-9])", ORIGIN_DEFAULT)) return 1; @@ -32,7 +32,7 @@ index 6c6a5979..785f5ee9 100644 vector_foreach_slot (conf->hwtable, hwe, i) { if (hwe->bl_product) { if (find_blacklist_device(conf->blist_device, -@@ -407,7 +404,8 @@ filter_property(const struct config *conf, struct udev_device *udev, +@@ -410,7 +407,8 @@ filter_property(const struct config *conf, struct udev_device *udev, *uid_attribute != '\0'; bool uid_attr_seen = false; @@ -43,10 +43,10 @@ index 6c6a5979..785f5ee9 100644 udev_device_get_properties_list_entry(udev)) { diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index d6b8c7f6..689d09aa 100644 +index c74129bd..dd9f4dc7 100644 --- a/multipath/multipath.conf.5 +++ b/multipath/multipath.conf.5 -@@ -1347,9 +1347,14 @@ keywords. Both are regular expressions. For a full description of these keywords +@@ -1351,9 +1351,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, @@ -62,7 +62,7 @@ index d6b8c7f6..689d09aa 100644 . .RS .PP -@@ -1360,10 +1365,6 @@ Blacklisting by missing properties is only applied to devices which do have the +@@ -1364,10 +1369,6 @@ Blacklisting by missing properties is only applied to devices which do have the property specified by \fIuid_attribute\fR (e.g. \fIID_SERIAL\fR) set. Previously, it was applied to every device, possibly causing devices to be blacklisted because of temporary I/O error conditions. diff --git a/0012-libdmmp-use-KBUILD_BUILD_TIMESTAMP-when-building-man.patch b/0012-libdmmp-use-KBUILD_BUILD_TIMESTAMP-when-building-man.patch deleted file mode 100644 index af81882..0000000 --- a/0012-libdmmp-use-KBUILD_BUILD_TIMESTAMP-when-building-man.patch +++ /dev/null @@ -1,347 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 17 May 2021 23:12:10 +0200 -Subject: [PATCH] libdmmp: use KBUILD_BUILD_TIMESTAMP when building man pages - -Use the latest commit timestamp of the "libdmmp.h" file as -the timestamp for the man pages. This should avoid spurious rebuilds -of the documentation. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libdmmp/Makefile | 2 ++ - libdmmp/docs/man/dmmp_context_free.3 | 2 +- - libdmmp/docs/man/dmmp_context_log_func_set.3 | 2 +- - libdmmp/docs/man/dmmp_context_log_priority_get.3 | 2 +- - libdmmp/docs/man/dmmp_context_log_priority_set.3 | 2 +- - libdmmp/docs/man/dmmp_context_new.3 | 2 +- - libdmmp/docs/man/dmmp_context_timeout_get.3 | 2 +- - libdmmp/docs/man/dmmp_context_timeout_set.3 | 2 +- - libdmmp/docs/man/dmmp_context_userdata_get.3 | 2 +- - libdmmp/docs/man/dmmp_context_userdata_set.3 | 2 +- - libdmmp/docs/man/dmmp_flush_mpath.3 | 2 +- - libdmmp/docs/man/dmmp_last_error_msg.3 | 2 +- - libdmmp/docs/man/dmmp_log_priority_str.3 | 2 +- - libdmmp/docs/man/dmmp_mpath_array_free.3 | 2 +- - libdmmp/docs/man/dmmp_mpath_array_get.3 | 2 +- - libdmmp/docs/man/dmmp_mpath_kdev_name_get.3 | 2 +- - libdmmp/docs/man/dmmp_mpath_name_get.3 | 2 +- - libdmmp/docs/man/dmmp_mpath_wwid_get.3 | 2 +- - libdmmp/docs/man/dmmp_path_array_get.3 | 2 +- - libdmmp/docs/man/dmmp_path_blk_name_get.3 | 2 +- - libdmmp/docs/man/dmmp_path_group_array_get.3 | 2 +- - libdmmp/docs/man/dmmp_path_group_id_get.3 | 2 +- - libdmmp/docs/man/dmmp_path_group_priority_get.3 | 2 +- - libdmmp/docs/man/dmmp_path_group_selector_get.3 | 2 +- - libdmmp/docs/man/dmmp_path_group_status_get.3 | 2 +- - libdmmp/docs/man/dmmp_path_group_status_str.3 | 2 +- - libdmmp/docs/man/dmmp_path_status_get.3 | 2 +- - libdmmp/docs/man/dmmp_path_status_str.3 | 2 +- - libdmmp/docs/man/dmmp_reconfig.3 | 2 +- - libdmmp/docs/man/dmmp_strerror.3 | 2 +- - 30 files changed, 31 insertions(+), 29 deletions(-) - -diff --git a/libdmmp/Makefile b/libdmmp/Makefile -index 764a0bc5..79b92fb2 100644 ---- a/libdmmp/Makefile -+++ b/libdmmp/Makefile -@@ -76,6 +76,8 @@ docs/man/%.3.gz: docs/man/%.3 - docs/man/dmmp_strerror.3: $(HEADERS) - TEMPFILE=$(shell mktemp); \ - cat $^ | perl docs/doc-preclean.pl >$$TEMPFILE; \ -+ LC_ALL=C \ -+ KBUILD_BUILD_TIMESTAMP=`git log -n1 --pretty=%cd --date=iso -- $^` \ - perl docs/kernel-doc -man $$TEMPFILE | \ - perl docs/split-man.pl docs/man; \ - rm -f $$TEMPFILE -diff --git a/libdmmp/docs/man/dmmp_context_free.3 b/libdmmp/docs/man/dmmp_context_free.3 -index 0d26f42c..7c109e13 100644 ---- a/libdmmp/docs/man/dmmp_context_free.3 -+++ b/libdmmp/docs/man/dmmp_context_free.3 -@@ -1,4 +1,4 @@ --.TH "dmmp_context_free" 3 "dmmp_context_free" "March 2021" "Device Mapper Multipath API - libdmmp Manual" -+.TH "dmmp_context_free" 3 "dmmp_context_free" "March 2018" "Device Mapper Multipath API - libdmmp Manual" - .SH NAME - dmmp_context_free \- Release the memory of struct dmmp_context. - .SH SYNOPSIS -diff --git a/libdmmp/docs/man/dmmp_context_log_func_set.3 b/libdmmp/docs/man/dmmp_context_log_func_set.3 -index 986793db..be311ecf 100644 ---- a/libdmmp/docs/man/dmmp_context_log_func_set.3 -+++ b/libdmmp/docs/man/dmmp_context_log_func_set.3 -@@ -1,4 +1,4 @@ --.TH "dmmp_context_log_func_set" 3 "dmmp_context_log_func_set" "March 2021" "Device Mapper Multipath API - libdmmp Manual" -+.TH "dmmp_context_log_func_set" 3 "dmmp_context_log_func_set" "March 2018" "Device Mapper Multipath API - libdmmp Manual" - .SH NAME - dmmp_context_log_func_set \- Set log handler function. - .SH SYNOPSIS -diff --git a/libdmmp/docs/man/dmmp_context_log_priority_get.3 b/libdmmp/docs/man/dmmp_context_log_priority_get.3 -index 9a273a28..be383013 100644 ---- a/libdmmp/docs/man/dmmp_context_log_priority_get.3 -+++ b/libdmmp/docs/man/dmmp_context_log_priority_get.3 -@@ -1,4 +1,4 @@ --.TH "dmmp_context_log_priority_get" 3 "dmmp_context_log_priority_get" "March 2021" "Device Mapper Multipath API - libdmmp Manual" -+.TH "dmmp_context_log_priority_get" 3 "dmmp_context_log_priority_get" "March 2018" "Device Mapper Multipath API - libdmmp Manual" - .SH NAME - dmmp_context_log_priority_get \- Get log priority. - .SH SYNOPSIS -diff --git a/libdmmp/docs/man/dmmp_context_log_priority_set.3 b/libdmmp/docs/man/dmmp_context_log_priority_set.3 -index 469c5a49..79e4d2e8 100644 ---- a/libdmmp/docs/man/dmmp_context_log_priority_set.3 -+++ b/libdmmp/docs/man/dmmp_context_log_priority_set.3 -@@ -1,4 +1,4 @@ --.TH "dmmp_context_log_priority_set" 3 "dmmp_context_log_priority_set" "March 2021" "Device Mapper Multipath API - libdmmp Manual" -+.TH "dmmp_context_log_priority_set" 3 "dmmp_context_log_priority_set" "March 2018" "Device Mapper Multipath API - libdmmp Manual" - .SH NAME - dmmp_context_log_priority_set \- Set log priority. - .SH SYNOPSIS -diff --git a/libdmmp/docs/man/dmmp_context_new.3 b/libdmmp/docs/man/dmmp_context_new.3 -index 0eaeb00d..12505f91 100644 ---- a/libdmmp/docs/man/dmmp_context_new.3 -+++ b/libdmmp/docs/man/dmmp_context_new.3 -@@ -1,4 +1,4 @@ --.TH "dmmp_context_new" 3 "dmmp_context_new" "March 2021" "Device Mapper Multipath API - libdmmp Manual" -+.TH "dmmp_context_new" 3 "dmmp_context_new" "March 2018" "Device Mapper Multipath API - libdmmp Manual" - .SH NAME - dmmp_context_new \- Create struct dmmp_context. - .SH SYNOPSIS -diff --git a/libdmmp/docs/man/dmmp_context_timeout_get.3 b/libdmmp/docs/man/dmmp_context_timeout_get.3 -index 1df27936..2ed825d5 100644 ---- a/libdmmp/docs/man/dmmp_context_timeout_get.3 -+++ b/libdmmp/docs/man/dmmp_context_timeout_get.3 -@@ -1,4 +1,4 @@ --.TH "dmmp_context_timeout_get" 3 "dmmp_context_timeout_get" "March 2021" "Device Mapper Multipath API - libdmmp Manual" -+.TH "dmmp_context_timeout_get" 3 "dmmp_context_timeout_get" "March 2018" "Device Mapper Multipath API - libdmmp Manual" - .SH NAME - dmmp_context_timeout_get \- Get IPC timeout. - .SH SYNOPSIS -diff --git a/libdmmp/docs/man/dmmp_context_timeout_set.3 b/libdmmp/docs/man/dmmp_context_timeout_set.3 -index f3d77092..16bc9d99 100644 ---- a/libdmmp/docs/man/dmmp_context_timeout_set.3 -+++ b/libdmmp/docs/man/dmmp_context_timeout_set.3 -@@ -1,4 +1,4 @@ --.TH "dmmp_context_timeout_set" 3 "dmmp_context_timeout_set" "March 2021" "Device Mapper Multipath API - libdmmp Manual" -+.TH "dmmp_context_timeout_set" 3 "dmmp_context_timeout_set" "March 2018" "Device Mapper Multipath API - libdmmp Manual" - .SH NAME - dmmp_context_timeout_set \- Set IPC timeout. - .SH SYNOPSIS -diff --git a/libdmmp/docs/man/dmmp_context_userdata_get.3 b/libdmmp/docs/man/dmmp_context_userdata_get.3 -index fb713d50..eff446c6 100644 ---- a/libdmmp/docs/man/dmmp_context_userdata_get.3 -+++ b/libdmmp/docs/man/dmmp_context_userdata_get.3 -@@ -1,4 +1,4 @@ --.TH "dmmp_context_userdata_get" 3 "dmmp_context_userdata_get" "March 2021" "Device Mapper Multipath API - libdmmp Manual" -+.TH "dmmp_context_userdata_get" 3 "dmmp_context_userdata_get" "March 2018" "Device Mapper Multipath API - libdmmp Manual" - .SH NAME - dmmp_context_userdata_get \- Get user data pointer. - .SH SYNOPSIS -diff --git a/libdmmp/docs/man/dmmp_context_userdata_set.3 b/libdmmp/docs/man/dmmp_context_userdata_set.3 -index c5bf63f3..d7be869f 100644 ---- a/libdmmp/docs/man/dmmp_context_userdata_set.3 -+++ b/libdmmp/docs/man/dmmp_context_userdata_set.3 -@@ -1,4 +1,4 @@ --.TH "dmmp_context_userdata_set" 3 "dmmp_context_userdata_set" "March 2021" "Device Mapper Multipath API - libdmmp Manual" -+.TH "dmmp_context_userdata_set" 3 "dmmp_context_userdata_set" "March 2018" "Device Mapper Multipath API - libdmmp Manual" - .SH NAME - dmmp_context_userdata_set \- Set user data pointer. - .SH SYNOPSIS -diff --git a/libdmmp/docs/man/dmmp_flush_mpath.3 b/libdmmp/docs/man/dmmp_flush_mpath.3 -index cdfd5266..359607ed 100644 ---- a/libdmmp/docs/man/dmmp_flush_mpath.3 -+++ b/libdmmp/docs/man/dmmp_flush_mpath.3 -@@ -1,4 +1,4 @@ --.TH "dmmp_flush_mpath" 3 "dmmp_flush_mpath" "March 2021" "Device Mapper Multipath API - libdmmp Manual" -+.TH "dmmp_flush_mpath" 3 "dmmp_flush_mpath" "March 2018" "Device Mapper Multipath API - libdmmp Manual" - .SH NAME - dmmp_flush_mpath \- Flush specified multipath device map if unused. - .SH SYNOPSIS -diff --git a/libdmmp/docs/man/dmmp_last_error_msg.3 b/libdmmp/docs/man/dmmp_last_error_msg.3 -index 20acbc6a..378c55a5 100644 ---- a/libdmmp/docs/man/dmmp_last_error_msg.3 -+++ b/libdmmp/docs/man/dmmp_last_error_msg.3 -@@ -1,4 +1,4 @@ --.TH "dmmp_last_error_msg" 3 "dmmp_last_error_msg" "March 2021" "Device Mapper Multipath API - libdmmp Manual" -+.TH "dmmp_last_error_msg" 3 "dmmp_last_error_msg" "March 2018" "Device Mapper Multipath API - libdmmp Manual" - .SH NAME - dmmp_last_error_msg \- Retrieves the last error message. - .SH SYNOPSIS -diff --git a/libdmmp/docs/man/dmmp_log_priority_str.3 b/libdmmp/docs/man/dmmp_log_priority_str.3 -index 3b5f8284..b2761602 100644 ---- a/libdmmp/docs/man/dmmp_log_priority_str.3 -+++ b/libdmmp/docs/man/dmmp_log_priority_str.3 -@@ -1,4 +1,4 @@ --.TH "dmmp_log_priority_str" 3 "dmmp_log_priority_str" "March 2021" "Device Mapper Multipath API - libdmmp Manual" -+.TH "dmmp_log_priority_str" 3 "dmmp_log_priority_str" "March 2018" "Device Mapper Multipath API - libdmmp Manual" - .SH NAME - dmmp_log_priority_str \- Convert log priority to string. - .SH SYNOPSIS -diff --git a/libdmmp/docs/man/dmmp_mpath_array_free.3 b/libdmmp/docs/man/dmmp_mpath_array_free.3 -index 8c294e0d..0514a66f 100644 ---- a/libdmmp/docs/man/dmmp_mpath_array_free.3 -+++ b/libdmmp/docs/man/dmmp_mpath_array_free.3 -@@ -1,4 +1,4 @@ --.TH "dmmp_mpath_array_free" 3 "dmmp_mpath_array_free" "March 2021" "Device Mapper Multipath API - libdmmp Manual" -+.TH "dmmp_mpath_array_free" 3 "dmmp_mpath_array_free" "March 2018" "Device Mapper Multipath API - libdmmp Manual" - .SH NAME - dmmp_mpath_array_free \- Free 'struct dmmp_mpath' pointer array. - .SH SYNOPSIS -diff --git a/libdmmp/docs/man/dmmp_mpath_array_get.3 b/libdmmp/docs/man/dmmp_mpath_array_get.3 -index e211db42..8b0e5b53 100644 ---- a/libdmmp/docs/man/dmmp_mpath_array_get.3 -+++ b/libdmmp/docs/man/dmmp_mpath_array_get.3 -@@ -1,4 +1,4 @@ --.TH "dmmp_mpath_array_get" 3 "dmmp_mpath_array_get" "March 2021" "Device Mapper Multipath API - libdmmp Manual" -+.TH "dmmp_mpath_array_get" 3 "dmmp_mpath_array_get" "March 2018" "Device Mapper Multipath API - libdmmp Manual" - .SH NAME - dmmp_mpath_array_get \- Query all existing multipath devices. - .SH SYNOPSIS -diff --git a/libdmmp/docs/man/dmmp_mpath_kdev_name_get.3 b/libdmmp/docs/man/dmmp_mpath_kdev_name_get.3 -index e802fe6d..ddead551 100644 ---- a/libdmmp/docs/man/dmmp_mpath_kdev_name_get.3 -+++ b/libdmmp/docs/man/dmmp_mpath_kdev_name_get.3 -@@ -1,4 +1,4 @@ --.TH "dmmp_mpath_kdev_name_get" 3 "dmmp_mpath_kdev_name_get" "March 2021" "Device Mapper Multipath API - libdmmp Manual" -+.TH "dmmp_mpath_kdev_name_get" 3 "dmmp_mpath_kdev_name_get" "March 2018" "Device Mapper Multipath API - libdmmp Manual" - .SH NAME - dmmp_mpath_kdev_name_get \- Retrieve kernel DEVNAME of certain mpath. - .SH SYNOPSIS -diff --git a/libdmmp/docs/man/dmmp_mpath_name_get.3 b/libdmmp/docs/man/dmmp_mpath_name_get.3 -index d70579e5..2b0027e5 100644 ---- a/libdmmp/docs/man/dmmp_mpath_name_get.3 -+++ b/libdmmp/docs/man/dmmp_mpath_name_get.3 -@@ -1,4 +1,4 @@ --.TH "dmmp_mpath_name_get" 3 "dmmp_mpath_name_get" "March 2021" "Device Mapper Multipath API - libdmmp Manual" -+.TH "dmmp_mpath_name_get" 3 "dmmp_mpath_name_get" "March 2018" "Device Mapper Multipath API - libdmmp Manual" - .SH NAME - dmmp_mpath_name_get \- Retrieve name(alias) of certain mpath. - .SH SYNOPSIS -diff --git a/libdmmp/docs/man/dmmp_mpath_wwid_get.3 b/libdmmp/docs/man/dmmp_mpath_wwid_get.3 -index 3d060e92..b8e9e7d8 100644 ---- a/libdmmp/docs/man/dmmp_mpath_wwid_get.3 -+++ b/libdmmp/docs/man/dmmp_mpath_wwid_get.3 -@@ -1,4 +1,4 @@ --.TH "dmmp_mpath_wwid_get" 3 "dmmp_mpath_wwid_get" "March 2021" "Device Mapper Multipath API - libdmmp Manual" -+.TH "dmmp_mpath_wwid_get" 3 "dmmp_mpath_wwid_get" "March 2018" "Device Mapper Multipath API - libdmmp Manual" - .SH NAME - dmmp_mpath_wwid_get \- Retrieve WWID of certain mpath. - .SH SYNOPSIS -diff --git a/libdmmp/docs/man/dmmp_path_array_get.3 b/libdmmp/docs/man/dmmp_path_array_get.3 -index 53340b3d..21f486be 100644 ---- a/libdmmp/docs/man/dmmp_path_array_get.3 -+++ b/libdmmp/docs/man/dmmp_path_array_get.3 -@@ -1,4 +1,4 @@ --.TH "dmmp_path_array_get" 3 "dmmp_path_array_get" "March 2021" "Device Mapper Multipath API - libdmmp Manual" -+.TH "dmmp_path_array_get" 3 "dmmp_path_array_get" "March 2018" "Device Mapper Multipath API - libdmmp Manual" - .SH NAME - dmmp_path_array_get \- Retrieve path pointer array. - .SH SYNOPSIS -diff --git a/libdmmp/docs/man/dmmp_path_blk_name_get.3 b/libdmmp/docs/man/dmmp_path_blk_name_get.3 -index da5f9f03..5938f0e7 100644 ---- a/libdmmp/docs/man/dmmp_path_blk_name_get.3 -+++ b/libdmmp/docs/man/dmmp_path_blk_name_get.3 -@@ -1,4 +1,4 @@ --.TH "dmmp_path_blk_name_get" 3 "dmmp_path_blk_name_get" "March 2021" "Device Mapper Multipath API - libdmmp Manual" -+.TH "dmmp_path_blk_name_get" 3 "dmmp_path_blk_name_get" "March 2018" "Device Mapper Multipath API - libdmmp Manual" - .SH NAME - dmmp_path_blk_name_get \- Retrieve block name. - .SH SYNOPSIS -diff --git a/libdmmp/docs/man/dmmp_path_group_array_get.3 b/libdmmp/docs/man/dmmp_path_group_array_get.3 -index 6eee4a2b..ca3187cb 100644 ---- a/libdmmp/docs/man/dmmp_path_group_array_get.3 -+++ b/libdmmp/docs/man/dmmp_path_group_array_get.3 -@@ -1,4 +1,4 @@ --.TH "dmmp_path_group_array_get" 3 "dmmp_path_group_array_get" "March 2021" "Device Mapper Multipath API - libdmmp Manual" -+.TH "dmmp_path_group_array_get" 3 "dmmp_path_group_array_get" "March 2018" "Device Mapper Multipath API - libdmmp Manual" - .SH NAME - dmmp_path_group_array_get \- Retrieve path groups pointer array. - .SH SYNOPSIS -diff --git a/libdmmp/docs/man/dmmp_path_group_id_get.3 b/libdmmp/docs/man/dmmp_path_group_id_get.3 -index 4f07b536..a84f31f0 100644 ---- a/libdmmp/docs/man/dmmp_path_group_id_get.3 -+++ b/libdmmp/docs/man/dmmp_path_group_id_get.3 -@@ -1,4 +1,4 @@ --.TH "dmmp_path_group_id_get" 3 "dmmp_path_group_id_get" "March 2021" "Device Mapper Multipath API - libdmmp Manual" -+.TH "dmmp_path_group_id_get" 3 "dmmp_path_group_id_get" "March 2018" "Device Mapper Multipath API - libdmmp Manual" - .SH NAME - dmmp_path_group_id_get \- Retrieve path group ID. - .SH SYNOPSIS -diff --git a/libdmmp/docs/man/dmmp_path_group_priority_get.3 b/libdmmp/docs/man/dmmp_path_group_priority_get.3 -index a48b2704..1cda8af3 100644 ---- a/libdmmp/docs/man/dmmp_path_group_priority_get.3 -+++ b/libdmmp/docs/man/dmmp_path_group_priority_get.3 -@@ -1,4 +1,4 @@ --.TH "dmmp_path_group_priority_get" 3 "dmmp_path_group_priority_get" "March 2021" "Device Mapper Multipath API - libdmmp Manual" -+.TH "dmmp_path_group_priority_get" 3 "dmmp_path_group_priority_get" "March 2018" "Device Mapper Multipath API - libdmmp Manual" - .SH NAME - dmmp_path_group_priority_get \- Retrieve path group priority. - .SH SYNOPSIS -diff --git a/libdmmp/docs/man/dmmp_path_group_selector_get.3 b/libdmmp/docs/man/dmmp_path_group_selector_get.3 -index 407b3f41..f55477bb 100644 ---- a/libdmmp/docs/man/dmmp_path_group_selector_get.3 -+++ b/libdmmp/docs/man/dmmp_path_group_selector_get.3 -@@ -1,4 +1,4 @@ --.TH "dmmp_path_group_selector_get" 3 "dmmp_path_group_selector_get" "March 2021" "Device Mapper Multipath API - libdmmp Manual" -+.TH "dmmp_path_group_selector_get" 3 "dmmp_path_group_selector_get" "March 2018" "Device Mapper Multipath API - libdmmp Manual" - .SH NAME - dmmp_path_group_selector_get \- Retrieve path group selector. - .SH SYNOPSIS -diff --git a/libdmmp/docs/man/dmmp_path_group_status_get.3 b/libdmmp/docs/man/dmmp_path_group_status_get.3 -index a81aeb3a..53e68b8e 100644 ---- a/libdmmp/docs/man/dmmp_path_group_status_get.3 -+++ b/libdmmp/docs/man/dmmp_path_group_status_get.3 -@@ -1,4 +1,4 @@ --.TH "dmmp_path_group_status_get" 3 "dmmp_path_group_status_get" "March 2021" "Device Mapper Multipath API - libdmmp Manual" -+.TH "dmmp_path_group_status_get" 3 "dmmp_path_group_status_get" "March 2018" "Device Mapper Multipath API - libdmmp Manual" - .SH NAME - dmmp_path_group_status_get \- Retrieve path group status. - .SH SYNOPSIS -diff --git a/libdmmp/docs/man/dmmp_path_group_status_str.3 b/libdmmp/docs/man/dmmp_path_group_status_str.3 -index e4a9f74b..98f877a4 100644 ---- a/libdmmp/docs/man/dmmp_path_group_status_str.3 -+++ b/libdmmp/docs/man/dmmp_path_group_status_str.3 -@@ -1,4 +1,4 @@ --.TH "dmmp_path_group_status_str" 3 "dmmp_path_group_status_str" "March 2021" "Device Mapper Multipath API - libdmmp Manual" -+.TH "dmmp_path_group_status_str" 3 "dmmp_path_group_status_str" "March 2018" "Device Mapper Multipath API - libdmmp Manual" - .SH NAME - dmmp_path_group_status_str \- Convert path group status to string. - .SH SYNOPSIS -diff --git a/libdmmp/docs/man/dmmp_path_status_get.3 b/libdmmp/docs/man/dmmp_path_status_get.3 -index 025cfee5..baa4437d 100644 ---- a/libdmmp/docs/man/dmmp_path_status_get.3 -+++ b/libdmmp/docs/man/dmmp_path_status_get.3 -@@ -1,4 +1,4 @@ --.TH "dmmp_path_status_get" 3 "dmmp_path_status_get" "March 2021" "Device Mapper Multipath API - libdmmp Manual" -+.TH "dmmp_path_status_get" 3 "dmmp_path_status_get" "March 2018" "Device Mapper Multipath API - libdmmp Manual" - .SH NAME - dmmp_path_status_get \- Retrieve the path status. - .SH SYNOPSIS -diff --git a/libdmmp/docs/man/dmmp_path_status_str.3 b/libdmmp/docs/man/dmmp_path_status_str.3 -index 3944d399..425e472a 100644 ---- a/libdmmp/docs/man/dmmp_path_status_str.3 -+++ b/libdmmp/docs/man/dmmp_path_status_str.3 -@@ -1,4 +1,4 @@ --.TH "dmmp_path_status_str" 3 "dmmp_path_status_str" "March 2021" "Device Mapper Multipath API - libdmmp Manual" -+.TH "dmmp_path_status_str" 3 "dmmp_path_status_str" "March 2018" "Device Mapper Multipath API - libdmmp Manual" - .SH NAME - dmmp_path_status_str \- Convert path status to string. - .SH SYNOPSIS -diff --git a/libdmmp/docs/man/dmmp_reconfig.3 b/libdmmp/docs/man/dmmp_reconfig.3 -index a743e308..36bd5041 100644 ---- a/libdmmp/docs/man/dmmp_reconfig.3 -+++ b/libdmmp/docs/man/dmmp_reconfig.3 -@@ -1,4 +1,4 @@ --.TH "dmmp_reconfig" 3 "dmmp_reconfig" "March 2021" "Device Mapper Multipath API - libdmmp Manual" -+.TH "dmmp_reconfig" 3 "dmmp_reconfig" "March 2018" "Device Mapper Multipath API - libdmmp Manual" - .SH NAME - dmmp_reconfig \- Instruct multipathd daemon to do reconfiguration. - .SH SYNOPSIS -diff --git a/libdmmp/docs/man/dmmp_strerror.3 b/libdmmp/docs/man/dmmp_strerror.3 -index 4d753d36..3acd9c9d 100644 ---- a/libdmmp/docs/man/dmmp_strerror.3 -+++ b/libdmmp/docs/man/dmmp_strerror.3 -@@ -1,4 +1,4 @@ --.TH "dmmp_strerror" 3 "dmmp_strerror" "March 2021" "Device Mapper Multipath API - libdmmp Manual" -+.TH "dmmp_strerror" 3 "dmmp_strerror" "March 2018" "Device Mapper Multipath API - libdmmp Manual" - .SH NAME - dmmp_strerror \- Convert error code to string. - .SH SYNOPSIS diff --git a/0026-RH-don-t-start-without-a-config-file.patch b/0013-RH-don-t-start-without-a-config-file.patch similarity index 100% rename from 0026-RH-don-t-start-without-a-config-file.patch rename to 0013-RH-don-t-start-without-a-config-file.patch diff --git a/0013-multipath-tools-add-info-about-HPE-Alletra-6000-and-.patch b/0013-multipath-tools-add-info-about-HPE-Alletra-6000-and-.patch deleted file mode 100644 index 551ba59..0000000 --- a/0013-multipath-tools-add-info-about-HPE-Alletra-6000-and-.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Sat, 5 Jun 2021 01:01:45 +0200 -Subject: [PATCH] multipath-tools: add info about HPE Alletra 6000 and 9000 - -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - README.alua | 2 +- - libmultipath/hwtable.c | 4 ++-- - 2 files changed, 3 insertions(+), 3 deletions(-) - -diff --git a/README.alua b/README.alua -index b15eb487..5d2b1c64 100644 ---- a/README.alua -+++ b/README.alua -@@ -6,7 +6,7 @@ To enable ALUA, the following options should be changed: - - EMC CLARiiON/VNX: - "Failover Mode" should be changed to "4" or "Active-Active mode(ALUA)-failover mode 4" - --- HPE 3PAR: -+- HPE 3PAR, Primera, and Alletra 9000: - "Host:" should be changed to "Generic-ALUA Persona 2 (UARepLun, SESLun, ALUA)". - - - Promise VTrak/Vess: -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index 58fa7387..e884d8c7 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -107,7 +107,7 @@ static struct hwentry default_hw[] = { - * HPE - */ - { -- /* 3PAR / Primera */ -+ /* 3PAR / Primera / Alletra 9000 */ - .vendor = "3PARdata", - .product = "VV", - .pgpolicy = GROUP_BY_PRIO, -@@ -225,7 +225,7 @@ static struct hwentry default_hw[] = { - .prio_name = PRIO_ALUA, - }, - { -- /* Nimble Storage */ -+ /* Nimble Storage / HPE Alletra 6000 */ - .vendor = "Nimble", - .product = "Server", - .hwhandler = "1 alua", diff --git a/0027-RH-Fix-nvme-function-missing-argument.patch b/0014-RH-Fix-nvme-function-missing-argument.patch similarity index 100% rename from 0027-RH-Fix-nvme-function-missing-argument.patch rename to 0014-RH-Fix-nvme-function-missing-argument.patch diff --git a/0014-multipathd-don-t-start-in-containers.patch b/0014-multipathd-don-t-start-in-containers.patch deleted file mode 100644 index 79fcaf5..0000000 --- a/0014-multipathd-don-t-start-in-containers.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Utkarsh Gupta -Date: Mon, 7 Jun 2021 20:08:24 +0530 -Subject: [PATCH] multipathd: don't start in containers - -Do not attempt to start multipath-tools in containers, -should switch for on-demand udev/socket based -activation in the future. - -Originally reported as: -https://bugs.launchpad.net/ubuntu/+source/multipath-tools/+bug/1823093 - -Author: Dimitri John Ledkov -Co-Author: Utkarsh Gupta -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - multipathd/multipathd.service | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service -index 7d547fa7..0b2ac814 100644 ---- a/multipathd/multipathd.service -+++ b/multipathd/multipathd.service -@@ -8,6 +8,7 @@ DefaultDependencies=no - Conflicts=shutdown.target - ConditionKernelCommandLine=!nompath - ConditionKernelCommandLine=!multipath=off -+ConditionVirtualization=!container - - [Service] - Type=notify diff --git a/0028-RH-use-rpm-optflags-if-present.patch b/0015-RH-use-rpm-optflags-if-present.patch similarity index 100% rename from 0028-RH-use-rpm-optflags-if-present.patch rename to 0015-RH-use-rpm-optflags-if-present.patch diff --git a/0015-libmultipath-fix-build-without-LIBDM_API_DEFERRED.patch b/0015-libmultipath-fix-build-without-LIBDM_API_DEFERRED.patch deleted file mode 100644 index 77068c0..0000000 --- a/0015-libmultipath-fix-build-without-LIBDM_API_DEFERRED.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 20 May 2021 21:26:01 +0200 -Subject: [PATCH] libmultipath: fix build without LIBDM_API_DEFERRED - -Build fails on distributions that don't support DM_DEFERRED_REMOVE -(libdevmapper < 1.02.89). Fix it. - -Resolves: https://github.com/opensvc/multipath-tools/issues/7 -Tested-by: Paul Menzel -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/devmapper.c | 11 ++++++++--- - 1 file changed, 8 insertions(+), 3 deletions(-) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index 095cbc0c..47a6d60e 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -49,6 +49,9 @@ static int dm_conf_verbosity; - - #ifdef LIBDM_API_DEFERRED - static int dm_cancel_remove_partmaps(const char * mapname); -+#define __DR_UNUSED__ /* empty */ -+#else -+#define __DR_UNUSED__ __attribute__((unused)) - #endif - - static int do_foreach_partmaps(const char * mapname, -@@ -384,7 +387,8 @@ libmp_dm_task_create(int task) - #define do_deferred(x) ((x) == DEFERRED_REMOVE_ON || (x) == DEFERRED_REMOVE_IN_PROGRESS) - - static int --dm_simplecmd (int task, const char *name, int no_flush, int need_sync, uint16_t udev_flags, int deferred_remove) { -+dm_simplecmd (int task, const char *name, int no_flush, int need_sync, -+ uint16_t udev_flags, int deferred_remove __DR_UNUSED__) { - int r = 0; - int udev_wait_flag = ((need_sync || udev_flags) && - (task == DM_DEVICE_RESUME || -@@ -1122,7 +1126,8 @@ dm_flush_map_nopaths(const char * mapname, int deferred_remove) - #else - - int --dm_flush_map_nopaths(const char * mapname, int deferred_remove) -+dm_flush_map_nopaths(const char * mapname, -+ int deferred_remove __attribute__((unused))) - { - return _dm_flush_map(mapname, 1, 0, 0, 0); - } -@@ -1573,7 +1578,7 @@ dm_cancel_deferred_remove (struct multipath *mpp) - #else - - int --dm_cancel_deferred_remove (struct multipath *mpp) -+dm_cancel_deferred_remove (struct multipath *mpp __attribute__((unused))) - { - return 0; - } diff --git a/0029-RH-add-mpathconf.patch b/0016-RH-add-mpathconf.patch similarity index 100% rename from 0029-RH-add-mpathconf.patch rename to 0016-RH-add-mpathconf.patch diff --git a/0016-libmultipath-use-uint64_t-for-sg_id.lun.patch b/0016-libmultipath-use-uint64_t-for-sg_id.lun.patch deleted file mode 100644 index 500700c..0000000 --- a/0016-libmultipath-use-uint64_t-for-sg_id.lun.patch +++ /dev/null @@ -1,128 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 30 Jun 2021 21:51:53 +0200 -Subject: [PATCH] libmultipath: use uint64_t for sg_id.lun - -SCSI LUNs are 64bit unsigned integers, and have been exposed as such by -the kernel for years. Storage using the full 8 bytes is fortunately rare. -Still, we should handle this properly. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/discovery.c | 10 +++++----- - libmultipath/print.c | 2 +- - libmultipath/prioritizers/weightedpath.c | 2 +- - libmultipath/structs.c | 2 +- - libmultipath/structs.h | 4 +++- - 5 files changed, 11 insertions(+), 9 deletions(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index bfe2f56c..e9f5703c 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -1427,7 +1427,7 @@ scsi_sysfs_pathinfo (struct path *pp, const struct _vector *hwtable) - attr_path = udev_device_get_sysname(parent); - if (!attr_path) - break; -- if (sscanf(attr_path, "%i:%i:%i:%i", -+ if (sscanf(attr_path, "%i:%i:%i:%" SCNu64, - &pp->sg_id.host_no, - &pp->sg_id.channel, - &pp->sg_id.scsi_id, -@@ -1462,7 +1462,7 @@ scsi_sysfs_pathinfo (struct path *pp, const struct _vector *hwtable) - /* - * host / bus / target / lun - */ -- condlog(3, "%s: h:b:t:l = %i:%i:%i:%i", -+ condlog(3, "%s: h:b:t:l = %i:%i:%i:%" PRIu64, - pp->dev, - pp->sg_id.host_no, - pp->sg_id.channel, -@@ -1577,7 +1577,7 @@ ccw_sysfs_pathinfo (struct path *pp, const struct _vector *hwtable) - &pp->sg_id.host_no, - &pp->sg_id.channel, - &pp->sg_id.scsi_id) == 3) { -- condlog(3, "%s: h:b:t:l = %i:%i:%i:%i", -+ condlog(3, "%s: h:b:t:l = %i:%i:%i:%" PRIu64, - pp->dev, - pp->sg_id.host_no, - pp->sg_id.channel, -@@ -1636,7 +1636,7 @@ cciss_sysfs_pathinfo (struct path *pp, const struct _vector *hwtable) - */ - pp->sg_id.lun = 0; - pp->sg_id.channel = 0; -- condlog(3, "%s: h:b:t:l = %i:%i:%i:%i", -+ condlog(3, "%s: h:b:t:l = %i:%i:%i:%" PRIu64, - pp->dev, - pp->sg_id.host_no, - pp->sg_id.channel, -@@ -1815,7 +1815,7 @@ scsi_ioctl_pathinfo (struct path * pp, int mask) - attr_path = udev_device_get_sysname(parent); - if (!attr_path) - break; -- if (sscanf(attr_path, "%i:%i:%i:%i", -+ if (sscanf(attr_path, "%i:%i:%i:%" SCNu64, - &pp->sg_id.host_no, - &pp->sg_id.channel, - &pp->sg_id.scsi_id, -diff --git a/libmultipath/print.c b/libmultipath/print.c -index 3c69bf48..29ce499d 100644 ---- a/libmultipath/print.c -+++ b/libmultipath/print.c -@@ -392,7 +392,7 @@ snprint_hcil (char * buff, size_t len, const struct path * pp) - if (!pp || pp->sg_id.host_no < 0) - return snprintf(buff, len, "#:#:#:#"); - -- return snprintf(buff, len, "%i:%i:%i:%i", -+ return snprintf(buff, len, "%i:%i:%i:%" PRIu64, - pp->sg_id.host_no, - pp->sg_id.channel, - pp->sg_id.scsi_id, -diff --git a/libmultipath/prioritizers/weightedpath.c b/libmultipath/prioritizers/weightedpath.c -index 916970df..650088b4 100644 ---- a/libmultipath/prioritizers/weightedpath.c -+++ b/libmultipath/prioritizers/weightedpath.c -@@ -101,7 +101,7 @@ int prio_path_weight(struct path *pp, char *prio_args) - } - - if (!strcmp(regex, HBTL)) { -- sprintf(path, "%d:%d:%d:%d", pp->sg_id.host_no, -+ sprintf(path, "%d:%d:%d:%" PRIu64, pp->sg_id.host_no, - pp->sg_id.channel, pp->sg_id.scsi_id, pp->sg_id.lun); - } else if (!strcmp(regex, DEV_NAME)) { - strcpy(path, pp->dev); -diff --git a/libmultipath/structs.c b/libmultipath/structs.c -index 8751fc2b..6e5a1038 100644 ---- a/libmultipath/structs.c -+++ b/libmultipath/structs.c -@@ -96,7 +96,7 @@ alloc_path (void) - pp->sg_id.host_no = -1; - pp->sg_id.channel = -1; - pp->sg_id.scsi_id = -1; -- pp->sg_id.lun = -1; -+ pp->sg_id.lun = SCSI_INVALID_LUN; - pp->sg_id.proto_id = SCSI_PROTOCOL_UNSPEC; - pp->fd = -1; - pp->tpgs = TPGS_UNDEF; -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index c8447e56..c52bcee1 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -178,6 +178,8 @@ enum scsi_protocol { - SCSI_PROTOCOL_UNSPEC = 0xf, /* No specific protocol */ - }; - -+#define SCSI_INVALID_LUN ~0ULL -+ - enum no_undef_states { - NU_NO = -1, - NU_UNDEF = 0, -@@ -258,7 +260,7 @@ struct sg_id { - int host_no; - int channel; - int scsi_id; -- int lun; -+ uint64_t lun; - short h_cmd_per_lun; - short d_queue_depth; - enum scsi_protocol proto_id; diff --git a/0030-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 96% rename from 0030-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 d20115a..055eeb6 100644 --- a/0030-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +++ b/0017-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch @@ -20,7 +20,7 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/multipath/main.c b/multipath/main.c -index 33377147..85e4481d 100644 +index 65ece830..748e7902 100644 --- a/multipath/main.c +++ b/multipath/main.c @@ -122,7 +122,7 @@ usage (char * progname) @@ -41,7 +41,7 @@ index 33377147..85e4481d 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" -@@ -455,6 +457,50 @@ static void cleanup_vecs(void) +@@ -450,6 +452,50 @@ static void cleanup_vecs(void) free_pathvec(vecs.pathvec, FREE_PATHS); } @@ -92,7 +92,7 @@ index 33377147..85e4481d 100644 static int configure (struct config *conf, enum mpath_cmds cmd, enum devtypes dev_type, char *devpath) -@@ -833,7 +879,7 @@ main (int argc, char *argv[]) +@@ -838,7 +884,7 @@ main (int argc, char *argv[]) conf->retrigger_tries = 0; conf->force_sync = 1; atexit(cleanup_vecs); @@ -101,7 +101,7 @@ index 33377147..85e4481d 100644 switch(arg) { case 1: printf("optarg : %s\n",optarg); break; -@@ -910,6 +956,10 @@ main (int argc, char *argv[]) +@@ -915,6 +961,10 @@ main (int argc, char *argv[]) case 'T': cmd = CMD_DUMP_CONFIG; break; diff --git a/0017-multipath-tools-Remove-trailing-leading-whitespaces.patch b/0017-multipath-tools-Remove-trailing-leading-whitespaces.patch deleted file mode 100644 index 7c403a9..0000000 --- a/0017-multipath-tools-Remove-trailing-leading-whitespaces.patch +++ /dev/null @@ -1,115 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Sat, 22 May 2021 21:17:36 +0200 -Subject: [PATCH] multipath-tools: Remove trailing/leading whitespaces - -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez -Reviewed-by: Martin Wilck " -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 2 +- - libmultipath/configure.c | 2 +- - libmultipath/devmapper.c | 4 ++-- - libmultipath/sysfs.c | 2 +- - multipath/multipath.8 | 2 +- - multipathd/cli_handlers.c | 2 +- - multipathd/main.c | 2 +- - 7 files changed, 8 insertions(+), 8 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 91100a20..d0ec9b44 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -101,7 +101,7 @@ OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 - WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int \ - -Werror=implicit-function-declaration -Werror=format-security \ - $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) --CPPFLAGS := -Wp,-D_FORTIFY_SOURCE=2 -+CPPFLAGS := -Wp,-D_FORTIFY_SOURCE=2 - CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ - -DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" \ - -MMD -MP -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 6ca1f4bb..a6ae3359 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -397,7 +397,7 @@ int setup_map(struct multipath *mpp, char *params, int params_size, - start_io_err_stat_thread(vecs); - - n_paths = VECTOR_SIZE(mpp->paths); -- /* -+ /* - * assign paths to path groups -- start with no groups and all paths - * in mpp->paths - */ -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index 47a6d60e..945e625b 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -602,8 +602,8 @@ int dm_addmap_reload(struct multipath *mpp, char *params, int flush) - return r; - - /* If the resume failed, dm will leave the device suspended, and -- * drop the new table, so doing a second resume will try using -- * the original table */ -+ * drop the new table, so doing a second resume will try using -+ * the original table */ - if (dm_is_suspended(mpp->alias)) - dm_simplecmd(DM_DEVICE_RESUME, mpp->alias, !flush, 1, - udev_flags, 0); -diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c -index 7a2af1ea..9ff145f2 100644 ---- a/libmultipath/sysfs.c -+++ b/libmultipath/sysfs.c -@@ -358,7 +358,7 @@ bool sysfs_is_multipathed(struct path *pp, bool set_wwid) - strchop(pp->wwid); - } - } -- } else if (nr < 0) -+ } else if (nr < 0) - condlog(1, "%s: error reading from %s: %m", - __func__, pathbuf); - -diff --git a/multipath/multipath.8 b/multipath/multipath.8 -index 5b29a5d9..17df59f5 100644 ---- a/multipath/multipath.8 -+++ b/multipath/multipath.8 -@@ -225,7 +225,7 @@ Dry run, do not create or update devmaps. - .TP - .B \-e - Enable all foreign libraries. This overrides the --.I enable_foreign -+.I enable_foreign - option from \fBmultipath.conf(5)\fR. - . - .TP -diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c -index 59d44b45..d70e1dbc 100644 ---- a/multipathd/cli_handlers.c -+++ b/multipathd/cli_handlers.c -@@ -1215,7 +1215,7 @@ cli_reconfigure(void * v, char ** reply, int * len, void * data) - - condlog(2, "reconfigure (operator)"); - -- rc = set_config_state(DAEMON_CONFIGURE); -+ rc = set_config_state(DAEMON_CONFIGURE); - if (rc == ETIMEDOUT) { - condlog(2, "timeout starting reconfiguration"); - return 1; -diff --git a/multipathd/main.c b/multipathd/main.c -index 2251e02c..bdd629e7 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -2014,7 +2014,7 @@ static int check_path_reinstate_state(struct path * pp) { - - /* If path became failed again or continue failed, should reset - * path san_path_err_forget_rate and path dis_reinstate_time to -- * start a new stable check. -+ * start a new stable check. - */ - if ((pp->state != PATH_UP) && (pp->state != PATH_GHOST) && - (pp->state != PATH_DELAYED)) { diff --git a/0031-RH-reset-default-find_mutipaths-value-to-off.patch b/0018-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 100% rename from 0031-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0018-RH-reset-default-find_mutipaths-value-to-off.patch diff --git a/0018-multipath-tools-make-HUAWEI-XSG1-config-work-with-al.patch b/0018-multipath-tools-make-HUAWEI-XSG1-config-work-with-al.patch deleted file mode 100644 index 614039e..0000000 --- a/0018-multipath-tools-make-HUAWEI-XSG1-config-work-with-al.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Mon, 5 Apr 2021 00:12:58 +0200 -Subject: [PATCH] multipath-tools: make HUAWEI/XSG1 config work with alua and - multibus - -And add recommended no_path_retry and pgfailback values. - -Info from: -- RHEL https://download.huawei.com/edownload/e/download.do?actionFlag=download&nid=EDOC1100113070&partNo=6001&mid=SUPE_DOC&_t=1612885511000 -- SLES https://download.huawei.com/edownload/e/download.do?actionFlag=download&nid=EDOC1100117892&partNo=6001&mid=SUPE_DOC&_t=1612885538000 - -- without HyperMetro: -vendor "HUAWEI" -product "XSG1" -path_grouping_policy multibus -no_path_retry 15 - -- with HyperMetro: -vendor "HUAWEI" -product "XSG1" -path_grouping_policy group_by_prio -prio alua -failback immediate -no_path_retry 15 - -ALUA is only used with HyperMetro(cluster of two arrays). - -Suggested-by: Martin Wilck -Cc: Zhouweigang (Jack) -Cc: Zou Ming -Cc: Benjamin Marzinski -Cc: Martin Wilck -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez -Reviewed-by: Martin Wilck " -Signed-off-by: Benjamin Marzinski ---- - libmultipath/hwtable.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index e884d8c7..2a896440 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -1078,11 +1078,14 @@ static struct hwentry default_hw[] = { - * Huawei - */ - { -- /* OceanStor V3 */ -+ /* OceanStor V3-V6 */ -+ // This config works with multibus and ALUA -+ // ALUA is required by HyperMetro - .vendor = "HUAWEI", - .product = "XSG1", - .pgpolicy = GROUP_BY_PRIO, -- .prio_name = PRIO_ALUA, -+ .pgfailback = -FAILBACK_IMMEDIATE, -+ .no_path_retry = 15, - }, - /* - * Kove diff --git a/0032-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0019-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 100% rename from 0032-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0019-RH-attempt-to-get-ANA-info-via-sysfs-first.patch diff --git a/0019-multipath.conf-fix-typo-in-ghost_delay-description.patch b/0019-multipath.conf-fix-typo-in-ghost_delay-description.patch deleted file mode 100644 index 03dcb3f..0000000 --- a/0019-multipath.conf-fix-typo-in-ghost_delay-description.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 15 Jul 2021 14:46:49 -0500 -Subject: [PATCH] multipath.conf: fix typo in ghost_delay description - -Signed-off-by: Benjamin Marzinski ---- - multipath/multipath.conf.5 | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 064e4826..d6b8c7f6 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -1251,7 +1251,7 @@ The default is: in \fB/sys/block//queue/max_sectors_kb\fR - Sets the number of seconds that multipath will wait after creating a device - with only ghost paths before marking it ready for use in systemd. This gives - the active paths time to appear before the multipath runs the hardware handler --to switch the ghost paths to active ones. Setting this to \fI0\fR or \fIon\fR -+to switch the ghost paths to active ones. Setting this to \fI0\fR or \fIno\fR - makes multipath immediately mark a device with only ghost paths as ready. - .RS - .TP diff --git a/0033-RH-make-parse_vpd_pg83-match-scsi_id-output.patch b/0020-RH-make-parse_vpd_pg83-match-scsi_id-output.patch similarity index 89% rename from 0033-RH-make-parse_vpd_pg83-match-scsi_id-output.patch rename to 0020-RH-make-parse_vpd_pg83-match-scsi_id-output.patch index e16060d..789af0d 100644 --- a/0033-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +++ b/0020-RH-make-parse_vpd_pg83-match-scsi_id-output.patch @@ -13,10 +13,10 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index e9f5703c..7c1bcdf0 100644 +index f25fe9e3..6fb81c28 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c -@@ -1135,12 +1135,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, +@@ -1136,12 +1136,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, naa_prio = 7; break; case 2: @@ -31,7 +31,7 @@ index e9f5703c..7c1bcdf0 100644 break; default: /* Default: no priority */ -@@ -1159,17 +1156,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, +@@ -1160,17 +1157,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, vpd = d; } break; diff --git a/0020-mpathpersist-fail-commands-when-no-usable-paths-exis.patch b/0020-mpathpersist-fail-commands-when-no-usable-paths-exis.patch deleted file mode 100644 index 32f4f60..0000000 --- a/0020-mpathpersist-fail-commands-when-no-usable-paths-exis.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 15 Jul 2021 17:09:05 -0500 -Subject: [PATCH] mpathpersist: fail commands when no usable paths exist - -"mpathpersist -oCK " will return success if it -is run on devices with no usable paths, but nothing is actually done. -The -L command will fail, but it should give up sooner, and with a more -helpful error message. - -Signed-off-by: Benjamin Marzinski ---- - libmpathpersist/mpath_persist.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c -index 190e9707..26710e79 100644 ---- a/libmpathpersist/mpath_persist.c -+++ b/libmpathpersist/mpath_persist.c -@@ -604,7 +604,8 @@ int mpath_prout_common(struct multipath *mpp,int rq_servact, int rq_scope, - return ret ; - } - } -- return MPATH_PR_SUCCESS; -+ condlog (0, "%s: no path available", mpp->wwid); -+ return MPATH_PR_DMMP_ERROR; - } - - int send_prout_activepath(char * dev, int rq_servact, int rq_scope, -@@ -663,6 +664,11 @@ int mpath_prout_rel(struct multipath *mpp,int rq_servact, int rq_scope, - - active_pathcount = count_active_paths(mpp); - -+ if (active_pathcount == 0) { -+ condlog (0, "%s: no path available", mpp->wwid); -+ return MPATH_PR_DMMP_ERROR; -+ } -+ - struct threadinfo thread[active_pathcount]; - memset(thread, 0, sizeof(thread)); - for (i = 0; i < active_pathcount; i++){ diff --git a/0021-multipath-print-warning-if-multipathd-is-not-running.patch b/0021-multipath-print-warning-if-multipathd-is-not-running.patch deleted file mode 100644 index d303392..0000000 --- a/0021-multipath-print-warning-if-multipathd-is-not-running.patch +++ /dev/null @@ -1,119 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 16 Jul 2021 12:39:17 -0500 -Subject: [PATCH] multipath: print warning if multipathd is not running. - -If multipath notices that multipath devices exist or were created, and -multipathd is not running, it now prints a warning message, so users are -notified of the issue. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 13 +++++++++++-- - libmultipath/configure.h | 1 + - libmultipath/libmultipath.version | 5 +++++ - multipath/main.c | 5 +++++ - 4 files changed, 22 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index a6ae3359..eb76fbc4 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -1083,7 +1083,8 @@ deadmap (struct multipath * mpp) - return 1; /* dead */ - } - --int check_daemon(void) -+extern int -+check_daemon(void) - { - int fd; - char *reply; -@@ -1138,6 +1139,8 @@ int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid, - struct config *conf; - int allow_queueing; - struct bitfield *size_mismatch_seen; -+ bool map_processed = false; -+ bool no_daemon = false; - - /* ignore refwwid if it's empty */ - if (refwwid && !strlen(refwwid)) -@@ -1288,7 +1291,9 @@ int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid, - conf = get_multipath_config(); - allow_queueing = conf->allow_queueing; - put_multipath_config(conf); -- if (!is_daemon && !allow_queueing && !check_daemon()) { -+ if (!is_daemon && !allow_queueing && -+ (no_daemon || !check_daemon())) { -+ no_daemon = true; - if (mpp->no_path_retry != NO_PATH_RETRY_UNDEF && - mpp->no_path_retry != NO_PATH_RETRY_FAIL) - condlog(3, "%s: multipathd not running, unset " -@@ -1311,6 +1316,7 @@ int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid, - else - remove_map(mpp, vecs->pathvec, vecs->mpvec, - KEEP_VEC); -+ map_processed = true; - } - /* - * Flush maps with only dead paths (ie not in sysfs) -@@ -1336,6 +1342,9 @@ int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid, - condlog(2, "%s: remove (dead)", alias); - } - } -+ if (map_processed && !is_daemon && (no_daemon || !check_daemon())) -+ condlog(2, "multipath devices exist, but multipathd service is not running"); -+ - ret = CP_OK; - out: - free(size_mismatch_seen); -diff --git a/libmultipath/configure.h b/libmultipath/configure.h -index 70cf77a3..741066b3 100644 ---- a/libmultipath/configure.h -+++ b/libmultipath/configure.h -@@ -60,3 +60,4 @@ struct udev_device *get_udev_device(const char *dev, enum devtypes dev_type); - void trigger_paths_udev_change(struct multipath *mpp, bool is_mpath); - void trigger_partitions_udev_change(struct udev_device *dev, const char *action, - int len); -+int check_daemon(void); -diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version -index 0cff3111..d8be5fd2 100644 ---- a/libmultipath/libmultipath.version -+++ b/libmultipath/libmultipath.version -@@ -274,3 +274,8 @@ global: - local: - *; - }; -+ -+LIBMULTIPATH_5.1.0 { -+global: -+ check_daemon; -+} LIBMULTIPATH_5.0.0; -diff --git a/multipath/main.c b/multipath/main.c -index 8fc0e15f..33377147 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -180,6 +180,7 @@ get_dm_mpvec (enum mpath_cmds cmd, vector curmp, vector pathvec, char * refwwid) - int i; - struct multipath * mpp; - int flags = (cmd == CMD_LIST_SHORT ? DI_NOIO : DI_ALL); -+ bool maps_present = false; - - if (dm_get_maps(curmp)) - return 1; -@@ -212,11 +213,15 @@ get_dm_mpvec (enum mpath_cmds cmd, vector curmp, vector pathvec, char * refwwid) - - if (cmd == CMD_CREATE) - reinstate_paths(mpp); -+ -+ maps_present = true; - } - - if (cmd == CMD_LIST_SHORT || cmd == CMD_LIST_LONG) - print_foreign_topology(libmp_verbosity); - -+ if (maps_present && !check_daemon()) -+ condlog(2, "multipath devices exist, but multipathd service is not running"); - return 0; - } - diff --git a/0022-libmultipath-remove-unneeded-code-in-coalesce_paths.patch b/0022-libmultipath-remove-unneeded-code-in-coalesce_paths.patch deleted file mode 100644 index a4913d3..0000000 --- a/0022-libmultipath-remove-unneeded-code-in-coalesce_paths.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 16 Jul 2021 17:58:14 -0500 -Subject: [PATCH] libmultipath: remove unneeded code in coalesce_paths - -The code at the end of coalesce_paths() removes a multipath device that -was just created/reloaded, if none of its path devices have pp->dev set. -This code is very old, and no longer has any actual effect. Multipath -devices no longer get placed in pathvec without having pp->dev set. Even -if they could, there's no point in creating/reloading the device and -then immediately removing it. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 46 ---------------------------------------- - 1 file changed, 46 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index eb76fbc4..df6ba725 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -1061,28 +1061,6 @@ int domap(struct multipath *mpp, char *params, int is_daemon) - return DOMAP_FAIL; - } - --static int --deadmap (struct multipath * mpp) --{ -- int i, j; -- struct pathgroup * pgp; -- struct path * pp; -- -- if (!mpp->pg) -- return 1; -- -- vector_foreach_slot (mpp->pg, pgp, i) { -- if (!pgp->paths) -- continue; -- -- vector_foreach_slot (pgp->paths, pp, j) -- if (strlen(pp->dev)) -- return 0; /* alive */ -- } -- -- return 1; /* dead */ --} -- - extern int - check_daemon(void) - { -@@ -1318,30 +1296,6 @@ int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid, - KEEP_VEC); - map_processed = true; - } -- /* -- * Flush maps with only dead paths (ie not in sysfs) -- * Keep maps with only failed paths -- */ -- if (mpvec) { -- vector_foreach_slot (newmp, mpp, i) { -- char alias[WWID_SIZE]; -- -- if (!deadmap(mpp)) -- continue; -- -- strlcpy(alias, mpp->alias, WWID_SIZE); -- -- vector_del_slot(newmp, i); -- i--; -- remove_map(mpp, vecs->pathvec, vecs->mpvec, KEEP_VEC); -- -- if (dm_flush_map(alias)) -- condlog(2, "%s: remove failed (dead)", -- alias); -- else -- condlog(2, "%s: remove (dead)", alias); -- } -- } - if (map_processed && !is_daemon && (no_daemon || !check_daemon())) - condlog(2, "multipath devices exist, but multipathd service is not running"); - diff --git a/0023-libmultipath-deal-with-dynamic-PTHREAD_STACK_MIN.patch b/0023-libmultipath-deal-with-dynamic-PTHREAD_STACK_MIN.patch deleted file mode 100644 index 11d8b4e..0000000 --- a/0023-libmultipath-deal-with-dynamic-PTHREAD_STACK_MIN.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 29 Jul 2021 13:16:57 -0500 -Subject: [PATCH] libmultipath: deal with dynamic PTHREAD_STACK_MIN - -Starting in glibc-2.34 (commit 5d98a7da), PTHREAD_STACK_MIN is defined -as sysconf(_SC_THREAD_STACK_MIN) if _GNU_SOURCE is defined. sysconf() -returns a long and can, at least in theory, return -1. This change -causes compilation to fail in setup_thread_attr() due to a comparision -with different signedness, since stacksize is a size_t. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/util.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/util.c b/libmultipath/util.c -index 0e37f3ff..17f8fcc6 100644 ---- a/libmultipath/util.c -+++ b/libmultipath/util.c -@@ -223,8 +223,8 @@ setup_thread_attr(pthread_attr_t *attr, size_t stacksize, int detached) - - ret = pthread_attr_init(attr); - assert(ret == 0); -- if (stacksize < PTHREAD_STACK_MIN) -- stacksize = PTHREAD_STACK_MIN; -+ if (PTHREAD_STACK_MIN > 0 && stacksize < (size_t)PTHREAD_STACK_MIN) -+ stacksize = (size_t)PTHREAD_STACK_MIN; - ret = pthread_attr_setstacksize(attr, stacksize); - assert(ret == 0); - if (detached) { diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index d81bbba..11e9992 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,48 +1,35 @@ Name: device-mapper-multipath -Version: 0.8.6 -Release: 5%{?dist} +Version: 0.8.7 +Release: 1%{?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 -L https://github.com/opensvc/multipath-tools/archive/0.8.6.tar.gz -o multipath-tools-0.8.6.tgz -Source0: multipath-tools-0.8.6.tgz +# curl -L https://github.com/opensvc/multipath-tools/archive/0.8.7.tar.gz -o multipath-tools-0.8.7.tgz +Source0: multipath-tools-0.8.7.tgz Source1: multipath.conf -Patch0001: 0001-libmultipath-fix-memory-leak-in-checker_cleanup_thre.patch -Patch0002: 0002-multipathd-fix-compilation-issue-with-liburcu-0.8.patch -Patch0003: 0003-multipathd-don-t-fail-to-remove-path-once-the-map-is.patch -Patch0004: 0004-multipathd-remove-duplicate-orphan_paths-in-flush_ma.patch -Patch0005: 0005-multipathd-fix-ev_remove_path-return-code-handling.patch -Patch0006: 0006-multipath-free-vectors-in-configure.patch -Patch0007: 0007-kpartx-Don-t-leak-memory-when-getblock-returns-NULL.patch -Patch0008: 0008-multipathd-don-t-rescan_path-on-wwid-change-in-uev_u.patch -Patch0009: 0009-multipathd-cli_handlers-cleanup-setting-reply-length.patch -Patch0010: 0010-multipathd-cli_getprkey-fix-return-value.patch -Patch0011: 0011-multipath-tools-enable-Wformat-overflow-2.patch -Patch0012: 0012-libdmmp-use-KBUILD_BUILD_TIMESTAMP-when-building-man.patch -Patch0013: 0013-multipath-tools-add-info-about-HPE-Alletra-6000-and-.patch -Patch0014: 0014-multipathd-don-t-start-in-containers.patch -Patch0015: 0015-libmultipath-fix-build-without-LIBDM_API_DEFERRED.patch -Patch0016: 0016-libmultipath-use-uint64_t-for-sg_id.lun.patch -Patch0017: 0017-multipath-tools-Remove-trailing-leading-whitespaces.patch -Patch0018: 0018-multipath-tools-make-HUAWEI-XSG1-config-work-with-al.patch -Patch0019: 0019-multipath.conf-fix-typo-in-ghost_delay-description.patch -Patch0020: 0020-mpathpersist-fail-commands-when-no-usable-paths-exis.patch -Patch0021: 0021-multipath-print-warning-if-multipathd-is-not-running.patch -Patch0022: 0022-libmultipath-remove-unneeded-code-in-coalesce_paths.patch -Patch0023: 0023-libmultipath-deal-with-dynamic-PTHREAD_STACK_MIN.patch -Patch0024: 0024-RH-fixup-udev-rules-for-redhat.patch -Patch0025: 0025-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0026: 0026-RH-don-t-start-without-a-config-file.patch -Patch0027: 0027-RH-Fix-nvme-function-missing-argument.patch -Patch0028: 0028-RH-use-rpm-optflags-if-present.patch -Patch0029: 0029-RH-add-mpathconf.patch -Patch0030: 0030-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0031: 0031-RH-reset-default-find_mutipaths-value-to-off.patch -Patch0032: 0032-RH-attempt-to-get-ANA-info-via-sysfs-first.patch -Patch0033: 0033-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +Patch0001: 0001-multipath-tools-add-info-about-IO-affinity-path-sele.patch +Patch0002: 0002-multipathd-fix-missing-persistent-reseravtion-for-ac.patch +Patch0003: 0003-multipath-tools-minor-fixes-to-multipath.conf.5-man-.patch +Patch0004: 0004-multipath-tools-make-IBM-XIV-config-work-with-alua-a.patch +Patch0005: 0005-multipathd.socket-add-missing-conditions-from-servic.patch +Patch0006: 0006-multipath-tools-make-IBM-2107900-DS8000-config-work-.patch +Patch0007: 0007-multipath-tools-make-EMC-SYMMETRIX-config-work-with-.patch +Patch0008: 0008-multipath-tools-make-EMC-Invista-config-work-with-al.patch +Patch0009: 0009-multipath-tools-make-COMPELNT-Compellent-Vol-config-.patch +Patch0010: 0010-multipath-tools-remove-Compellent-maintainer.patch +Patch0011: 0011-RH-fixup-udev-rules-for-redhat.patch +Patch0012: 0012-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0013: 0013-RH-don-t-start-without-a-config-file.patch +Patch0014: 0014-RH-Fix-nvme-function-missing-argument.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-reset-default-find_mutipaths-value-to-off.patch +Patch0019: 0019-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0020: 0020-RH-make-parse_vpd_pg83-match-scsi_id-output.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -126,7 +113,7 @@ This package contains the files needed to develop applications that use device-mapper-multipath's libdmmp C API library %prep -%autosetup -n multipath-tools-0.8.6 -p1 +%autosetup -n multipath-tools-0.8.7 -p1 cp %{SOURCE1} . %build @@ -240,6 +227,14 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Wed Oct 6 2021 Benjamin Marzinski - 0.8.7-1 +- Update source to upstream version 0.8.7 + * Previous patches 0001-0023 are included in the commit. +- Add patches from upstream staging branch + * Patches 0001-0010 are from the upstream staging branch +- Rename redhat patches + * Previous patches 0024-0033 are now patches 0011-0020 + * Fri Jul 30 2021 Benjamin Marzinski - 0.8.6-5 - Update to the head of the upstream staging branch plus redhat patches * Patches 0016-0018 are from the upstream staging branch diff --git a/sources b/sources index 13188ae..ba0504a 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (multipath-tools-0.8.6.tgz) = 82e5b7307e599ba6b059679c3987a442fb5be4885f0a27c260a99a07cb336b88d48e314b4ec951944e0200e4731522d8da043d98fa566857ecc6d100791c0e38 +SHA512 (multipath-tools-0.8.7.tgz) = c01aea837b13429d17688455b813947342ca1cabba19b22e13ce640c77e68335a6d410280a8298595e239131e6fcbb655fa6de5ff9857eac99aa175046a450cd SHA512 (multipath.conf) = 71953dce5a68adcf60a942305f5a66023e6f4c4baf53b1bfdb4edf65ed5b8e03db804363c36d1dcfd85591f4766f52b515269904c53b84d7b076da0b80b09942 From be2d12e9d4ba37a92c3425e081c9c45885007029 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Wed, 6 Oct 2021 22:13:34 -0500 Subject: [PATCH 24/67] device-mapper-multipath-0.8.7-2 Modify 0013-RH-don-t-start-without-a-config-file.patch * add condtion to multipathd.socket as well --- 0013-RH-don-t-start-without-a-config-file.patch | 15 ++++++++++++++- device-mapper-multipath.spec | 6 +++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/0013-RH-don-t-start-without-a-config-file.patch b/0013-RH-don-t-start-without-a-config-file.patch index 5290d9e..8061a99 100644 --- a/0013-RH-don-t-start-without-a-config-file.patch +++ b/0013-RH-don-t-start-without-a-config-file.patch @@ -17,7 +17,8 @@ Signed-off-by: Benjamin Marzinski multipath/multipath.rules | 1 + multipathd/multipathd.8 | 2 ++ multipathd/multipathd.service | 1 + - 5 files changed, 18 insertions(+) + multipathd/multipathd.socket | 1 + + 6 files changed, 19 insertions(+) diff --git a/libmultipath/config.c b/libmultipath/config.c index 30046a17..5f35c3d3 100644 @@ -92,3 +93,15 @@ index 0b2ac814..6d57c7e8 100644 DefaultDependencies=no Conflicts=shutdown.target ConditionKernelCommandLine=!nompath +diff --git a/multipathd/multipathd.socket b/multipathd/multipathd.socket +index c777e5e3..3c20a2ff 100644 +--- a/multipathd/multipathd.socket ++++ b/multipathd/multipathd.socket +@@ -1,6 +1,7 @@ + [Unit] + Description=multipathd control socket + DefaultDependencies=no ++ConditionPathExists=/etc/multipath.conf + ConditionKernelCommandLine=!nompath + ConditionKernelCommandLine=!multipath=off + ConditionVirtualization=!container diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 11e9992..242f450 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.8.7 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -227,6 +227,10 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Wed Oct 6 2021 Benjamin Marzinski - 0.8.7-2 +- Modify 0013-RH-don-t-start-without-a-config-file.patch + * add condtion to multipathd.socket as well + * Wed Oct 6 2021 Benjamin Marzinski - 0.8.7-1 - Update source to upstream version 0.8.7 * Previous patches 0001-0023 are included in the commit. From ce5b96a800c23ddedb710ae2d385618fac8812a4 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 28 Oct 2021 19:53:00 -0500 Subject: [PATCH 25/67] device-mapper-multipath-0.8.7-3 Update to the head of the upstream staging branch * Patches 0011 & 0012 are from the upstream staging branch Rename redhat patches * Previous patches 0011-0020 are now patches 0013-0022 --- ...-tools-make-EMC-Invista-config-work-.patch | 35 +++++++++++++++++ ...-tools-make-EMC-SYMMETRIX-config-wor.patch | 38 +++++++++++++++++++ ... 0013-RH-fixup-udev-rules-for-redhat.patch | 0 ...property-blacklist-exception-builtin.patch | 0 ...RH-don-t-start-without-a-config-file.patch | 0 ...H-Fix-nvme-function-missing-argument.patch | 0 ... 0017-RH-use-rpm-optflags-if-present.patch | 0 ...hconf.patch => 0018-RH-add-mpathconf.patch | 0 ...om-kernel-cmdline-mpath.wwids-with-A.patch | 0 ...-default-find_mutipaths-value-to-off.patch | 0 ...empt-to-get-ANA-info-via-sysfs-first.patch | 0 ...-parse_vpd_pg83-match-scsi_id-output.patch | 0 device-mapper-multipath.spec | 30 +++++++++------ 13 files changed, 92 insertions(+), 11 deletions(-) create mode 100644 0011-Revert-multipath-tools-make-EMC-Invista-config-work-.patch create mode 100644 0012-Revert-multipath-tools-make-EMC-SYMMETRIX-config-wor.patch rename 0011-RH-fixup-udev-rules-for-redhat.patch => 0013-RH-fixup-udev-rules-for-redhat.patch (100%) rename 0012-RH-Remove-the-property-blacklist-exception-builtin.patch => 0014-RH-Remove-the-property-blacklist-exception-builtin.patch (100%) rename 0013-RH-don-t-start-without-a-config-file.patch => 0015-RH-don-t-start-without-a-config-file.patch (100%) rename 0014-RH-Fix-nvme-function-missing-argument.patch => 0016-RH-Fix-nvme-function-missing-argument.patch (100%) rename 0015-RH-use-rpm-optflags-if-present.patch => 0017-RH-use-rpm-optflags-if-present.patch (100%) rename 0016-RH-add-mpathconf.patch => 0018-RH-add-mpathconf.patch (100%) rename 0017-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch => 0019-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch (100%) rename 0018-RH-reset-default-find_mutipaths-value-to-off.patch => 0020-RH-reset-default-find_mutipaths-value-to-off.patch (100%) rename 0019-RH-attempt-to-get-ANA-info-via-sysfs-first.patch => 0021-RH-attempt-to-get-ANA-info-via-sysfs-first.patch (100%) rename 0020-RH-make-parse_vpd_pg83-match-scsi_id-output.patch => 0022-RH-make-parse_vpd_pg83-match-scsi_id-output.patch (100%) diff --git a/0011-Revert-multipath-tools-make-EMC-Invista-config-work-.patch b/0011-Revert-multipath-tools-make-EMC-Invista-config-work-.patch new file mode 100644 index 0000000..1912f80 --- /dev/null +++ b/0011-Revert-multipath-tools-make-EMC-Invista-config-work-.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 20 Oct 2021 20:44:54 +0200 +Subject: [PATCH] Revert "multipath-tools: make EMC/Invista config work with + alua and multibus" + +This reverts commit 309ff281aaa07e862540d3d645a8263f3e9baaed. + +Mail from , 20210930: + +"OPM is no longer supported in the Dell VPLEX product. If we at Dell had +wished to change the default device stanzas for any of our products they +would have been done when the product and/or feature is released. +Please remove this patch as well. It is not needed." + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/hwtable.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index 763982cd..211087ad 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -350,9 +350,8 @@ static struct hwentry default_hw[] = { + .vendor = "EMC", + .product = "Invista", + .bl_product = "LUNZ", +- .pgpolicy = GROUP_BY_PRIO, ++ .pgpolicy = MULTIBUS, + .no_path_retry = 5, +- .pgfailback = -FAILBACK_IMMEDIATE, + }, + { + /* XtremIO */ diff --git a/0012-Revert-multipath-tools-make-EMC-SYMMETRIX-config-wor.patch b/0012-Revert-multipath-tools-make-EMC-SYMMETRIX-config-wor.patch new file mode 100644 index 0000000..b889ea8 --- /dev/null +++ b/0012-Revert-multipath-tools-make-EMC-SYMMETRIX-config-wor.patch @@ -0,0 +1,38 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 20 Oct 2021 20:46:09 +0200 +Subject: [PATCH] Revert "multipath-tools: make EMC/SYMMETRIX config work with + alua and multibus" + +This reverts commit 831af0dbfa171cd39d968ba6174669f11a278be9. + +Mail from "berthiaume, wayne" , 210930: + +"As a representative of Dell I request this patch be withdrawn. If we had +wanted the default stanza changed we would have already implemented it. +Also for your information we only advertise the entire enterprise storage +product line (DMX, VMAX, VMAX AFA, PowerMax) as SYMMETRIX in the VPD page. +The ALUA capability is only used for mobility devices in an SRDF/Metro +configuration and the current device stanza still works well in all of our +testing." + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/hwtable.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index 211087ad..a8ba28e3 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -329,9 +329,8 @@ static struct hwentry default_hw[] = { + /* Symmetrix / DMX / VMAX / PowerMax */ + .vendor = "EMC", + .product = "SYMMETRIX", +- .pgpolicy = GROUP_BY_PRIO, ++ .pgpolicy = MULTIBUS, + .no_path_retry = 6, +- .pgfailback = -FAILBACK_IMMEDIATE, + }, + { + /* DGC CLARiiON CX/AX / VNX and Unity */ diff --git a/0011-RH-fixup-udev-rules-for-redhat.patch b/0013-RH-fixup-udev-rules-for-redhat.patch similarity index 100% rename from 0011-RH-fixup-udev-rules-for-redhat.patch rename to 0013-RH-fixup-udev-rules-for-redhat.patch diff --git a/0012-RH-Remove-the-property-blacklist-exception-builtin.patch b/0014-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 100% rename from 0012-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0014-RH-Remove-the-property-blacklist-exception-builtin.patch diff --git a/0013-RH-don-t-start-without-a-config-file.patch b/0015-RH-don-t-start-without-a-config-file.patch similarity index 100% rename from 0013-RH-don-t-start-without-a-config-file.patch rename to 0015-RH-don-t-start-without-a-config-file.patch diff --git a/0014-RH-Fix-nvme-function-missing-argument.patch b/0016-RH-Fix-nvme-function-missing-argument.patch similarity index 100% rename from 0014-RH-Fix-nvme-function-missing-argument.patch rename to 0016-RH-Fix-nvme-function-missing-argument.patch diff --git a/0015-RH-use-rpm-optflags-if-present.patch b/0017-RH-use-rpm-optflags-if-present.patch similarity index 100% rename from 0015-RH-use-rpm-optflags-if-present.patch rename to 0017-RH-use-rpm-optflags-if-present.patch diff --git a/0016-RH-add-mpathconf.patch b/0018-RH-add-mpathconf.patch similarity index 100% rename from 0016-RH-add-mpathconf.patch rename to 0018-RH-add-mpathconf.patch diff --git a/0017-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0019-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 100% rename from 0017-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0019-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch diff --git a/0018-RH-reset-default-find_mutipaths-value-to-off.patch b/0020-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 100% rename from 0018-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0020-RH-reset-default-find_mutipaths-value-to-off.patch diff --git a/0019-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0021-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 100% rename from 0019-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0021-RH-attempt-to-get-ANA-info-via-sysfs-first.patch diff --git a/0020-RH-make-parse_vpd_pg83-match-scsi_id-output.patch b/0022-RH-make-parse_vpd_pg83-match-scsi_id-output.patch similarity index 100% rename from 0020-RH-make-parse_vpd_pg83-match-scsi_id-output.patch rename to 0022-RH-make-parse_vpd_pg83-match-scsi_id-output.patch diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 242f450..3a0813a 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.8.7 -Release: 2%{?dist} +Release: 3%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -20,16 +20,18 @@ Patch0007: 0007-multipath-tools-make-EMC-SYMMETRIX-config-work-with-.patch Patch0008: 0008-multipath-tools-make-EMC-Invista-config-work-with-al.patch Patch0009: 0009-multipath-tools-make-COMPELNT-Compellent-Vol-config-.patch Patch0010: 0010-multipath-tools-remove-Compellent-maintainer.patch -Patch0011: 0011-RH-fixup-udev-rules-for-redhat.patch -Patch0012: 0012-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0013: 0013-RH-don-t-start-without-a-config-file.patch -Patch0014: 0014-RH-Fix-nvme-function-missing-argument.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-reset-default-find_mutipaths-value-to-off.patch -Patch0019: 0019-RH-attempt-to-get-ANA-info-via-sysfs-first.patch -Patch0020: 0020-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +Patch0011: 0011-Revert-multipath-tools-make-EMC-Invista-config-work-.patch +Patch0012: 0012-Revert-multipath-tools-make-EMC-SYMMETRIX-config-wor.patch +Patch0013: 0013-RH-fixup-udev-rules-for-redhat.patch +Patch0014: 0014-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0015: 0015-RH-don-t-start-without-a-config-file.patch +Patch0016: 0016-RH-Fix-nvme-function-missing-argument.patch +Patch0017: 0017-RH-use-rpm-optflags-if-present.patch +Patch0018: 0018-RH-add-mpathconf.patch +Patch0019: 0019-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0020: 0020-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0021: 0021-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0022: 0022-RH-make-parse_vpd_pg83-match-scsi_id-output.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -227,6 +229,12 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Thu Oct 28 2021 Benjamin Marzinski - 0.8.7-3 +- Update to the head of the upstream staging branch + * Patches 0011 & 0012 are from the upstream staging branch +- Rename redhat patches + * Previous patches 0011-0020 are now patches 0013-0022 + * Wed Oct 6 2021 Benjamin Marzinski - 0.8.7-2 - Modify 0013-RH-don-t-start-without-a-config-file.patch * add condtion to multipathd.socket as well From 18d73f233394f89bd8852c096f6cfd54ab5def14 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Mon, 13 Dec 2021 13:09:30 -0600 Subject: [PATCH 26/67] device-mapper-multipath-0.8.7-4 Update to the head of the upstream staging branch * Patches 0013 - 0024 are from the upstream staging branch Rename redhat patches * Previous patches 0013-0022 are now patches 0025-0034 --- ...ipath-fix-exit-status-of-multipath-T.patch | 26 + ...-section-name-to-invalid-keyword-out.patch | 70 +++ ...-typedef-for-keyword-handler-functio.patch | 85 +++ ...nt-the-correct-file-when-parsing-fai.patch | 28 + ...s-file-and-line-number-to-keyword-ha.patch | 528 ++++++++++++++++++ ...e-set_int-take-a-range-for-valid-val.patch | 251 +++++++++ ...multipath-improve-checks-for-set_str.patch | 171 ++++++ ...recate-file-and-directory-config-opt.patch | 115 ++++ ...tipath-split-set_int-to-enable-reuse.patch | 192 +++++++ ...path-cleanup-invalid-config-handling.patch | 202 +++++++ ...don-t-return-error-on-invalid-values.patch | 219 ++++++++ ...d-unnecessary-path-read-only-reloads.patch | 129 +++++ ... 0025-RH-fixup-udev-rules-for-redhat.patch | 0 ...property-blacklist-exception-builtin.patch | 6 +- ...RH-don-t-start-without-a-config-file.patch | 0 ...H-Fix-nvme-function-missing-argument.patch | 0 ... 0029-RH-use-rpm-optflags-if-present.patch | 16 +- ...hconf.patch => 0030-RH-add-mpathconf.patch | 15 +- ...om-kernel-cmdline-mpath.wwids-with-A.patch | 6 +- ...-default-find_mutipaths-value-to-off.patch | 0 ...empt-to-get-ANA-info-via-sysfs-first.patch | 0 ...-parse_vpd_pg83-match-scsi_id-output.patch | 53 +- device-mapper-multipath.spec | 40 +- 23 files changed, 2120 insertions(+), 32 deletions(-) create mode 100644 0013-multipath-fix-exit-status-of-multipath-T.patch create mode 100644 0014-libmultipath-add-section-name-to-invalid-keyword-out.patch create mode 100644 0015-libmultipath-use-typedef-for-keyword-handler-functio.patch create mode 100644 0016-libmultipath-print-the-correct-file-when-parsing-fai.patch create mode 100644 0017-libmultipath-pass-file-and-line-number-to-keyword-ha.patch create mode 100644 0018-libmultipath-make-set_int-take-a-range-for-valid-val.patch create mode 100644 0019-libmultipath-improve-checks-for-set_str.patch create mode 100644 0020-libmultipath-deprecate-file-and-directory-config-opt.patch create mode 100644 0021-libmultipath-split-set_int-to-enable-reuse.patch create mode 100644 0022-libmultipath-cleanup-invalid-config-handling.patch create mode 100644 0023-libmultipath-don-t-return-error-on-invalid-values.patch create mode 100644 0024-multipathd-avoid-unnecessary-path-read-only-reloads.patch rename 0013-RH-fixup-udev-rules-for-redhat.patch => 0025-RH-fixup-udev-rules-for-redhat.patch (100%) rename 0014-RH-Remove-the-property-blacklist-exception-builtin.patch => 0026-RH-Remove-the-property-blacklist-exception-builtin.patch (96%) rename 0015-RH-don-t-start-without-a-config-file.patch => 0027-RH-don-t-start-without-a-config-file.patch (100%) rename 0016-RH-Fix-nvme-function-missing-argument.patch => 0028-RH-Fix-nvme-function-missing-argument.patch (100%) rename 0017-RH-use-rpm-optflags-if-present.patch => 0029-RH-use-rpm-optflags-if-present.patch (82%) rename 0018-RH-add-mpathconf.patch => 0030-RH-add-mpathconf.patch (98%) rename 0019-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch => 0031-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch (97%) rename 0020-RH-reset-default-find_mutipaths-value-to-off.patch => 0032-RH-reset-default-find_mutipaths-value-to-off.patch (100%) rename 0021-RH-attempt-to-get-ANA-info-via-sysfs-first.patch => 0033-RH-attempt-to-get-ANA-info-via-sysfs-first.patch (100%) rename 0022-RH-make-parse_vpd_pg83-match-scsi_id-output.patch => 0034-RH-make-parse_vpd_pg83-match-scsi_id-output.patch (50%) diff --git a/0013-multipath-fix-exit-status-of-multipath-T.patch b/0013-multipath-fix-exit-status-of-multipath-T.patch new file mode 100644 index 0000000..783e95e --- /dev/null +++ b/0013-multipath-fix-exit-status-of-multipath-T.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 22 Oct 2021 12:58:11 +0200 +Subject: [PATCH] multipath: fix exit status of multipath -T + +We must set the return value in configure(). + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/main.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/multipath/main.c b/multipath/main.c +index 65ece830..b2d300e5 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -560,6 +560,7 @@ configure (struct config *conf, enum mpath_cmds cmd, + + dump_config(conf, hwes, curmp); + vector_free(hwes); ++ r = RTVL_OK; + goto out; + } + diff --git a/0014-libmultipath-add-section-name-to-invalid-keyword-out.patch b/0014-libmultipath-add-section-name-to-invalid-keyword-out.patch new file mode 100644 index 0000000..f4fce9f --- /dev/null +++ b/0014-libmultipath-add-section-name-to-invalid-keyword-out.patch @@ -0,0 +1,70 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 11 Nov 2021 12:53:44 -0600 +Subject: [PATCH] libmultipath: add section name to invalid keyword output + +If users forget the closing brace for a section in multipath.conf, +multipath has no way to detect that. When it sees the keyword at the +start of the next section, it will complain that there is an invalid +keyword, because that keyword doesn't belong in previous section (which +was never ended with a closing brace). This can confuse users. To make +this easier to understand, when multipath prints an invalid keyword +message, it now also prints the current section name, which can give +users a hint that they didn't end the previous section. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/parser.c | 20 +++++++++++++------- + 1 file changed, 13 insertions(+), 7 deletions(-) + +diff --git a/libmultipath/parser.c b/libmultipath/parser.c +index 8ca91bf2..611054f7 100644 +--- a/libmultipath/parser.c ++++ b/libmultipath/parser.c +@@ -504,7 +504,7 @@ validate_config_strvec(vector strvec, const char *file) + + static int + process_stream(struct config *conf, FILE *stream, vector keywords, +- const char *file) ++ const char *section, const char *file) + { + int i; + int r = 0, t; +@@ -568,16 +568,22 @@ process_stream(struct config *conf, FILE *stream, vector keywords, + if (keyword->sub) { + kw_level++; + r += process_stream(conf, stream, +- keyword->sub, file); ++ keyword->sub, ++ keyword->string, ++ file); + kw_level--; + } + break; + } + } +- if (i >= VECTOR_SIZE(keywords)) +- condlog(1, "%s line %d, invalid keyword: %s", +- file, line_nr, str); +- ++ if (i >= VECTOR_SIZE(keywords)) { ++ if (section) ++ condlog(1, "%s line %d, invalid keyword in the %s section: %s", ++ file, line_nr, section, str); ++ else ++ condlog(1, "%s line %d, invalid keyword: %s", ++ file, line_nr, str); ++ } + free_strvec(strvec); + } + if (kw_level == 1) +@@ -608,7 +614,7 @@ process_file(struct config *conf, const char *file) + + /* Stream handling */ + line_nr = 0; +- r = process_stream(conf, stream, conf->keywords, file); ++ r = process_stream(conf, stream, conf->keywords, NULL, file); + fclose(stream); + //free_keywords(keywords); + diff --git a/0015-libmultipath-use-typedef-for-keyword-handler-functio.patch b/0015-libmultipath-use-typedef-for-keyword-handler-functio.patch new file mode 100644 index 0000000..c3a41d2 --- /dev/null +++ b/0015-libmultipath-use-typedef-for-keyword-handler-functio.patch @@ -0,0 +1,85 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 11 Nov 2021 12:53:45 -0600 +Subject: [PATCH] libmultipath: use typedef for keyword handler function + +Don't keep writing out the function type. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/parser.c | 6 +++--- + libmultipath/parser.h | 15 ++++++--------- + 2 files changed, 9 insertions(+), 12 deletions(-) + +diff --git a/libmultipath/parser.c b/libmultipath/parser.c +index 611054f7..ebe1cbd9 100644 +--- a/libmultipath/parser.c ++++ b/libmultipath/parser.c +@@ -33,7 +33,7 @@ static int line_nr; + + int + keyword_alloc(vector keywords, char *string, +- int (*handler) (struct config *, vector), ++ handler_fn *handler, + print_fn *print, + int unique) + { +@@ -72,7 +72,7 @@ install_sublevel_end(void) + + int + _install_keyword(vector keywords, char *string, +- int (*handler) (struct config *, vector), ++ handler_fn *handler, + print_fn *print, + int unique) + { +@@ -558,7 +558,7 @@ process_stream(struct config *conf, FILE *stream, vector keywords, + goto out; + } + if (keyword->handler) { +- t = (*keyword->handler) (conf, strvec); ++ t = keyword->handler(conf, strvec); + r += t; + if (t) + condlog(1, "multipath.conf +%d, parsing failed: %s", +diff --git a/libmultipath/parser.h b/libmultipath/parser.h +index b43d46f8..3452bde1 100644 +--- a/libmultipath/parser.h ++++ b/libmultipath/parser.h +@@ -43,10 +43,11 @@ struct strbuf; + + /* keyword definition */ + typedef int print_fn(struct config *, struct strbuf *, const void *); ++typedef int handler_fn(struct config *, vector); + + struct keyword { + char *string; +- int (*handler) (struct config *, vector); ++ handler_fn *handler; + print_fn *print; + vector sub; + int unique; +@@ -62,18 +63,14 @@ struct keyword { + for (i = 0; i < (k)->sub->allocated && ((p) = (k)->sub->slot[i]); i++) + + /* Prototypes */ +-extern int keyword_alloc(vector keywords, char *string, +- int (*handler) (struct config *, vector), +- print_fn *print, +- int unique); ++extern int keyword_alloc(vector keywords, char *string, handler_fn *handler, ++ print_fn *print, int unique); + #define install_keyword_root(str, h) keyword_alloc(keywords, str, h, NULL, 1) + extern void install_sublevel(void); + extern void install_sublevel_end(void); + +-extern int _install_keyword(vector keywords, char *string, +- int (*handler) (struct config *, vector), +- print_fn *print, +- int unique); ++extern int _install_keyword(vector keywords, char *string, handler_fn *handler, ++ print_fn *print, int unique); + #define install_keyword(str, vec, pri) _install_keyword(keywords, str, vec, pri, 1) + #define install_keyword_multi(str, vec, pri) _install_keyword(keywords, str, vec, pri, 0) + extern void dump_keywords(vector keydump, int level); diff --git a/0016-libmultipath-print-the-correct-file-when-parsing-fai.patch b/0016-libmultipath-print-the-correct-file-when-parsing-fai.patch new file mode 100644 index 0000000..5d9f2f4 --- /dev/null +++ b/0016-libmultipath-print-the-correct-file-when-parsing-fai.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 11 Nov 2021 12:53:46 -0600 +Subject: [PATCH] libmultipath: print the correct file when parsing fails + +Don't assume that parsing failed on multipath.conf + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/parser.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/parser.c b/libmultipath/parser.c +index ebe1cbd9..d5595fb0 100644 +--- a/libmultipath/parser.c ++++ b/libmultipath/parser.c +@@ -561,8 +561,8 @@ process_stream(struct config *conf, FILE *stream, vector keywords, + t = keyword->handler(conf, strvec); + r += t; + if (t) +- condlog(1, "multipath.conf +%d, parsing failed: %s", +- line_nr, buf); ++ condlog(1, "%s line %d, parsing failed: %s", ++ file, line_nr, buf); + } + + if (keyword->sub) { diff --git a/0017-libmultipath-pass-file-and-line-number-to-keyword-ha.patch b/0017-libmultipath-pass-file-and-line-number-to-keyword-ha.patch new file mode 100644 index 0000000..50f9184 --- /dev/null +++ b/0017-libmultipath-pass-file-and-line-number-to-keyword-ha.patch @@ -0,0 +1,528 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 11 Nov 2021 12:53:47 -0600 +Subject: [PATCH] libmultipath: pass file and line number to keyword handlers + +This will make it possible for the keyword handlers to print more useful +warning messages. It will be used by future patches. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/dict.c | 143 +++++++++++++++++++++++++----------------- + libmultipath/parser.c | 3 +- + libmultipath/parser.h | 2 +- + 3 files changed, 90 insertions(+), 58 deletions(-) + +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index 7a727389..eb2c44c0 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -29,7 +29,7 @@ + #include "strbuf.h" + + static int +-set_int(vector strvec, void *ptr) ++set_int(vector strvec, void *ptr, const char *file, int line_nr) + { + int *int_ptr = (int *)ptr; + char *buff, *eptr; +@@ -58,7 +58,7 @@ set_int(vector strvec, void *ptr) + } + + static int +-set_uint(vector strvec, void *ptr) ++set_uint(vector strvec, void *ptr, const char *file, int line_nr) + { + unsigned int *uint_ptr = (unsigned int *)ptr; + char *buff, *eptr, *p; +@@ -90,7 +90,7 @@ set_uint(vector strvec, void *ptr) + } + + static int +-set_str(vector strvec, void *ptr) ++set_str(vector strvec, void *ptr, const char *file, int line_nr) + { + char **str_ptr = (char **)ptr; + +@@ -105,7 +105,7 @@ set_str(vector strvec, void *ptr) + } + + static int +-set_yes_no(vector strvec, void *ptr) ++set_yes_no(vector strvec, void *ptr, const char *file, int line_nr) + { + char * buff; + int *int_ptr = (int *)ptr; +@@ -124,7 +124,7 @@ set_yes_no(vector strvec, void *ptr) + } + + static int +-set_yes_no_undef(vector strvec, void *ptr) ++set_yes_no_undef(vector strvec, void *ptr, const char *file, int line_nr) + { + char * buff; + int *int_ptr = (int *)ptr; +@@ -187,9 +187,10 @@ static int print_yes_no_undef(struct strbuf *buff, long v) + + #define declare_def_handler(option, function) \ + static int \ +-def_ ## option ## _handler (struct config *conf, vector strvec) \ ++def_ ## option ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ + { \ +- return function (strvec, &conf->option); \ ++ return function (strvec, &conf->option, file, line_nr); \ + } + + #define declare_def_snprint(option, function) \ +@@ -224,12 +225,13 @@ snprint_def_ ## option (struct config *conf, struct strbuf *buff, \ + + #define declare_hw_handler(option, function) \ + static int \ +-hw_ ## option ## _handler (struct config *conf, vector strvec) \ ++hw_ ## option ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ + { \ + struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable); \ + if (!hwe) \ + return 1; \ +- return function (strvec, &hwe->option); \ ++ return function (strvec, &hwe->option, file, line_nr); \ + } + + #define declare_hw_snprint(option, function) \ +@@ -243,11 +245,12 @@ snprint_hw_ ## option (struct config *conf, struct strbuf *buff, \ + + #define declare_ovr_handler(option, function) \ + static int \ +-ovr_ ## option ## _handler (struct config *conf, vector strvec) \ ++ovr_ ## option ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ + { \ + if (!conf->overrides) \ + return 1; \ +- return function (strvec, &conf->overrides->option); \ ++ return function (strvec, &conf->overrides->option, file, line_nr); \ + } + + #define declare_ovr_snprint(option, function) \ +@@ -260,12 +263,13 @@ snprint_ovr_ ## option (struct config *conf, struct strbuf *buff, \ + + #define declare_mp_handler(option, function) \ + static int \ +-mp_ ## option ## _handler (struct config *conf, vector strvec) \ ++mp_ ## option ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ + { \ + struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable); \ + if (!mpe) \ + return 1; \ +- return function (strvec, &mpe->option); \ ++ return function (strvec, &mpe->option, file, line_nr); \ + } + + #define declare_mp_snprint(option, function) \ +@@ -277,9 +281,10 @@ snprint_mp_ ## option (struct config *conf, struct strbuf *buff, \ + return function(buff, mpe->option); \ + } + +-static int checkint_handler(struct config *conf, vector strvec) ++static int checkint_handler(struct config *conf, vector strvec, ++ const char *file, int line_nr) + { +- int rc = set_uint(strvec, &conf->checkint); ++ int rc = set_uint(strvec, &conf->checkint, file, line_nr); + + if (rc) + return rc; +@@ -302,9 +307,10 @@ declare_def_snprint(reassign_maps, print_yes_no) + declare_def_handler(multipath_dir, set_str) + declare_def_snprint(multipath_dir, print_str) + +-static int def_partition_delim_handler(struct config *conf, vector strvec) ++static int def_partition_delim_handler(struct config *conf, vector strvec, ++ const char *file, int line_nr) + { +- int rc = set_str(strvec, &conf->partition_delim); ++ int rc = set_str(strvec, &conf->partition_delim, file, line_nr); + + if (rc != 0) + return rc; +@@ -334,13 +340,13 @@ static const char * const find_multipaths_optvals[] = { + }; + + static int +-def_find_multipaths_handler(struct config *conf, vector strvec) ++def_find_multipaths_handler(struct config *conf, vector strvec, ++ const char *file, int line_nr) + { + char *buff; + int i; + +- if (set_yes_no_undef(strvec, &conf->find_multipaths) == 0 && +- conf->find_multipaths != FIND_MULTIPATHS_UNDEF) ++ if (set_yes_no_undef(strvec, &conf->find_multipaths, file, line_nr) == 0 && conf->find_multipaths != FIND_MULTIPATHS_UNDEF) + return 0; + + buff = set_value(strvec); +@@ -396,7 +402,8 @@ static int snprint_uid_attrs(struct config *conf, struct strbuf *buff, + return total; + } + +-static int uid_attrs_handler(struct config *conf, vector strvec) ++static int uid_attrs_handler(struct config *conf, vector strvec, ++ const char *file, int line_nr) + { + char *val; + +@@ -597,7 +604,8 @@ declare_hw_handler(skip_kpartx, set_yes_no_undef) + declare_hw_snprint(skip_kpartx, print_yes_no_undef) + declare_mp_handler(skip_kpartx, set_yes_no_undef) + declare_mp_snprint(skip_kpartx, print_yes_no_undef) +-static int def_disable_changed_wwids_handler(struct config *conf, vector strvec) ++static int def_disable_changed_wwids_handler(struct config *conf, vector strvec, ++ const char *file, int line_nr) + { + return 0; + } +@@ -629,20 +637,23 @@ declare_def_snprint_defstr(enable_foreign, print_str, + DEFAULT_ENABLE_FOREIGN) + + static int +-def_config_dir_handler(struct config *conf, vector strvec) ++def_config_dir_handler(struct config *conf, vector strvec, const char *file, ++ int line_nr) + { + /* this is only valid in the main config file */ + if (conf->processed_main_config) + return 0; +- return set_str(strvec, &conf->config_dir); ++ return set_str(strvec, &conf->config_dir, file, line_nr); + } + declare_def_snprint(config_dir, print_str) + + #define declare_def_attr_handler(option, function) \ + static int \ +-def_ ## option ## _handler (struct config *conf, vector strvec) \ ++def_ ## option ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ + { \ +- return function (strvec, &conf->option, &conf->attribute_flags);\ ++ return function (strvec, &conf->option, &conf->attribute_flags, \ ++ file, line_nr); \ + } + + #define declare_def_attr_snprint(option, function) \ +@@ -655,12 +666,14 @@ snprint_def_ ## option (struct config *conf, struct strbuf *buff, \ + + #define declare_mp_attr_handler(option, function) \ + static int \ +-mp_ ## option ## _handler (struct config *conf, vector strvec) \ ++mp_ ## option ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ + { \ + struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable); \ + if (!mpe) \ + return 1; \ +- return function (strvec, &mpe->option, &mpe->attribute_flags); \ ++ return function (strvec, &mpe->option, &mpe->attribute_flags, \ ++ file, line_nr); \ + } + + #define declare_mp_attr_snprint(option, function) \ +@@ -673,7 +686,7 @@ snprint_mp_ ## option (struct config *conf, struct strbuf *buff, \ + } + + static int +-set_mode(vector strvec, void *ptr, int *flags) ++set_mode(vector strvec, void *ptr, int *flags, const char *file, int line_nr) + { + mode_t mode; + mode_t *mode_ptr = (mode_t *)ptr; +@@ -694,7 +707,7 @@ set_mode(vector strvec, void *ptr, int *flags) + } + + static int +-set_uid(vector strvec, void *ptr, int *flags) ++set_uid(vector strvec, void *ptr, int *flags, const char *file, int line_nr) + { + uid_t uid; + uid_t *uid_ptr = (uid_t *)ptr; +@@ -719,7 +732,7 @@ set_uid(vector strvec, void *ptr, int *flags) + } + + static int +-set_gid(vector strvec, void *ptr, int *flags) ++set_gid(vector strvec, void *ptr, int *flags, const char *file, int line_nr) + { + gid_t gid; + gid_t *gid_ptr = (gid_t *)ptr; +@@ -786,7 +799,7 @@ declare_mp_attr_handler(gid, set_gid) + declare_mp_attr_snprint(gid, print_gid) + + static int +-set_undef_off_zero(vector strvec, void *ptr) ++set_undef_off_zero(vector strvec, void *ptr, const char *file, int line_nr) + { + char * buff; + int *int_ptr = (int *)ptr; +@@ -827,7 +840,7 @@ declare_hw_handler(fast_io_fail, set_undef_off_zero) + declare_hw_snprint(fast_io_fail, print_undef_off_zero) + + static int +-set_dev_loss(vector strvec, void *ptr) ++set_dev_loss(vector strvec, void *ptr, const char *file, int line_nr) + { + char * buff; + unsigned int *uint_ptr = (unsigned int *)ptr; +@@ -870,7 +883,7 @@ declare_hw_handler(eh_deadline, set_undef_off_zero) + declare_hw_snprint(eh_deadline, print_undef_off_zero) + + static int +-set_pgpolicy(vector strvec, void *ptr) ++set_pgpolicy(vector strvec, void *ptr, const char *file, int line_nr) + { + char * buff; + int *int_ptr = (int *)ptr; +@@ -936,7 +949,8 @@ get_sys_max_fds(int *max_fds) + + + static int +-max_fds_handler(struct config *conf, vector strvec) ++max_fds_handler(struct config *conf, vector strvec, const char *file, ++ int line_nr) + { + char * buff; + int r = 0, max_fds; +@@ -981,7 +995,7 @@ snprint_max_fds (struct config *conf, struct strbuf *buff, const void *data) + } + + static int +-set_rr_weight(vector strvec, void *ptr) ++set_rr_weight(vector strvec, void *ptr, const char *file, int line_nr) + { + int *int_ptr = (int *)ptr; + char * buff; +@@ -1025,7 +1039,7 @@ declare_mp_handler(rr_weight, set_rr_weight) + declare_mp_snprint(rr_weight, print_rr_weight) + + static int +-set_pgfailback(vector strvec, void *ptr) ++set_pgfailback(vector strvec, void *ptr, const char *file, int line_nr) + { + int *int_ptr = (int *)ptr; + char * buff; +@@ -1075,7 +1089,7 @@ declare_mp_handler(pgfailback, set_pgfailback) + declare_mp_snprint(pgfailback, print_pgfailback) + + static int +-no_path_retry_helper(vector strvec, void *ptr) ++no_path_retry_helper(vector strvec, void *ptr, const char *file, int line_nr) + { + int *int_ptr = (int *)ptr; + char * buff; +@@ -1120,7 +1134,8 @@ declare_mp_handler(no_path_retry, no_path_retry_helper) + declare_mp_snprint(no_path_retry, print_no_path_retry) + + static int +-def_log_checker_err_handler(struct config *conf, vector strvec) ++def_log_checker_err_handler(struct config *conf, vector strvec, ++ const char *file, int line_nr) + { + char * buff; + +@@ -1193,7 +1208,8 @@ print_reservation_key(struct strbuf *buff, + } + + static int +-def_reservation_key_handler(struct config *conf, vector strvec) ++def_reservation_key_handler(struct config *conf, vector strvec, ++ const char *file, int line_nr) + { + return set_reservation_key(strvec, &conf->reservation_key, + &conf->sa_flags, +@@ -1209,7 +1225,8 @@ snprint_def_reservation_key (struct config *conf, struct strbuf *buff, + } + + static int +-mp_reservation_key_handler(struct config *conf, vector strvec) ++mp_reservation_key_handler(struct config *conf, vector strvec, const char *file, ++ int line_nr) + { + struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable); + if (!mpe) +@@ -1229,7 +1246,7 @@ snprint_mp_reservation_key (struct config *conf, struct strbuf *buff, + } + + static int +-set_off_int_undef(vector strvec, void *ptr) ++set_off_int_undef(vector strvec, void *ptr, const char *file, int line_nr) + { + int *int_ptr = (int *)ptr; + char * buff; +@@ -1370,7 +1387,8 @@ declare_hw_snprint(recheck_wwid, print_yes_no_undef) + + + static int +-def_uxsock_timeout_handler(struct config *conf, vector strvec) ++def_uxsock_timeout_handler(struct config *conf, vector strvec, const char *file, ++ int line_nr) + { + unsigned int uxsock_timeout; + char *buff; +@@ -1390,7 +1408,8 @@ def_uxsock_timeout_handler(struct config *conf, vector strvec) + } + + static int +-hw_vpd_vendor_handler(struct config *conf, vector strvec) ++hw_vpd_vendor_handler(struct config *conf, vector strvec, const char *file, ++ int line_nr) + { + int i; + char *buff; +@@ -1430,7 +1449,8 @@ snprint_hw_vpd_vendor(struct config *conf, struct strbuf *buff, + * blacklist block handlers + */ + static int +-blacklist_handler(struct config *conf, vector strvec) ++blacklist_handler(struct config *conf, vector strvec, const char*file, ++ int line_nr) + { + if (!conf->blist_devnode) + conf->blist_devnode = vector_alloc(); +@@ -1452,7 +1472,8 @@ blacklist_handler(struct config *conf, vector strvec) + } + + static int +-blacklist_exceptions_handler(struct config *conf, vector strvec) ++blacklist_exceptions_handler(struct config *conf, vector strvec, ++ const char *file, int line_nr) + { + if (!conf->elist_devnode) + conf->elist_devnode = vector_alloc(); +@@ -1475,7 +1496,8 @@ blacklist_exceptions_handler(struct config *conf, vector strvec) + + #define declare_ble_handler(option) \ + static int \ +-ble_ ## option ## _handler (struct config *conf, vector strvec) \ ++ble_ ## option ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ + { \ + char *buff; \ + int rc; \ +@@ -1494,7 +1516,8 @@ ble_ ## option ## _handler (struct config *conf, vector strvec) \ + + #define declare_ble_device_handler(name, option, vend, prod) \ + static int \ +-ble_ ## option ## _ ## name ## _handler (struct config *conf, vector strvec) \ ++ble_ ## option ## _ ## name ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ + { \ + char * buff; \ + int rc; \ +@@ -1536,13 +1559,15 @@ snprint_ble_simple (struct config *conf, struct strbuf *buff, const void *data) + } + + static int +-ble_device_handler(struct config *conf, vector strvec) ++ble_device_handler(struct config *conf, vector strvec, const char *file, ++ int line_nr) + { + return alloc_ble_device(conf->blist_device); + } + + static int +-ble_except_device_handler(struct config *conf, vector strvec) ++ble_except_device_handler(struct config *conf, vector strvec, const char *file, ++ int line_nr) + { + return alloc_ble_device(conf->elist_device); + } +@@ -1574,7 +1599,8 @@ static int snprint_bled_product(struct config *conf, struct strbuf *buff, + * devices block handlers + */ + static int +-devices_handler(struct config *conf, vector strvec) ++devices_handler(struct config *conf, vector strvec, const char *file, ++ int line_nr) + { + if (!conf->hwtable) + conf->hwtable = vector_alloc(); +@@ -1586,7 +1612,8 @@ devices_handler(struct config *conf, vector strvec) + } + + static int +-device_handler(struct config *conf, vector strvec) ++device_handler(struct config *conf, vector strvec, const char *file, ++ int line_nr) + { + struct hwentry * hwe; + +@@ -1623,7 +1650,8 @@ declare_hw_snprint(hwhandler, print_str) + * overrides handlers + */ + static int +-overrides_handler(struct config *conf, vector strvec) ++overrides_handler(struct config *conf, vector strvec, const char *file, ++ int line_nr) + { + if (!conf->overrides) + conf->overrides = alloc_hwe(); +@@ -1640,7 +1668,8 @@ overrides_handler(struct config *conf, vector strvec) + * multipaths block handlers + */ + static int +-multipaths_handler(struct config *conf, vector strvec) ++multipaths_handler(struct config *conf, vector strvec, const char *file, ++ int line_nr) + { + if (!conf->mptable) + conf->mptable = vector_alloc(); +@@ -1652,7 +1681,8 @@ multipaths_handler(struct config *conf, vector strvec) + } + + static int +-multipath_handler(struct config *conf, vector strvec) ++multipath_handler(struct config *conf, vector strvec, const char *file, ++ int line_nr) + { + struct mpentry * mpe; + +@@ -1681,7 +1711,8 @@ declare_mp_snprint(alias, print_str) + */ + + static int +-deprecated_handler(struct config *conf, vector strvec) ++deprecated_handler(struct config *conf, vector strvec, const char *file, ++ int line_nr) + { + char * buff; + +diff --git a/libmultipath/parser.c b/libmultipath/parser.c +index d5595fb0..68262d0e 100644 +--- a/libmultipath/parser.c ++++ b/libmultipath/parser.c +@@ -558,7 +558,8 @@ process_stream(struct config *conf, FILE *stream, vector keywords, + goto out; + } + if (keyword->handler) { +- t = keyword->handler(conf, strvec); ++ t = keyword->handler(conf, strvec, file, ++ line_nr); + r += t; + if (t) + condlog(1, "%s line %d, parsing failed: %s", +diff --git a/libmultipath/parser.h b/libmultipath/parser.h +index 3452bde1..11ea2278 100644 +--- a/libmultipath/parser.h ++++ b/libmultipath/parser.h +@@ -43,7 +43,7 @@ struct strbuf; + + /* keyword definition */ + typedef int print_fn(struct config *, struct strbuf *, const void *); +-typedef int handler_fn(struct config *, vector); ++typedef int handler_fn(struct config *, vector, const char *file, int line_nr); + + struct keyword { + char *string; diff --git a/0018-libmultipath-make-set_int-take-a-range-for-valid-val.patch b/0018-libmultipath-make-set_int-take-a-range-for-valid-val.patch new file mode 100644 index 0000000..21969af --- /dev/null +++ b/0018-libmultipath-make-set_int-take-a-range-for-valid-val.patch @@ -0,0 +1,251 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 11 Nov 2021 12:53:48 -0600 +Subject: [PATCH] libmultipath: make set_int take a range for valid values + +If a value outside of the valid range is passed to set_int, it caps the +value at appropriate limit, and issues a warning. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/dict.c | 121 +++++++++++++++++++++++++++----------------- + 1 file changed, 75 insertions(+), 46 deletions(-) + +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index eb2c44c0..57b6a7b6 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -29,7 +29,8 @@ + #include "strbuf.h" + + static int +-set_int(vector strvec, void *ptr, const char *file, int line_nr) ++set_int(vector strvec, void *ptr, int min, int max, const char *file, ++ int line_nr) + { + int *int_ptr = (int *)ptr; + char *buff, *eptr; +@@ -44,11 +45,17 @@ set_int(vector strvec, void *ptr, const char *file, int line_nr) + if (eptr > buff) + while (isspace(*eptr)) + eptr++; +- if (*buff == '\0' || *eptr != '\0' || res > INT_MAX || res < INT_MIN) { +- condlog(1, "%s: invalid value for %s: \"%s\"", +- __func__, (char*)VECTOR_SLOT(strvec, 0), buff); ++ if (*buff == '\0' || *eptr != '\0') { ++ condlog(1, "%s line %d, invalid value for %s: \"%s\"", ++ file, line_nr, (char*)VECTOR_SLOT(strvec, 0), buff); + rc = 1; + } else { ++ if (res > max || res < min) { ++ res = (res > max) ? max : min; ++ condlog(1, "%s line %d, value for %s too %s, capping at %ld", ++ file, line_nr, (char*)VECTOR_SLOT(strvec, 0), ++ (res == max)? "large" : "small", res); ++ } + rc = 0; + *int_ptr = res; + } +@@ -77,8 +84,8 @@ set_uint(vector strvec, void *ptr, const char *file, int line_nr) + while (isspace(*eptr)) + eptr++; + if (*buff == '\0' || *eptr != '\0' || !isdigit(*p) || res > UINT_MAX) { +- condlog(1, "%s: invalid value for %s: \"%s\"", +- __func__, (char*)VECTOR_SLOT(strvec, 0), buff); ++ condlog(1, "%s line %d, invalid value for %s: \"%s\"", ++ file, line_nr, (char*)VECTOR_SLOT(strvec, 0), buff); + rc = 1; + } else { + rc = 0; +@@ -193,6 +200,14 @@ def_ ## option ## _handler (struct config *conf, vector strvec, \ + return function (strvec, &conf->option, file, line_nr); \ + } + ++#define declare_def_range_handler(option, minval, maxval) \ ++static int \ ++def_ ## option ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ ++{ \ ++ return set_int(strvec, &conf->option, minval, maxval, file, line_nr); \ ++} ++ + #define declare_def_snprint(option, function) \ + static int \ + snprint_def_ ## option (struct config *conf, struct strbuf *buff, \ +@@ -234,6 +249,18 @@ hw_ ## option ## _handler (struct config *conf, vector strvec, \ + return function (strvec, &hwe->option, file, line_nr); \ + } + ++#define declare_hw_range_handler(option, minval, maxval) \ ++static int \ ++hw_ ## option ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ ++{ \ ++ struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable); \ ++ if (!hwe) \ ++ return 1; \ ++ return set_int(strvec, &hwe->option, minval, maxval, file, line_nr); \ ++} ++ ++ + #define declare_hw_snprint(option, function) \ + static int \ + snprint_hw_ ## option (struct config *conf, struct strbuf *buff, \ +@@ -253,6 +280,17 @@ ovr_ ## option ## _handler (struct config *conf, vector strvec, \ + return function (strvec, &conf->overrides->option, file, line_nr); \ + } + ++#define declare_ovr_range_handler(option, minval, maxval) \ ++static int \ ++ovr_ ## option ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ ++{ \ ++ if (!conf->overrides) \ ++ return 1; \ ++ return set_int(strvec, &conf->overrides->option, minval, maxval, \ ++ file, line_nr); \ ++} ++ + #define declare_ovr_snprint(option, function) \ + static int \ + snprint_ovr_ ## option (struct config *conf, struct strbuf *buff, \ +@@ -272,6 +310,17 @@ mp_ ## option ## _handler (struct config *conf, vector strvec, \ + return function (strvec, &mpe->option, file, line_nr); \ + } + ++#define declare_mp_range_handler(option, minval, maxval) \ ++static int \ ++mp_ ## option ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ ++{ \ ++ struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable); \ ++ if (!mpe) \ ++ return 1; \ ++ return set_int(strvec, &mpe->option, minval, maxval, file, line_nr); \ ++} ++ + #define declare_mp_snprint(option, function) \ + static int \ + snprint_mp_ ## option (struct config *conf, struct strbuf *buff, \ +@@ -298,7 +347,7 @@ declare_def_snprint(checkint, print_int) + declare_def_handler(max_checkint, set_uint) + declare_def_snprint(max_checkint, print_int) + +-declare_def_handler(verbosity, set_int) ++declare_def_range_handler(verbosity, 0, MAX_VERBOSITY) + declare_def_snprint(verbosity, print_int) + + declare_def_handler(reassign_maps, set_yes_no) +@@ -473,22 +522,22 @@ declare_ovr_snprint(checker_name, print_str) + declare_hw_handler(checker_name, set_str) + declare_hw_snprint(checker_name, print_str) + +-declare_def_handler(minio, set_int) ++declare_def_range_handler(minio, 0, INT_MAX) + declare_def_snprint_defint(minio, print_int, DEFAULT_MINIO) +-declare_ovr_handler(minio, set_int) ++declare_ovr_range_handler(minio, 0, INT_MAX) + declare_ovr_snprint(minio, print_nonzero) +-declare_hw_handler(minio, set_int) ++declare_hw_range_handler(minio, 0, INT_MAX) + declare_hw_snprint(minio, print_nonzero) +-declare_mp_handler(minio, set_int) ++declare_mp_range_handler(minio, 0, INT_MAX) + declare_mp_snprint(minio, print_nonzero) + +-declare_def_handler(minio_rq, set_int) ++declare_def_range_handler(minio_rq, 0, INT_MAX) + declare_def_snprint_defint(minio_rq, print_int, DEFAULT_MINIO_RQ) +-declare_ovr_handler(minio_rq, set_int) ++declare_ovr_range_handler(minio_rq, 0, INT_MAX) + declare_ovr_snprint(minio_rq, print_nonzero) +-declare_hw_handler(minio_rq, set_int) ++declare_hw_range_handler(minio_rq, 0, INT_MAX) + declare_hw_snprint(minio_rq, print_nonzero) +-declare_mp_handler(minio_rq, set_int) ++declare_mp_range_handler(minio_rq, 0, INT_MAX) + declare_mp_snprint(minio_rq, print_nonzero) + + declare_def_handler(queue_without_daemon, set_yes_no) +@@ -512,7 +561,7 @@ snprint_def_queue_without_daemon(struct config *conf, struct strbuf *buff, + return append_strbuf_quoted(buff, qwd); + } + +-declare_def_handler(checker_timeout, set_int) ++declare_def_range_handler(checker_timeout, 0, INT_MAX) + declare_def_snprint(checker_timeout, print_nonzero) + + declare_def_handler(allow_usb_devices, set_yes_no) +@@ -583,13 +632,13 @@ declare_hw_snprint(deferred_remove, print_yes_no_undef) + declare_mp_handler(deferred_remove, set_yes_no_undef) + declare_mp_snprint(deferred_remove, print_yes_no_undef) + +-declare_def_handler(retrigger_tries, set_int) ++declare_def_range_handler(retrigger_tries, 0, INT_MAX) + declare_def_snprint(retrigger_tries, print_int) + +-declare_def_handler(retrigger_delay, set_int) ++declare_def_range_handler(retrigger_delay, 0, INT_MAX) + declare_def_snprint(retrigger_delay, print_int) + +-declare_def_handler(uev_wait_timeout, set_int) ++declare_def_range_handler(uev_wait_timeout, 0, INT_MAX) + declare_def_snprint(uev_wait_timeout, print_int) + + declare_def_handler(strict_timing, set_yes_no) +@@ -616,19 +665,19 @@ static int snprint_def_disable_changed_wwids(struct config *conf, + return print_ignored(buff); + } + +-declare_def_handler(remove_retries, set_int) ++declare_def_range_handler(remove_retries, 0, INT_MAX) + declare_def_snprint(remove_retries, print_int) + +-declare_def_handler(max_sectors_kb, set_int) ++declare_def_range_handler(max_sectors_kb, 0, INT_MAX) + declare_def_snprint(max_sectors_kb, print_nonzero) +-declare_ovr_handler(max_sectors_kb, set_int) ++declare_ovr_range_handler(max_sectors_kb, 0, INT_MAX) + declare_ovr_snprint(max_sectors_kb, print_nonzero) +-declare_hw_handler(max_sectors_kb, set_int) ++declare_hw_range_handler(max_sectors_kb, 0, INT_MAX) + declare_hw_snprint(max_sectors_kb, print_nonzero) +-declare_mp_handler(max_sectors_kb, set_int) ++declare_mp_range_handler(max_sectors_kb, 0, INT_MAX) + declare_mp_snprint(max_sectors_kb, print_nonzero) + +-declare_def_handler(find_multipaths_timeout, set_int) ++declare_def_range_handler(find_multipaths_timeout, INT_MIN, INT_MAX) + declare_def_snprint_defint(find_multipaths_timeout, print_int, + DEFAULT_FIND_MULTIPATHS_TIMEOUT) + +@@ -1385,27 +1434,7 @@ declare_ovr_snprint(recheck_wwid, print_yes_no_undef) + declare_hw_handler(recheck_wwid, set_yes_no_undef) + declare_hw_snprint(recheck_wwid, print_yes_no_undef) + +- +-static int +-def_uxsock_timeout_handler(struct config *conf, vector strvec, const char *file, +- int line_nr) +-{ +- unsigned int uxsock_timeout; +- char *buff; +- +- buff = set_value(strvec); +- if (!buff) +- return 1; +- +- if (sscanf(buff, "%u", &uxsock_timeout) == 1 && +- uxsock_timeout > DEFAULT_REPLY_TIMEOUT) +- conf->uxsock_timeout = uxsock_timeout; +- else +- conf->uxsock_timeout = DEFAULT_REPLY_TIMEOUT; +- +- free(buff); +- return 0; +-} ++declare_def_range_handler(uxsock_timeout, DEFAULT_REPLY_TIMEOUT, INT_MAX) + + static int + hw_vpd_vendor_handler(struct config *conf, vector strvec, const char *file, diff --git a/0019-libmultipath-improve-checks-for-set_str.patch b/0019-libmultipath-improve-checks-for-set_str.patch new file mode 100644 index 0000000..0cd8627 --- /dev/null +++ b/0019-libmultipath-improve-checks-for-set_str.patch @@ -0,0 +1,171 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 11 Nov 2021 12:53:49 -0600 +Subject: [PATCH] libmultipath: improve checks for set_str + +multipath always requires absolute pathnames, so make sure all file and +directory names start with a slash. Also check that the directories +exist. Finally, some strings, like the alias, will be used in paths. +These must not contain the slash character '/', since it is a forbidden +character in file/directory names. This patch adds seperate handlers for +these three cases. If a config line is invalid, these handlers retain +the existing config string, if any. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/dict.c | 88 +++++++++++++++++++++++++++++++++++++++------ + 1 file changed, 78 insertions(+), 10 deletions(-) + +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index 57b6a7b6..149d3348 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -5,6 +5,8 @@ + * Copyright (c) 2005 Kiyoshi Ueda, NEC + */ + #include ++#include ++#include + #include + #include + #include "checkers.h" +@@ -111,6 +113,72 @@ set_str(vector strvec, void *ptr, const char *file, int line_nr) + return 0; + } + ++static int ++set_dir(vector strvec, void *ptr, const char *file, int line_nr) ++{ ++ char **str_ptr = (char **)ptr; ++ char *old_str = *str_ptr; ++ struct stat sb; ++ ++ *str_ptr = set_value(strvec); ++ if (!*str_ptr) { ++ free(old_str); ++ return 1; ++ } ++ if ((*str_ptr)[0] != '/'){ ++ condlog(1, "%s line %d, %s is not an absolute directory path. Ignoring", file, line_nr, *str_ptr); ++ *str_ptr = old_str; ++ } else { ++ if (stat(*str_ptr, &sb) == 0 && S_ISDIR(sb.st_mode)) ++ free(old_str); ++ else { ++ condlog(1, "%s line %d, %s is not an existing directory. Ignoring", file, line_nr, *str_ptr); ++ *str_ptr = old_str; ++ } ++ } ++ return 0; ++} ++ ++static int ++set_path(vector strvec, void *ptr, const char *file, int line_nr) ++{ ++ char **str_ptr = (char **)ptr; ++ char *old_str = *str_ptr; ++ ++ *str_ptr = set_value(strvec); ++ if (!*str_ptr) { ++ free(old_str); ++ return 1; ++ } ++ if ((*str_ptr)[0] != '/'){ ++ condlog(1, "%s line %d, %s is not an absolute path. Ignoring", ++ file, line_nr, *str_ptr); ++ *str_ptr = old_str; ++ } else ++ free(old_str); ++ return 0; ++} ++ ++static int ++set_str_noslash(vector strvec, void *ptr, const char *file, int line_nr) ++{ ++ char **str_ptr = (char **)ptr; ++ char *old_str = *str_ptr; ++ ++ *str_ptr = set_value(strvec); ++ if (!*str_ptr) { ++ free(old_str); ++ return 1; ++ } ++ if (strchr(*str_ptr, '/')) { ++ condlog(1, "%s line %d, %s cannot contain a slash. Ignoring", ++ file, line_nr, *str_ptr); ++ *str_ptr = old_str; ++ } else ++ free(old_str); ++ return 0; ++} ++ + static int + set_yes_no(vector strvec, void *ptr, const char *file, int line_nr) + { +@@ -353,13 +421,13 @@ declare_def_snprint(verbosity, print_int) + declare_def_handler(reassign_maps, set_yes_no) + declare_def_snprint(reassign_maps, print_yes_no) + +-declare_def_handler(multipath_dir, set_str) ++declare_def_handler(multipath_dir, set_dir) + declare_def_snprint(multipath_dir, print_str) + + static int def_partition_delim_handler(struct config *conf, vector strvec, + const char *file, int line_nr) + { +- int rc = set_str(strvec, &conf->partition_delim, file, line_nr); ++ int rc = set_str_noslash(strvec, &conf->partition_delim, file, line_nr); + + if (rc != 0) + return rc; +@@ -490,11 +558,11 @@ declare_hw_snprint(prio_name, print_str) + declare_mp_handler(prio_name, set_str) + declare_mp_snprint(prio_name, print_str) + +-declare_def_handler(alias_prefix, set_str) ++declare_def_handler(alias_prefix, set_str_noslash) + declare_def_snprint_defstr(alias_prefix, print_str, DEFAULT_ALIAS_PREFIX) +-declare_ovr_handler(alias_prefix, set_str) ++declare_ovr_handler(alias_prefix, set_str_noslash) + declare_ovr_snprint(alias_prefix, print_str) +-declare_hw_handler(alias_prefix, set_str) ++declare_hw_handler(alias_prefix, set_str_noslash) + declare_hw_snprint(alias_prefix, print_str) + + declare_def_handler(prio_args, set_str) +@@ -586,13 +654,13 @@ declare_hw_snprint(user_friendly_names, print_yes_no_undef) + declare_mp_handler(user_friendly_names, set_yes_no_undef) + declare_mp_snprint(user_friendly_names, print_yes_no_undef) + +-declare_def_handler(bindings_file, set_str) ++declare_def_handler(bindings_file, set_path) + declare_def_snprint(bindings_file, print_str) + +-declare_def_handler(wwids_file, set_str) ++declare_def_handler(wwids_file, set_path) + declare_def_snprint(wwids_file, print_str) + +-declare_def_handler(prkeys_file, set_str) ++declare_def_handler(prkeys_file, set_path) + declare_def_snprint(prkeys_file, print_str) + + declare_def_handler(retain_hwhandler, set_yes_no_undef) +@@ -692,7 +760,7 @@ def_config_dir_handler(struct config *conf, vector strvec, const char *file, + /* this is only valid in the main config file */ + if (conf->processed_main_config) + return 0; +- return set_str(strvec, &conf->config_dir, file, line_nr); ++ return set_path(strvec, &conf->config_dir, file, line_nr); + } + declare_def_snprint(config_dir, print_str) + +@@ -1732,7 +1800,7 @@ multipath_handler(struct config *conf, vector strvec, const char *file, + declare_mp_handler(wwid, set_str) + declare_mp_snprint(wwid, print_str) + +-declare_mp_handler(alias, set_str) ++declare_mp_handler(alias, set_str_noslash) + declare_mp_snprint(alias, print_str) + + /* diff --git a/0020-libmultipath-deprecate-file-and-directory-config-opt.patch b/0020-libmultipath-deprecate-file-and-directory-config-opt.patch new file mode 100644 index 0000000..32e1b23 --- /dev/null +++ b/0020-libmultipath-deprecate-file-and-directory-config-opt.patch @@ -0,0 +1,115 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 11 Nov 2021 12:53:50 -0600 +Subject: [PATCH] libmultipath: deprecate file and directory config options + +Having multipath able to select pathnames for the files and directories +it needs causes unnecessary maintainer headaches. Mark these as +deprecated, but still support them for now. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/dict.c | 19 +++++++++++++++---- + multipath/multipath.conf.5 | 5 +++++ + 2 files changed, 20 insertions(+), 4 deletions(-) + +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index 149d3348..d14be340 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -268,6 +268,15 @@ def_ ## option ## _handler (struct config *conf, vector strvec, \ + return function (strvec, &conf->option, file, line_nr); \ + } + ++#define declare_def_warn_handler(option, function) \ ++static int \ ++def_ ## option ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ ++{ \ ++ condlog(2, "%s line %d, \"" #option "\" is deprecated and will be disabled in a future release", file, line_nr); \ ++ return function (strvec, &conf->option, file, line_nr); \ ++} ++ + #define declare_def_range_handler(option, minval, maxval) \ + static int \ + def_ ## option ## _handler (struct config *conf, vector strvec, \ +@@ -421,7 +430,7 @@ declare_def_snprint(verbosity, print_int) + declare_def_handler(reassign_maps, set_yes_no) + declare_def_snprint(reassign_maps, print_yes_no) + +-declare_def_handler(multipath_dir, set_dir) ++declare_def_warn_handler(multipath_dir, set_dir) + declare_def_snprint(multipath_dir, print_str) + + static int def_partition_delim_handler(struct config *conf, vector strvec, +@@ -654,13 +663,13 @@ declare_hw_snprint(user_friendly_names, print_yes_no_undef) + declare_mp_handler(user_friendly_names, set_yes_no_undef) + declare_mp_snprint(user_friendly_names, print_yes_no_undef) + +-declare_def_handler(bindings_file, set_path) ++declare_def_warn_handler(bindings_file, set_path) + declare_def_snprint(bindings_file, print_str) + +-declare_def_handler(wwids_file, set_path) ++declare_def_warn_handler(wwids_file, set_path) + declare_def_snprint(wwids_file, print_str) + +-declare_def_handler(prkeys_file, set_path) ++declare_def_warn_handler(prkeys_file, set_path) + declare_def_snprint(prkeys_file, print_str) + + declare_def_handler(retain_hwhandler, set_yes_no_undef) +@@ -760,6 +769,8 @@ def_config_dir_handler(struct config *conf, vector strvec, const char *file, + /* this is only valid in the main config file */ + if (conf->processed_main_config) + return 0; ++ condlog(2, "%s line %d, \"config_dir\" is deprecated and will be disabled in a future release", ++ file, line_nr); + return set_path(strvec, &conf->config_dir, file, line_nr); + } + declare_def_snprint(config_dir, print_str) +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 +index c74129bd..88d2a1df 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5 +@@ -178,6 +178,7 @@ The default is: \fBno\fR + . + .TP + .B multipath_dir ++This option is deprecated, and will be removed in a future release. + Directory where the dynamic shared objects are stored. Defined at compile time, + commonly \fI/lib64/multipath/\fR or \fI/lib/multipath/\fR. + .RS +@@ -742,6 +743,7 @@ The default is: \fB\fR + . + .TP + .B bindings_file ++This option is deprecated, and will be removed in a future release. + The full pathname of the binding file to be used when the user_friendly_names + option is set. + .RS +@@ -752,6 +754,7 @@ The default is: \fB/etc/multipath/bindings\fR + . + .TP + .B wwids_file ++This option is deprecated, and will be removed in a future release. + The full pathname of the WWIDs file, which is used by multipath to keep track + of the WWIDs for LUNs it has created multipath devices on in the past. + .RS +@@ -762,6 +765,7 @@ The default is: \fB/etc/multipath/wwids\fR + . + .TP + .B prkeys_file ++This option is deprecated, and will be removed in a future release. + The full pathname of the prkeys file, which is used by multipathd to keep + track of the persistent reservation key used for a specific WWID, when + \fIreservation_key\fR is set to \fBfile\fR. +@@ -933,6 +937,7 @@ The default is: \fB\fR + . + .TP + .B config_dir ++This option is deprecated, and will be removed in a future release. + If set to anything other than "", multipath will search this directory + alphabetically for file ending in ".conf" and it will read configuration + information from them, just as if it was in \fI/etc/multipath.conf\fR. diff --git a/0021-libmultipath-split-set_int-to-enable-reuse.patch b/0021-libmultipath-split-set_int-to-enable-reuse.patch new file mode 100644 index 0000000..4f4b09a --- /dev/null +++ b/0021-libmultipath-split-set_int-to-enable-reuse.patch @@ -0,0 +1,192 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 11 Nov 2021 12:53:51 -0600 +Subject: [PATCH] libmultipath: split set_int to enable reuse + +Split the code that does the actual value parsing out of set_int(), into +a helper function, do_set_int(), so that it can be used by other +handlers. These functions no longer set the config value at all, when +they have invalid input. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/dict.c | 82 +++++++++++++++++++++++++-------------------- + 1 file changed, 46 insertions(+), 36 deletions(-) + +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index d14be340..68647061 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -31,17 +31,12 @@ + #include "strbuf.h" + + static int +-set_int(vector strvec, void *ptr, int min, int max, const char *file, +- int line_nr) ++do_set_int(vector strvec, void *ptr, int min, int max, const char *file, ++ int line_nr, char *buff) + { + int *int_ptr = (int *)ptr; +- char *buff, *eptr; ++ char *eptr; + long res; +- int rc; +- +- buff = set_value(strvec); +- if (!buff) +- return 1; + + res = strtol(buff, &eptr, 10); + if (eptr > buff) +@@ -50,17 +45,30 @@ set_int(vector strvec, void *ptr, int min, int max, const char *file, + if (*buff == '\0' || *eptr != '\0') { + condlog(1, "%s line %d, invalid value for %s: \"%s\"", + file, line_nr, (char*)VECTOR_SLOT(strvec, 0), buff); +- rc = 1; +- } else { +- if (res > max || res < min) { +- res = (res > max) ? max : min; +- condlog(1, "%s line %d, value for %s too %s, capping at %ld", ++ return 1; ++ } ++ if (res > max || res < min) { ++ res = (res > max) ? max : min; ++ condlog(1, "%s line %d, value for %s too %s, capping at %ld", + file, line_nr, (char*)VECTOR_SLOT(strvec, 0), +- (res == max)? "large" : "small", res); +- } +- rc = 0; +- *int_ptr = res; ++ (res == max)? "large" : "small", res); + } ++ *int_ptr = res; ++ return 0; ++} ++ ++static int ++set_int(vector strvec, void *ptr, int min, int max, const char *file, ++ int line_nr) ++{ ++ char *buff; ++ int rc; ++ ++ buff = set_value(strvec); ++ if (!buff) ++ return 1; ++ ++ rc = do_set_int(strvec, ptr, min, max, file, line_nr, buff); + + FREE(buff); + return rc; +@@ -929,6 +937,7 @@ declare_mp_attr_snprint(gid, print_gid) + static int + set_undef_off_zero(vector strvec, void *ptr, const char *file, int line_nr) + { ++ int rc = 0; + char * buff; + int *int_ptr = (int *)ptr; + +@@ -938,10 +947,10 @@ set_undef_off_zero(vector strvec, void *ptr, const char *file, int line_nr) + + if (strcmp(buff, "off") == 0) + *int_ptr = UOZ_OFF; +- else if (sscanf(buff, "%d", int_ptr) != 1 || +- *int_ptr < UOZ_ZERO) +- *int_ptr = UOZ_UNDEF; +- else if (*int_ptr == 0) ++ else ++ rc = do_set_int(strvec, int_ptr, 0, INT_MAX, file, line_nr, ++ buff); ++ if (rc == 0 && *int_ptr == 0) + *int_ptr = UOZ_ZERO; + + FREE(buff); +@@ -1093,14 +1102,12 @@ max_fds_handler(struct config *conf, vector strvec, const char *file, + /* Assume safe limit */ + max_fds = 4096; + } +- if (strlen(buff) == 3 && +- !strcmp(buff, "max")) +- conf->max_fds = max_fds; +- else +- conf->max_fds = atoi(buff); +- +- if (conf->max_fds > max_fds) ++ if (!strcmp(buff, "max")) { + conf->max_fds = max_fds; ++ r = 0; ++ } else ++ r = do_set_int(strvec, &conf->max_fds, 0, max_fds, file, ++ line_nr, buff); + + FREE(buff); + +@@ -1169,6 +1176,7 @@ declare_mp_snprint(rr_weight, print_rr_weight) + static int + set_pgfailback(vector strvec, void *ptr, const char *file, int line_nr) + { ++ int rc = 0; + int *int_ptr = (int *)ptr; + char * buff; + +@@ -1183,11 +1191,11 @@ set_pgfailback(vector strvec, void *ptr, const char *file, int line_nr) + else if (strlen(buff) == 10 && !strcmp(buff, "followover")) + *int_ptr = -FAILBACK_FOLLOWOVER; + else +- *int_ptr = atoi(buff); ++ rc = do_set_int(strvec, ptr, 0, INT_MAX, file, line_nr, buff); + + FREE(buff); + +- return 0; ++ return rc; + } + + int +@@ -1219,6 +1227,7 @@ declare_mp_snprint(pgfailback, print_pgfailback) + static int + no_path_retry_helper(vector strvec, void *ptr, const char *file, int line_nr) + { ++ int rc = 0; + int *int_ptr = (int *)ptr; + char * buff; + +@@ -1230,11 +1239,11 @@ no_path_retry_helper(vector strvec, void *ptr, const char *file, int line_nr) + *int_ptr = NO_PATH_RETRY_FAIL; + else if (!strcmp(buff, "queue")) + *int_ptr = NO_PATH_RETRY_QUEUE; +- else if ((*int_ptr = atoi(buff)) < 1) +- *int_ptr = NO_PATH_RETRY_UNDEF; ++ else ++ rc = do_set_int(strvec, ptr, 1, INT_MAX, file, line_nr, buff); + + FREE(buff); +- return 0; ++ return rc; + } + + int +@@ -1376,6 +1385,7 @@ snprint_mp_reservation_key (struct config *conf, struct strbuf *buff, + static int + set_off_int_undef(vector strvec, void *ptr, const char *file, int line_nr) + { ++ int rc =0; + int *int_ptr = (int *)ptr; + char * buff; + +@@ -1385,11 +1395,11 @@ set_off_int_undef(vector strvec, void *ptr, const char *file, int line_nr) + + if (!strcmp(buff, "no") || !strcmp(buff, "0")) + *int_ptr = NU_NO; +- else if ((*int_ptr = atoi(buff)) < 1) +- *int_ptr = NU_UNDEF; ++ else ++ rc = do_set_int(strvec, ptr, 1, INT_MAX, file, line_nr, buff); + + FREE(buff); +- return 0; ++ return rc; + } + + int diff --git a/0022-libmultipath-cleanup-invalid-config-handling.patch b/0022-libmultipath-cleanup-invalid-config-handling.patch new file mode 100644 index 0000000..fcdca11 --- /dev/null +++ b/0022-libmultipath-cleanup-invalid-config-handling.patch @@ -0,0 +1,202 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 11 Nov 2021 12:53:52 -0600 +Subject: [PATCH] libmultipath: cleanup invalid config handling + +Add error reporting to the remaining config handlers. If the value is +invalid, do not change the existing config option's value. Also print +an error whenever 0 is returned for an invalid value. When the handler +returns 1, config processing already fails with an error message. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/dict.c | 73 +++++++++++++++++++++++++++++++-------------- + 1 file changed, 51 insertions(+), 22 deletions(-) + +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index 68647061..c534d703 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -199,8 +199,11 @@ set_yes_no(vector strvec, void *ptr, const char *file, int line_nr) + + if (strcmp(buff, "yes") == 0 || strcmp(buff, "1") == 0) + *int_ptr = YN_YES; +- else ++ else if (strcmp(buff, "no") == 0 || strcmp(buff, "0") == 0) + *int_ptr = YN_NO; ++ else ++ condlog(1, "%s line %d, invalid value for %s: \"%s\"", ++ file, line_nr, (char*)VECTOR_SLOT(strvec, 0), buff); + + FREE(buff); + return 0; +@@ -221,7 +224,8 @@ set_yes_no_undef(vector strvec, void *ptr, const char *file, int line_nr) + else if (strcmp(buff, "yes") == 0 || strcmp(buff, "1") == 0) + *int_ptr = YNU_YES; + else +- *int_ptr = YNU_UNDEF; ++ condlog(1, "%s line %d, invalid value for %s: \"%s\"", ++ file, line_nr, (char*)VECTOR_SLOT(strvec, 0), buff); + + FREE(buff); + return 0; +@@ -480,9 +484,6 @@ def_find_multipaths_handler(struct config *conf, vector strvec, + char *buff; + int i; + +- if (set_yes_no_undef(strvec, &conf->find_multipaths, file, line_nr) == 0 && conf->find_multipaths != FIND_MULTIPATHS_UNDEF) +- return 0; +- + buff = set_value(strvec); + if (!buff) + return 1; +@@ -495,9 +496,14 @@ def_find_multipaths_handler(struct config *conf, vector strvec, + } + } + +- if (conf->find_multipaths == YNU_UNDEF) { +- condlog(0, "illegal value for find_multipaths: %s", buff); +- conf->find_multipaths = DEFAULT_FIND_MULTIPATHS; ++ if (i >= __FIND_MULTIPATHS_LAST) { ++ if (strcmp(buff, "no") == 0 || strcmp(buff, "0") == 0) ++ conf->find_multipaths = FIND_MULTIPATHS_OFF; ++ else if (strcmp(buff, "yes") == 0 || strcmp(buff, "1") == 0) ++ conf->find_multipaths = FIND_MULTIPATHS_ON; ++ else ++ condlog(1, "%s line %d, invalid value for find_multipaths: \"%s\"", ++ file, line_nr, buff); + } + + FREE(buff); +@@ -546,8 +552,10 @@ static int uid_attrs_handler(struct config *conf, vector strvec, + if (!val) + return 1; + if (parse_uid_attrs(val, conf)) +- condlog(1, "error parsing uid_attrs: \"%s\"", val); +- condlog(3, "parsed %d uid_attrs", VECTOR_SIZE(&conf->uid_attrs)); ++ condlog(1, "%s line %d,error parsing uid_attrs: \"%s\"", file, ++ line_nr, val); ++ else ++ condlog(4, "parsed %d uid_attrs", VECTOR_SIZE(&conf->uid_attrs)); + FREE(val); + return 0; + } +@@ -775,8 +783,11 @@ def_config_dir_handler(struct config *conf, vector strvec, const char *file, + int line_nr) + { + /* this is only valid in the main config file */ +- if (conf->processed_main_config) ++ if (conf->processed_main_config) { ++ condlog(1, "%s line %d, config_dir option only valid in /etc/multipath.conf", ++ file, line_nr); + return 0; ++ } + condlog(2, "%s line %d, \"config_dir\" is deprecated and will be disabled in a future release", + file, line_nr); + return set_path(strvec, &conf->config_dir, file, line_nr); +@@ -836,7 +847,9 @@ set_mode(vector strvec, void *ptr, int *flags, const char *file, int line_nr) + if (sscanf(buff, "%o", &mode) == 1 && mode <= 0777) { + *flags |= (1 << ATTR_MODE); + *mode_ptr = mode; +- } ++ } else ++ condlog(1, "%s line %d, invalid value for mode: \"%s\"", ++ file, line_nr, buff); + + FREE(buff); + return 0; +@@ -861,7 +874,9 @@ set_uid(vector strvec, void *ptr, int *flags, const char *file, int line_nr) + else if (sscanf(buff, "%u", &uid) == 1){ + *flags |= (1 << ATTR_UID); + *uid_ptr = uid; +- } ++ } else ++ condlog(1, "%s line %d, invalid value for uid: \"%s\"", ++ file, line_nr, buff); + + FREE(buff); + return 0; +@@ -887,7 +902,9 @@ set_gid(vector strvec, void *ptr, int *flags, const char *file, int line_nr) + else if (sscanf(buff, "%u", &gid) == 1){ + *flags |= (1 << ATTR_GID); + *gid_ptr = gid; +- } ++ } else ++ condlog(1, "%s line %d, invalid value for gid: \"%s\"", ++ file, line_nr, buff); + FREE(buff); + return 0; + } +@@ -989,7 +1006,8 @@ set_dev_loss(vector strvec, void *ptr, const char *file, int line_nr) + if (!strcmp(buff, "infinity")) + *uint_ptr = MAX_DEV_LOSS_TMO; + else if (sscanf(buff, "%u", uint_ptr) != 1) +- *uint_ptr = DEV_LOSS_TMO_UNSET; ++ condlog(1, "%s line %d, invalid value for dev_loss_tmo: \"%s\"", ++ file, line_nr, buff); + + FREE(buff); + return 0; +@@ -1023,13 +1041,19 @@ static int + set_pgpolicy(vector strvec, void *ptr, const char *file, int line_nr) + { + char * buff; ++ int policy; + int *int_ptr = (int *)ptr; + + buff = set_value(strvec); + if (!buff) + return 1; + +- *int_ptr = get_pgpolicy_id(buff); ++ policy = get_pgpolicy_id(buff); ++ if (policy != IOPOLICY_UNDEF) ++ *int_ptr = policy; ++ else ++ condlog(1, "%s line %d, invalid value for path_grouping_policy: \"%s\"", ++ file, line_nr, buff); + FREE(buff); + + return 0; +@@ -1142,10 +1166,11 @@ set_rr_weight(vector strvec, void *ptr, const char *file, int line_nr) + + if (!strcmp(buff, "priorities")) + *int_ptr = RR_WEIGHT_PRIO; +- +- if (!strcmp(buff, "uniform")) ++ else if (!strcmp(buff, "uniform")) + *int_ptr = RR_WEIGHT_NONE; +- ++ else ++ condlog(1, "%s line %d, invalid value for rr_weight: \"%s\"", ++ file, line_nr, buff); + FREE(buff); + + return 0; +@@ -1281,10 +1306,13 @@ def_log_checker_err_handler(struct config *conf, vector strvec, + if (!buff) + return 1; + +- if (strlen(buff) == 4 && !strcmp(buff, "once")) ++ if (!strcmp(buff, "once")) + conf->log_checker_err = LOG_CHKR_ERR_ONCE; +- else if (strlen(buff) == 6 && !strcmp(buff, "always")) ++ else if (!strcmp(buff, "always")) + conf->log_checker_err = LOG_CHKR_ERR_ALWAYS; ++ else ++ condlog(1, "%s line %d, invalid value for log_checker_err: \"%s\"", ++ file, line_nr, buff); + + free(buff); + return 0; +@@ -1545,7 +1573,8 @@ hw_vpd_vendor_handler(struct config *conf, vector strvec, const char *file, + goto out; + } + } +- hwe->vpd_vendor_id = 0; ++ condlog(1, "%s line %d, invalid value for vpd_vendor: \"%s\"", ++ file, line_nr, buff); + out: + FREE(buff); + return 0; diff --git a/0023-libmultipath-don-t-return-error-on-invalid-values.patch b/0023-libmultipath-don-t-return-error-on-invalid-values.patch new file mode 100644 index 0000000..2d651e2 --- /dev/null +++ b/0023-libmultipath-don-t-return-error-on-invalid-values.patch @@ -0,0 +1,219 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 11 Nov 2021 19:24:31 -0600 +Subject: [PATCH] libmultipath: don't return error on invalid values + +do_set_int and set_uint return 1 for invalid values. This can cause +multipath to fail completely, while reading the config. The config +handlers should only return a non-zero value if there is an internal +error, not if there is just an invalid value. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/dict.c | 64 ++++++++++++++++++--------------------------- + 1 file changed, 25 insertions(+), 39 deletions(-) + +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index c534d703..1b75be47 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -30,7 +30,7 @@ + #include "dict.h" + #include "strbuf.h" + +-static int ++static void + do_set_int(vector strvec, void *ptr, int min, int max, const char *file, + int line_nr, char *buff) + { +@@ -45,7 +45,7 @@ do_set_int(vector strvec, void *ptr, int min, int max, const char *file, + if (*buff == '\0' || *eptr != '\0') { + condlog(1, "%s line %d, invalid value for %s: \"%s\"", + file, line_nr, (char*)VECTOR_SLOT(strvec, 0), buff); +- return 1; ++ return; + } + if (res > max || res < min) { + res = (res > max) ? max : min; +@@ -54,7 +54,7 @@ do_set_int(vector strvec, void *ptr, int min, int max, const char *file, + (res == max)? "large" : "small", res); + } + *int_ptr = res; +- return 0; ++ return; + } + + static int +@@ -62,16 +62,15 @@ set_int(vector strvec, void *ptr, int min, int max, const char *file, + int line_nr) + { + char *buff; +- int rc; + + buff = set_value(strvec); + if (!buff) + return 1; + +- rc = do_set_int(strvec, ptr, min, max, file, line_nr, buff); ++ do_set_int(strvec, ptr, min, max, file, line_nr, buff); + + FREE(buff); +- return rc; ++ return 0; + } + + static int +@@ -80,7 +79,6 @@ set_uint(vector strvec, void *ptr, const char *file, int line_nr) + unsigned int *uint_ptr = (unsigned int *)ptr; + char *buff, *eptr, *p; + unsigned long res; +- int rc; + + buff = set_value(strvec); + if (!buff) +@@ -93,17 +91,14 @@ set_uint(vector strvec, void *ptr, const char *file, int line_nr) + if (eptr > buff) + while (isspace(*eptr)) + eptr++; +- if (*buff == '\0' || *eptr != '\0' || !isdigit(*p) || res > UINT_MAX) { ++ if (*buff == '\0' || *eptr != '\0' || !isdigit(*p) || res > UINT_MAX) + condlog(1, "%s line %d, invalid value for %s: \"%s\"", + file, line_nr, (char*)VECTOR_SLOT(strvec, 0), buff); +- rc = 1; +- } else { +- rc = 0; ++ else + *uint_ptr = res; +- } + + FREE(buff); +- return rc; ++ return 0; + } + + static int +@@ -954,7 +949,6 @@ declare_mp_attr_snprint(gid, print_gid) + static int + set_undef_off_zero(vector strvec, void *ptr, const char *file, int line_nr) + { +- int rc = 0; + char * buff; + int *int_ptr = (int *)ptr; + +@@ -964,11 +958,10 @@ set_undef_off_zero(vector strvec, void *ptr, const char *file, int line_nr) + + if (strcmp(buff, "off") == 0) + *int_ptr = UOZ_OFF; +- else +- rc = do_set_int(strvec, int_ptr, 0, INT_MAX, file, line_nr, +- buff); +- if (rc == 0 && *int_ptr == 0) ++ else if (strcmp(buff, "0") == 0) + *int_ptr = UOZ_ZERO; ++ else ++ do_set_int(strvec, int_ptr, 1, INT_MAX, file, line_nr, buff); + + FREE(buff); + return 0; +@@ -1114,28 +1107,24 @@ max_fds_handler(struct config *conf, vector strvec, const char *file, + int line_nr) + { + char * buff; +- int r = 0, max_fds; ++ int max_fds; + + buff = set_value(strvec); + + if (!buff) + return 1; + +- r = get_sys_max_fds(&max_fds); +- if (r) { +- /* Assume safe limit */ +- max_fds = 4096; +- } +- if (!strcmp(buff, "max")) { ++ if (get_sys_max_fds(&max_fds) != 0) ++ max_fds = 4096; /* Assume safe limit */ ++ if (!strcmp(buff, "max")) + conf->max_fds = max_fds; +- r = 0; +- } else +- r = do_set_int(strvec, &conf->max_fds, 0, max_fds, file, +- line_nr, buff); ++ else ++ do_set_int(strvec, &conf->max_fds, 0, max_fds, file, line_nr, ++ buff); + + FREE(buff); + +- return r; ++ return 0; + } + + static int +@@ -1201,7 +1190,6 @@ declare_mp_snprint(rr_weight, print_rr_weight) + static int + set_pgfailback(vector strvec, void *ptr, const char *file, int line_nr) + { +- int rc = 0; + int *int_ptr = (int *)ptr; + char * buff; + +@@ -1216,11 +1204,11 @@ set_pgfailback(vector strvec, void *ptr, const char *file, int line_nr) + else if (strlen(buff) == 10 && !strcmp(buff, "followover")) + *int_ptr = -FAILBACK_FOLLOWOVER; + else +- rc = do_set_int(strvec, ptr, 0, INT_MAX, file, line_nr, buff); ++ do_set_int(strvec, ptr, 0, INT_MAX, file, line_nr, buff); + + FREE(buff); + +- return rc; ++ return 0; + } + + int +@@ -1252,7 +1240,6 @@ declare_mp_snprint(pgfailback, print_pgfailback) + static int + no_path_retry_helper(vector strvec, void *ptr, const char *file, int line_nr) + { +- int rc = 0; + int *int_ptr = (int *)ptr; + char * buff; + +@@ -1265,10 +1252,10 @@ no_path_retry_helper(vector strvec, void *ptr, const char *file, int line_nr) + else if (!strcmp(buff, "queue")) + *int_ptr = NO_PATH_RETRY_QUEUE; + else +- rc = do_set_int(strvec, ptr, 1, INT_MAX, file, line_nr, buff); ++ do_set_int(strvec, ptr, 1, INT_MAX, file, line_nr, buff); + + FREE(buff); +- return rc; ++ return 0; + } + + int +@@ -1413,7 +1400,6 @@ snprint_mp_reservation_key (struct config *conf, struct strbuf *buff, + static int + set_off_int_undef(vector strvec, void *ptr, const char *file, int line_nr) + { +- int rc =0; + int *int_ptr = (int *)ptr; + char * buff; + +@@ -1424,10 +1410,10 @@ set_off_int_undef(vector strvec, void *ptr, const char *file, int line_nr) + if (!strcmp(buff, "no") || !strcmp(buff, "0")) + *int_ptr = NU_NO; + else +- rc = do_set_int(strvec, ptr, 1, INT_MAX, file, line_nr, buff); ++ do_set_int(strvec, ptr, 1, INT_MAX, file, line_nr, buff); + + FREE(buff); +- return rc; ++ return 0; + } + + int diff --git a/0024-multipathd-avoid-unnecessary-path-read-only-reloads.patch b/0024-multipathd-avoid-unnecessary-path-read-only-reloads.patch new file mode 100644 index 0000000..7bbe406 --- /dev/null +++ b/0024-multipathd-avoid-unnecessary-path-read-only-reloads.patch @@ -0,0 +1,129 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 15 Nov 2021 10:54:35 -0600 +Subject: [PATCH] multipathd: avoid unnecessary path read-only reloads + +A mulitpath device can only be reloaded read/write when all paths are +read/write. Also, whenever a read-only device is rescanned, the scsi +subsystem will first unconditionally issue a uevent with DISK_RO=0 +before checking the read-only status, and if it the device is still +read-only, issuing another uevent with DISK_RO=1. These uevents cause +pointless reloads when read-only paths are rescanned. To avoid this, +check to see if all paths are read/write before changing a multipath +device from read-only to read/write. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/libmultipath.version | 5 +++++ + libmultipath/sysfs.c | 22 ++++++++++++++++++++++ + libmultipath/sysfs.h | 1 + + multipathd/main.c | 31 ++++++++++++++++++++++++++++++- + 4 files changed, 58 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version +index eb5b5b55..dd1b4122 100644 +--- a/libmultipath/libmultipath.version ++++ b/libmultipath/libmultipath.version +@@ -287,3 +287,8 @@ global: + local: + *; + }; ++ ++LIBMULTIPATH_9.1.0 { ++global: ++ sysfs_get_ro; ++} LIBMULTIPATH_9.0.0; +diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c +index 9ff145f2..24c12b6a 100644 +--- a/libmultipath/sysfs.c ++++ b/libmultipath/sysfs.c +@@ -236,6 +236,28 @@ sysfs_get_size (struct path *pp, unsigned long long * size) + return 0; + } + ++int ++sysfs_get_ro (struct path *pp) ++{ ++ int ro; ++ char buff[3]; /* Either "0\n\0" or "1\n\0" */ ++ ++ if (!pp->udev) ++ return -1; ++ ++ if (sysfs_attr_get_value(pp->udev, "ro", buff, sizeof(buff)) <= 0) { ++ condlog(3, "%s: Cannot read ro attribute in sysfs", pp->dev); ++ return -1; ++ } ++ ++ if (sscanf(buff, "%d\n", &ro) != 1 || ro < 0 || ro > 1) { ++ condlog(3, "%s: Cannot parse ro attribute", pp->dev); ++ return -1; ++ } ++ ++ return ro; ++} ++ + int sysfs_check_holders(char * check_devt, char * new_devt) + { + unsigned int major, new_minor, table_minor; +diff --git a/libmultipath/sysfs.h b/libmultipath/sysfs.h +index 72b39ab2..c948c467 100644 +--- a/libmultipath/sysfs.h ++++ b/libmultipath/sysfs.h +@@ -13,6 +13,7 @@ ssize_t sysfs_attr_get_value(struct udev_device *dev, const char *attr_name, + ssize_t sysfs_bin_attr_get_value(struct udev_device *dev, const char *attr_name, + unsigned char * value, size_t value_len); + int sysfs_get_size (struct path *pp, unsigned long long * size); ++int sysfs_get_ro(struct path *pp); + int sysfs_check_holders(char * check_devt, char * new_devt); + bool sysfs_is_multipathed(struct path *pp, bool set_wwid); + #endif +diff --git a/multipathd/main.c b/multipathd/main.c +index 1defeaf1..6145e512 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -1324,6 +1324,35 @@ fail: + return REMOVE_PATH_MAP_ERROR; + } + ++static bool ++needs_ro_update(struct multipath *mpp, int ro) ++{ ++ struct pathgroup * pgp; ++ struct path * pp; ++ unsigned int i, j; ++ struct dm_info *dmi = NULL; ++ ++ if (!mpp || ro < 0) ++ return false; ++ dm_get_info(mpp->alias, &dmi); ++ if (!dmi) /* assume we do need to reload the device */ ++ return true; ++ if (dmi->read_only == ro) { ++ free(dmi); ++ return false; ++ } ++ free(dmi); ++ if (ro == 1) ++ return true; ++ vector_foreach_slot (mpp->pg, pgp, i) { ++ vector_foreach_slot (pgp->paths, pp, j) { ++ if (sysfs_get_ro(pp) == 1) ++ return false; ++ } ++ } ++ return true; ++} ++ + static int + uev_update_path (struct uevent *uev, struct vectors * vecs) + { +@@ -1388,7 +1417,7 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) + } + + ro = uevent_get_disk_ro(uev); +- if (mpp && ro >= 0) { ++ if (needs_ro_update(mpp, ro)) { + condlog(2, "%s: update path write_protect to '%d' (uevent)", uev->kernel, ro); + + if (mpp->wait_for_udev) diff --git a/0013-RH-fixup-udev-rules-for-redhat.patch b/0025-RH-fixup-udev-rules-for-redhat.patch similarity index 100% rename from 0013-RH-fixup-udev-rules-for-redhat.patch rename to 0025-RH-fixup-udev-rules-for-redhat.patch diff --git a/0014-RH-Remove-the-property-blacklist-exception-builtin.patch b/0026-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 96% rename from 0014-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0026-RH-Remove-the-property-blacklist-exception-builtin.patch index c1cdc10..3bb4786 100644 --- a/0014-RH-Remove-the-property-blacklist-exception-builtin.patch +++ b/0026-RH-Remove-the-property-blacklist-exception-builtin.patch @@ -43,10 +43,10 @@ index 4e315c97..1e463ef6 100644 udev_device_get_properties_list_entry(udev)) { diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index c74129bd..dd9f4dc7 100644 +index 88d2a1df..7f85f766 100644 --- a/multipath/multipath.conf.5 +++ b/multipath/multipath.conf.5 -@@ -1351,9 +1351,14 @@ keywords. Both are regular expressions. For a full description of these keywords +@@ -1356,9 +1356,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, @@ -62,7 +62,7 @@ index c74129bd..dd9f4dc7 100644 . .RS .PP -@@ -1364,10 +1369,6 @@ Blacklisting by missing properties is only applied to devices which do have the +@@ -1369,10 +1374,6 @@ Blacklisting by missing properties is only applied to devices which do have the property specified by \fIuid_attribute\fR (e.g. \fIID_SERIAL\fR) set. Previously, it was applied to every device, possibly causing devices to be blacklisted because of temporary I/O error conditions. diff --git a/0015-RH-don-t-start-without-a-config-file.patch b/0027-RH-don-t-start-without-a-config-file.patch similarity index 100% rename from 0015-RH-don-t-start-without-a-config-file.patch rename to 0027-RH-don-t-start-without-a-config-file.patch diff --git a/0016-RH-Fix-nvme-function-missing-argument.patch b/0028-RH-Fix-nvme-function-missing-argument.patch similarity index 100% rename from 0016-RH-Fix-nvme-function-missing-argument.patch rename to 0028-RH-Fix-nvme-function-missing-argument.patch diff --git a/0017-RH-use-rpm-optflags-if-present.patch b/0029-RH-use-rpm-optflags-if-present.patch similarity index 82% rename from 0017-RH-use-rpm-optflags-if-present.patch rename to 0029-RH-use-rpm-optflags-if-present.patch index 303ad0d..a1c081c 100644 --- a/0017-RH-use-rpm-optflags-if-present.patch +++ b/0029-RH-use-rpm-optflags-if-present.patch @@ -9,14 +9,14 @@ still being generic. Signed-off-by: Benjamin Marzinski --- - Makefile.inc | 24 ++++++++++++++++++------ - 1 file changed, 18 insertions(+), 6 deletions(-) + Makefile.inc | 26 +++++++++++++++++++------- + 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 2a75dc9c..db35feb6 100644 +index 2a75dc9c..5ac660de 100644 --- a/Makefile.inc +++ b/Makefile.inc -@@ -92,16 +92,28 @@ TEST_CC_OPTION = $(shell \ +@@ -92,23 +92,35 @@ TEST_CC_OPTION = $(shell \ echo "$(2)"; \ fi) @@ -50,6 +50,14 @@ index 2a75dc9c..db35feb6 100644 CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ -DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" \ -MMD -MP + BIN_CFLAGS = -fPIE -DPIE + LIB_CFLAGS = -fPIC + SHARED_FLAGS = -shared +-LDFLAGS := $(LDFLAGS) -Wl,-z,relro -Wl,-z,now -Wl,-z,defs ++LDFLAGS := $(LDFLAGS) $(RPM_LD_FLAGS) -Wl,-z,relro -Wl,-z,now -Wl,-z,defs + BIN_LDFLAGS = -pie + + # Check whether a function with name $1 has been declared in header file $2. @@ -139,4 +151,4 @@ check_file = $(shell \ %.o: %.c diff --git a/0018-RH-add-mpathconf.patch b/0030-RH-add-mpathconf.patch similarity index 98% rename from 0018-RH-add-mpathconf.patch rename to 0030-RH-add-mpathconf.patch index 7fb97f6..f7bbecb 100644 --- a/0018-RH-add-mpathconf.patch +++ b/0030-RH-add-mpathconf.patch @@ -14,9 +14,9 @@ Signed-off-by: Benjamin Marzinski --- libmultipath/config.c | 2 + multipath/Makefile | 5 + - multipath/mpathconf | 561 ++++++++++++++++++++++++++++++++++++++++++ + multipath/mpathconf | 556 ++++++++++++++++++++++++++++++++++++++++++ multipath/mpathconf.8 | 135 ++++++++++ - 4 files changed, 703 insertions(+) + 4 files changed, 698 insertions(+) create mode 100644 multipath/mpathconf create mode 100644 multipath/mpathconf.8 @@ -69,10 +69,10 @@ index b9bbb3cf..e720c7f6 100644 $(RM) core *.o $(EXEC) *.gz diff --git a/multipath/mpathconf b/multipath/mpathconf new file mode 100644 -index 00000000..039b3e47 +index 00000000..c00d2555 --- /dev/null +++ b/multipath/mpathconf -@@ -0,0 +1,561 @@ +@@ -0,0 +1,556 @@ +#!/bin/bash +# +# Copyright (C) 2010 Red Hat, Inc. All rights reserved. @@ -107,11 +107,6 @@ index 00000000..039b3e47 +defaults { + user_friendly_names yes + find_multipaths yes -+ enable_foreign \"^$\" -+} -+ -+blacklist_exceptions { -+ property \"(SCSI_IDENT_|ID_WWN)\" +}" + +CONFIGFILE="/etc/multipath.conf" @@ -130,7 +125,7 @@ index 00000000..039b3e47 + echo "Only allow certain wwids (instead of enable): --allow " + echo "Set user_friendly_names (Default y): --user_friendly_names " + echo "Set find_multipaths (Default y): --find_multipaths " -+ echo "Set default property blacklist (Default y): --property_blacklist " ++ echo "Set default property blacklist (Default n): --property_blacklist " + echo "Set enable_foreign to show foreign devices (Default n): --enable_foreign " + echo "Load the dm-multipath modules on enable (Default y): --with_module " + echo "start/stop/reload multipathd (Default n): --with_multipathd " diff --git a/0019-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0031-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 97% rename from 0019-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0031-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch index 055eeb6..3ce47ac 100644 --- a/0019-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +++ b/0031-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch @@ -20,7 +20,7 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/multipath/main.c b/multipath/main.c -index 65ece830..748e7902 100644 +index b2d300e5..80fa68e5 100644 --- a/multipath/main.c +++ b/multipath/main.c @@ -122,7 +122,7 @@ usage (char * progname) @@ -92,7 +92,7 @@ index 65ece830..748e7902 100644 static int configure (struct config *conf, enum mpath_cmds cmd, enum devtypes dev_type, char *devpath) -@@ -838,7 +884,7 @@ main (int argc, char *argv[]) +@@ -839,7 +885,7 @@ main (int argc, char *argv[]) conf->retrigger_tries = 0; conf->force_sync = 1; atexit(cleanup_vecs); @@ -101,7 +101,7 @@ index 65ece830..748e7902 100644 switch(arg) { case 1: printf("optarg : %s\n",optarg); break; -@@ -915,6 +961,10 @@ main (int argc, char *argv[]) +@@ -916,6 +962,10 @@ main (int argc, char *argv[]) case 'T': cmd = CMD_DUMP_CONFIG; break; diff --git a/0020-RH-reset-default-find_mutipaths-value-to-off.patch b/0032-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 100% rename from 0020-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0032-RH-reset-default-find_mutipaths-value-to-off.patch diff --git a/0021-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0033-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 100% rename from 0021-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0033-RH-attempt-to-get-ANA-info-via-sysfs-first.patch diff --git a/0022-RH-make-parse_vpd_pg83-match-scsi_id-output.patch b/0034-RH-make-parse_vpd_pg83-match-scsi_id-output.patch similarity index 50% rename from 0022-RH-make-parse_vpd_pg83-match-scsi_id-output.patch rename to 0034-RH-make-parse_vpd_pg83-match-scsi_id-output.patch index 789af0d..1d10c09 100644 --- a/0022-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +++ b/0034-RH-make-parse_vpd_pg83-match-scsi_id-output.patch @@ -10,7 +10,8 @@ that. Signed-off-by: Benjamin Marzinski --- libmultipath/discovery.c | 18 ++---------------- - 1 file changed, 2 insertions(+), 16 deletions(-) + tests/vpd.c | 6 ++++++ + 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c index f25fe9e3..6fb81c28 100644 @@ -49,3 +50,53 @@ index f25fe9e3..6fb81c28 100644 case 0x1: /* T-10 Vendor ID: Prio 2 */ if (prio < 2) { +diff --git a/tests/vpd.c b/tests/vpd.c +index 8e730d37..7bf7990f 100644 +--- a/tests/vpd.c ++++ b/tests/vpd.c +@@ -230,11 +230,13 @@ static const char * const str_prefix[] = { + [STR_IQN] = "iqn.", + }; + ++#if 0 + static const char byte0[] = { + [STR_EUI] = '2', + [STR_NAA] = '3', + [STR_IQN] = '8', + }; ++#endif + + /** + * create_scsi_string_desc() - create a SCSI name string descriptor. +@@ -659,6 +661,7 @@ make_test_vpd_naa(2, 18); + make_test_vpd_naa(2, 17); + make_test_vpd_naa(2, 16); + ++#if 0 + /* SCSI Name string: EUI64, WWID size: 17 */ + make_test_vpd_str(0, 20, 18) + make_test_vpd_str(0, 20, 17) +@@ -694,6 +697,7 @@ make_test_vpd_str(18, 20, 18) + make_test_vpd_str(18, 20, 17) + make_test_vpd_str(18, 20, 16) + make_test_vpd_str(18, 20, 15) ++#endif + + static int test_vpd(void) + { +@@ -767,6 +771,7 @@ static int test_vpd(void) + cmocka_unit_test(test_vpd_naa_2_18), + cmocka_unit_test(test_vpd_naa_2_17), + cmocka_unit_test(test_vpd_naa_2_16), ++/* + cmocka_unit_test(test_vpd_str_0_20_18), + cmocka_unit_test(test_vpd_str_0_20_17), + cmocka_unit_test(test_vpd_str_0_20_16), +@@ -791,6 +796,7 @@ static int test_vpd(void) + cmocka_unit_test(test_vpd_str_18_20_17), + cmocka_unit_test(test_vpd_str_18_20_16), + cmocka_unit_test(test_vpd_str_18_20_15), ++*/ + }; + return cmocka_run_group_tests(tests, setup, teardown); + } diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 3a0813a..5d804e2 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.8.7 -Release: 3%{?dist} +Release: 4%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -22,16 +22,28 @@ Patch0009: 0009-multipath-tools-make-COMPELNT-Compellent-Vol-config-.patch Patch0010: 0010-multipath-tools-remove-Compellent-maintainer.patch Patch0011: 0011-Revert-multipath-tools-make-EMC-Invista-config-work-.patch Patch0012: 0012-Revert-multipath-tools-make-EMC-SYMMETRIX-config-wor.patch -Patch0013: 0013-RH-fixup-udev-rules-for-redhat.patch -Patch0014: 0014-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0015: 0015-RH-don-t-start-without-a-config-file.patch -Patch0016: 0016-RH-Fix-nvme-function-missing-argument.patch -Patch0017: 0017-RH-use-rpm-optflags-if-present.patch -Patch0018: 0018-RH-add-mpathconf.patch -Patch0019: 0019-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0020: 0020-RH-reset-default-find_mutipaths-value-to-off.patch -Patch0021: 0021-RH-attempt-to-get-ANA-info-via-sysfs-first.patch -Patch0022: 0022-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +Patch0013: 0013-multipath-fix-exit-status-of-multipath-T.patch +Patch0014: 0014-libmultipath-add-section-name-to-invalid-keyword-out.patch +Patch0015: 0015-libmultipath-use-typedef-for-keyword-handler-functio.patch +Patch0016: 0016-libmultipath-print-the-correct-file-when-parsing-fai.patch +Patch0017: 0017-libmultipath-pass-file-and-line-number-to-keyword-ha.patch +Patch0018: 0018-libmultipath-make-set_int-take-a-range-for-valid-val.patch +Patch0019: 0019-libmultipath-improve-checks-for-set_str.patch +Patch0020: 0020-libmultipath-deprecate-file-and-directory-config-opt.patch +Patch0021: 0021-libmultipath-split-set_int-to-enable-reuse.patch +Patch0022: 0022-libmultipath-cleanup-invalid-config-handling.patch +Patch0023: 0023-libmultipath-don-t-return-error-on-invalid-values.patch +Patch0024: 0024-multipathd-avoid-unnecessary-path-read-only-reloads.patch +Patch0025: 0025-RH-fixup-udev-rules-for-redhat.patch +Patch0026: 0026-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0027: 0027-RH-don-t-start-without-a-config-file.patch +Patch0028: 0028-RH-Fix-nvme-function-missing-argument.patch +Patch0029: 0029-RH-use-rpm-optflags-if-present.patch +Patch0030: 0030-RH-add-mpathconf.patch +Patch0031: 0031-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0032: 0032-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0033: 0033-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0034: 0034-RH-make-parse_vpd_pg83-match-scsi_id-output.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -229,6 +241,12 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Mon Dec 13 2021 Benjamin Marzinski - 0.8.7-4 +- Update to the head of the upstream staging branch + * Patches 0013 - 0024 are from the upstream staging branch +- Rename redhat patches + * Previous patches 0013-0022 are now patches 0025-0034 + * Thu Oct 28 2021 Benjamin Marzinski - 0.8.7-3 - Update to the head of the upstream staging branch * Patches 0011 & 0012 are from the upstream staging branch From 81ff4f74fa44a86da69e743637f4d0bee213e469 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 6 Jan 2022 18:55:09 -0600 Subject: [PATCH 27/67] device-mapper-multipath-0.8.7-5 Modify 0030-RH-add-mpathconf.patch * fix setting property_blacklist with no blacklist_exceptions section --- 0030-RH-add-mpathconf.patch | 18 +++++++++++++----- device-mapper-multipath.spec | 6 +++++- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/0030-RH-add-mpathconf.patch b/0030-RH-add-mpathconf.patch index f7bbecb..aaa4150 100644 --- a/0030-RH-add-mpathconf.patch +++ b/0030-RH-add-mpathconf.patch @@ -14,9 +14,9 @@ Signed-off-by: Benjamin Marzinski --- libmultipath/config.c | 2 + multipath/Makefile | 5 + - multipath/mpathconf | 556 ++++++++++++++++++++++++++++++++++++++++++ + multipath/mpathconf | 564 ++++++++++++++++++++++++++++++++++++++++++ multipath/mpathconf.8 | 135 ++++++++++ - 4 files changed, 698 insertions(+) + 4 files changed, 706 insertions(+) create mode 100644 multipath/mpathconf create mode 100644 multipath/mpathconf.8 @@ -69,10 +69,10 @@ index b9bbb3cf..e720c7f6 100644 $(RM) core *.o $(EXEC) *.gz diff --git a/multipath/mpathconf b/multipath/mpathconf new file mode 100644 -index 00000000..c00d2555 +index 00000000..0de6b121 --- /dev/null +++ b/multipath/mpathconf -@@ -0,0 +1,556 @@ +@@ -0,0 +1,564 @@ +#!/bin/bash +# +# Copyright (C) 2010 Red Hat, Inc. All rights reserved. @@ -571,7 +571,15 @@ index 00000000..c00d2555 + CHANGED_CONFIG=1 + fi +elif [ "$PROPERTY" = "y" ]; then -+ if [ -z "$HAVE_PROPERTY" ]; then ++ if [ -z "$HAVE_PROPERTY" -a -z "$HAVE_EXCEPTIONS" ]; then ++ cat >> $TMPFILE << _EOF_ ++ ++blacklist_exceptions { ++ property "(SCSI_IDENT_|ID_WWN)" ++} ++_EOF_ ++ CHANGED_CONFIG=1 ++ elif [ -z "$HAVE_PROPERTY" ]; then + sed -i '/^blacklist_exceptions[[:space:]]*{/ a\ + property "(SCSI_IDENT_|ID_WWN)" +' $TMPFILE diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 5d804e2..8fdacee 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.8.7 -Release: 4%{?dist} +Release: 5%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -241,6 +241,10 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Thu Jan 6 2022 Benjamin Marzinski - 0.8.7-5 +- Modify 0030-RH-add-mpathconf.patch + * fix setting property_blacklist with no blacklist_exceptions section + * Mon Dec 13 2021 Benjamin Marzinski - 0.8.7-4 - Update to the head of the upstream staging branch * Patches 0013 - 0024 are from the upstream staging branch From 06885ec9cccc647a0bf00efe0c7d4c553152130e Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 20 Jan 2022 00:33:34 +0000 Subject: [PATCH 28/67] - Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- device-mapper-multipath.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 8fdacee..d2fe5d3 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.8.7 -Release: 5%{?dist} +Release: 6%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -241,6 +241,9 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Thu Jan 20 2022 Fedora Release Engineering - 0.8.7-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild + * Thu Jan 6 2022 Benjamin Marzinski - 0.8.7-5 - Modify 0030-RH-add-mpathconf.patch * fix setting property_blacklist with no blacklist_exceptions section From 3121417f062d392daf54d726171efdde420e64d6 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Wed, 26 Jan 2022 13:59:40 -0600 Subject: [PATCH 29/67] device-mapper-multipath-0.8.7-7 Add 0035-libmultipath-use-asprintf-to-allocate-prefixed_uuid.patch Resolves: bz #2045309 --- ...e-asprintf-to-allocate-prefixed_uuid.patch | 59 +++++++++++++++++++ device-mapper-multipath.spec | 7 ++- 2 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 0035-libmultipath-use-asprintf-to-allocate-prefixed_uuid.patch diff --git a/0035-libmultipath-use-asprintf-to-allocate-prefixed_uuid.patch b/0035-libmultipath-use-asprintf-to-allocate-prefixed_uuid.patch new file mode 100644 index 0000000..6e60d4a --- /dev/null +++ b/0035-libmultipath-use-asprintf-to-allocate-prefixed_uuid.patch @@ -0,0 +1,59 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 25 Jan 2022 23:02:33 -0600 +Subject: [PATCH] libmultipath: use asprintf() to allocate prefixed_uuid + +gcc 12.0.1 failed building libmultipath due to a format-overflow false +positive on 32-bit architectures. This isn't so surprising as +format-overflow=2 is very aggressive in the assumptions it makes about +the arguments. Here, it assumes that mpp->wwid could take up all the +space that a pointer could point to, even if I add code to this function +to explicitly null terminate mpp->wwid to fit in WWID_SIZE. + +To avoid this and simplify the function, switch from using calloc() and +sprintf() to just using asprintf(). + +For reference, the gcc build error that this fixes is: + +devmapper.c: In function 'dm_addmap.constprop.0': +devmapper.h:27:21: error: '%s' directive writing up to 2147483644 bytes into a region of size 2147483641 [-Werror=format-overflow=] + 27 | #define UUID_PREFIX "mpath-" + | ^~~~~~~~ +devmapper.c:484:53: note: format string is defined here + 484 | sprintf(prefixed_uuid, UUID_PREFIX "%s", mpp->wwid); + | ^~ + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/devmapper.c | 7 ++----- + 1 file changed, 2 insertions(+), 5 deletions(-) + +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index c05dc201..bae07125 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -474,14 +474,11 @@ dm_addmap (int task, const char *target, struct multipath *mpp, + dm_task_set_ro(dmt); + + if (task == DM_DEVICE_CREATE) { +- prefixed_uuid = MALLOC(UUID_PREFIX_LEN + +- strlen(mpp->wwid) + 1); +- if (!prefixed_uuid) { ++ if (asprintf(&prefixed_uuid, UUID_PREFIX "%s", mpp->wwid) < 0) { + condlog(0, "cannot create prefixed uuid : %s", + strerror(errno)); + goto addout; + } +- sprintf(prefixed_uuid, UUID_PREFIX "%s", mpp->wwid); + if (!dm_task_set_uuid(dmt, prefixed_uuid)) + goto freeout; + dm_task_skip_lockfs(dmt); +@@ -517,7 +514,7 @@ dm_addmap (int task, const char *target, struct multipath *mpp, + libmp_udev_wait(cookie); + freeout: + if (prefixed_uuid) +- FREE(prefixed_uuid); ++ free(prefixed_uuid); + + addout: + dm_task_destroy (dmt); diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index d2fe5d3..f8d3470 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.8.7 -Release: 6%{?dist} +Release: 7%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -44,6 +44,7 @@ Patch0031: 0031-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch Patch0032: 0032-RH-reset-default-find_mutipaths-value-to-off.patch Patch0033: 0033-RH-attempt-to-get-ANA-info-via-sysfs-first.patch Patch0034: 0034-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +Patch0035: 0035-libmultipath-use-asprintf-to-allocate-prefixed_uuid.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -241,6 +242,10 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Wed Jan 26 2022 Benjamin Marzinski - 0.8.7-7 +- Add 0035-libmultipath-use-asprintf-to-allocate-prefixed_uuid.patch +- Resolves: bz #2045309 + * Thu Jan 20 2022 Fedora Release Engineering - 0.8.7-6 - Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild From 05385b92f8ad7b0b48998de861df7521db0ee8aa Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Mon, 7 Feb 2022 14:02:45 -0600 Subject: [PATCH 30/67] device-mapper-multipath-0.8.7-8 Add 0036-RH-add-support-to-mpathconf-for-setting-arbitrary-de.patch * add the ability for mpathconf to set arbitray options with --option Add 0037-RH-add-support-to-mpathconf-for-setting-recheck_wwid.patch * add --recheck_wwid option to mpathconf --- ...o-mpathconf-for-setting-arbitrary-de.patch | 149 +++++++++++++++++ ...o-mpathconf-for-setting-recheck_wwid.patch | 154 ++++++++++++++++++ device-mapper-multipath.spec | 10 +- 3 files changed, 312 insertions(+), 1 deletion(-) create mode 100644 0036-RH-add-support-to-mpathconf-for-setting-arbitrary-de.patch create mode 100644 0037-RH-add-support-to-mpathconf-for-setting-recheck_wwid.patch diff --git a/0036-RH-add-support-to-mpathconf-for-setting-arbitrary-de.patch b/0036-RH-add-support-to-mpathconf-for-setting-arbitrary-de.patch new file mode 100644 index 0000000..dff41f8 --- /dev/null +++ b/0036-RH-add-support-to-mpathconf-for-setting-arbitrary-de.patch @@ -0,0 +1,149 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 2 Feb 2022 17:00:21 -0600 +Subject: [PATCH] RH: add support to mpathconf for setting arbitrary default + options + +mpathconf now supports --option :[] for setting, changing, +or removing options from the defaults section of multipath.conf. + +Signed-off-by: Benjamin Marzinski +--- + multipath/mpathconf | 58 ++++++++++++++++++++++++++++++++++++++++--- + multipath/mpathconf.8 | 7 ++++++ + 2 files changed, 62 insertions(+), 3 deletions(-) + +diff --git a/multipath/mpathconf b/multipath/mpathconf +index 0de6b121..6e33fb99 100644 +--- a/multipath/mpathconf ++++ b/multipath/mpathconf +@@ -17,7 +17,7 @@ + # This program was largely ripped off from lvmconf + # + +-unset ENABLE FIND FRIENDLY PROPERTY FOREIGN MODULE MULTIPATHD HAVE_DISABLE HAVE_WWID_DISABLE HAVE_FIND HAVE_BLACKLIST HAVE_EXCEPTIONS HAVE_DEFAULTS HAVE_FRIENDLY HAVE_PROPERTY HAVE_FOREIGN HAVE_MULTIPATHD HAVE_MODULE HAVE_OUTFILE SHOW_STATUS CHANGED_CONFIG WWID_LIST ++unset ENABLE FIND FRIENDLY PROPERTY FOREIGN MODULE MULTIPATHD HAVE_DISABLE HAVE_WWID_DISABLE HAVE_FIND HAVE_BLACKLIST HAVE_EXCEPTIONS HAVE_DEFAULTS HAVE_FRIENDLY HAVE_PROPERTY HAVE_FOREIGN HAVE_MULTIPATHD HAVE_MODULE HAVE_OUTFILE SHOW_STATUS CHANGED_CONFIG WWID_LIST HAVE_OPTION OPTION_NAME OPTION_VALUE + + DEFAULT_CONFIG="# device-mapper-multipath configuration file + +@@ -52,6 +52,7 @@ function usage + echo "Set find_multipaths (Default y): --find_multipaths " + echo "Set default property blacklist (Default n): --property_blacklist " + echo "Set enable_foreign to show foreign devices (Default n): --enable_foreign " ++ echo "Add/Change/Remove option in defaults section: --option :" + echo "Load the dm-multipath modules on enable (Default y): --with_module " + echo "start/stop/reload multipathd (Default n): --with_multipathd " + echo "select output file (Default /etc/multipath.conf): --outfile " +@@ -162,6 +163,20 @@ function parse_args + exit 1 + fi + ;; ++ --option) ++ if [ -n "$2" ]; then ++ OPTION_NAME=$(echo $2 | cut -s -f1 -d:) ++ OPTION_VALUE=$(echo $2 | cut -s -f2 -d:) ++ if [ -z "$OPTION_NAME" ]; then ++ usage ++ exit 1 ++ fi ++ shift 2 ++ else ++ usage ++ exit 1 ++ fi ++ ;; + --enable_foreign) + if [ -n "$2" ]; then + FOREIGN=$2 +@@ -208,12 +223,15 @@ function parse_args + + function validate_args + { +- if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$PROPERTY" -o -n "$MODULE" ]; then ++ if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$PROPERTY" -o -n "$MODULE" -o -n "$FOREIGN" -o -n "$OPTION_NAME" ]; then + echo "ignoring extra parameters on disable" + FRIENDLY="" + FIND="" + PROPERTY="" + MODULE="" ++ FOREIGN="" ++ OPTION_NAME="" ++ OPTION_VALUE="" + fi + if [ -n "$FRIENDLY" ] && [ "$FRIENDLY" != "y" -a "$FRIENDLY" != "n" ]; then + echo "--user_friendly_names must be either 'y' or 'n'" +@@ -235,7 +253,19 @@ function validate_args + echo "--enable_foreign must be either 'y' or 'n'" + exit 1 + fi +- if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" -a -z "$PROPERTY" -a -z "$FOREIGN" ]; then ++ if [ -n "$OPTION_NAME" ]; then ++ if [[ $OPTION_NAME =~ [[:space:]]|#|\"|!|\{|\} ]]; then ++ echo "--option name \"$OPTION_NAME\" is invalid" ++ exit 1 ++ elif [[ $OPTION_VALUE =~ \"|#|!|\{|\} ]]; then ++ echo "--option value \"$OPTION_VALUE\" is invalid" ++ exit 1 ++ fi ++ if [[ $OPTION_VALUE =~ [[:space:]] ]]; then ++ OPTION_VALUE=\"$OPTION_VALUE\" ++ fi ++ fi ++ if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" -a -z "$PROPERTY" -a -z "$FOREIGN" -a -z "$OPTION_NAME" ]; then + SHOW_STATUS=1 + fi + if [ -n "$MODULE" ] && [ "$MODULE" != "y" -a "$MODULE" != "n" ]; then +@@ -348,6 +378,13 @@ if [ "$HAVE_DEFAULTS" = "1" ]; then + elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign" ; then + HAVE_FOREIGN=3 + fi ++ if [ -n "$OPTION_NAME" ]; then ++ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q '^[[:space:]]*'"$OPTION_NAME"'[[:space:]][[:space:]]*'"$OPTION_VALUE" ; then ++ HAVE_OPTION=1 ++ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q '^[[:space:]]*'"$OPTION_NAME"'\([[:space:]].*\)\?$' ; then ++ HAVE_OPTION=0 ++ fi ++ fi + fi + + if [ "$HAVE_EXCEPTIONS" = "1" ]; then +@@ -532,6 +569,21 @@ elif [ "$FOREIGN" = "y" ]; then + fi + fi + ++if [ -n "$OPTION_NAME" -a -n "$OPTION_VALUE" ]; then ++ if [ -z "$HAVE_OPTION" ]; then ++ sed -i '/^defaults[[:space:]]*{/ a\ ++ '"$OPTION_NAME"' '"$OPTION_VALUE"' ++' $TMPFILE ++ CHANGED_CONFIG=1 ++ elif [ "$HAVE_OPTION" = 0 ]; then ++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*'"$OPTION_NAME"'\([[:space:]].*\)\?$/ '"$OPTION_NAME"' '"$OPTION_VALUE"'/' $TMPFILE ++ CHANGED_CONFIG=1 ++ fi ++elif [ -n "$OPTION_NAME" -a -n "$HAVE_OPTION" ]; then ++ sed -i '/^defaults[[:space:]]*{/,/^}/{/^[[:space:]]*'"$OPTION_NAME"'\([[:space:]].*\)\?$/d}' $TMPFILE ++ CHANGED_CONFIG=1 ++fi ++ + if [ -f "$OUTPUTFILE" ]; then + cp $OUTPUTFILE $OUTPUTFILE.old + if [ $? != 0 ]; then +diff --git a/multipath/mpathconf.8 b/multipath/mpathconf.8 +index a14d831e..496383b7 100644 +--- a/multipath/mpathconf.8 ++++ b/multipath/mpathconf.8 +@@ -101,6 +101,13 @@ to the + defaults section. if set to \fBn\fP, this removes the line, if present. This + command can be used along with any other command. + .TP ++.B --option \fB:[]\fP ++Sets the defaults section option \fB\fP to \fB\fP. If the ++option was not previously set in the defaults section, it is added. If it was ++set, its value is changed to \fB\fP. If \fB\fP is left blank, ++then the option is removed from the defaults section, if was set there. This ++command can be used along with any other command. ++.TP + .B --outfile \fB\fP + Write the resulting multipath configuration to \fB\fP instead of + \fB/etc/multipath.conf\fP. diff --git a/0037-RH-add-support-to-mpathconf-for-setting-recheck_wwid.patch b/0037-RH-add-support-to-mpathconf-for-setting-recheck_wwid.patch new file mode 100644 index 0000000..5330d38 --- /dev/null +++ b/0037-RH-add-support-to-mpathconf-for-setting-recheck_wwid.patch @@ -0,0 +1,154 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 3 Feb 2022 13:26:18 -0600 +Subject: [PATCH] RH: add support to mpathconf for setting recheck_wwid + +mpathconf now supports --recheck_wwid for setthing the +recheck_wwid option + +Signed-off-by: Benjamin Marzinski +--- + multipath/mpathconf | 48 ++++++++++++++++++++++++++++++++++++++++--- + multipath/mpathconf.8 | 9 ++++++++ + 2 files changed, 54 insertions(+), 3 deletions(-) + +diff --git a/multipath/mpathconf b/multipath/mpathconf +index 6e33fb99..319664b1 100644 +--- a/multipath/mpathconf ++++ b/multipath/mpathconf +@@ -17,7 +17,7 @@ + # This program was largely ripped off from lvmconf + # + +-unset ENABLE FIND FRIENDLY PROPERTY FOREIGN MODULE MULTIPATHD HAVE_DISABLE HAVE_WWID_DISABLE HAVE_FIND HAVE_BLACKLIST HAVE_EXCEPTIONS HAVE_DEFAULTS HAVE_FRIENDLY HAVE_PROPERTY HAVE_FOREIGN HAVE_MULTIPATHD HAVE_MODULE HAVE_OUTFILE SHOW_STATUS CHANGED_CONFIG WWID_LIST HAVE_OPTION OPTION_NAME OPTION_VALUE ++unset ENABLE FIND FRIENDLY PROPERTY FOREIGN MODULE MULTIPATHD HAVE_DISABLE HAVE_WWID_DISABLE HAVE_FIND HAVE_BLACKLIST HAVE_EXCEPTIONS HAVE_DEFAULTS HAVE_FRIENDLY HAVE_PROPERTY HAVE_FOREIGN HAVE_MULTIPATHD HAVE_MODULE HAVE_OUTFILE SHOW_STATUS CHANGED_CONFIG WWID_LIST HAVE_OPTION OPTION_NAME OPTION_VALUE HAVE_RECHECK_WWID RECHECK_WWID + + DEFAULT_CONFIG="# device-mapper-multipath configuration file + +@@ -52,6 +52,7 @@ function usage + echo "Set find_multipaths (Default y): --find_multipaths " + echo "Set default property blacklist (Default n): --property_blacklist " + echo "Set enable_foreign to show foreign devices (Default n): --enable_foreign " ++ echo "Set recheck_wwid (Defaut n): --recheck_wwid " + echo "Add/Change/Remove option in defaults section: --option :" + echo "Load the dm-multipath modules on enable (Default y): --with_module " + echo "start/stop/reload multipathd (Default n): --with_multipathd " +@@ -145,6 +146,15 @@ function parse_args + exit 1 + fi + ;; ++ --recheck_wwid) ++ if [ -n "$2" ]; then ++ RECHECK_WWID=$2 ++ shift 2 ++ else ++ usage ++ exit 1 ++ fi ++ ;; + --find_multipaths) + if [ -n "$2" ]; then + FIND=$2 +@@ -223,7 +233,7 @@ function parse_args + + function validate_args + { +- if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$PROPERTY" -o -n "$MODULE" -o -n "$FOREIGN" -o -n "$OPTION_NAME" ]; then ++ if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$PROPERTY" -o -n "$MODULE" -o -n "$FOREIGN" -o -n "$OPTION_NAME" -o -n "$RECHECK_WWID" ]; then + echo "ignoring extra parameters on disable" + FRIENDLY="" + FIND="" +@@ -232,11 +242,16 @@ function validate_args + FOREIGN="" + OPTION_NAME="" + OPTION_VALUE="" ++ RECHECK_WWID="" + fi + if [ -n "$FRIENDLY" ] && [ "$FRIENDLY" != "y" -a "$FRIENDLY" != "n" ]; then + echo "--user_friendly_names must be either 'y' or 'n'" + exit 1 + fi ++ if [ -n "$RECHECK_WWID" ] && [ "$RECHECK_WWID" != "y" -a "$RECHECK_WWID" != "n" ]; then ++ echo "--recheck_wwid must be either 'y' or 'n'" ++ exit 1 ++ fi + if [ "$FIND" = "y" ]; then + FIND="yes" + elif [ "$FIND" = "n" ]; then +@@ -265,7 +280,7 @@ function validate_args + OPTION_VALUE=\"$OPTION_VALUE\" + fi + fi +- if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" -a -z "$PROPERTY" -a -z "$FOREIGN" -a -z "$OPTION_NAME" ]; then ++ if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" -a -z "$PROPERTY" -a -z "$FOREIGN" -a -z "$OPTION_NAME" -a -z "$RECHECK_WWID" ]; then + SHOW_STATUS=1 + fi + if [ -n "$MODULE" ] && [ "$MODULE" != "y" -a "$MODULE" != "n" ]; then +@@ -367,6 +382,11 @@ if [ "$HAVE_DEFAULTS" = "1" ]; then + elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]][[:space:]]*\(no\|0\)" ; then + HAVE_FRIENDLY=0 + fi ++ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*recheck_wwid[[:space:]][[:space:]]*\(yes\|1\)" ; then ++ HAVE_RECHECK_WWID=1 ++ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*recheck_wwid[[:space:]][[:space:]]*\(no\|0\)" ; then ++ HAVE_RECHECK_WWID=0 ++ fi + if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*enable_foreign" ; then + HAVE_FOREIGN=0 + elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]][[:space:]]*\"\.\*\"" ; then +@@ -411,6 +431,11 @@ if [ -n "$SHOW_STATUS" ]; then + else + echo "user_friendly_names is enabled" + fi ++ if [ -z "$HAVE_RECHECK_WWID" -o "$HAVE_RECHECK_WWID" = 0 ]; then ++ echo "recheck_wwid is disabled" ++ else ++ echo "recheck_wwid is enabled" ++ fi + if [ -z "$HAVE_PROPERTY" -o "$HAVE_PROPERTY" = 0 ]; then + echo "default property blacklist is disabled" + else +@@ -527,6 +552,23 @@ elif [ "$FRIENDLY" = "y" ]; then + fi + fi + ++if [ "$RECHECK_WWID" = "n" ]; then ++ if [ "$HAVE_RECHECK_WWID" = 1 ]; then ++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*recheck_wwid[[:space:]][[:space:]]*\(yes\|1\)/ recheck_wwid no/' $TMPFILE ++ CHANGED_CONFIG=1 ++ fi ++elif [ "$RECHECK_WWID" = "y" ]; then ++ if [ -z "$HAVE_RECHECK_WWID" ]; then ++ sed -i '/^defaults[[:space:]]*{/ a\ ++ recheck_wwid yes ++' $TMPFILE ++ CHANGED_CONFIG=1 ++ elif [ "$HAVE_RECHECK_WWID" = 0 ]; then ++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*recheck_wwid[[:space:]][[:space:]]*\(no\|0\)/ recheck_wwid yes/' $TMPFILE ++ CHANGED_CONFIG=1 ++ fi ++fi ++ + if [ "$PROPERTY" = "n" ]; then + if [ "$HAVE_PROPERTY" = 1 ]; then + sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*property[[:space:]][[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/# property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE +diff --git a/multipath/mpathconf.8 b/multipath/mpathconf.8 +index 496383b7..9c2fb835 100644 +--- a/multipath/mpathconf.8 ++++ b/multipath/mpathconf.8 +@@ -77,6 +77,15 @@ to the + defaults section. If set to \fBn\fP, this removes the line, if present. This + command can be used along with any other command. + .TP ++.B --recheck_wwid \fP { \fBy\fP | \fBn\fP } ++If set to \fBy\fP, this adds the line ++.B recheck_wwid yes ++to the ++.B /etc/multipath.conf ++defaults section, or sets an existing line to \fByes\fP. If set to \fBn\fP, this ++sets an existing \fBrecheck_wwid\fP line to \fBno\fP. This command can be used ++along with any other command. ++.TP + .B --find_multipaths\fP { \fByes\fP | \fBno\fP | \fBstrict\fP | \fBgreedy\fP | \fBsmart\fP } + If set to \fB\fP, this adds the line + .B find_multipaths diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index f8d3470..195cd07 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.8.7 -Release: 7%{?dist} +Release: 8%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -45,6 +45,8 @@ Patch0032: 0032-RH-reset-default-find_mutipaths-value-to-off.patch Patch0033: 0033-RH-attempt-to-get-ANA-info-via-sysfs-first.patch Patch0034: 0034-RH-make-parse_vpd_pg83-match-scsi_id-output.patch Patch0035: 0035-libmultipath-use-asprintf-to-allocate-prefixed_uuid.patch +Patch0036: 0036-RH-add-support-to-mpathconf-for-setting-arbitrary-de.patch +Patch0037: 0037-RH-add-support-to-mpathconf-for-setting-recheck_wwid.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -242,6 +244,12 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Mon Feb 7 2022 Benjamin Marzinski - 0.8.7-8 +- Add 0036-RH-add-support-to-mpathconf-for-setting-arbitrary-de.patch + * add the ability for mpathconf to set arbitray options with --option +- Add 0037-RH-add-support-to-mpathconf-for-setting-recheck_wwid.patch + * add --recheck_wwid option to mpathconf + * Wed Jan 26 2022 Benjamin Marzinski - 0.8.7-7 - Add 0035-libmultipath-use-asprintf-to-allocate-prefixed_uuid.patch - Resolves: bz #2045309 From dad5d3a23562843fd21d0f72a5eb28ca35e0a9f5 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Mon, 28 Mar 2022 15:47:01 -0500 Subject: [PATCH 31/67] device-mapper-multipath-0.8.9-1 Update source to upstream version 0.8.9 * Previous patches 0001-0024 & 0035 are included in the commit. Add patches from upstream staging branch * Patches 0001-0005 are from the upstream staging branch Rename redhat patches * Previous patches 0025-0034 are now patches 0006-0015 Combine redhat patches * Previous patches 0036 & 0037 are now part of patch 0011 Add 0016-RH-add-scsi-device-handlers-to-modules-load.d.patch Spec file changes * Install multipath.conf and scsi_dh.conf to /usr/lib/modules-load.d --- .gitignore | 1 + ...add-info-about-IO-affinity-path-sele.patch | 45 -- ...identify-more-arrays-under-IBM-2145-.patch | 29 + ...add-HPE-as-vendor-for-OPEN-XP8-array.patch | 32 ++ ...issing-persistent-reseravtion-for-ac.patch | 52 -- ...path-tools-add-HP-HSVX740-to-hwtable.patch | 30 +- ...minor-fixes-to-multipath.conf.5-man-.patch | 48 -- ...add-DellEMC-ME5-PowerVault-ME5-to-ha.patch | 37 ++ ...make-IBM-XIV-config-work-with-alua-a.patch | 39 -- ...update-mpp-force_readonly-in-ev_add_.patch | 136 +++++ ...t-add-missing-conditions-from-servic.patch | 32 -- ... 0006-RH-fixup-udev-rules-for-redhat.patch | 32 +- ...make-IBM-2107900-DS8000-config-work-.patch | 40 -- ...property-blacklist-exception-builtin.patch | 12 +- ...make-EMC-SYMMETRIX-config-work-with-.patch | 35 -- ...RH-don-t-start-without-a-config-file.patch | 20 +- ...make-EMC-Invista-config-work-with-al.patch | 37 -- ...H-Fix-nvme-function-missing-argument.patch | 0 ...make-COMPELNT-Compellent-Vol-config-.patch | 35 -- ... 0010-RH-use-rpm-optflags-if-present.patch | 9 +- ...hconf.patch => 0011-RH-add-mpathconf.patch | 173 ++++-- ...-tools-make-EMC-Invista-config-work-.patch | 35 -- ...om-kernel-cmdline-mpath.wwids-with-A.patch | 30 +- ...-tools-make-EMC-SYMMETRIX-config-wor.patch | 38 -- ...-default-find_mutipaths-value-to-off.patch | 4 +- ...ipath-fix-exit-status-of-multipath-T.patch | 26 - ...empt-to-get-ANA-info-via-sysfs-first.patch | 0 ...-section-name-to-invalid-keyword-out.patch | 70 --- ...-parse_vpd_pg83-match-scsi_id-output.patch | 54 +- ...-typedef-for-keyword-handler-functio.patch | 85 --- ...si-device-handlers-to-modules-load.d.patch | 25 + ...nt-the-correct-file-when-parsing-fai.patch | 28 - ...s-file-and-line-number-to-keyword-ha.patch | 528 ------------------ ...e-set_int-take-a-range-for-valid-val.patch | 251 --------- ...multipath-improve-checks-for-set_str.patch | 171 ------ ...recate-file-and-directory-config-opt.patch | 115 ---- ...tipath-split-set_int-to-enable-reuse.patch | 192 ------- ...path-cleanup-invalid-config-handling.patch | 202 ------- ...don-t-return-error-on-invalid-values.patch | 219 -------- ...d-unnecessary-path-read-only-reloads.patch | 129 ----- ...e-asprintf-to-allocate-prefixed_uuid.patch | 59 -- ...o-mpathconf-for-setting-arbitrary-de.patch | 149 ----- ...o-mpathconf-for-setting-recheck_wwid.patch | 154 ----- device-mapper-multipath.spec | 79 ++- sources | 2 +- 45 files changed, 530 insertions(+), 2989 deletions(-) delete mode 100644 0001-multipath-tools-add-info-about-IO-affinity-path-sele.patch create mode 100644 0001-multipath-tools-identify-more-arrays-under-IBM-2145-.patch create mode 100644 0002-multipath-tools-add-HPE-as-vendor-for-OPEN-XP8-array.patch delete mode 100644 0002-multipathd-fix-missing-persistent-reseravtion-for-ac.patch rename 0010-multipath-tools-remove-Compellent-maintainer.patch => 0003-multipath-tools-add-HP-HSVX740-to-hwtable.patch (51%) delete mode 100644 0003-multipath-tools-minor-fixes-to-multipath.conf.5-man-.patch create mode 100644 0004-multipath-tools-add-DellEMC-ME5-PowerVault-ME5-to-ha.patch delete mode 100644 0004-multipath-tools-make-IBM-XIV-config-work-with-alua-a.patch create mode 100644 0005-multipath-tools-update-mpp-force_readonly-in-ev_add_.patch delete mode 100644 0005-multipathd.socket-add-missing-conditions-from-servic.patch rename 0025-RH-fixup-udev-rules-for-redhat.patch => 0006-RH-fixup-udev-rules-for-redhat.patch (67%) delete mode 100644 0006-multipath-tools-make-IBM-2107900-DS8000-config-work-.patch rename 0026-RH-Remove-the-property-blacklist-exception-builtin.patch => 0007-RH-Remove-the-property-blacklist-exception-builtin.patch (92%) delete mode 100644 0007-multipath-tools-make-EMC-SYMMETRIX-config-work-with-.patch rename 0027-RH-don-t-start-without-a-config-file.patch => 0008-RH-don-t-start-without-a-config-file.patch (87%) delete mode 100644 0008-multipath-tools-make-EMC-Invista-config-work-with-al.patch rename 0028-RH-Fix-nvme-function-missing-argument.patch => 0009-RH-Fix-nvme-function-missing-argument.patch (100%) delete mode 100644 0009-multipath-tools-make-COMPELNT-Compellent-Vol-config-.patch rename 0029-RH-use-rpm-optflags-if-present.patch => 0010-RH-use-rpm-optflags-if-present.patch (94%) rename 0030-RH-add-mpathconf.patch => 0011-RH-add-mpathconf.patch (80%) delete mode 100644 0011-Revert-multipath-tools-make-EMC-Invista-config-work-.patch rename 0031-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch => 0012-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch (88%) delete mode 100644 0012-Revert-multipath-tools-make-EMC-SYMMETRIX-config-wor.patch rename 0032-RH-reset-default-find_mutipaths-value-to-off.patch => 0013-RH-reset-default-find_mutipaths-value-to-off.patch (94%) delete mode 100644 0013-multipath-fix-exit-status-of-multipath-T.patch rename 0033-RH-attempt-to-get-ANA-info-via-sysfs-first.patch => 0014-RH-attempt-to-get-ANA-info-via-sysfs-first.patch (100%) delete mode 100644 0014-libmultipath-add-section-name-to-invalid-keyword-out.patch rename 0034-RH-make-parse_vpd_pg83-match-scsi_id-output.patch => 0015-RH-make-parse_vpd_pg83-match-scsi_id-output.patch (67%) delete mode 100644 0015-libmultipath-use-typedef-for-keyword-handler-functio.patch create mode 100644 0016-RH-add-scsi-device-handlers-to-modules-load.d.patch delete mode 100644 0016-libmultipath-print-the-correct-file-when-parsing-fai.patch delete mode 100644 0017-libmultipath-pass-file-and-line-number-to-keyword-ha.patch delete mode 100644 0018-libmultipath-make-set_int-take-a-range-for-valid-val.patch delete mode 100644 0019-libmultipath-improve-checks-for-set_str.patch delete mode 100644 0020-libmultipath-deprecate-file-and-directory-config-opt.patch delete mode 100644 0021-libmultipath-split-set_int-to-enable-reuse.patch delete mode 100644 0022-libmultipath-cleanup-invalid-config-handling.patch delete mode 100644 0023-libmultipath-don-t-return-error-on-invalid-values.patch delete mode 100644 0024-multipathd-avoid-unnecessary-path-read-only-reloads.patch delete mode 100644 0035-libmultipath-use-asprintf-to-allocate-prefixed_uuid.patch delete mode 100644 0036-RH-add-support-to-mpathconf-for-setting-arbitrary-de.patch delete mode 100644 0037-RH-add-support-to-mpathconf-for-setting-recheck_wwid.patch diff --git a/.gitignore b/.gitignore index 03e544c..d5360ef 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,4 @@ multipath-tools-091027.tar.gz /multipath-tools-0.8.5.tgz /multipath-tools-0.8.6.tgz /multipath-tools-0.8.7.tgz +/multipath-tools-0.8.9.tgz diff --git a/0001-multipath-tools-add-info-about-IO-affinity-path-sele.patch b/0001-multipath-tools-add-info-about-IO-affinity-path-sele.patch deleted file mode 100644 index 559d5a5..0000000 --- a/0001-multipath-tools-add-info-about-IO-affinity-path-sele.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Wed, 8 Sep 2021 22:33:54 +0200 -Subject: [PATCH] multipath-tools: add info about IO affinity path selector to - manpage - -Added in 5.11: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e4d2e82b2300b03f66b3ca8417590c86e661fab1 - -Cc: Mike Christie -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - multipath/multipath.conf.5 | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index d6b8c7f6..42a15ffd 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -6,7 +6,7 @@ - .\" - .\" ---------------------------------------------------------------------------- - . --.TH MULTIPATH.CONF 5 2018-05-21 Linux -+.TH MULTIPATH.CONF 5 2021-09-08 Linux - . - . - .\" ---------------------------------------------------------------------------- -@@ -210,6 +210,10 @@ of outstanding I/O to the path and its relative throughput. - estimation of future service time based on the history of previous I/O submitted - to each path. - .TP -+.I "io-affinity 0" -+(Since 5.11 kernel) Choose the path for the next bunch of I/O based on a CPU to -+path mapping the user passes in and what CPU we are executing on. -+.TP - The default is: \fBservice-time 0\fR - .RE - . diff --git a/0001-multipath-tools-identify-more-arrays-under-IBM-2145-.patch b/0001-multipath-tools-identify-more-arrays-under-IBM-2145-.patch new file mode 100644 index 0000000..c34345e --- /dev/null +++ b/0001-multipath-tools-identify-more-arrays-under-IBM-2145-.patch @@ -0,0 +1,29 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Thu, 24 Feb 2022 22:06:08 +0100 +Subject: [PATCH] multipath-tools: identify more arrays under IBM/2145 ID + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/hwtable.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index bd157103..643caa32 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -665,7 +665,7 @@ static struct hwentry default_hw[] = { + }, + { + // Storwize V5000 and V7000 lines / SAN Volume Controller (SVC) / Flex System V7000 / +- // FlashSystem V840/V9000/5000/5100/5200/7200/9100/9200/9200R ++ // FlashSystem V840/V9000/5000/5100/5200/7200/7300/9100/9200/9200R/9500 + .vendor = "IBM", + .product = "^2145", + .no_path_retry = NO_PATH_RETRY_QUEUE, diff --git a/0002-multipath-tools-add-HPE-as-vendor-for-OPEN-XP8-array.patch b/0002-multipath-tools-add-HPE-as-vendor-for-OPEN-XP8-array.patch new file mode 100644 index 0000000..7df0d4b --- /dev/null +++ b/0002-multipath-tools-add-HPE-as-vendor-for-OPEN-XP8-array.patch @@ -0,0 +1,32 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Thu, 24 Feb 2022 22:23:34 +0100 +Subject: [PATCH] multipath-tools: add HPE as vendor for OPEN- (XP8 arrays) + +Cc: Matthias Rudolph +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/hwtable.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index 643caa32..3b9e0e0f 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -467,8 +467,8 @@ static struct hwentry default_hw[] = { + * Maintainer: Matthias Rudolph + */ + { +- /* USP-V, HUS VM, VSP, VSP G1X00 and VSP GX00 families / HP XP */ +- .vendor = "(HITACHI|HP)", ++ /* USP-V, HUS VM, VSP, VSP G1X00 and VSP GX00 families / HPE XP */ ++ .vendor = "(HITACHI|HP|HPE)", + .product = "^OPEN-", + .pgpolicy = MULTIBUS, + }, diff --git a/0002-multipathd-fix-missing-persistent-reseravtion-for-ac.patch b/0002-multipathd-fix-missing-persistent-reseravtion-for-ac.patch deleted file mode 100644 index 5312160..0000000 --- a/0002-multipathd-fix-missing-persistent-reseravtion-for-ac.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: lixiaokeng -Date: Mon, 13 Sep 2021 10:43:14 +0800 -Subject: [PATCH] multipathd: fix missing persistent reseravtion for active - path - -There are two paths(sucu as sda and adb) for one LUN. The two -paths log in, but before the two uevents have been processed -(for example there are many uevent), users use multipathd add -path /dev/sda to cause mpatha and use mpathpersist -o -I to -register prkey for mpatha. The add map uevent is after add path -uevent, the the uevent(add sdb) will delay and missing persistent -reseravtion check. - -Here, we add persistent reseravtion check in update_map() which -is called ev_add_map(). - -Signed-off-by: Lixiaokeng -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 3aff241d..1defeaf1 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -490,6 +490,8 @@ update_map (struct multipath *mpp, struct vectors *vecs, int new_map) - { - int retries = 3; - char *params __attribute__((cleanup(cleanup_charp))) = NULL; -+ struct path *pp; -+ int i; - - retry: - condlog(4, "%s: updating new map", mpp->alias); -@@ -502,6 +504,15 @@ retry: - verify_paths(mpp); - mpp->action = ACT_RELOAD; - -+ if (mpp->prflag) { -+ vector_foreach_slot(mpp->paths, pp, i) { -+ if ((pp->state == PATH_UP) || (pp->state == PATH_GHOST)) { -+ /* persistent reseravtion check*/ -+ mpath_pr_event_handle(pp); -+ } -+ } -+ } -+ - if (setup_map(mpp, ¶ms, vecs)) { - condlog(0, "%s: failed to setup new map in update", mpp->alias); - retries = -1; diff --git a/0010-multipath-tools-remove-Compellent-maintainer.patch b/0003-multipath-tools-add-HP-HSVX740-to-hwtable.patch similarity index 51% rename from 0010-multipath-tools-remove-Compellent-maintainer.patch rename to 0003-multipath-tools-add-HP-HSVX740-to-hwtable.patch index f8e9cc0..b950020 100644 --- a/0010-multipath-tools-remove-Compellent-maintainer.patch +++ b/0003-multipath-tools-add-HP-HSVX740-to-hwtable.patch @@ -1,9 +1,9 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Xose Vazquez Perez -Date: Tue, 28 Sep 2021 22:39:17 +0200 -Subject: [PATCH] multipath-tools: remove Compellent maintainer +Date: Thu, 24 Feb 2022 22:24:39 +0100 +Subject: [PATCH] multipath-tools: add HP/HSVX740 to hwtable -e-mail was bounced: 550 5.1.1 User Unknown +Info from: https://community.hpe.com/hpeb/attachments/hpeb/itrc-248/61618/1/HP_DM_MP_Guide.pdf Cc: Martin Wilck Cc: Benjamin Marzinski @@ -13,23 +13,19 @@ Signed-off-by: Xose Vazquez Perez Reviewed-by: Martin Wilck Signed-off-by: Benjamin Marzinski --- - libmultipath/hwtable.c | 6 +----- - 1 file changed, 1 insertion(+), 5 deletions(-) + libmultipath/hwtable.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index 7fc5bc04..763982cd 100644 +index 3b9e0e0f..ff8ed036 100644 --- a/libmultipath/hwtable.c +++ b/libmultipath/hwtable.c -@@ -361,11 +361,7 @@ static struct hwentry default_hw[] = { - .pgpolicy = MULTIBUS, - }, +@@ -192,7 +192,7 @@ static struct hwentry default_hw[] = { { -- /* -- * SC Series, formerly Compellent -- * -- * Maintainer: Sean McGinnis -- */ -+ /* SC Series, formerly Compellent */ - .vendor = "COMPELNT", - .product = "Compellent Vol", + /* SAN Virtualization Services Platform */ + .vendor = "HP", +- .product = "HSVX700", ++ .product = "(HSVX700|HSVX740)", + .hwhandler = "1 alua", .pgpolicy = GROUP_BY_PRIO, + .pgfailback = -FAILBACK_IMMEDIATE, diff --git a/0003-multipath-tools-minor-fixes-to-multipath.conf.5-man-.patch b/0003-multipath-tools-minor-fixes-to-multipath.conf.5-man-.patch deleted file mode 100644 index ddad7b0..0000000 --- a/0003-multipath-tools-minor-fixes-to-multipath.conf.5-man-.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Thu, 16 Sep 2021 00:44:49 +0200 -Subject: [PATCH] multipath-tools: minor fixes to multipath.conf.5 man page - -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez -Signed-off-by: Benjamin Marzinski ---- - multipath/multipath.conf.5 | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 42a15ffd..c74129bd 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -1,9 +1,9 @@ - .\" ---------------------------------------------------------------------------- --.\" Update the date below if you make any significant change. - .\" Make sure there are no errors with: - .\" groff -z -wall -b -e -t multipath/multipath.conf.5 - .\" man --warnings -E UTF-8 -l -Tutf8 -Z multipath/multipath.conf.5 >/dev/null - .\" -+.\" Update the date below if you make any significant change. - .\" ---------------------------------------------------------------------------- - . - .TH MULTIPATH.CONF 5 2021-09-08 Linux -@@ -189,7 +189,7 @@ The default is: \fB\fR - .TP - .B path_selector - The default path selector algorithm to use; they are offered by the --kernel multipath target. There are three selector algorithms: -+kernel multipath target: - .RS - .TP 12 - .I "round-robin 0" -@@ -206,7 +206,7 @@ of outstanding I/O to the path. - of outstanding I/O to the path and its relative throughput. - .TP - .I "historical-service-time 0" --(Since 5.8 kernel) Choose the path for the next bunch of IOs based on the -+(Since 5.8 kernel) Choose the path for the next bunch of I/O based on the - estimation of future service time based on the history of previous I/O submitted - to each path. - .TP diff --git a/0004-multipath-tools-add-DellEMC-ME5-PowerVault-ME5-to-ha.patch b/0004-multipath-tools-add-DellEMC-ME5-PowerVault-ME5-to-ha.patch new file mode 100644 index 0000000..8834238 --- /dev/null +++ b/0004-multipath-tools-add-DellEMC-ME5-PowerVault-ME5-to-ha.patch @@ -0,0 +1,37 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Wed, 23 Feb 2022 23:16:44 +0100 +Subject: [PATCH] multipath-tools: add DellEMC/ME5 (PowerVault ME5) to hardware + table + +Convert PowerVault ME4 template for all ME series. + +[MW] https://dl.dell.com/content/manual51886263-dell-powervault-me5-series-administrator's-guide.pdf + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/hwtable.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index ff8ed036..0e1c0a41 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -397,9 +397,9 @@ static struct hwentry default_hw[] = { + .fast_io_fail = 15, + }, + { +- /* PowerVault ME4 */ ++ /* PowerVault ME 4/5 families */ + .vendor = "DellEMC", +- .product = "ME4", ++ .product = "^ME", + .pgpolicy = GROUP_BY_PRIO, + .prio_name = PRIO_ALUA, + .hwhandler = "1 alua", diff --git a/0004-multipath-tools-make-IBM-XIV-config-work-with-alua-a.patch b/0004-multipath-tools-make-IBM-XIV-config-work-with-alua-a.patch deleted file mode 100644 index da06d58..0000000 --- a/0004-multipath-tools-make-IBM-XIV-config-work-with-alua-a.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Sat, 25 Sep 2021 00:27:36 +0200 -Subject: [PATCH] multipath-tools: make IBM/XIV config work with alua and - multibus - -And add recommended pgfailback value. - -ALUA is supported since XIV_Gen2 and microcode 10.2.1 -(All ports across all controllers in single Target Port Group) - -https://www.ibm.com/support/pages/ibm-flashsystem%C2%AE-a9000-and-a9000r-hyperswap-solution-deployment-linux%C2%AE-ibm-z-systems%C2%AE -https://www.google.com/search?q=%222810XIV%22+%22path_grouping_policy%22+site%3Aibm.com - -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/hwtable.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index 0caac0da..72f81c60 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -712,7 +712,8 @@ static struct hwentry default_hw[] = { - .vendor = "(XIV|IBM)", - .product = "(NEXTRA|2810XIV)", - .no_path_retry = NO_PATH_RETRY_QUEUE, -- .pgpolicy = MULTIBUS, -+ .pgpolicy = GROUP_BY_PRIO, -+ .pgfailback = 15, - }, - { - /* TMS RamSan / FlashSystem 710/720/810/820/840/900 */ diff --git a/0005-multipath-tools-update-mpp-force_readonly-in-ev_add_.patch b/0005-multipath-tools-update-mpp-force_readonly-in-ev_add_.patch new file mode 100644 index 0000000..a2538e4 --- /dev/null +++ b/0005-multipath-tools-update-mpp-force_readonly-in-ev_add_.patch @@ -0,0 +1,136 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Uday Shankar +Date: Wed, 9 Mar 2022 13:03:26 -0700 +Subject: [PATCH] multipath-tools: update mpp->force_readonly in ev_add_path + +When NVMe disks are added to the system, no uevent containing the +DISK_RO property is generated. As a result, dm-* nodes backed by +readonly NVMe disks will not have their RO state set properly. The +result looks like this: + +$ multipath -l +eui.00c92c091fd6564424a9376600011bd1 dm-3 NVME,Pure Storage FlashArray +size=1.0T features='0' hwhandler='0' wp=rw +|-+- policy='service-time 0' prio=0 status=active +| `- 0:2:2:72657 nvme0n2 259:4 active undef running +`-+- policy='service-time 0' prio=0 status=enabled + `- 1:0:2:72657 nvme1n2 259:1 active undef running +$ cat /sys/block/dm-3/ro +0 +$ cat /sys/block/nvme*n2/ro +1 +1 + +This is not a problem for SCSI disks, since the kernel will emit change +uevents containing the DISK_RO property when the disk is added to the +system. See the following thread for my initial attempt to fix this +issue at the kernel level: +https://lore.kernel.org/linux-block/Yib8GqCA5e3SQYty@infradead.org/T/#t + +Fix the issue by picking up the path ro state from sysfs in ev_add_path, +setting the mpp->force_readonly accordingly, and changing +dm_addmap_create to be aware of mpp->force_readonly. + +Signed-off-by: Uday Shankar +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/devmapper.c | 2 +- + multipathd/main.c | 50 ++++++++++++++++++++++------------------ + 2 files changed, 29 insertions(+), 23 deletions(-) + +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index 2507f77f..9819e29b 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -540,7 +540,7 @@ int dm_addmap_create (struct multipath *mpp, char * params) + int ro; + uint16_t udev_flags = build_udev_flags(mpp, 0); + +- for (ro = 0; ro <= 1; ro++) { ++ for (ro = mpp->force_readonly ? 1 : 0; ro <= 1; ro++) { + int err; + + if (dm_addmap(DM_DEVICE_CREATE, TGT_MPATH, mpp, params, ro, +diff --git a/multipathd/main.c b/multipathd/main.c +index f2c0b280..a67865df 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -1130,6 +1130,28 @@ out: + return ret; + } + ++static int ++sysfs_get_ro (struct path *pp) ++{ ++ int ro; ++ char buff[3]; /* Either "0\n\0" or "1\n\0" */ ++ ++ if (!pp->udev) ++ return -1; ++ ++ if (sysfs_attr_get_value(pp->udev, "ro", buff, sizeof(buff)) <= 0) { ++ condlog(3, "%s: Cannot read ro attribute in sysfs", pp->dev); ++ return -1; ++ } ++ ++ if (sscanf(buff, "%d\n", &ro) != 1 || ro < 0 || ro > 1) { ++ condlog(3, "%s: Cannot parse ro attribute", pp->dev); ++ return -1; ++ } ++ ++ return ro; ++} ++ + /* + * returns: + * 0: added +@@ -1143,6 +1165,7 @@ ev_add_path (struct path * pp, struct vectors * vecs, int need_do_map) + int retries = 3; + int start_waiter = 0; + int ret; ++ int ro; + + /* + * need path UID to go any further +@@ -1207,6 +1230,11 @@ rescan: + /* persistent reservation check*/ + mpath_pr_event_handle(pp); + ++ /* ro check - if new path is ro, force map to be ro as well */ ++ ro = sysfs_get_ro(pp); ++ if (ro == 1) ++ mpp->force_readonly = 1; ++ + if (!need_do_map) + return 0; + +@@ -1446,28 +1474,6 @@ finish_path_init(struct path *pp, struct vectors * vecs) + return -1; + } + +-static int +-sysfs_get_ro (struct path *pp) +-{ +- int ro; +- char buff[3]; /* Either "0\n\0" or "1\n\0" */ +- +- if (!pp->udev) +- return -1; +- +- if (sysfs_attr_get_value(pp->udev, "ro", buff, sizeof(buff)) <= 0) { +- condlog(3, "%s: Cannot read ro attribute in sysfs", pp->dev); +- return -1; +- } +- +- if (sscanf(buff, "%d\n", &ro) != 1 || ro < 0 || ro > 1) { +- condlog(3, "%s: Cannot parse ro attribute", pp->dev); +- return -1; +- } +- +- return ro; +-} +- + static bool + needs_ro_update(struct multipath *mpp, int ro) + { diff --git a/0005-multipathd.socket-add-missing-conditions-from-servic.patch b/0005-multipathd.socket-add-missing-conditions-from-servic.patch deleted file mode 100644 index e6b34a2..0000000 --- a/0005-multipathd.socket-add-missing-conditions-from-servic.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Luca BRUNO -Date: Fri, 24 Sep 2021 09:34:01 +0000 -Subject: [PATCH] multipathd.socket: add missing conditions from service unit - -This aligns 'multipathd' socket and service units, by adding the -start conditions that are set on the service but not on the socket. -It should help avoiding situations where the socket unit ends up -marked as failed after hitting its retry-limit. - -Fixes: https://github.com/opensvc/multipath-tools/issues/15 -Signed-off-by: Luca BRUNO -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - multipathd/multipathd.socket | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/multipathd/multipathd.socket b/multipathd/multipathd.socket -index 0ed4a1f7..c777e5e3 100644 ---- a/multipathd/multipathd.socket -+++ b/multipathd/multipathd.socket -@@ -1,6 +1,9 @@ - [Unit] - Description=multipathd control socket - DefaultDependencies=no -+ConditionKernelCommandLine=!nompath -+ConditionKernelCommandLine=!multipath=off -+ConditionVirtualization=!container - Before=sockets.target - - [Socket] diff --git a/0025-RH-fixup-udev-rules-for-redhat.patch b/0006-RH-fixup-udev-rules-for-redhat.patch similarity index 67% rename from 0025-RH-fixup-udev-rules-for-redhat.patch rename to 0006-RH-fixup-udev-rules-for-redhat.patch index df4455e..6153d90 100644 --- a/0025-RH-fixup-udev-rules-for-redhat.patch +++ b/0006-RH-fixup-udev-rules-for-redhat.patch @@ -15,10 +15,10 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index d0ec9b44..2a75dc9c 100644 +index d24da43e..fb23635c 100644 --- a/Makefile.inc +++ b/Makefile.inc -@@ -55,7 +55,7 @@ endif +@@ -75,7 +75,7 @@ endif prefix = exec_prefix = $(prefix) usr_prefix = $(prefix) @@ -26,12 +26,12 @@ index d0ec9b44..2a75dc9c 100644 +bindir = $(exec_prefix)/usr/sbin libudevdir = $(prefix)/$(SYSTEMDPATH)/udev udevrulesdir = $(libudevdir)/rules.d - multipathdir = $(TOPDIR)/libmultipath + modulesloaddir = $(prefix)/$(SYSTEMDPATH)/modules-load.d diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules -index d7527d7d..0e0d70d5 100644 +index 1969dee0..d2b28233 100644 --- a/kpartx/kpartx.rules +++ b/kpartx/kpartx.rules -@@ -36,6 +36,6 @@ LABEL="mpath_kpartx_end" +@@ -39,6 +39,6 @@ LABEL="mpath_kpartx_end" GOTO="kpartx_end" LABEL="run_kpartx" @@ -40,24 +40,24 @@ index d7527d7d..0e0d70d5 100644 LABEL="kpartx_end" diff --git a/multipath/Makefile b/multipath/Makefile -index 0828a8f7..b9bbb3cf 100644 +index c930499d..2059a4f4 100644 --- a/multipath/Makefile +++ b/multipath/Makefile -@@ -24,7 +24,7 @@ install: +@@ -22,7 +22,7 @@ install: $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ $(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) $(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) -- $(INSTALL_PROGRAM) -m 644 $(EXEC).rules $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules -+ $(INSTALL_PROGRAM) -m 644 $(EXEC).rules $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules +- $(INSTALL_PROGRAM) -m 644 $(EXEC).rules $(DESTDIR)$(udevrulesdir)/56-multipath.rules ++ $(INSTALL_PROGRAM) -m 644 $(EXEC).rules $(DESTDIR)$(udevrulesdir)/62-multipath.rules + $(INSTALL_PROGRAM) -d $(DESTDIR)$(modulesloaddir) + $(INSTALL_PROGRAM) -m 644 modules-load.conf $(DESTDIR)$(modulesloaddir)/multipath.conf $(INSTALL_PROGRAM) -d $(DESTDIR)$(man8dir) - $(INSTALL_PROGRAM) -m 644 $(EXEC).8.gz $(DESTDIR)$(man8dir) - $(INSTALL_PROGRAM) -d $(DESTDIR)$(man5dir) -@@ -33,7 +33,7 @@ install: - uninstall: - $(RM) $(DESTDIR)$(bindir)/$(EXEC) +@@ -40,7 +40,7 @@ uninstall: $(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules + $(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf + $(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf - $(RM) $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules + $(RM) $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules - $(RM) $(DESTDIR)$(man8dir)/$(EXEC).8.gz - $(RM) $(DESTDIR)$(man5dir)/$(EXEC).conf.5.gz + $(RM) $(DESTDIR)$(man8dir)/$(EXEC).8 + $(RM) $(DESTDIR)$(man5dir)/$(EXEC).conf.5 diff --git a/0006-multipath-tools-make-IBM-2107900-DS8000-config-work-.patch b/0006-multipath-tools-make-IBM-2107900-DS8000-config-work-.patch deleted file mode 100644 index 97cc8ef..0000000 --- a/0006-multipath-tools-make-IBM-2107900-DS8000-config-work-.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Tue, 28 Sep 2021 18:52:10 +0200 -Subject: [PATCH] multipath-tools: make IBM/2107900 (DS8000) config work with - alua and multibus - -ALUA is supported since the beginning: -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/scsi/device_handler/scsi_dh_alua.c?id=057ea7c9683c3d684128cced796f03c179ecf1c2#n683 - -... the DS8000 is an Asymmetric Logical Unit Access (ALUA) capable storage array, -pag#160(144): https://www.redbooks.ibm.com/redbooks/pdfs/sg248887.pdf - -kernel log: -https://marc.info/?l=linux-scsi&m=156407413807511&q=mbox - -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/hwtable.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index 72f81c60..f115c4f9 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -656,7 +656,8 @@ static struct hwentry default_hw[] = { - .vendor = "IBM", - .product = "^2107900", - .no_path_retry = NO_PATH_RETRY_QUEUE, -- .pgpolicy = MULTIBUS, -+ .pgpolicy = GROUP_BY_PRIO, -+ .pgfailback = -FAILBACK_IMMEDIATE, - }, - { - // Storwize V5000 and V7000 lines / SAN Volume Controller (SVC) / Flex System V7000 / diff --git a/0026-RH-Remove-the-property-blacklist-exception-builtin.patch b/0007-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 92% rename from 0026-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0007-RH-Remove-the-property-blacklist-exception-builtin.patch index 3bb4786..edc8dc1 100644 --- a/0026-RH-Remove-the-property-blacklist-exception-builtin.patch +++ b/0007-RH-Remove-the-property-blacklist-exception-builtin.patch @@ -19,10 +19,10 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c -index 4e315c97..1e463ef6 100644 +index 8d15d2ea..eff690fd 100644 --- a/libmultipath/blacklist.c +++ b/libmultipath/blacklist.c -@@ -202,9 +202,6 @@ setup_default_blist (struct config * conf) +@@ -201,9 +201,6 @@ setup_default_blist (struct config * conf) if (store_ble(conf->blist_devnode, "!^(sd[a-z]|dasd[a-z]|nvme[0-9])", ORIGIN_DEFAULT)) return 1; @@ -32,7 +32,7 @@ index 4e315c97..1e463ef6 100644 vector_foreach_slot (conf->hwtable, hwe, i) { if (hwe->bl_product) { if (find_blacklist_device(conf->blist_device, -@@ -410,7 +407,8 @@ filter_property(const struct config *conf, struct udev_device *udev, +@@ -409,7 +406,8 @@ filter_property(const struct config *conf, struct udev_device *udev, *uid_attribute != '\0'; bool uid_attr_seen = false; @@ -43,10 +43,10 @@ index 4e315c97..1e463ef6 100644 udev_device_get_properties_list_entry(udev)) { diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 88d2a1df..7f85f766 100644 +index 605b46e0..1844a250 100644 --- a/multipath/multipath.conf.5 +++ b/multipath/multipath.conf.5 -@@ -1356,9 +1356,14 @@ keywords. Both are regular expressions. For a full description of these keywords +@@ -1365,9 +1365,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, @@ -62,7 +62,7 @@ index 88d2a1df..7f85f766 100644 . .RS .PP -@@ -1369,10 +1374,6 @@ Blacklisting by missing properties is only applied to devices which do have the +@@ -1378,10 +1383,6 @@ Blacklisting by missing properties is only applied to devices which do have the property specified by \fIuid_attribute\fR (e.g. \fIID_SERIAL\fR) set. Previously, it was applied to every device, possibly causing devices to be blacklisted because of temporary I/O error conditions. diff --git a/0007-multipath-tools-make-EMC-SYMMETRIX-config-work-with-.patch b/0007-multipath-tools-make-EMC-SYMMETRIX-config-work-with-.patch deleted file mode 100644 index 201232a..0000000 --- a/0007-multipath-tools-make-EMC-SYMMETRIX-config-work-with-.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Tue, 28 Sep 2021 19:20:59 +0200 -Subject: [PATCH] multipath-tools: make EMC/SYMMETRIX config work with alua and - multibus - -ALUA is supported since VMAX3 and HYPERMAX OS 5977.811.784, pag#113: -https://www.delltechnologies.com/en-us/collaterals/unauth/technical-guides-support-information/products/storage-2/docu5128.pdf - -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/hwtable.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index f115c4f9..7095aaf1 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -329,8 +329,9 @@ static struct hwentry default_hw[] = { - /* Symmetrix / DMX / VMAX / PowerMax */ - .vendor = "EMC", - .product = "SYMMETRIX", -- .pgpolicy = MULTIBUS, -+ .pgpolicy = GROUP_BY_PRIO, - .no_path_retry = 6, -+ .pgfailback = -FAILBACK_IMMEDIATE, - }, - { - /* DGC CLARiiON CX/AX / VNX and Unity */ diff --git a/0027-RH-don-t-start-without-a-config-file.patch b/0008-RH-don-t-start-without-a-config-file.patch similarity index 87% rename from 0027-RH-don-t-start-without-a-config-file.patch rename to 0008-RH-don-t-start-without-a-config-file.patch index 8061a99..82bf02f 100644 --- a/0027-RH-don-t-start-without-a-config-file.patch +++ b/0008-RH-don-t-start-without-a-config-file.patch @@ -21,10 +21,10 @@ Signed-off-by: Benjamin Marzinski 6 files changed, 19 insertions(+) diff --git a/libmultipath/config.c b/libmultipath/config.c -index 30046a17..5f35c3d3 100644 +index c595e768..b193de5c 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c -@@ -895,6 +895,19 @@ int _init_config (const char *file, struct config *conf) +@@ -894,6 +894,19 @@ int _init_config (const char *file, struct config *conf) goto out; } factorize_hwtable(conf->hwtable, builtin_hwtable_size, file); @@ -45,7 +45,7 @@ index 30046a17..5f35c3d3 100644 conf->processed_main_config = 1; diff --git a/libmultipath/config.h b/libmultipath/config.h -index 933fe0d1..5f01c1fc 100644 +index c73389b5..69a01cb7 100644 --- a/libmultipath/config.h +++ b/libmultipath/config.h @@ -9,6 +9,7 @@ @@ -69,7 +69,7 @@ index 9df11a95..0486bf70 100644 ENV{DEVTYPE}!="partition", GOTO="test_dev" IMPORT{parent}="DM_MULTIPATH_DEVICE_PATH" diff --git a/multipathd/multipathd.8 b/multipathd/multipathd.8 -index 048a838d..8bd47a80 100644 +index 1e318bdc..6aab9325 100644 --- a/multipathd/multipathd.8 +++ b/multipathd/multipathd.8 @@ -39,6 +39,8 @@ map regains its maximum performance and redundancy. @@ -82,17 +82,17 @@ index 048a838d..8bd47a80 100644 . .\" ---------------------------------------------------------------------------- diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service -index 0b2ac814..6d57c7e8 100644 +index aec62dbb..d76f94f9 100644 --- a/multipathd/multipathd.service +++ b/multipathd/multipathd.service -@@ -4,6 +4,7 @@ Wants=systemd-udev-trigger.service systemd-udev-settle.service - Before=iscsi.service iscsid.service lvm2-activation-early.service - Before=local-fs-pre.target blk-availability.service shutdown.target - After=multipathd.socket systemd-udev-trigger.service systemd-udev-settle.service +@@ -6,6 +6,7 @@ Wants=systemd-udevd-kernel.socket + After=systemd-udevd-kernel.socket + After=multipathd.socket systemd-remount-fs.service + Before=initrd-cleanup.service +ConditionPathExists=/etc/multipath.conf DefaultDependencies=no Conflicts=shutdown.target - ConditionKernelCommandLine=!nompath + Conflicts=initrd-cleanup.service diff --git a/multipathd/multipathd.socket b/multipathd/multipathd.socket index c777e5e3..3c20a2ff 100644 --- a/multipathd/multipathd.socket diff --git a/0008-multipath-tools-make-EMC-Invista-config-work-with-al.patch b/0008-multipath-tools-make-EMC-Invista-config-work-with-al.patch deleted file mode 100644 index 723f023..0000000 --- a/0008-multipath-tools-make-EMC-Invista-config-work-with-al.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Tue, 28 Sep 2021 19:31:21 +0200 -Subject: [PATCH] multipath-tools: make EMC/Invista config work with alua and - multibus - -Optimal Path Management (OPM) was introduced with VPLEX 5.5 to improve VPLEX -performance. OPM uses the ALUA mechanism to spread the I/O load across VPLEX directors -while gaining cache locality, pag #187: -https://www.delltechnologies.com/en-us/collaterals/unauth/technical-guides-support-information/products/storage-2/docu5128.pdf - -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/hwtable.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index 7095aaf1..4e8b52ff 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -350,8 +350,9 @@ static struct hwentry default_hw[] = { - .vendor = "EMC", - .product = "Invista", - .bl_product = "LUNZ", -- .pgpolicy = MULTIBUS, -+ .pgpolicy = GROUP_BY_PRIO, - .no_path_retry = 5, -+ .pgfailback = -FAILBACK_IMMEDIATE, - }, - { - /* XtremIO */ diff --git a/0028-RH-Fix-nvme-function-missing-argument.patch b/0009-RH-Fix-nvme-function-missing-argument.patch similarity index 100% rename from 0028-RH-Fix-nvme-function-missing-argument.patch rename to 0009-RH-Fix-nvme-function-missing-argument.patch diff --git a/0009-multipath-tools-make-COMPELNT-Compellent-Vol-config-.patch b/0009-multipath-tools-make-COMPELNT-Compellent-Vol-config-.patch deleted file mode 100644 index e2a93ee..0000000 --- a/0009-multipath-tools-make-COMPELNT-Compellent-Vol-config-.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Tue, 28 Sep 2021 22:15:56 +0200 -Subject: [PATCH] multipath-tools: make "COMPELNT/Compellent Vol" config work - with alua and multibus - -ALUA is needed by SAS arrays, pag#124: -https://downloads.dell.com/manuals/all-products/esuprt_solutions_int/esuprt_solutions_int_solutions_resources/general-solution-resources_white-papers2_en-us.pdf - -Cc: Sean McGinnis -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/hwtable.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index 4e8b52ff..7fc5bc04 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -368,7 +368,8 @@ static struct hwentry default_hw[] = { - */ - .vendor = "COMPELNT", - .product = "Compellent Vol", -- .pgpolicy = MULTIBUS, -+ .pgpolicy = GROUP_BY_PRIO, -+ .pgfailback = -FAILBACK_IMMEDIATE, - .no_path_retry = NO_PATH_RETRY_QUEUE, - }, - { diff --git a/0029-RH-use-rpm-optflags-if-present.patch b/0010-RH-use-rpm-optflags-if-present.patch similarity index 94% rename from 0029-RH-use-rpm-optflags-if-present.patch rename to 0010-RH-use-rpm-optflags-if-present.patch index a1c081c..7436fd0 100644 --- a/0029-RH-use-rpm-optflags-if-present.patch +++ b/0010-RH-use-rpm-optflags-if-present.patch @@ -13,10 +13,10 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 2a75dc9c..5ac660de 100644 +index fb23635c..4511ab1f 100644 --- a/Makefile.inc +++ b/Makefile.inc -@@ -92,23 +92,35 @@ TEST_CC_OPTION = $(shell \ +@@ -114,23 +114,35 @@ TEST_CC_OPTION = $(shell \ echo "$(2)"; \ fi) @@ -58,9 +58,12 @@ index 2a75dc9c..5ac660de 100644 BIN_LDFLAGS = -pie # Check whether a function with name $1 has been declared in header file $2. -@@ -139,4 +151,4 @@ check_file = $(shell \ +@@ -174,7 +186,7 @@ check_var = $(shell \ %.o: %.c @echo building $@ because of $? - $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< + $(CC) $(CFLAGS) -c -o $@ $< + + %.abi: %.so.0 + abidw $< >$@ diff --git a/0030-RH-add-mpathconf.patch b/0011-RH-add-mpathconf.patch similarity index 80% rename from 0030-RH-add-mpathconf.patch rename to 0011-RH-add-mpathconf.patch index aaa4150..80b882a 100644 --- a/0030-RH-add-mpathconf.patch +++ b/0011-RH-add-mpathconf.patch @@ -13,18 +13,18 @@ a single command. Signed-off-by: Benjamin Marzinski --- libmultipath/config.c | 2 + - multipath/Makefile | 5 + - multipath/mpathconf | 564 ++++++++++++++++++++++++++++++++++++++++++ - multipath/mpathconf.8 | 135 ++++++++++ - 4 files changed, 706 insertions(+) + multipath/Makefile | 4 + + multipath/mpathconf | 658 ++++++++++++++++++++++++++++++++++++++++++ + multipath/mpathconf.8 | 151 ++++++++++ + 4 files changed, 815 insertions(+) create mode 100644 multipath/mpathconf create mode 100644 multipath/mpathconf.8 diff --git a/libmultipath/config.c b/libmultipath/config.c -index 5f35c3d3..cee3bbb7 100644 +index b193de5c..a8ec3bf4 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c -@@ -897,6 +897,8 @@ int _init_config (const char *file, struct config *conf) +@@ -896,6 +896,8 @@ int _init_config (const char *file, struct config *conf) factorize_hwtable(conf->hwtable, builtin_hwtable_size, file); } else { condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices."); @@ -34,45 +34,42 @@ index 5f35c3d3..cee3bbb7 100644 conf->blist_devnode = vector_alloc(); if (!conf->blist_devnode) { diff --git a/multipath/Makefile b/multipath/Makefile -index b9bbb3cf..e720c7f6 100644 +index 2059a4f4..e2ebe431 100644 --- a/multipath/Makefile +++ b/multipath/Makefile -@@ -18,10 +18,12 @@ $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so - $(CC) $(CFLAGS) $(OBJS) -o $(EXEC) $(LDFLAGS) $(LIBDEPS) - $(GZIP) $(EXEC).8 > $(EXEC).8.gz - $(GZIP) $(EXEC).conf.5 > $(EXEC).conf.5.gz -+ $(GZIP) mpathconf.8 > mpathconf.8.gz - +@@ -20,6 +20,7 @@ $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so install: $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ + $(INSTALL_PROGRAM) -m 755 mpathconf $(DESTDIR)$(bindir)/ $(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) $(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) - $(INSTALL_PROGRAM) -m 644 $(EXEC).rules $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules -@@ -29,13 +31,16 @@ install: - $(INSTALL_PROGRAM) -m 644 $(EXEC).8.gz $(DESTDIR)$(man8dir) + $(INSTALL_PROGRAM) -m 644 $(EXEC).rules $(DESTDIR)$(udevrulesdir)/62-multipath.rules +@@ -29,6 +30,7 @@ install: + $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(man8dir) $(INSTALL_PROGRAM) -d $(DESTDIR)$(man5dir) - $(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5.gz $(DESTDIR)$(man5dir) -+ $(INSTALL_PROGRAM) -m 644 mpathconf.8.gz $(DESTDIR)$(man8dir) - - uninstall: - $(RM) $(DESTDIR)$(bindir)/$(EXEC) - $(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules + $(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5 $(DESTDIR)$(man5dir) ++ $(INSTALL_PROGRAM) -m 644 mpathconf.8 $(DESTDIR)$(man8dir) + ifneq ($(SCSI_DH_MODULES_PRELOAD),) + $(INSTALL_PROGRAM) -m 644 scsi_dh.conf $(DESTDIR)$(modulesloaddir)/scsi_dh.conf + for _x in $(SCSI_DH_MODULES_PRELOAD); do echo "$$_x"; done \ +@@ -41,8 +43,10 @@ uninstall: + $(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf + $(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf $(RM) $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules + $(RM) $(DESTDIR)$(bindir)/mpathconf - $(RM) $(DESTDIR)$(man8dir)/$(EXEC).8.gz - $(RM) $(DESTDIR)$(man5dir)/$(EXEC).conf.5.gz -+ $(RM) $(DESTDIR)$(man8dir)/mpathconf.8.gz + $(RM) $(DESTDIR)$(man8dir)/$(EXEC).8 + $(RM) $(DESTDIR)$(man5dir)/$(EXEC).conf.5 ++ $(RM) $(DESTDIR)$(man8dir)/mpathconf.8 clean: dep_clean - $(RM) core *.o $(EXEC) *.gz + $(RM) core *.o $(EXEC) diff --git a/multipath/mpathconf b/multipath/mpathconf new file mode 100644 -index 00000000..0de6b121 +index 00000000..319664b1 --- /dev/null +++ b/multipath/mpathconf -@@ -0,0 +1,564 @@ +@@ -0,0 +1,658 @@ +#!/bin/bash +# +# Copyright (C) 2010 Red Hat, Inc. All rights reserved. @@ -92,7 +89,7 @@ index 00000000..0de6b121 +# This program was largely ripped off from lvmconf +# + -+unset ENABLE FIND FRIENDLY PROPERTY FOREIGN MODULE MULTIPATHD HAVE_DISABLE HAVE_WWID_DISABLE HAVE_FIND HAVE_BLACKLIST HAVE_EXCEPTIONS HAVE_DEFAULTS HAVE_FRIENDLY HAVE_PROPERTY HAVE_FOREIGN HAVE_MULTIPATHD HAVE_MODULE HAVE_OUTFILE SHOW_STATUS CHANGED_CONFIG WWID_LIST ++unset ENABLE FIND FRIENDLY PROPERTY FOREIGN MODULE MULTIPATHD HAVE_DISABLE HAVE_WWID_DISABLE HAVE_FIND HAVE_BLACKLIST HAVE_EXCEPTIONS HAVE_DEFAULTS HAVE_FRIENDLY HAVE_PROPERTY HAVE_FOREIGN HAVE_MULTIPATHD HAVE_MODULE HAVE_OUTFILE SHOW_STATUS CHANGED_CONFIG WWID_LIST HAVE_OPTION OPTION_NAME OPTION_VALUE HAVE_RECHECK_WWID RECHECK_WWID + +DEFAULT_CONFIG="# device-mapper-multipath configuration file + @@ -127,6 +124,8 @@ index 00000000..0de6b121 + echo "Set find_multipaths (Default y): --find_multipaths " + echo "Set default property blacklist (Default n): --property_blacklist " + echo "Set enable_foreign to show foreign devices (Default n): --enable_foreign " ++ echo "Set recheck_wwid (Defaut n): --recheck_wwid " ++ echo "Add/Change/Remove option in defaults section: --option :" + echo "Load the dm-multipath modules on enable (Default y): --with_module " + echo "start/stop/reload multipathd (Default n): --with_multipathd " + echo "select output file (Default /etc/multipath.conf): --outfile " @@ -219,6 +218,15 @@ index 00000000..0de6b121 + exit 1 + fi + ;; ++ --recheck_wwid) ++ if [ -n "$2" ]; then ++ RECHECK_WWID=$2 ++ shift 2 ++ else ++ usage ++ exit 1 ++ fi ++ ;; + --find_multipaths) + if [ -n "$2" ]; then + FIND=$2 @@ -237,6 +245,20 @@ index 00000000..0de6b121 + exit 1 + fi + ;; ++ --option) ++ if [ -n "$2" ]; then ++ OPTION_NAME=$(echo $2 | cut -s -f1 -d:) ++ OPTION_VALUE=$(echo $2 | cut -s -f2 -d:) ++ if [ -z "$OPTION_NAME" ]; then ++ usage ++ exit 1 ++ fi ++ shift 2 ++ else ++ usage ++ exit 1 ++ fi ++ ;; + --enable_foreign) + if [ -n "$2" ]; then + FOREIGN=$2 @@ -283,17 +305,25 @@ index 00000000..0de6b121 + +function validate_args +{ -+ if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$PROPERTY" -o -n "$MODULE" ]; then ++ if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$PROPERTY" -o -n "$MODULE" -o -n "$FOREIGN" -o -n "$OPTION_NAME" -o -n "$RECHECK_WWID" ]; then + echo "ignoring extra parameters on disable" + FRIENDLY="" + FIND="" + PROPERTY="" + MODULE="" ++ FOREIGN="" ++ OPTION_NAME="" ++ OPTION_VALUE="" ++ RECHECK_WWID="" + fi + if [ -n "$FRIENDLY" ] && [ "$FRIENDLY" != "y" -a "$FRIENDLY" != "n" ]; then + echo "--user_friendly_names must be either 'y' or 'n'" + exit 1 + fi ++ if [ -n "$RECHECK_WWID" ] && [ "$RECHECK_WWID" != "y" -a "$RECHECK_WWID" != "n" ]; then ++ echo "--recheck_wwid must be either 'y' or 'n'" ++ exit 1 ++ fi + if [ "$FIND" = "y" ]; then + FIND="yes" + elif [ "$FIND" = "n" ]; then @@ -310,7 +340,19 @@ index 00000000..0de6b121 + echo "--enable_foreign must be either 'y' or 'n'" + exit 1 + fi -+ if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" -a -z "$PROPERTY" -a -z "$FOREIGN" ]; then ++ if [ -n "$OPTION_NAME" ]; then ++ if [[ $OPTION_NAME =~ [[:space:]]|#|\"|!|\{|\} ]]; then ++ echo "--option name \"$OPTION_NAME\" is invalid" ++ exit 1 ++ elif [[ $OPTION_VALUE =~ \"|#|!|\{|\} ]]; then ++ echo "--option value \"$OPTION_VALUE\" is invalid" ++ exit 1 ++ fi ++ if [[ $OPTION_VALUE =~ [[:space:]] ]]; then ++ OPTION_VALUE=\"$OPTION_VALUE\" ++ fi ++ fi ++ if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" -a -z "$PROPERTY" -a -z "$FOREIGN" -a -z "$OPTION_NAME" -a -z "$RECHECK_WWID" ]; then + SHOW_STATUS=1 + fi + if [ -n "$MODULE" ] && [ "$MODULE" != "y" -a "$MODULE" != "n" ]; then @@ -412,6 +454,11 @@ index 00000000..0de6b121 + elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]][[:space:]]*\(no\|0\)" ; then + HAVE_FRIENDLY=0 + fi ++ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*recheck_wwid[[:space:]][[:space:]]*\(yes\|1\)" ; then ++ HAVE_RECHECK_WWID=1 ++ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*recheck_wwid[[:space:]][[:space:]]*\(no\|0\)" ; then ++ HAVE_RECHECK_WWID=0 ++ fi + if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*enable_foreign" ; then + HAVE_FOREIGN=0 + elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]][[:space:]]*\"\.\*\"" ; then @@ -423,6 +470,13 @@ index 00000000..0de6b121 + elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign" ; then + HAVE_FOREIGN=3 + fi ++ if [ -n "$OPTION_NAME" ]; then ++ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q '^[[:space:]]*'"$OPTION_NAME"'[[:space:]][[:space:]]*'"$OPTION_VALUE" ; then ++ HAVE_OPTION=1 ++ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q '^[[:space:]]*'"$OPTION_NAME"'\([[:space:]].*\)\?$' ; then ++ HAVE_OPTION=0 ++ fi ++ fi +fi + +if [ "$HAVE_EXCEPTIONS" = "1" ]; then @@ -449,6 +503,11 @@ index 00000000..0de6b121 + else + echo "user_friendly_names is enabled" + fi ++ if [ -z "$HAVE_RECHECK_WWID" -o "$HAVE_RECHECK_WWID" = 0 ]; then ++ echo "recheck_wwid is disabled" ++ else ++ echo "recheck_wwid is enabled" ++ fi + if [ -z "$HAVE_PROPERTY" -o "$HAVE_PROPERTY" = 0 ]; then + echo "default property blacklist is disabled" + else @@ -565,6 +624,23 @@ index 00000000..0de6b121 + fi +fi + ++if [ "$RECHECK_WWID" = "n" ]; then ++ if [ "$HAVE_RECHECK_WWID" = 1 ]; then ++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*recheck_wwid[[:space:]][[:space:]]*\(yes\|1\)/ recheck_wwid no/' $TMPFILE ++ CHANGED_CONFIG=1 ++ fi ++elif [ "$RECHECK_WWID" = "y" ]; then ++ if [ -z "$HAVE_RECHECK_WWID" ]; then ++ sed -i '/^defaults[[:space:]]*{/ a\ ++ recheck_wwid yes ++' $TMPFILE ++ CHANGED_CONFIG=1 ++ elif [ "$HAVE_RECHECK_WWID" = 0 ]; then ++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*recheck_wwid[[:space:]][[:space:]]*\(no\|0\)/ recheck_wwid yes/' $TMPFILE ++ CHANGED_CONFIG=1 ++ fi ++fi ++ +if [ "$PROPERTY" = "n" ]; then + if [ "$HAVE_PROPERTY" = 1 ]; then + sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*property[[:space:]][[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/# property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE @@ -607,6 +683,21 @@ index 00000000..0de6b121 + fi +fi + ++if [ -n "$OPTION_NAME" -a -n "$OPTION_VALUE" ]; then ++ if [ -z "$HAVE_OPTION" ]; then ++ sed -i '/^defaults[[:space:]]*{/ a\ ++ '"$OPTION_NAME"' '"$OPTION_VALUE"' ++' $TMPFILE ++ CHANGED_CONFIG=1 ++ elif [ "$HAVE_OPTION" = 0 ]; then ++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*'"$OPTION_NAME"'\([[:space:]].*\)\?$/ '"$OPTION_NAME"' '"$OPTION_VALUE"'/' $TMPFILE ++ CHANGED_CONFIG=1 ++ fi ++elif [ -n "$OPTION_NAME" -a -n "$HAVE_OPTION" ]; then ++ sed -i '/^defaults[[:space:]]*{/,/^}/{/^[[:space:]]*'"$OPTION_NAME"'\([[:space:]].*\)\?$/d}' $TMPFILE ++ CHANGED_CONFIG=1 ++fi ++ +if [ -f "$OUTPUTFILE" ]; then + cp $OUTPUTFILE $OUTPUTFILE.old + if [ $? != 0 ]; then @@ -639,10 +730,10 @@ index 00000000..0de6b121 +fi diff --git a/multipath/mpathconf.8 b/multipath/mpathconf.8 new file mode 100644 -index 00000000..a14d831e +index 00000000..9c2fb835 --- /dev/null +++ b/multipath/mpathconf.8 -@@ -0,0 +1,135 @@ +@@ -0,0 +1,151 @@ +.TH MPATHCONF 8 "June 2010" "" "Linux Administrator's Manual" +.SH NAME +mpathconf - A tool for configuring device-mapper-multipath @@ -722,6 +813,15 @@ index 00000000..a14d831e +defaults section. If set to \fBn\fP, this removes the line, if present. This +command can be used along with any other command. +.TP ++.B --recheck_wwid \fP { \fBy\fP | \fBn\fP } ++If set to \fBy\fP, this adds the line ++.B recheck_wwid yes ++to the ++.B /etc/multipath.conf ++defaults section, or sets an existing line to \fByes\fP. If set to \fBn\fP, this ++sets an existing \fBrecheck_wwid\fP line to \fBno\fP. This command can be used ++along with any other command. ++.TP +.B --find_multipaths\fP { \fByes\fP | \fBno\fP | \fBstrict\fP | \fBgreedy\fP | \fBsmart\fP } +If set to \fB\fP, this adds the line +.B find_multipaths @@ -746,6 +846,13 @@ index 00000000..a14d831e +defaults section. if set to \fBn\fP, this removes the line, if present. This +command can be used along with any other command. +.TP ++.B --option \fB:[]\fP ++Sets the defaults section option \fB\fP to \fB\fP. If the ++option was not previously set in the defaults section, it is added. If it was ++set, its value is changed to \fB\fP. If \fB\fP is left blank, ++then the option is removed from the defaults section, if was set there. This ++command can be used along with any other command. ++.TP +.B --outfile \fB\fP +Write the resulting multipath configuration to \fB\fP instead of +\fB/etc/multipath.conf\fP. diff --git a/0011-Revert-multipath-tools-make-EMC-Invista-config-work-.patch b/0011-Revert-multipath-tools-make-EMC-Invista-config-work-.patch deleted file mode 100644 index 1912f80..0000000 --- a/0011-Revert-multipath-tools-make-EMC-Invista-config-work-.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 20 Oct 2021 20:44:54 +0200 -Subject: [PATCH] Revert "multipath-tools: make EMC/Invista config work with - alua and multibus" - -This reverts commit 309ff281aaa07e862540d3d645a8263f3e9baaed. - -Mail from , 20210930: - -"OPM is no longer supported in the Dell VPLEX product. If we at Dell had -wished to change the default device stanzas for any of our products they -would have been done when the product and/or feature is released. -Please remove this patch as well. It is not needed." - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/hwtable.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index 763982cd..211087ad 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -350,9 +350,8 @@ static struct hwentry default_hw[] = { - .vendor = "EMC", - .product = "Invista", - .bl_product = "LUNZ", -- .pgpolicy = GROUP_BY_PRIO, -+ .pgpolicy = MULTIBUS, - .no_path_retry = 5, -- .pgfailback = -FAILBACK_IMMEDIATE, - }, - { - /* XtremIO */ diff --git a/0031-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0012-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 88% rename from 0031-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0012-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch index 3ce47ac..c133e00 100644 --- a/0031-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +++ b/0012-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch @@ -20,10 +20,10 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/multipath/main.c b/multipath/main.c -index b2d300e5..80fa68e5 100644 +index d09f62db..0d786ee5 100644 --- a/multipath/main.c +++ b/multipath/main.c -@@ -122,7 +122,7 @@ usage (char * progname) +@@ -120,7 +120,7 @@ usage (char * progname) fprintf (stderr, " %s [-v level] [-R retries] -F\n", progname); fprintf (stderr, " %s [-v level] [-l|-ll] [device]\n", progname); fprintf (stderr, " %s [-v level] [-a|-w] device\n", progname); @@ -32,7 +32,7 @@ index b2d300e5..80fa68e5 100644 fprintf (stderr, " %s [-v level] [-i] [-c|-C] device\n", progname); fprintf (stderr, " %s [-v level] [-i] [-u|-U]\n", progname); fprintf (stderr, " %s [-h|-t|-T]\n", progname); -@@ -136,6 +136,8 @@ usage (char * progname) +@@ -134,6 +134,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" @@ -41,7 +41,7 @@ index b2d300e5..80fa68e5 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" -@@ -450,6 +452,50 @@ static void cleanup_vecs(void) +@@ -448,6 +450,50 @@ static void cleanup_vecs(void) free_pathvec(vecs.pathvec, FREE_PATHS); } @@ -92,16 +92,16 @@ index b2d300e5..80fa68e5 100644 static int configure (struct config *conf, enum mpath_cmds cmd, enum devtypes dev_type, char *devpath) -@@ -839,7 +885,7 @@ main (int argc, char *argv[]) - conf->retrigger_tries = 0; +@@ -841,7 +887,7 @@ main (int argc, char *argv[]) conf->force_sync = 1; - atexit(cleanup_vecs); + if (atexit(cleanup_vecs)) + condlog(1, "failed to register cleanup handler for vecs: %m"); - while ((arg = getopt(argc, argv, ":adDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { + while ((arg = getopt(argc, argv, ":aAdDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { switch(arg) { - case 1: printf("optarg : %s\n",optarg); - break; -@@ -916,6 +962,10 @@ main (int argc, char *argv[]) + case 'v': + if (!isdigit(optarg[0])) { +@@ -912,6 +958,10 @@ main (int argc, char *argv[]) case 'T': cmd = CMD_DUMP_CONFIG; break; @@ -113,7 +113,7 @@ index b2d300e5..80fa68e5 100644 usage(argv[0]); exit(RTVL_OK); diff --git a/multipath/multipath.8 b/multipath/multipath.8 -index 17df59f5..5ca75359 100644 +index 4c7e9885..1d062664 100644 --- a/multipath/multipath.8 +++ b/multipath/multipath.8 @@ -63,7 +63,7 @@ multipath \- Device mapper target autoconfig. @@ -138,13 +138,13 @@ index 17df59f5..5ca75359 100644 Remove the WWID for the specified device from the WWIDs file. . diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service -index 6d57c7e8..dfc1e962 100644 +index d76f94f9..bb5f383a 100644 --- a/multipathd/multipathd.service +++ b/multipathd/multipathd.service -@@ -16,6 +16,7 @@ Type=notify +@@ -17,6 +17,7 @@ ConditionVirtualization=!container + [Service] + Type=notify NotifyAccess=main - LimitCORE=infinity - ExecStartPre=-/sbin/modprobe -a scsi_dh_alua scsi_dh_emc scsi_dh_rdac dm-multipath +ExecStartPre=-/sbin/multipath -A ExecStart=/sbin/multipathd -d -s ExecReload=/sbin/multipathd reconfigure diff --git a/0012-Revert-multipath-tools-make-EMC-SYMMETRIX-config-wor.patch b/0012-Revert-multipath-tools-make-EMC-SYMMETRIX-config-wor.patch deleted file mode 100644 index b889ea8..0000000 --- a/0012-Revert-multipath-tools-make-EMC-SYMMETRIX-config-wor.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 20 Oct 2021 20:46:09 +0200 -Subject: [PATCH] Revert "multipath-tools: make EMC/SYMMETRIX config work with - alua and multibus" - -This reverts commit 831af0dbfa171cd39d968ba6174669f11a278be9. - -Mail from "berthiaume, wayne" , 210930: - -"As a representative of Dell I request this patch be withdrawn. If we had -wanted the default stanza changed we would have already implemented it. -Also for your information we only advertise the entire enterprise storage -product line (DMX, VMAX, VMAX AFA, PowerMax) as SYMMETRIX in the VPD page. -The ALUA capability is only used for mobility devices in an SRDF/Metro -configuration and the current device stanza still works well in all of our -testing." - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/hwtable.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index 211087ad..a8ba28e3 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -329,9 +329,8 @@ static struct hwentry default_hw[] = { - /* Symmetrix / DMX / VMAX / PowerMax */ - .vendor = "EMC", - .product = "SYMMETRIX", -- .pgpolicy = GROUP_BY_PRIO, -+ .pgpolicy = MULTIBUS, - .no_path_retry = 6, -- .pgfailback = -FAILBACK_IMMEDIATE, - }, - { - /* DGC CLARiiON CX/AX / VNX and Unity */ diff --git a/0032-RH-reset-default-find_mutipaths-value-to-off.patch b/0013-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 94% rename from 0032-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0013-RH-reset-default-find_mutipaths-value-to-off.patch index d5b5601..f1e8c33 100644 --- a/0032-RH-reset-default-find_mutipaths-value-to-off.patch +++ b/0013-RH-reset-default-find_mutipaths-value-to-off.patch @@ -12,10 +12,10 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h -index c27946c7..e0dd32ad 100644 +index 7d95413d..4fe08991 100644 --- a/libmultipath/defaults.h +++ b/libmultipath/defaults.h -@@ -23,7 +23,7 @@ +@@ -24,7 +24,7 @@ #define DEFAULT_NO_PATH_RETRY NO_PATH_RETRY_UNDEF #define DEFAULT_VERBOSITY 2 #define DEFAULT_REASSIGN_MAPS 0 diff --git a/0013-multipath-fix-exit-status-of-multipath-T.patch b/0013-multipath-fix-exit-status-of-multipath-T.patch deleted file mode 100644 index 783e95e..0000000 --- a/0013-multipath-fix-exit-status-of-multipath-T.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 22 Oct 2021 12:58:11 +0200 -Subject: [PATCH] multipath: fix exit status of multipath -T - -We must set the return value in configure(). - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/main.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/multipath/main.c b/multipath/main.c -index 65ece830..b2d300e5 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -560,6 +560,7 @@ configure (struct config *conf, enum mpath_cmds cmd, - - dump_config(conf, hwes, curmp); - vector_free(hwes); -+ r = RTVL_OK; - goto out; - } - diff --git a/0033-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0014-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 100% rename from 0033-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0014-RH-attempt-to-get-ANA-info-via-sysfs-first.patch diff --git a/0014-libmultipath-add-section-name-to-invalid-keyword-out.patch b/0014-libmultipath-add-section-name-to-invalid-keyword-out.patch deleted file mode 100644 index f4fce9f..0000000 --- a/0014-libmultipath-add-section-name-to-invalid-keyword-out.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 11 Nov 2021 12:53:44 -0600 -Subject: [PATCH] libmultipath: add section name to invalid keyword output - -If users forget the closing brace for a section in multipath.conf, -multipath has no way to detect that. When it sees the keyword at the -start of the next section, it will complain that there is an invalid -keyword, because that keyword doesn't belong in previous section (which -was never ended with a closing brace). This can confuse users. To make -this easier to understand, when multipath prints an invalid keyword -message, it now also prints the current section name, which can give -users a hint that they didn't end the previous section. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/parser.c | 20 +++++++++++++------- - 1 file changed, 13 insertions(+), 7 deletions(-) - -diff --git a/libmultipath/parser.c b/libmultipath/parser.c -index 8ca91bf2..611054f7 100644 ---- a/libmultipath/parser.c -+++ b/libmultipath/parser.c -@@ -504,7 +504,7 @@ validate_config_strvec(vector strvec, const char *file) - - static int - process_stream(struct config *conf, FILE *stream, vector keywords, -- const char *file) -+ const char *section, const char *file) - { - int i; - int r = 0, t; -@@ -568,16 +568,22 @@ process_stream(struct config *conf, FILE *stream, vector keywords, - if (keyword->sub) { - kw_level++; - r += process_stream(conf, stream, -- keyword->sub, file); -+ keyword->sub, -+ keyword->string, -+ file); - kw_level--; - } - break; - } - } -- if (i >= VECTOR_SIZE(keywords)) -- condlog(1, "%s line %d, invalid keyword: %s", -- file, line_nr, str); -- -+ if (i >= VECTOR_SIZE(keywords)) { -+ if (section) -+ condlog(1, "%s line %d, invalid keyword in the %s section: %s", -+ file, line_nr, section, str); -+ else -+ condlog(1, "%s line %d, invalid keyword: %s", -+ file, line_nr, str); -+ } - free_strvec(strvec); - } - if (kw_level == 1) -@@ -608,7 +614,7 @@ process_file(struct config *conf, const char *file) - - /* Stream handling */ - line_nr = 0; -- r = process_stream(conf, stream, conf->keywords, file); -+ r = process_stream(conf, stream, conf->keywords, NULL, file); - fclose(stream); - //free_keywords(keywords); - diff --git a/0034-RH-make-parse_vpd_pg83-match-scsi_id-output.patch b/0015-RH-make-parse_vpd_pg83-match-scsi_id-output.patch similarity index 67% rename from 0034-RH-make-parse_vpd_pg83-match-scsi_id-output.patch rename to 0015-RH-make-parse_vpd_pg83-match-scsi_id-output.patch index 1d10c09..bbc0212 100644 --- a/0034-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +++ b/0015-RH-make-parse_vpd_pg83-match-scsi_id-output.patch @@ -9,52 +9,46 @@ that. Signed-off-by: Benjamin Marzinski --- - libmultipath/discovery.c | 18 ++---------------- + libmultipath/discovery.c | 12 ++---------- tests/vpd.c | 6 ++++++ - 2 files changed, 8 insertions(+), 16 deletions(-) + 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index f25fe9e3..6fb81c28 100644 +index b969fba1..d2f2a8cf 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c -@@ -1136,12 +1136,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, - naa_prio = 7; +@@ -1156,13 +1156,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, + good_len = 8; break; case 2: - /* IEEE Extended: Prio 6 */ -- naa_prio = 6; +- new_prio = 6; +- good_len = 8; - break; case 3: - /* IEEE Locally assigned: Prio 1 */ -- naa_prio = 1; +- new_prio = 1; + /* IEEE Extended or Locally assigned: Prio 6 */ -+ naa_prio = 6; ++ new_prio = 6; + good_len = 8; break; default: - /* Default: no priority */ -@@ -1160,17 +1157,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, - vpd = d; - } +@@ -1180,10 +1176,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, + break; + case 0x8: + /* SCSI Name: Prio 3 */ +- invalid = (d[3] < 4 || (memcmp(d + 4, "eui.", 4) && +- memcmp(d + 4, "naa.", 4) && +- memcmp(d + 4, "iqn.", 4))); +- new_prio = 3; break; -- case 0x8: -- /* SCSI Name: Prio 3 */ -- if (memcmp(d + 4, "eui.", 4) && -- memcmp(d + 4, "naa.", 4) && -- memcmp(d + 4, "iqn.", 4)) -- break; -- if (prio < 3) { -- prio = 3; -- vpd = d; -- } -- break; case 0x1: /* T-10 Vendor ID: Prio 2 */ - if (prio < 2) { diff --git a/tests/vpd.c b/tests/vpd.c -index 8e730d37..7bf7990f 100644 +index a7d2092c..2366cfba 100644 --- a/tests/vpd.c +++ b/tests/vpd.c -@@ -230,11 +230,13 @@ static const char * const str_prefix[] = { +@@ -231,11 +231,13 @@ static const char * const str_prefix[] = { [STR_IQN] = "iqn.", }; @@ -68,7 +62,7 @@ index 8e730d37..7bf7990f 100644 /** * create_scsi_string_desc() - create a SCSI name string descriptor. -@@ -659,6 +661,7 @@ make_test_vpd_naa(2, 18); +@@ -766,6 +768,7 @@ make_test_vpd_naa(2, 18); make_test_vpd_naa(2, 17); make_test_vpd_naa(2, 16); @@ -76,7 +70,7 @@ index 8e730d37..7bf7990f 100644 /* SCSI Name string: EUI64, WWID size: 17 */ make_test_vpd_str(0, 20, 18) make_test_vpd_str(0, 20, 17) -@@ -694,6 +697,7 @@ make_test_vpd_str(18, 20, 18) +@@ -801,6 +804,7 @@ make_test_vpd_str(18, 20, 18) make_test_vpd_str(18, 20, 17) make_test_vpd_str(18, 20, 16) make_test_vpd_str(18, 20, 15) @@ -84,7 +78,7 @@ index 8e730d37..7bf7990f 100644 static int test_vpd(void) { -@@ -767,6 +771,7 @@ static int test_vpd(void) +@@ -909,6 +913,7 @@ static int test_vpd(void) cmocka_unit_test(test_vpd_naa_2_18), cmocka_unit_test(test_vpd_naa_2_17), cmocka_unit_test(test_vpd_naa_2_16), @@ -92,7 +86,7 @@ index 8e730d37..7bf7990f 100644 cmocka_unit_test(test_vpd_str_0_20_18), cmocka_unit_test(test_vpd_str_0_20_17), cmocka_unit_test(test_vpd_str_0_20_16), -@@ -791,6 +796,7 @@ static int test_vpd(void) +@@ -933,6 +938,7 @@ static int test_vpd(void) cmocka_unit_test(test_vpd_str_18_20_17), cmocka_unit_test(test_vpd_str_18_20_16), cmocka_unit_test(test_vpd_str_18_20_15), diff --git a/0015-libmultipath-use-typedef-for-keyword-handler-functio.patch b/0015-libmultipath-use-typedef-for-keyword-handler-functio.patch deleted file mode 100644 index c3a41d2..0000000 --- a/0015-libmultipath-use-typedef-for-keyword-handler-functio.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 11 Nov 2021 12:53:45 -0600 -Subject: [PATCH] libmultipath: use typedef for keyword handler function - -Don't keep writing out the function type. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/parser.c | 6 +++--- - libmultipath/parser.h | 15 ++++++--------- - 2 files changed, 9 insertions(+), 12 deletions(-) - -diff --git a/libmultipath/parser.c b/libmultipath/parser.c -index 611054f7..ebe1cbd9 100644 ---- a/libmultipath/parser.c -+++ b/libmultipath/parser.c -@@ -33,7 +33,7 @@ static int line_nr; - - int - keyword_alloc(vector keywords, char *string, -- int (*handler) (struct config *, vector), -+ handler_fn *handler, - print_fn *print, - int unique) - { -@@ -72,7 +72,7 @@ install_sublevel_end(void) - - int - _install_keyword(vector keywords, char *string, -- int (*handler) (struct config *, vector), -+ handler_fn *handler, - print_fn *print, - int unique) - { -@@ -558,7 +558,7 @@ process_stream(struct config *conf, FILE *stream, vector keywords, - goto out; - } - if (keyword->handler) { -- t = (*keyword->handler) (conf, strvec); -+ t = keyword->handler(conf, strvec); - r += t; - if (t) - condlog(1, "multipath.conf +%d, parsing failed: %s", -diff --git a/libmultipath/parser.h b/libmultipath/parser.h -index b43d46f8..3452bde1 100644 ---- a/libmultipath/parser.h -+++ b/libmultipath/parser.h -@@ -43,10 +43,11 @@ struct strbuf; - - /* keyword definition */ - typedef int print_fn(struct config *, struct strbuf *, const void *); -+typedef int handler_fn(struct config *, vector); - - struct keyword { - char *string; -- int (*handler) (struct config *, vector); -+ handler_fn *handler; - print_fn *print; - vector sub; - int unique; -@@ -62,18 +63,14 @@ struct keyword { - for (i = 0; i < (k)->sub->allocated && ((p) = (k)->sub->slot[i]); i++) - - /* Prototypes */ --extern int keyword_alloc(vector keywords, char *string, -- int (*handler) (struct config *, vector), -- print_fn *print, -- int unique); -+extern int keyword_alloc(vector keywords, char *string, handler_fn *handler, -+ print_fn *print, int unique); - #define install_keyword_root(str, h) keyword_alloc(keywords, str, h, NULL, 1) - extern void install_sublevel(void); - extern void install_sublevel_end(void); - --extern int _install_keyword(vector keywords, char *string, -- int (*handler) (struct config *, vector), -- print_fn *print, -- int unique); -+extern int _install_keyword(vector keywords, char *string, handler_fn *handler, -+ print_fn *print, int unique); - #define install_keyword(str, vec, pri) _install_keyword(keywords, str, vec, pri, 1) - #define install_keyword_multi(str, vec, pri) _install_keyword(keywords, str, vec, pri, 0) - extern void dump_keywords(vector keydump, int level); diff --git a/0016-RH-add-scsi-device-handlers-to-modules-load.d.patch b/0016-RH-add-scsi-device-handlers-to-modules-load.d.patch new file mode 100644 index 0000000..07f921f --- /dev/null +++ b/0016-RH-add-scsi-device-handlers-to-modules-load.d.patch @@ -0,0 +1,25 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Fri, 25 Mar 2022 18:12:06 -0500 +Subject: [PATCH] RH: add scsi device handlers to modules-load.d + +Make scsi_dh_alua scsi_dh_emc and scsi_dh_rdac get loaded in early boot. + +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 4511ab1f..fec82b00 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -11,7 +11,7 @@ + + # List of scsi device handler modules to load on boot, e.g. + # SCSI_DH_MODULES_PRELOAD := scsi_dh_alua scsi_dh_rdac +-SCSI_DH_MODULES_PRELOAD := ++SCSI_DH_MODULES_PRELOAD := scsi_dh_alua scsi_dh_emc scsi_dh_rdac + + + PKGCONFIG ?= pkg-config diff --git a/0016-libmultipath-print-the-correct-file-when-parsing-fai.patch b/0016-libmultipath-print-the-correct-file-when-parsing-fai.patch deleted file mode 100644 index 5d9f2f4..0000000 --- a/0016-libmultipath-print-the-correct-file-when-parsing-fai.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 11 Nov 2021 12:53:46 -0600 -Subject: [PATCH] libmultipath: print the correct file when parsing fails - -Don't assume that parsing failed on multipath.conf - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/parser.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/parser.c b/libmultipath/parser.c -index ebe1cbd9..d5595fb0 100644 ---- a/libmultipath/parser.c -+++ b/libmultipath/parser.c -@@ -561,8 +561,8 @@ process_stream(struct config *conf, FILE *stream, vector keywords, - t = keyword->handler(conf, strvec); - r += t; - if (t) -- condlog(1, "multipath.conf +%d, parsing failed: %s", -- line_nr, buf); -+ condlog(1, "%s line %d, parsing failed: %s", -+ file, line_nr, buf); - } - - if (keyword->sub) { diff --git a/0017-libmultipath-pass-file-and-line-number-to-keyword-ha.patch b/0017-libmultipath-pass-file-and-line-number-to-keyword-ha.patch deleted file mode 100644 index 50f9184..0000000 --- a/0017-libmultipath-pass-file-and-line-number-to-keyword-ha.patch +++ /dev/null @@ -1,528 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 11 Nov 2021 12:53:47 -0600 -Subject: [PATCH] libmultipath: pass file and line number to keyword handlers - -This will make it possible for the keyword handlers to print more useful -warning messages. It will be used by future patches. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/dict.c | 143 +++++++++++++++++++++++++----------------- - libmultipath/parser.c | 3 +- - libmultipath/parser.h | 2 +- - 3 files changed, 90 insertions(+), 58 deletions(-) - -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index 7a727389..eb2c44c0 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -29,7 +29,7 @@ - #include "strbuf.h" - - static int --set_int(vector strvec, void *ptr) -+set_int(vector strvec, void *ptr, const char *file, int line_nr) - { - int *int_ptr = (int *)ptr; - char *buff, *eptr; -@@ -58,7 +58,7 @@ set_int(vector strvec, void *ptr) - } - - static int --set_uint(vector strvec, void *ptr) -+set_uint(vector strvec, void *ptr, const char *file, int line_nr) - { - unsigned int *uint_ptr = (unsigned int *)ptr; - char *buff, *eptr, *p; -@@ -90,7 +90,7 @@ set_uint(vector strvec, void *ptr) - } - - static int --set_str(vector strvec, void *ptr) -+set_str(vector strvec, void *ptr, const char *file, int line_nr) - { - char **str_ptr = (char **)ptr; - -@@ -105,7 +105,7 @@ set_str(vector strvec, void *ptr) - } - - static int --set_yes_no(vector strvec, void *ptr) -+set_yes_no(vector strvec, void *ptr, const char *file, int line_nr) - { - char * buff; - int *int_ptr = (int *)ptr; -@@ -124,7 +124,7 @@ set_yes_no(vector strvec, void *ptr) - } - - static int --set_yes_no_undef(vector strvec, void *ptr) -+set_yes_no_undef(vector strvec, void *ptr, const char *file, int line_nr) - { - char * buff; - int *int_ptr = (int *)ptr; -@@ -187,9 +187,10 @@ static int print_yes_no_undef(struct strbuf *buff, long v) - - #define declare_def_handler(option, function) \ - static int \ --def_ ## option ## _handler (struct config *conf, vector strvec) \ -+def_ ## option ## _handler (struct config *conf, vector strvec, \ -+ const char *file, int line_nr) \ - { \ -- return function (strvec, &conf->option); \ -+ return function (strvec, &conf->option, file, line_nr); \ - } - - #define declare_def_snprint(option, function) \ -@@ -224,12 +225,13 @@ snprint_def_ ## option (struct config *conf, struct strbuf *buff, \ - - #define declare_hw_handler(option, function) \ - static int \ --hw_ ## option ## _handler (struct config *conf, vector strvec) \ -+hw_ ## option ## _handler (struct config *conf, vector strvec, \ -+ const char *file, int line_nr) \ - { \ - struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable); \ - if (!hwe) \ - return 1; \ -- return function (strvec, &hwe->option); \ -+ return function (strvec, &hwe->option, file, line_nr); \ - } - - #define declare_hw_snprint(option, function) \ -@@ -243,11 +245,12 @@ snprint_hw_ ## option (struct config *conf, struct strbuf *buff, \ - - #define declare_ovr_handler(option, function) \ - static int \ --ovr_ ## option ## _handler (struct config *conf, vector strvec) \ -+ovr_ ## option ## _handler (struct config *conf, vector strvec, \ -+ const char *file, int line_nr) \ - { \ - if (!conf->overrides) \ - return 1; \ -- return function (strvec, &conf->overrides->option); \ -+ return function (strvec, &conf->overrides->option, file, line_nr); \ - } - - #define declare_ovr_snprint(option, function) \ -@@ -260,12 +263,13 @@ snprint_ovr_ ## option (struct config *conf, struct strbuf *buff, \ - - #define declare_mp_handler(option, function) \ - static int \ --mp_ ## option ## _handler (struct config *conf, vector strvec) \ -+mp_ ## option ## _handler (struct config *conf, vector strvec, \ -+ const char *file, int line_nr) \ - { \ - struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable); \ - if (!mpe) \ - return 1; \ -- return function (strvec, &mpe->option); \ -+ return function (strvec, &mpe->option, file, line_nr); \ - } - - #define declare_mp_snprint(option, function) \ -@@ -277,9 +281,10 @@ snprint_mp_ ## option (struct config *conf, struct strbuf *buff, \ - return function(buff, mpe->option); \ - } - --static int checkint_handler(struct config *conf, vector strvec) -+static int checkint_handler(struct config *conf, vector strvec, -+ const char *file, int line_nr) - { -- int rc = set_uint(strvec, &conf->checkint); -+ int rc = set_uint(strvec, &conf->checkint, file, line_nr); - - if (rc) - return rc; -@@ -302,9 +307,10 @@ declare_def_snprint(reassign_maps, print_yes_no) - declare_def_handler(multipath_dir, set_str) - declare_def_snprint(multipath_dir, print_str) - --static int def_partition_delim_handler(struct config *conf, vector strvec) -+static int def_partition_delim_handler(struct config *conf, vector strvec, -+ const char *file, int line_nr) - { -- int rc = set_str(strvec, &conf->partition_delim); -+ int rc = set_str(strvec, &conf->partition_delim, file, line_nr); - - if (rc != 0) - return rc; -@@ -334,13 +340,13 @@ static const char * const find_multipaths_optvals[] = { - }; - - static int --def_find_multipaths_handler(struct config *conf, vector strvec) -+def_find_multipaths_handler(struct config *conf, vector strvec, -+ const char *file, int line_nr) - { - char *buff; - int i; - -- if (set_yes_no_undef(strvec, &conf->find_multipaths) == 0 && -- conf->find_multipaths != FIND_MULTIPATHS_UNDEF) -+ if (set_yes_no_undef(strvec, &conf->find_multipaths, file, line_nr) == 0 && conf->find_multipaths != FIND_MULTIPATHS_UNDEF) - return 0; - - buff = set_value(strvec); -@@ -396,7 +402,8 @@ static int snprint_uid_attrs(struct config *conf, struct strbuf *buff, - return total; - } - --static int uid_attrs_handler(struct config *conf, vector strvec) -+static int uid_attrs_handler(struct config *conf, vector strvec, -+ const char *file, int line_nr) - { - char *val; - -@@ -597,7 +604,8 @@ declare_hw_handler(skip_kpartx, set_yes_no_undef) - declare_hw_snprint(skip_kpartx, print_yes_no_undef) - declare_mp_handler(skip_kpartx, set_yes_no_undef) - declare_mp_snprint(skip_kpartx, print_yes_no_undef) --static int def_disable_changed_wwids_handler(struct config *conf, vector strvec) -+static int def_disable_changed_wwids_handler(struct config *conf, vector strvec, -+ const char *file, int line_nr) - { - return 0; - } -@@ -629,20 +637,23 @@ declare_def_snprint_defstr(enable_foreign, print_str, - DEFAULT_ENABLE_FOREIGN) - - static int --def_config_dir_handler(struct config *conf, vector strvec) -+def_config_dir_handler(struct config *conf, vector strvec, const char *file, -+ int line_nr) - { - /* this is only valid in the main config file */ - if (conf->processed_main_config) - return 0; -- return set_str(strvec, &conf->config_dir); -+ return set_str(strvec, &conf->config_dir, file, line_nr); - } - declare_def_snprint(config_dir, print_str) - - #define declare_def_attr_handler(option, function) \ - static int \ --def_ ## option ## _handler (struct config *conf, vector strvec) \ -+def_ ## option ## _handler (struct config *conf, vector strvec, \ -+ const char *file, int line_nr) \ - { \ -- return function (strvec, &conf->option, &conf->attribute_flags);\ -+ return function (strvec, &conf->option, &conf->attribute_flags, \ -+ file, line_nr); \ - } - - #define declare_def_attr_snprint(option, function) \ -@@ -655,12 +666,14 @@ snprint_def_ ## option (struct config *conf, struct strbuf *buff, \ - - #define declare_mp_attr_handler(option, function) \ - static int \ --mp_ ## option ## _handler (struct config *conf, vector strvec) \ -+mp_ ## option ## _handler (struct config *conf, vector strvec, \ -+ const char *file, int line_nr) \ - { \ - struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable); \ - if (!mpe) \ - return 1; \ -- return function (strvec, &mpe->option, &mpe->attribute_flags); \ -+ return function (strvec, &mpe->option, &mpe->attribute_flags, \ -+ file, line_nr); \ - } - - #define declare_mp_attr_snprint(option, function) \ -@@ -673,7 +686,7 @@ snprint_mp_ ## option (struct config *conf, struct strbuf *buff, \ - } - - static int --set_mode(vector strvec, void *ptr, int *flags) -+set_mode(vector strvec, void *ptr, int *flags, const char *file, int line_nr) - { - mode_t mode; - mode_t *mode_ptr = (mode_t *)ptr; -@@ -694,7 +707,7 @@ set_mode(vector strvec, void *ptr, int *flags) - } - - static int --set_uid(vector strvec, void *ptr, int *flags) -+set_uid(vector strvec, void *ptr, int *flags, const char *file, int line_nr) - { - uid_t uid; - uid_t *uid_ptr = (uid_t *)ptr; -@@ -719,7 +732,7 @@ set_uid(vector strvec, void *ptr, int *flags) - } - - static int --set_gid(vector strvec, void *ptr, int *flags) -+set_gid(vector strvec, void *ptr, int *flags, const char *file, int line_nr) - { - gid_t gid; - gid_t *gid_ptr = (gid_t *)ptr; -@@ -786,7 +799,7 @@ declare_mp_attr_handler(gid, set_gid) - declare_mp_attr_snprint(gid, print_gid) - - static int --set_undef_off_zero(vector strvec, void *ptr) -+set_undef_off_zero(vector strvec, void *ptr, const char *file, int line_nr) - { - char * buff; - int *int_ptr = (int *)ptr; -@@ -827,7 +840,7 @@ declare_hw_handler(fast_io_fail, set_undef_off_zero) - declare_hw_snprint(fast_io_fail, print_undef_off_zero) - - static int --set_dev_loss(vector strvec, void *ptr) -+set_dev_loss(vector strvec, void *ptr, const char *file, int line_nr) - { - char * buff; - unsigned int *uint_ptr = (unsigned int *)ptr; -@@ -870,7 +883,7 @@ declare_hw_handler(eh_deadline, set_undef_off_zero) - declare_hw_snprint(eh_deadline, print_undef_off_zero) - - static int --set_pgpolicy(vector strvec, void *ptr) -+set_pgpolicy(vector strvec, void *ptr, const char *file, int line_nr) - { - char * buff; - int *int_ptr = (int *)ptr; -@@ -936,7 +949,8 @@ get_sys_max_fds(int *max_fds) - - - static int --max_fds_handler(struct config *conf, vector strvec) -+max_fds_handler(struct config *conf, vector strvec, const char *file, -+ int line_nr) - { - char * buff; - int r = 0, max_fds; -@@ -981,7 +995,7 @@ snprint_max_fds (struct config *conf, struct strbuf *buff, const void *data) - } - - static int --set_rr_weight(vector strvec, void *ptr) -+set_rr_weight(vector strvec, void *ptr, const char *file, int line_nr) - { - int *int_ptr = (int *)ptr; - char * buff; -@@ -1025,7 +1039,7 @@ declare_mp_handler(rr_weight, set_rr_weight) - declare_mp_snprint(rr_weight, print_rr_weight) - - static int --set_pgfailback(vector strvec, void *ptr) -+set_pgfailback(vector strvec, void *ptr, const char *file, int line_nr) - { - int *int_ptr = (int *)ptr; - char * buff; -@@ -1075,7 +1089,7 @@ declare_mp_handler(pgfailback, set_pgfailback) - declare_mp_snprint(pgfailback, print_pgfailback) - - static int --no_path_retry_helper(vector strvec, void *ptr) -+no_path_retry_helper(vector strvec, void *ptr, const char *file, int line_nr) - { - int *int_ptr = (int *)ptr; - char * buff; -@@ -1120,7 +1134,8 @@ declare_mp_handler(no_path_retry, no_path_retry_helper) - declare_mp_snprint(no_path_retry, print_no_path_retry) - - static int --def_log_checker_err_handler(struct config *conf, vector strvec) -+def_log_checker_err_handler(struct config *conf, vector strvec, -+ const char *file, int line_nr) - { - char * buff; - -@@ -1193,7 +1208,8 @@ print_reservation_key(struct strbuf *buff, - } - - static int --def_reservation_key_handler(struct config *conf, vector strvec) -+def_reservation_key_handler(struct config *conf, vector strvec, -+ const char *file, int line_nr) - { - return set_reservation_key(strvec, &conf->reservation_key, - &conf->sa_flags, -@@ -1209,7 +1225,8 @@ snprint_def_reservation_key (struct config *conf, struct strbuf *buff, - } - - static int --mp_reservation_key_handler(struct config *conf, vector strvec) -+mp_reservation_key_handler(struct config *conf, vector strvec, const char *file, -+ int line_nr) - { - struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable); - if (!mpe) -@@ -1229,7 +1246,7 @@ snprint_mp_reservation_key (struct config *conf, struct strbuf *buff, - } - - static int --set_off_int_undef(vector strvec, void *ptr) -+set_off_int_undef(vector strvec, void *ptr, const char *file, int line_nr) - { - int *int_ptr = (int *)ptr; - char * buff; -@@ -1370,7 +1387,8 @@ declare_hw_snprint(recheck_wwid, print_yes_no_undef) - - - static int --def_uxsock_timeout_handler(struct config *conf, vector strvec) -+def_uxsock_timeout_handler(struct config *conf, vector strvec, const char *file, -+ int line_nr) - { - unsigned int uxsock_timeout; - char *buff; -@@ -1390,7 +1408,8 @@ def_uxsock_timeout_handler(struct config *conf, vector strvec) - } - - static int --hw_vpd_vendor_handler(struct config *conf, vector strvec) -+hw_vpd_vendor_handler(struct config *conf, vector strvec, const char *file, -+ int line_nr) - { - int i; - char *buff; -@@ -1430,7 +1449,8 @@ snprint_hw_vpd_vendor(struct config *conf, struct strbuf *buff, - * blacklist block handlers - */ - static int --blacklist_handler(struct config *conf, vector strvec) -+blacklist_handler(struct config *conf, vector strvec, const char*file, -+ int line_nr) - { - if (!conf->blist_devnode) - conf->blist_devnode = vector_alloc(); -@@ -1452,7 +1472,8 @@ blacklist_handler(struct config *conf, vector strvec) - } - - static int --blacklist_exceptions_handler(struct config *conf, vector strvec) -+blacklist_exceptions_handler(struct config *conf, vector strvec, -+ const char *file, int line_nr) - { - if (!conf->elist_devnode) - conf->elist_devnode = vector_alloc(); -@@ -1475,7 +1496,8 @@ blacklist_exceptions_handler(struct config *conf, vector strvec) - - #define declare_ble_handler(option) \ - static int \ --ble_ ## option ## _handler (struct config *conf, vector strvec) \ -+ble_ ## option ## _handler (struct config *conf, vector strvec, \ -+ const char *file, int line_nr) \ - { \ - char *buff; \ - int rc; \ -@@ -1494,7 +1516,8 @@ ble_ ## option ## _handler (struct config *conf, vector strvec) \ - - #define declare_ble_device_handler(name, option, vend, prod) \ - static int \ --ble_ ## option ## _ ## name ## _handler (struct config *conf, vector strvec) \ -+ble_ ## option ## _ ## name ## _handler (struct config *conf, vector strvec, \ -+ const char *file, int line_nr) \ - { \ - char * buff; \ - int rc; \ -@@ -1536,13 +1559,15 @@ snprint_ble_simple (struct config *conf, struct strbuf *buff, const void *data) - } - - static int --ble_device_handler(struct config *conf, vector strvec) -+ble_device_handler(struct config *conf, vector strvec, const char *file, -+ int line_nr) - { - return alloc_ble_device(conf->blist_device); - } - - static int --ble_except_device_handler(struct config *conf, vector strvec) -+ble_except_device_handler(struct config *conf, vector strvec, const char *file, -+ int line_nr) - { - return alloc_ble_device(conf->elist_device); - } -@@ -1574,7 +1599,8 @@ static int snprint_bled_product(struct config *conf, struct strbuf *buff, - * devices block handlers - */ - static int --devices_handler(struct config *conf, vector strvec) -+devices_handler(struct config *conf, vector strvec, const char *file, -+ int line_nr) - { - if (!conf->hwtable) - conf->hwtable = vector_alloc(); -@@ -1586,7 +1612,8 @@ devices_handler(struct config *conf, vector strvec) - } - - static int --device_handler(struct config *conf, vector strvec) -+device_handler(struct config *conf, vector strvec, const char *file, -+ int line_nr) - { - struct hwentry * hwe; - -@@ -1623,7 +1650,8 @@ declare_hw_snprint(hwhandler, print_str) - * overrides handlers - */ - static int --overrides_handler(struct config *conf, vector strvec) -+overrides_handler(struct config *conf, vector strvec, const char *file, -+ int line_nr) - { - if (!conf->overrides) - conf->overrides = alloc_hwe(); -@@ -1640,7 +1668,8 @@ overrides_handler(struct config *conf, vector strvec) - * multipaths block handlers - */ - static int --multipaths_handler(struct config *conf, vector strvec) -+multipaths_handler(struct config *conf, vector strvec, const char *file, -+ int line_nr) - { - if (!conf->mptable) - conf->mptable = vector_alloc(); -@@ -1652,7 +1681,8 @@ multipaths_handler(struct config *conf, vector strvec) - } - - static int --multipath_handler(struct config *conf, vector strvec) -+multipath_handler(struct config *conf, vector strvec, const char *file, -+ int line_nr) - { - struct mpentry * mpe; - -@@ -1681,7 +1711,8 @@ declare_mp_snprint(alias, print_str) - */ - - static int --deprecated_handler(struct config *conf, vector strvec) -+deprecated_handler(struct config *conf, vector strvec, const char *file, -+ int line_nr) - { - char * buff; - -diff --git a/libmultipath/parser.c b/libmultipath/parser.c -index d5595fb0..68262d0e 100644 ---- a/libmultipath/parser.c -+++ b/libmultipath/parser.c -@@ -558,7 +558,8 @@ process_stream(struct config *conf, FILE *stream, vector keywords, - goto out; - } - if (keyword->handler) { -- t = keyword->handler(conf, strvec); -+ t = keyword->handler(conf, strvec, file, -+ line_nr); - r += t; - if (t) - condlog(1, "%s line %d, parsing failed: %s", -diff --git a/libmultipath/parser.h b/libmultipath/parser.h -index 3452bde1..11ea2278 100644 ---- a/libmultipath/parser.h -+++ b/libmultipath/parser.h -@@ -43,7 +43,7 @@ struct strbuf; - - /* keyword definition */ - typedef int print_fn(struct config *, struct strbuf *, const void *); --typedef int handler_fn(struct config *, vector); -+typedef int handler_fn(struct config *, vector, const char *file, int line_nr); - - struct keyword { - char *string; diff --git a/0018-libmultipath-make-set_int-take-a-range-for-valid-val.patch b/0018-libmultipath-make-set_int-take-a-range-for-valid-val.patch deleted file mode 100644 index 21969af..0000000 --- a/0018-libmultipath-make-set_int-take-a-range-for-valid-val.patch +++ /dev/null @@ -1,251 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 11 Nov 2021 12:53:48 -0600 -Subject: [PATCH] libmultipath: make set_int take a range for valid values - -If a value outside of the valid range is passed to set_int, it caps the -value at appropriate limit, and issues a warning. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/dict.c | 121 +++++++++++++++++++++++++++----------------- - 1 file changed, 75 insertions(+), 46 deletions(-) - -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index eb2c44c0..57b6a7b6 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -29,7 +29,8 @@ - #include "strbuf.h" - - static int --set_int(vector strvec, void *ptr, const char *file, int line_nr) -+set_int(vector strvec, void *ptr, int min, int max, const char *file, -+ int line_nr) - { - int *int_ptr = (int *)ptr; - char *buff, *eptr; -@@ -44,11 +45,17 @@ set_int(vector strvec, void *ptr, const char *file, int line_nr) - if (eptr > buff) - while (isspace(*eptr)) - eptr++; -- if (*buff == '\0' || *eptr != '\0' || res > INT_MAX || res < INT_MIN) { -- condlog(1, "%s: invalid value for %s: \"%s\"", -- __func__, (char*)VECTOR_SLOT(strvec, 0), buff); -+ if (*buff == '\0' || *eptr != '\0') { -+ condlog(1, "%s line %d, invalid value for %s: \"%s\"", -+ file, line_nr, (char*)VECTOR_SLOT(strvec, 0), buff); - rc = 1; - } else { -+ if (res > max || res < min) { -+ res = (res > max) ? max : min; -+ condlog(1, "%s line %d, value for %s too %s, capping at %ld", -+ file, line_nr, (char*)VECTOR_SLOT(strvec, 0), -+ (res == max)? "large" : "small", res); -+ } - rc = 0; - *int_ptr = res; - } -@@ -77,8 +84,8 @@ set_uint(vector strvec, void *ptr, const char *file, int line_nr) - while (isspace(*eptr)) - eptr++; - if (*buff == '\0' || *eptr != '\0' || !isdigit(*p) || res > UINT_MAX) { -- condlog(1, "%s: invalid value for %s: \"%s\"", -- __func__, (char*)VECTOR_SLOT(strvec, 0), buff); -+ condlog(1, "%s line %d, invalid value for %s: \"%s\"", -+ file, line_nr, (char*)VECTOR_SLOT(strvec, 0), buff); - rc = 1; - } else { - rc = 0; -@@ -193,6 +200,14 @@ def_ ## option ## _handler (struct config *conf, vector strvec, \ - return function (strvec, &conf->option, file, line_nr); \ - } - -+#define declare_def_range_handler(option, minval, maxval) \ -+static int \ -+def_ ## option ## _handler (struct config *conf, vector strvec, \ -+ const char *file, int line_nr) \ -+{ \ -+ return set_int(strvec, &conf->option, minval, maxval, file, line_nr); \ -+} -+ - #define declare_def_snprint(option, function) \ - static int \ - snprint_def_ ## option (struct config *conf, struct strbuf *buff, \ -@@ -234,6 +249,18 @@ hw_ ## option ## _handler (struct config *conf, vector strvec, \ - return function (strvec, &hwe->option, file, line_nr); \ - } - -+#define declare_hw_range_handler(option, minval, maxval) \ -+static int \ -+hw_ ## option ## _handler (struct config *conf, vector strvec, \ -+ const char *file, int line_nr) \ -+{ \ -+ struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable); \ -+ if (!hwe) \ -+ return 1; \ -+ return set_int(strvec, &hwe->option, minval, maxval, file, line_nr); \ -+} -+ -+ - #define declare_hw_snprint(option, function) \ - static int \ - snprint_hw_ ## option (struct config *conf, struct strbuf *buff, \ -@@ -253,6 +280,17 @@ ovr_ ## option ## _handler (struct config *conf, vector strvec, \ - return function (strvec, &conf->overrides->option, file, line_nr); \ - } - -+#define declare_ovr_range_handler(option, minval, maxval) \ -+static int \ -+ovr_ ## option ## _handler (struct config *conf, vector strvec, \ -+ const char *file, int line_nr) \ -+{ \ -+ if (!conf->overrides) \ -+ return 1; \ -+ return set_int(strvec, &conf->overrides->option, minval, maxval, \ -+ file, line_nr); \ -+} -+ - #define declare_ovr_snprint(option, function) \ - static int \ - snprint_ovr_ ## option (struct config *conf, struct strbuf *buff, \ -@@ -272,6 +310,17 @@ mp_ ## option ## _handler (struct config *conf, vector strvec, \ - return function (strvec, &mpe->option, file, line_nr); \ - } - -+#define declare_mp_range_handler(option, minval, maxval) \ -+static int \ -+mp_ ## option ## _handler (struct config *conf, vector strvec, \ -+ const char *file, int line_nr) \ -+{ \ -+ struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable); \ -+ if (!mpe) \ -+ return 1; \ -+ return set_int(strvec, &mpe->option, minval, maxval, file, line_nr); \ -+} -+ - #define declare_mp_snprint(option, function) \ - static int \ - snprint_mp_ ## option (struct config *conf, struct strbuf *buff, \ -@@ -298,7 +347,7 @@ declare_def_snprint(checkint, print_int) - declare_def_handler(max_checkint, set_uint) - declare_def_snprint(max_checkint, print_int) - --declare_def_handler(verbosity, set_int) -+declare_def_range_handler(verbosity, 0, MAX_VERBOSITY) - declare_def_snprint(verbosity, print_int) - - declare_def_handler(reassign_maps, set_yes_no) -@@ -473,22 +522,22 @@ declare_ovr_snprint(checker_name, print_str) - declare_hw_handler(checker_name, set_str) - declare_hw_snprint(checker_name, print_str) - --declare_def_handler(minio, set_int) -+declare_def_range_handler(minio, 0, INT_MAX) - declare_def_snprint_defint(minio, print_int, DEFAULT_MINIO) --declare_ovr_handler(minio, set_int) -+declare_ovr_range_handler(minio, 0, INT_MAX) - declare_ovr_snprint(minio, print_nonzero) --declare_hw_handler(minio, set_int) -+declare_hw_range_handler(minio, 0, INT_MAX) - declare_hw_snprint(minio, print_nonzero) --declare_mp_handler(minio, set_int) -+declare_mp_range_handler(minio, 0, INT_MAX) - declare_mp_snprint(minio, print_nonzero) - --declare_def_handler(minio_rq, set_int) -+declare_def_range_handler(minio_rq, 0, INT_MAX) - declare_def_snprint_defint(minio_rq, print_int, DEFAULT_MINIO_RQ) --declare_ovr_handler(minio_rq, set_int) -+declare_ovr_range_handler(minio_rq, 0, INT_MAX) - declare_ovr_snprint(minio_rq, print_nonzero) --declare_hw_handler(minio_rq, set_int) -+declare_hw_range_handler(minio_rq, 0, INT_MAX) - declare_hw_snprint(minio_rq, print_nonzero) --declare_mp_handler(minio_rq, set_int) -+declare_mp_range_handler(minio_rq, 0, INT_MAX) - declare_mp_snprint(minio_rq, print_nonzero) - - declare_def_handler(queue_without_daemon, set_yes_no) -@@ -512,7 +561,7 @@ snprint_def_queue_without_daemon(struct config *conf, struct strbuf *buff, - return append_strbuf_quoted(buff, qwd); - } - --declare_def_handler(checker_timeout, set_int) -+declare_def_range_handler(checker_timeout, 0, INT_MAX) - declare_def_snprint(checker_timeout, print_nonzero) - - declare_def_handler(allow_usb_devices, set_yes_no) -@@ -583,13 +632,13 @@ declare_hw_snprint(deferred_remove, print_yes_no_undef) - declare_mp_handler(deferred_remove, set_yes_no_undef) - declare_mp_snprint(deferred_remove, print_yes_no_undef) - --declare_def_handler(retrigger_tries, set_int) -+declare_def_range_handler(retrigger_tries, 0, INT_MAX) - declare_def_snprint(retrigger_tries, print_int) - --declare_def_handler(retrigger_delay, set_int) -+declare_def_range_handler(retrigger_delay, 0, INT_MAX) - declare_def_snprint(retrigger_delay, print_int) - --declare_def_handler(uev_wait_timeout, set_int) -+declare_def_range_handler(uev_wait_timeout, 0, INT_MAX) - declare_def_snprint(uev_wait_timeout, print_int) - - declare_def_handler(strict_timing, set_yes_no) -@@ -616,19 +665,19 @@ static int snprint_def_disable_changed_wwids(struct config *conf, - return print_ignored(buff); - } - --declare_def_handler(remove_retries, set_int) -+declare_def_range_handler(remove_retries, 0, INT_MAX) - declare_def_snprint(remove_retries, print_int) - --declare_def_handler(max_sectors_kb, set_int) -+declare_def_range_handler(max_sectors_kb, 0, INT_MAX) - declare_def_snprint(max_sectors_kb, print_nonzero) --declare_ovr_handler(max_sectors_kb, set_int) -+declare_ovr_range_handler(max_sectors_kb, 0, INT_MAX) - declare_ovr_snprint(max_sectors_kb, print_nonzero) --declare_hw_handler(max_sectors_kb, set_int) -+declare_hw_range_handler(max_sectors_kb, 0, INT_MAX) - declare_hw_snprint(max_sectors_kb, print_nonzero) --declare_mp_handler(max_sectors_kb, set_int) -+declare_mp_range_handler(max_sectors_kb, 0, INT_MAX) - declare_mp_snprint(max_sectors_kb, print_nonzero) - --declare_def_handler(find_multipaths_timeout, set_int) -+declare_def_range_handler(find_multipaths_timeout, INT_MIN, INT_MAX) - declare_def_snprint_defint(find_multipaths_timeout, print_int, - DEFAULT_FIND_MULTIPATHS_TIMEOUT) - -@@ -1385,27 +1434,7 @@ declare_ovr_snprint(recheck_wwid, print_yes_no_undef) - declare_hw_handler(recheck_wwid, set_yes_no_undef) - declare_hw_snprint(recheck_wwid, print_yes_no_undef) - -- --static int --def_uxsock_timeout_handler(struct config *conf, vector strvec, const char *file, -- int line_nr) --{ -- unsigned int uxsock_timeout; -- char *buff; -- -- buff = set_value(strvec); -- if (!buff) -- return 1; -- -- if (sscanf(buff, "%u", &uxsock_timeout) == 1 && -- uxsock_timeout > DEFAULT_REPLY_TIMEOUT) -- conf->uxsock_timeout = uxsock_timeout; -- else -- conf->uxsock_timeout = DEFAULT_REPLY_TIMEOUT; -- -- free(buff); -- return 0; --} -+declare_def_range_handler(uxsock_timeout, DEFAULT_REPLY_TIMEOUT, INT_MAX) - - static int - hw_vpd_vendor_handler(struct config *conf, vector strvec, const char *file, diff --git a/0019-libmultipath-improve-checks-for-set_str.patch b/0019-libmultipath-improve-checks-for-set_str.patch deleted file mode 100644 index 0cd8627..0000000 --- a/0019-libmultipath-improve-checks-for-set_str.patch +++ /dev/null @@ -1,171 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 11 Nov 2021 12:53:49 -0600 -Subject: [PATCH] libmultipath: improve checks for set_str - -multipath always requires absolute pathnames, so make sure all file and -directory names start with a slash. Also check that the directories -exist. Finally, some strings, like the alias, will be used in paths. -These must not contain the slash character '/', since it is a forbidden -character in file/directory names. This patch adds seperate handlers for -these three cases. If a config line is invalid, these handlers retain -the existing config string, if any. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/dict.c | 88 +++++++++++++++++++++++++++++++++++++++------ - 1 file changed, 78 insertions(+), 10 deletions(-) - -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index 57b6a7b6..149d3348 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -5,6 +5,8 @@ - * Copyright (c) 2005 Kiyoshi Ueda, NEC - */ - #include -+#include -+#include - #include - #include - #include "checkers.h" -@@ -111,6 +113,72 @@ set_str(vector strvec, void *ptr, const char *file, int line_nr) - return 0; - } - -+static int -+set_dir(vector strvec, void *ptr, const char *file, int line_nr) -+{ -+ char **str_ptr = (char **)ptr; -+ char *old_str = *str_ptr; -+ struct stat sb; -+ -+ *str_ptr = set_value(strvec); -+ if (!*str_ptr) { -+ free(old_str); -+ return 1; -+ } -+ if ((*str_ptr)[0] != '/'){ -+ condlog(1, "%s line %d, %s is not an absolute directory path. Ignoring", file, line_nr, *str_ptr); -+ *str_ptr = old_str; -+ } else { -+ if (stat(*str_ptr, &sb) == 0 && S_ISDIR(sb.st_mode)) -+ free(old_str); -+ else { -+ condlog(1, "%s line %d, %s is not an existing directory. Ignoring", file, line_nr, *str_ptr); -+ *str_ptr = old_str; -+ } -+ } -+ return 0; -+} -+ -+static int -+set_path(vector strvec, void *ptr, const char *file, int line_nr) -+{ -+ char **str_ptr = (char **)ptr; -+ char *old_str = *str_ptr; -+ -+ *str_ptr = set_value(strvec); -+ if (!*str_ptr) { -+ free(old_str); -+ return 1; -+ } -+ if ((*str_ptr)[0] != '/'){ -+ condlog(1, "%s line %d, %s is not an absolute path. Ignoring", -+ file, line_nr, *str_ptr); -+ *str_ptr = old_str; -+ } else -+ free(old_str); -+ return 0; -+} -+ -+static int -+set_str_noslash(vector strvec, void *ptr, const char *file, int line_nr) -+{ -+ char **str_ptr = (char **)ptr; -+ char *old_str = *str_ptr; -+ -+ *str_ptr = set_value(strvec); -+ if (!*str_ptr) { -+ free(old_str); -+ return 1; -+ } -+ if (strchr(*str_ptr, '/')) { -+ condlog(1, "%s line %d, %s cannot contain a slash. Ignoring", -+ file, line_nr, *str_ptr); -+ *str_ptr = old_str; -+ } else -+ free(old_str); -+ return 0; -+} -+ - static int - set_yes_no(vector strvec, void *ptr, const char *file, int line_nr) - { -@@ -353,13 +421,13 @@ declare_def_snprint(verbosity, print_int) - declare_def_handler(reassign_maps, set_yes_no) - declare_def_snprint(reassign_maps, print_yes_no) - --declare_def_handler(multipath_dir, set_str) -+declare_def_handler(multipath_dir, set_dir) - declare_def_snprint(multipath_dir, print_str) - - static int def_partition_delim_handler(struct config *conf, vector strvec, - const char *file, int line_nr) - { -- int rc = set_str(strvec, &conf->partition_delim, file, line_nr); -+ int rc = set_str_noslash(strvec, &conf->partition_delim, file, line_nr); - - if (rc != 0) - return rc; -@@ -490,11 +558,11 @@ declare_hw_snprint(prio_name, print_str) - declare_mp_handler(prio_name, set_str) - declare_mp_snprint(prio_name, print_str) - --declare_def_handler(alias_prefix, set_str) -+declare_def_handler(alias_prefix, set_str_noslash) - declare_def_snprint_defstr(alias_prefix, print_str, DEFAULT_ALIAS_PREFIX) --declare_ovr_handler(alias_prefix, set_str) -+declare_ovr_handler(alias_prefix, set_str_noslash) - declare_ovr_snprint(alias_prefix, print_str) --declare_hw_handler(alias_prefix, set_str) -+declare_hw_handler(alias_prefix, set_str_noslash) - declare_hw_snprint(alias_prefix, print_str) - - declare_def_handler(prio_args, set_str) -@@ -586,13 +654,13 @@ declare_hw_snprint(user_friendly_names, print_yes_no_undef) - declare_mp_handler(user_friendly_names, set_yes_no_undef) - declare_mp_snprint(user_friendly_names, print_yes_no_undef) - --declare_def_handler(bindings_file, set_str) -+declare_def_handler(bindings_file, set_path) - declare_def_snprint(bindings_file, print_str) - --declare_def_handler(wwids_file, set_str) -+declare_def_handler(wwids_file, set_path) - declare_def_snprint(wwids_file, print_str) - --declare_def_handler(prkeys_file, set_str) -+declare_def_handler(prkeys_file, set_path) - declare_def_snprint(prkeys_file, print_str) - - declare_def_handler(retain_hwhandler, set_yes_no_undef) -@@ -692,7 +760,7 @@ def_config_dir_handler(struct config *conf, vector strvec, const char *file, - /* this is only valid in the main config file */ - if (conf->processed_main_config) - return 0; -- return set_str(strvec, &conf->config_dir, file, line_nr); -+ return set_path(strvec, &conf->config_dir, file, line_nr); - } - declare_def_snprint(config_dir, print_str) - -@@ -1732,7 +1800,7 @@ multipath_handler(struct config *conf, vector strvec, const char *file, - declare_mp_handler(wwid, set_str) - declare_mp_snprint(wwid, print_str) - --declare_mp_handler(alias, set_str) -+declare_mp_handler(alias, set_str_noslash) - declare_mp_snprint(alias, print_str) - - /* diff --git a/0020-libmultipath-deprecate-file-and-directory-config-opt.patch b/0020-libmultipath-deprecate-file-and-directory-config-opt.patch deleted file mode 100644 index 32e1b23..0000000 --- a/0020-libmultipath-deprecate-file-and-directory-config-opt.patch +++ /dev/null @@ -1,115 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 11 Nov 2021 12:53:50 -0600 -Subject: [PATCH] libmultipath: deprecate file and directory config options - -Having multipath able to select pathnames for the files and directories -it needs causes unnecessary maintainer headaches. Mark these as -deprecated, but still support them for now. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/dict.c | 19 +++++++++++++++---- - multipath/multipath.conf.5 | 5 +++++ - 2 files changed, 20 insertions(+), 4 deletions(-) - -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index 149d3348..d14be340 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -268,6 +268,15 @@ def_ ## option ## _handler (struct config *conf, vector strvec, \ - return function (strvec, &conf->option, file, line_nr); \ - } - -+#define declare_def_warn_handler(option, function) \ -+static int \ -+def_ ## option ## _handler (struct config *conf, vector strvec, \ -+ const char *file, int line_nr) \ -+{ \ -+ condlog(2, "%s line %d, \"" #option "\" is deprecated and will be disabled in a future release", file, line_nr); \ -+ return function (strvec, &conf->option, file, line_nr); \ -+} -+ - #define declare_def_range_handler(option, minval, maxval) \ - static int \ - def_ ## option ## _handler (struct config *conf, vector strvec, \ -@@ -421,7 +430,7 @@ declare_def_snprint(verbosity, print_int) - declare_def_handler(reassign_maps, set_yes_no) - declare_def_snprint(reassign_maps, print_yes_no) - --declare_def_handler(multipath_dir, set_dir) -+declare_def_warn_handler(multipath_dir, set_dir) - declare_def_snprint(multipath_dir, print_str) - - static int def_partition_delim_handler(struct config *conf, vector strvec, -@@ -654,13 +663,13 @@ declare_hw_snprint(user_friendly_names, print_yes_no_undef) - declare_mp_handler(user_friendly_names, set_yes_no_undef) - declare_mp_snprint(user_friendly_names, print_yes_no_undef) - --declare_def_handler(bindings_file, set_path) -+declare_def_warn_handler(bindings_file, set_path) - declare_def_snprint(bindings_file, print_str) - --declare_def_handler(wwids_file, set_path) -+declare_def_warn_handler(wwids_file, set_path) - declare_def_snprint(wwids_file, print_str) - --declare_def_handler(prkeys_file, set_path) -+declare_def_warn_handler(prkeys_file, set_path) - declare_def_snprint(prkeys_file, print_str) - - declare_def_handler(retain_hwhandler, set_yes_no_undef) -@@ -760,6 +769,8 @@ def_config_dir_handler(struct config *conf, vector strvec, const char *file, - /* this is only valid in the main config file */ - if (conf->processed_main_config) - return 0; -+ condlog(2, "%s line %d, \"config_dir\" is deprecated and will be disabled in a future release", -+ file, line_nr); - return set_path(strvec, &conf->config_dir, file, line_nr); - } - declare_def_snprint(config_dir, print_str) -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index c74129bd..88d2a1df 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -178,6 +178,7 @@ The default is: \fBno\fR - . - .TP - .B multipath_dir -+This option is deprecated, and will be removed in a future release. - Directory where the dynamic shared objects are stored. Defined at compile time, - commonly \fI/lib64/multipath/\fR or \fI/lib/multipath/\fR. - .RS -@@ -742,6 +743,7 @@ The default is: \fB\fR - . - .TP - .B bindings_file -+This option is deprecated, and will be removed in a future release. - The full pathname of the binding file to be used when the user_friendly_names - option is set. - .RS -@@ -752,6 +754,7 @@ The default is: \fB/etc/multipath/bindings\fR - . - .TP - .B wwids_file -+This option is deprecated, and will be removed in a future release. - The full pathname of the WWIDs file, which is used by multipath to keep track - of the WWIDs for LUNs it has created multipath devices on in the past. - .RS -@@ -762,6 +765,7 @@ The default is: \fB/etc/multipath/wwids\fR - . - .TP - .B prkeys_file -+This option is deprecated, and will be removed in a future release. - The full pathname of the prkeys file, which is used by multipathd to keep - track of the persistent reservation key used for a specific WWID, when - \fIreservation_key\fR is set to \fBfile\fR. -@@ -933,6 +937,7 @@ The default is: \fB\fR - . - .TP - .B config_dir -+This option is deprecated, and will be removed in a future release. - If set to anything other than "", multipath will search this directory - alphabetically for file ending in ".conf" and it will read configuration - information from them, just as if it was in \fI/etc/multipath.conf\fR. diff --git a/0021-libmultipath-split-set_int-to-enable-reuse.patch b/0021-libmultipath-split-set_int-to-enable-reuse.patch deleted file mode 100644 index 4f4b09a..0000000 --- a/0021-libmultipath-split-set_int-to-enable-reuse.patch +++ /dev/null @@ -1,192 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 11 Nov 2021 12:53:51 -0600 -Subject: [PATCH] libmultipath: split set_int to enable reuse - -Split the code that does the actual value parsing out of set_int(), into -a helper function, do_set_int(), so that it can be used by other -handlers. These functions no longer set the config value at all, when -they have invalid input. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/dict.c | 82 +++++++++++++++++++++++++-------------------- - 1 file changed, 46 insertions(+), 36 deletions(-) - -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index d14be340..68647061 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -31,17 +31,12 @@ - #include "strbuf.h" - - static int --set_int(vector strvec, void *ptr, int min, int max, const char *file, -- int line_nr) -+do_set_int(vector strvec, void *ptr, int min, int max, const char *file, -+ int line_nr, char *buff) - { - int *int_ptr = (int *)ptr; -- char *buff, *eptr; -+ char *eptr; - long res; -- int rc; -- -- buff = set_value(strvec); -- if (!buff) -- return 1; - - res = strtol(buff, &eptr, 10); - if (eptr > buff) -@@ -50,17 +45,30 @@ set_int(vector strvec, void *ptr, int min, int max, const char *file, - if (*buff == '\0' || *eptr != '\0') { - condlog(1, "%s line %d, invalid value for %s: \"%s\"", - file, line_nr, (char*)VECTOR_SLOT(strvec, 0), buff); -- rc = 1; -- } else { -- if (res > max || res < min) { -- res = (res > max) ? max : min; -- condlog(1, "%s line %d, value for %s too %s, capping at %ld", -+ return 1; -+ } -+ if (res > max || res < min) { -+ res = (res > max) ? max : min; -+ condlog(1, "%s line %d, value for %s too %s, capping at %ld", - file, line_nr, (char*)VECTOR_SLOT(strvec, 0), -- (res == max)? "large" : "small", res); -- } -- rc = 0; -- *int_ptr = res; -+ (res == max)? "large" : "small", res); - } -+ *int_ptr = res; -+ return 0; -+} -+ -+static int -+set_int(vector strvec, void *ptr, int min, int max, const char *file, -+ int line_nr) -+{ -+ char *buff; -+ int rc; -+ -+ buff = set_value(strvec); -+ if (!buff) -+ return 1; -+ -+ rc = do_set_int(strvec, ptr, min, max, file, line_nr, buff); - - FREE(buff); - return rc; -@@ -929,6 +937,7 @@ declare_mp_attr_snprint(gid, print_gid) - static int - set_undef_off_zero(vector strvec, void *ptr, const char *file, int line_nr) - { -+ int rc = 0; - char * buff; - int *int_ptr = (int *)ptr; - -@@ -938,10 +947,10 @@ set_undef_off_zero(vector strvec, void *ptr, const char *file, int line_nr) - - if (strcmp(buff, "off") == 0) - *int_ptr = UOZ_OFF; -- else if (sscanf(buff, "%d", int_ptr) != 1 || -- *int_ptr < UOZ_ZERO) -- *int_ptr = UOZ_UNDEF; -- else if (*int_ptr == 0) -+ else -+ rc = do_set_int(strvec, int_ptr, 0, INT_MAX, file, line_nr, -+ buff); -+ if (rc == 0 && *int_ptr == 0) - *int_ptr = UOZ_ZERO; - - FREE(buff); -@@ -1093,14 +1102,12 @@ max_fds_handler(struct config *conf, vector strvec, const char *file, - /* Assume safe limit */ - max_fds = 4096; - } -- if (strlen(buff) == 3 && -- !strcmp(buff, "max")) -- conf->max_fds = max_fds; -- else -- conf->max_fds = atoi(buff); -- -- if (conf->max_fds > max_fds) -+ if (!strcmp(buff, "max")) { - conf->max_fds = max_fds; -+ r = 0; -+ } else -+ r = do_set_int(strvec, &conf->max_fds, 0, max_fds, file, -+ line_nr, buff); - - FREE(buff); - -@@ -1169,6 +1176,7 @@ declare_mp_snprint(rr_weight, print_rr_weight) - static int - set_pgfailback(vector strvec, void *ptr, const char *file, int line_nr) - { -+ int rc = 0; - int *int_ptr = (int *)ptr; - char * buff; - -@@ -1183,11 +1191,11 @@ set_pgfailback(vector strvec, void *ptr, const char *file, int line_nr) - else if (strlen(buff) == 10 && !strcmp(buff, "followover")) - *int_ptr = -FAILBACK_FOLLOWOVER; - else -- *int_ptr = atoi(buff); -+ rc = do_set_int(strvec, ptr, 0, INT_MAX, file, line_nr, buff); - - FREE(buff); - -- return 0; -+ return rc; - } - - int -@@ -1219,6 +1227,7 @@ declare_mp_snprint(pgfailback, print_pgfailback) - static int - no_path_retry_helper(vector strvec, void *ptr, const char *file, int line_nr) - { -+ int rc = 0; - int *int_ptr = (int *)ptr; - char * buff; - -@@ -1230,11 +1239,11 @@ no_path_retry_helper(vector strvec, void *ptr, const char *file, int line_nr) - *int_ptr = NO_PATH_RETRY_FAIL; - else if (!strcmp(buff, "queue")) - *int_ptr = NO_PATH_RETRY_QUEUE; -- else if ((*int_ptr = atoi(buff)) < 1) -- *int_ptr = NO_PATH_RETRY_UNDEF; -+ else -+ rc = do_set_int(strvec, ptr, 1, INT_MAX, file, line_nr, buff); - - FREE(buff); -- return 0; -+ return rc; - } - - int -@@ -1376,6 +1385,7 @@ snprint_mp_reservation_key (struct config *conf, struct strbuf *buff, - static int - set_off_int_undef(vector strvec, void *ptr, const char *file, int line_nr) - { -+ int rc =0; - int *int_ptr = (int *)ptr; - char * buff; - -@@ -1385,11 +1395,11 @@ set_off_int_undef(vector strvec, void *ptr, const char *file, int line_nr) - - if (!strcmp(buff, "no") || !strcmp(buff, "0")) - *int_ptr = NU_NO; -- else if ((*int_ptr = atoi(buff)) < 1) -- *int_ptr = NU_UNDEF; -+ else -+ rc = do_set_int(strvec, ptr, 1, INT_MAX, file, line_nr, buff); - - FREE(buff); -- return 0; -+ return rc; - } - - int diff --git a/0022-libmultipath-cleanup-invalid-config-handling.patch b/0022-libmultipath-cleanup-invalid-config-handling.patch deleted file mode 100644 index fcdca11..0000000 --- a/0022-libmultipath-cleanup-invalid-config-handling.patch +++ /dev/null @@ -1,202 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 11 Nov 2021 12:53:52 -0600 -Subject: [PATCH] libmultipath: cleanup invalid config handling - -Add error reporting to the remaining config handlers. If the value is -invalid, do not change the existing config option's value. Also print -an error whenever 0 is returned for an invalid value. When the handler -returns 1, config processing already fails with an error message. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/dict.c | 73 +++++++++++++++++++++++++++++++-------------- - 1 file changed, 51 insertions(+), 22 deletions(-) - -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index 68647061..c534d703 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -199,8 +199,11 @@ set_yes_no(vector strvec, void *ptr, const char *file, int line_nr) - - if (strcmp(buff, "yes") == 0 || strcmp(buff, "1") == 0) - *int_ptr = YN_YES; -- else -+ else if (strcmp(buff, "no") == 0 || strcmp(buff, "0") == 0) - *int_ptr = YN_NO; -+ else -+ condlog(1, "%s line %d, invalid value for %s: \"%s\"", -+ file, line_nr, (char*)VECTOR_SLOT(strvec, 0), buff); - - FREE(buff); - return 0; -@@ -221,7 +224,8 @@ set_yes_no_undef(vector strvec, void *ptr, const char *file, int line_nr) - else if (strcmp(buff, "yes") == 0 || strcmp(buff, "1") == 0) - *int_ptr = YNU_YES; - else -- *int_ptr = YNU_UNDEF; -+ condlog(1, "%s line %d, invalid value for %s: \"%s\"", -+ file, line_nr, (char*)VECTOR_SLOT(strvec, 0), buff); - - FREE(buff); - return 0; -@@ -480,9 +484,6 @@ def_find_multipaths_handler(struct config *conf, vector strvec, - char *buff; - int i; - -- if (set_yes_no_undef(strvec, &conf->find_multipaths, file, line_nr) == 0 && conf->find_multipaths != FIND_MULTIPATHS_UNDEF) -- return 0; -- - buff = set_value(strvec); - if (!buff) - return 1; -@@ -495,9 +496,14 @@ def_find_multipaths_handler(struct config *conf, vector strvec, - } - } - -- if (conf->find_multipaths == YNU_UNDEF) { -- condlog(0, "illegal value for find_multipaths: %s", buff); -- conf->find_multipaths = DEFAULT_FIND_MULTIPATHS; -+ if (i >= __FIND_MULTIPATHS_LAST) { -+ if (strcmp(buff, "no") == 0 || strcmp(buff, "0") == 0) -+ conf->find_multipaths = FIND_MULTIPATHS_OFF; -+ else if (strcmp(buff, "yes") == 0 || strcmp(buff, "1") == 0) -+ conf->find_multipaths = FIND_MULTIPATHS_ON; -+ else -+ condlog(1, "%s line %d, invalid value for find_multipaths: \"%s\"", -+ file, line_nr, buff); - } - - FREE(buff); -@@ -546,8 +552,10 @@ static int uid_attrs_handler(struct config *conf, vector strvec, - if (!val) - return 1; - if (parse_uid_attrs(val, conf)) -- condlog(1, "error parsing uid_attrs: \"%s\"", val); -- condlog(3, "parsed %d uid_attrs", VECTOR_SIZE(&conf->uid_attrs)); -+ condlog(1, "%s line %d,error parsing uid_attrs: \"%s\"", file, -+ line_nr, val); -+ else -+ condlog(4, "parsed %d uid_attrs", VECTOR_SIZE(&conf->uid_attrs)); - FREE(val); - return 0; - } -@@ -775,8 +783,11 @@ def_config_dir_handler(struct config *conf, vector strvec, const char *file, - int line_nr) - { - /* this is only valid in the main config file */ -- if (conf->processed_main_config) -+ if (conf->processed_main_config) { -+ condlog(1, "%s line %d, config_dir option only valid in /etc/multipath.conf", -+ file, line_nr); - return 0; -+ } - condlog(2, "%s line %d, \"config_dir\" is deprecated and will be disabled in a future release", - file, line_nr); - return set_path(strvec, &conf->config_dir, file, line_nr); -@@ -836,7 +847,9 @@ set_mode(vector strvec, void *ptr, int *flags, const char *file, int line_nr) - if (sscanf(buff, "%o", &mode) == 1 && mode <= 0777) { - *flags |= (1 << ATTR_MODE); - *mode_ptr = mode; -- } -+ } else -+ condlog(1, "%s line %d, invalid value for mode: \"%s\"", -+ file, line_nr, buff); - - FREE(buff); - return 0; -@@ -861,7 +874,9 @@ set_uid(vector strvec, void *ptr, int *flags, const char *file, int line_nr) - else if (sscanf(buff, "%u", &uid) == 1){ - *flags |= (1 << ATTR_UID); - *uid_ptr = uid; -- } -+ } else -+ condlog(1, "%s line %d, invalid value for uid: \"%s\"", -+ file, line_nr, buff); - - FREE(buff); - return 0; -@@ -887,7 +902,9 @@ set_gid(vector strvec, void *ptr, int *flags, const char *file, int line_nr) - else if (sscanf(buff, "%u", &gid) == 1){ - *flags |= (1 << ATTR_GID); - *gid_ptr = gid; -- } -+ } else -+ condlog(1, "%s line %d, invalid value for gid: \"%s\"", -+ file, line_nr, buff); - FREE(buff); - return 0; - } -@@ -989,7 +1006,8 @@ set_dev_loss(vector strvec, void *ptr, const char *file, int line_nr) - if (!strcmp(buff, "infinity")) - *uint_ptr = MAX_DEV_LOSS_TMO; - else if (sscanf(buff, "%u", uint_ptr) != 1) -- *uint_ptr = DEV_LOSS_TMO_UNSET; -+ condlog(1, "%s line %d, invalid value for dev_loss_tmo: \"%s\"", -+ file, line_nr, buff); - - FREE(buff); - return 0; -@@ -1023,13 +1041,19 @@ static int - set_pgpolicy(vector strvec, void *ptr, const char *file, int line_nr) - { - char * buff; -+ int policy; - int *int_ptr = (int *)ptr; - - buff = set_value(strvec); - if (!buff) - return 1; - -- *int_ptr = get_pgpolicy_id(buff); -+ policy = get_pgpolicy_id(buff); -+ if (policy != IOPOLICY_UNDEF) -+ *int_ptr = policy; -+ else -+ condlog(1, "%s line %d, invalid value for path_grouping_policy: \"%s\"", -+ file, line_nr, buff); - FREE(buff); - - return 0; -@@ -1142,10 +1166,11 @@ set_rr_weight(vector strvec, void *ptr, const char *file, int line_nr) - - if (!strcmp(buff, "priorities")) - *int_ptr = RR_WEIGHT_PRIO; -- -- if (!strcmp(buff, "uniform")) -+ else if (!strcmp(buff, "uniform")) - *int_ptr = RR_WEIGHT_NONE; -- -+ else -+ condlog(1, "%s line %d, invalid value for rr_weight: \"%s\"", -+ file, line_nr, buff); - FREE(buff); - - return 0; -@@ -1281,10 +1306,13 @@ def_log_checker_err_handler(struct config *conf, vector strvec, - if (!buff) - return 1; - -- if (strlen(buff) == 4 && !strcmp(buff, "once")) -+ if (!strcmp(buff, "once")) - conf->log_checker_err = LOG_CHKR_ERR_ONCE; -- else if (strlen(buff) == 6 && !strcmp(buff, "always")) -+ else if (!strcmp(buff, "always")) - conf->log_checker_err = LOG_CHKR_ERR_ALWAYS; -+ else -+ condlog(1, "%s line %d, invalid value for log_checker_err: \"%s\"", -+ file, line_nr, buff); - - free(buff); - return 0; -@@ -1545,7 +1573,8 @@ hw_vpd_vendor_handler(struct config *conf, vector strvec, const char *file, - goto out; - } - } -- hwe->vpd_vendor_id = 0; -+ condlog(1, "%s line %d, invalid value for vpd_vendor: \"%s\"", -+ file, line_nr, buff); - out: - FREE(buff); - return 0; diff --git a/0023-libmultipath-don-t-return-error-on-invalid-values.patch b/0023-libmultipath-don-t-return-error-on-invalid-values.patch deleted file mode 100644 index 2d651e2..0000000 --- a/0023-libmultipath-don-t-return-error-on-invalid-values.patch +++ /dev/null @@ -1,219 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 11 Nov 2021 19:24:31 -0600 -Subject: [PATCH] libmultipath: don't return error on invalid values - -do_set_int and set_uint return 1 for invalid values. This can cause -multipath to fail completely, while reading the config. The config -handlers should only return a non-zero value if there is an internal -error, not if there is just an invalid value. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/dict.c | 64 ++++++++++++++++++--------------------------- - 1 file changed, 25 insertions(+), 39 deletions(-) - -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index c534d703..1b75be47 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -30,7 +30,7 @@ - #include "dict.h" - #include "strbuf.h" - --static int -+static void - do_set_int(vector strvec, void *ptr, int min, int max, const char *file, - int line_nr, char *buff) - { -@@ -45,7 +45,7 @@ do_set_int(vector strvec, void *ptr, int min, int max, const char *file, - if (*buff == '\0' || *eptr != '\0') { - condlog(1, "%s line %d, invalid value for %s: \"%s\"", - file, line_nr, (char*)VECTOR_SLOT(strvec, 0), buff); -- return 1; -+ return; - } - if (res > max || res < min) { - res = (res > max) ? max : min; -@@ -54,7 +54,7 @@ do_set_int(vector strvec, void *ptr, int min, int max, const char *file, - (res == max)? "large" : "small", res); - } - *int_ptr = res; -- return 0; -+ return; - } - - static int -@@ -62,16 +62,15 @@ set_int(vector strvec, void *ptr, int min, int max, const char *file, - int line_nr) - { - char *buff; -- int rc; - - buff = set_value(strvec); - if (!buff) - return 1; - -- rc = do_set_int(strvec, ptr, min, max, file, line_nr, buff); -+ do_set_int(strvec, ptr, min, max, file, line_nr, buff); - - FREE(buff); -- return rc; -+ return 0; - } - - static int -@@ -80,7 +79,6 @@ set_uint(vector strvec, void *ptr, const char *file, int line_nr) - unsigned int *uint_ptr = (unsigned int *)ptr; - char *buff, *eptr, *p; - unsigned long res; -- int rc; - - buff = set_value(strvec); - if (!buff) -@@ -93,17 +91,14 @@ set_uint(vector strvec, void *ptr, const char *file, int line_nr) - if (eptr > buff) - while (isspace(*eptr)) - eptr++; -- if (*buff == '\0' || *eptr != '\0' || !isdigit(*p) || res > UINT_MAX) { -+ if (*buff == '\0' || *eptr != '\0' || !isdigit(*p) || res > UINT_MAX) - condlog(1, "%s line %d, invalid value for %s: \"%s\"", - file, line_nr, (char*)VECTOR_SLOT(strvec, 0), buff); -- rc = 1; -- } else { -- rc = 0; -+ else - *uint_ptr = res; -- } - - FREE(buff); -- return rc; -+ return 0; - } - - static int -@@ -954,7 +949,6 @@ declare_mp_attr_snprint(gid, print_gid) - static int - set_undef_off_zero(vector strvec, void *ptr, const char *file, int line_nr) - { -- int rc = 0; - char * buff; - int *int_ptr = (int *)ptr; - -@@ -964,11 +958,10 @@ set_undef_off_zero(vector strvec, void *ptr, const char *file, int line_nr) - - if (strcmp(buff, "off") == 0) - *int_ptr = UOZ_OFF; -- else -- rc = do_set_int(strvec, int_ptr, 0, INT_MAX, file, line_nr, -- buff); -- if (rc == 0 && *int_ptr == 0) -+ else if (strcmp(buff, "0") == 0) - *int_ptr = UOZ_ZERO; -+ else -+ do_set_int(strvec, int_ptr, 1, INT_MAX, file, line_nr, buff); - - FREE(buff); - return 0; -@@ -1114,28 +1107,24 @@ max_fds_handler(struct config *conf, vector strvec, const char *file, - int line_nr) - { - char * buff; -- int r = 0, max_fds; -+ int max_fds; - - buff = set_value(strvec); - - if (!buff) - return 1; - -- r = get_sys_max_fds(&max_fds); -- if (r) { -- /* Assume safe limit */ -- max_fds = 4096; -- } -- if (!strcmp(buff, "max")) { -+ if (get_sys_max_fds(&max_fds) != 0) -+ max_fds = 4096; /* Assume safe limit */ -+ if (!strcmp(buff, "max")) - conf->max_fds = max_fds; -- r = 0; -- } else -- r = do_set_int(strvec, &conf->max_fds, 0, max_fds, file, -- line_nr, buff); -+ else -+ do_set_int(strvec, &conf->max_fds, 0, max_fds, file, line_nr, -+ buff); - - FREE(buff); - -- return r; -+ return 0; - } - - static int -@@ -1201,7 +1190,6 @@ declare_mp_snprint(rr_weight, print_rr_weight) - static int - set_pgfailback(vector strvec, void *ptr, const char *file, int line_nr) - { -- int rc = 0; - int *int_ptr = (int *)ptr; - char * buff; - -@@ -1216,11 +1204,11 @@ set_pgfailback(vector strvec, void *ptr, const char *file, int line_nr) - else if (strlen(buff) == 10 && !strcmp(buff, "followover")) - *int_ptr = -FAILBACK_FOLLOWOVER; - else -- rc = do_set_int(strvec, ptr, 0, INT_MAX, file, line_nr, buff); -+ do_set_int(strvec, ptr, 0, INT_MAX, file, line_nr, buff); - - FREE(buff); - -- return rc; -+ return 0; - } - - int -@@ -1252,7 +1240,6 @@ declare_mp_snprint(pgfailback, print_pgfailback) - static int - no_path_retry_helper(vector strvec, void *ptr, const char *file, int line_nr) - { -- int rc = 0; - int *int_ptr = (int *)ptr; - char * buff; - -@@ -1265,10 +1252,10 @@ no_path_retry_helper(vector strvec, void *ptr, const char *file, int line_nr) - else if (!strcmp(buff, "queue")) - *int_ptr = NO_PATH_RETRY_QUEUE; - else -- rc = do_set_int(strvec, ptr, 1, INT_MAX, file, line_nr, buff); -+ do_set_int(strvec, ptr, 1, INT_MAX, file, line_nr, buff); - - FREE(buff); -- return rc; -+ return 0; - } - - int -@@ -1413,7 +1400,6 @@ snprint_mp_reservation_key (struct config *conf, struct strbuf *buff, - static int - set_off_int_undef(vector strvec, void *ptr, const char *file, int line_nr) - { -- int rc =0; - int *int_ptr = (int *)ptr; - char * buff; - -@@ -1424,10 +1410,10 @@ set_off_int_undef(vector strvec, void *ptr, const char *file, int line_nr) - if (!strcmp(buff, "no") || !strcmp(buff, "0")) - *int_ptr = NU_NO; - else -- rc = do_set_int(strvec, ptr, 1, INT_MAX, file, line_nr, buff); -+ do_set_int(strvec, ptr, 1, INT_MAX, file, line_nr, buff); - - FREE(buff); -- return rc; -+ return 0; - } - - int diff --git a/0024-multipathd-avoid-unnecessary-path-read-only-reloads.patch b/0024-multipathd-avoid-unnecessary-path-read-only-reloads.patch deleted file mode 100644 index 7bbe406..0000000 --- a/0024-multipathd-avoid-unnecessary-path-read-only-reloads.patch +++ /dev/null @@ -1,129 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 15 Nov 2021 10:54:35 -0600 -Subject: [PATCH] multipathd: avoid unnecessary path read-only reloads - -A mulitpath device can only be reloaded read/write when all paths are -read/write. Also, whenever a read-only device is rescanned, the scsi -subsystem will first unconditionally issue a uevent with DISK_RO=0 -before checking the read-only status, and if it the device is still -read-only, issuing another uevent with DISK_RO=1. These uevents cause -pointless reloads when read-only paths are rescanned. To avoid this, -check to see if all paths are read/write before changing a multipath -device from read-only to read/write. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/libmultipath.version | 5 +++++ - libmultipath/sysfs.c | 22 ++++++++++++++++++++++ - libmultipath/sysfs.h | 1 + - multipathd/main.c | 31 ++++++++++++++++++++++++++++++- - 4 files changed, 58 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version -index eb5b5b55..dd1b4122 100644 ---- a/libmultipath/libmultipath.version -+++ b/libmultipath/libmultipath.version -@@ -287,3 +287,8 @@ global: - local: - *; - }; -+ -+LIBMULTIPATH_9.1.0 { -+global: -+ sysfs_get_ro; -+} LIBMULTIPATH_9.0.0; -diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c -index 9ff145f2..24c12b6a 100644 ---- a/libmultipath/sysfs.c -+++ b/libmultipath/sysfs.c -@@ -236,6 +236,28 @@ sysfs_get_size (struct path *pp, unsigned long long * size) - return 0; - } - -+int -+sysfs_get_ro (struct path *pp) -+{ -+ int ro; -+ char buff[3]; /* Either "0\n\0" or "1\n\0" */ -+ -+ if (!pp->udev) -+ return -1; -+ -+ if (sysfs_attr_get_value(pp->udev, "ro", buff, sizeof(buff)) <= 0) { -+ condlog(3, "%s: Cannot read ro attribute in sysfs", pp->dev); -+ return -1; -+ } -+ -+ if (sscanf(buff, "%d\n", &ro) != 1 || ro < 0 || ro > 1) { -+ condlog(3, "%s: Cannot parse ro attribute", pp->dev); -+ return -1; -+ } -+ -+ return ro; -+} -+ - int sysfs_check_holders(char * check_devt, char * new_devt) - { - unsigned int major, new_minor, table_minor; -diff --git a/libmultipath/sysfs.h b/libmultipath/sysfs.h -index 72b39ab2..c948c467 100644 ---- a/libmultipath/sysfs.h -+++ b/libmultipath/sysfs.h -@@ -13,6 +13,7 @@ ssize_t sysfs_attr_get_value(struct udev_device *dev, const char *attr_name, - ssize_t sysfs_bin_attr_get_value(struct udev_device *dev, const char *attr_name, - unsigned char * value, size_t value_len); - int sysfs_get_size (struct path *pp, unsigned long long * size); -+int sysfs_get_ro(struct path *pp); - int sysfs_check_holders(char * check_devt, char * new_devt); - bool sysfs_is_multipathed(struct path *pp, bool set_wwid); - #endif -diff --git a/multipathd/main.c b/multipathd/main.c -index 1defeaf1..6145e512 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -1324,6 +1324,35 @@ fail: - return REMOVE_PATH_MAP_ERROR; - } - -+static bool -+needs_ro_update(struct multipath *mpp, int ro) -+{ -+ struct pathgroup * pgp; -+ struct path * pp; -+ unsigned int i, j; -+ struct dm_info *dmi = NULL; -+ -+ if (!mpp || ro < 0) -+ return false; -+ dm_get_info(mpp->alias, &dmi); -+ if (!dmi) /* assume we do need to reload the device */ -+ return true; -+ if (dmi->read_only == ro) { -+ free(dmi); -+ return false; -+ } -+ free(dmi); -+ if (ro == 1) -+ return true; -+ vector_foreach_slot (mpp->pg, pgp, i) { -+ vector_foreach_slot (pgp->paths, pp, j) { -+ if (sysfs_get_ro(pp) == 1) -+ return false; -+ } -+ } -+ return true; -+} -+ - static int - uev_update_path (struct uevent *uev, struct vectors * vecs) - { -@@ -1388,7 +1417,7 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) - } - - ro = uevent_get_disk_ro(uev); -- if (mpp && ro >= 0) { -+ if (needs_ro_update(mpp, ro)) { - condlog(2, "%s: update path write_protect to '%d' (uevent)", uev->kernel, ro); - - if (mpp->wait_for_udev) diff --git a/0035-libmultipath-use-asprintf-to-allocate-prefixed_uuid.patch b/0035-libmultipath-use-asprintf-to-allocate-prefixed_uuid.patch deleted file mode 100644 index 6e60d4a..0000000 --- a/0035-libmultipath-use-asprintf-to-allocate-prefixed_uuid.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 25 Jan 2022 23:02:33 -0600 -Subject: [PATCH] libmultipath: use asprintf() to allocate prefixed_uuid - -gcc 12.0.1 failed building libmultipath due to a format-overflow false -positive on 32-bit architectures. This isn't so surprising as -format-overflow=2 is very aggressive in the assumptions it makes about -the arguments. Here, it assumes that mpp->wwid could take up all the -space that a pointer could point to, even if I add code to this function -to explicitly null terminate mpp->wwid to fit in WWID_SIZE. - -To avoid this and simplify the function, switch from using calloc() and -sprintf() to just using asprintf(). - -For reference, the gcc build error that this fixes is: - -devmapper.c: In function 'dm_addmap.constprop.0': -devmapper.h:27:21: error: '%s' directive writing up to 2147483644 bytes into a region of size 2147483641 [-Werror=format-overflow=] - 27 | #define UUID_PREFIX "mpath-" - | ^~~~~~~~ -devmapper.c:484:53: note: format string is defined here - 484 | sprintf(prefixed_uuid, UUID_PREFIX "%s", mpp->wwid); - | ^~ - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/devmapper.c | 7 ++----- - 1 file changed, 2 insertions(+), 5 deletions(-) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index c05dc201..bae07125 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -474,14 +474,11 @@ dm_addmap (int task, const char *target, struct multipath *mpp, - dm_task_set_ro(dmt); - - if (task == DM_DEVICE_CREATE) { -- prefixed_uuid = MALLOC(UUID_PREFIX_LEN + -- strlen(mpp->wwid) + 1); -- if (!prefixed_uuid) { -+ if (asprintf(&prefixed_uuid, UUID_PREFIX "%s", mpp->wwid) < 0) { - condlog(0, "cannot create prefixed uuid : %s", - strerror(errno)); - goto addout; - } -- sprintf(prefixed_uuid, UUID_PREFIX "%s", mpp->wwid); - if (!dm_task_set_uuid(dmt, prefixed_uuid)) - goto freeout; - dm_task_skip_lockfs(dmt); -@@ -517,7 +514,7 @@ dm_addmap (int task, const char *target, struct multipath *mpp, - libmp_udev_wait(cookie); - freeout: - if (prefixed_uuid) -- FREE(prefixed_uuid); -+ free(prefixed_uuid); - - addout: - dm_task_destroy (dmt); diff --git a/0036-RH-add-support-to-mpathconf-for-setting-arbitrary-de.patch b/0036-RH-add-support-to-mpathconf-for-setting-arbitrary-de.patch deleted file mode 100644 index dff41f8..0000000 --- a/0036-RH-add-support-to-mpathconf-for-setting-arbitrary-de.patch +++ /dev/null @@ -1,149 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 2 Feb 2022 17:00:21 -0600 -Subject: [PATCH] RH: add support to mpathconf for setting arbitrary default - options - -mpathconf now supports --option :[] for setting, changing, -or removing options from the defaults section of multipath.conf. - -Signed-off-by: Benjamin Marzinski ---- - multipath/mpathconf | 58 ++++++++++++++++++++++++++++++++++++++++--- - multipath/mpathconf.8 | 7 ++++++ - 2 files changed, 62 insertions(+), 3 deletions(-) - -diff --git a/multipath/mpathconf b/multipath/mpathconf -index 0de6b121..6e33fb99 100644 ---- a/multipath/mpathconf -+++ b/multipath/mpathconf -@@ -17,7 +17,7 @@ - # This program was largely ripped off from lvmconf - # - --unset ENABLE FIND FRIENDLY PROPERTY FOREIGN MODULE MULTIPATHD HAVE_DISABLE HAVE_WWID_DISABLE HAVE_FIND HAVE_BLACKLIST HAVE_EXCEPTIONS HAVE_DEFAULTS HAVE_FRIENDLY HAVE_PROPERTY HAVE_FOREIGN HAVE_MULTIPATHD HAVE_MODULE HAVE_OUTFILE SHOW_STATUS CHANGED_CONFIG WWID_LIST -+unset ENABLE FIND FRIENDLY PROPERTY FOREIGN MODULE MULTIPATHD HAVE_DISABLE HAVE_WWID_DISABLE HAVE_FIND HAVE_BLACKLIST HAVE_EXCEPTIONS HAVE_DEFAULTS HAVE_FRIENDLY HAVE_PROPERTY HAVE_FOREIGN HAVE_MULTIPATHD HAVE_MODULE HAVE_OUTFILE SHOW_STATUS CHANGED_CONFIG WWID_LIST HAVE_OPTION OPTION_NAME OPTION_VALUE - - DEFAULT_CONFIG="# device-mapper-multipath configuration file - -@@ -52,6 +52,7 @@ function usage - echo "Set find_multipaths (Default y): --find_multipaths " - echo "Set default property blacklist (Default n): --property_blacklist " - echo "Set enable_foreign to show foreign devices (Default n): --enable_foreign " -+ echo "Add/Change/Remove option in defaults section: --option :" - echo "Load the dm-multipath modules on enable (Default y): --with_module " - echo "start/stop/reload multipathd (Default n): --with_multipathd " - echo "select output file (Default /etc/multipath.conf): --outfile " -@@ -162,6 +163,20 @@ function parse_args - exit 1 - fi - ;; -+ --option) -+ if [ -n "$2" ]; then -+ OPTION_NAME=$(echo $2 | cut -s -f1 -d:) -+ OPTION_VALUE=$(echo $2 | cut -s -f2 -d:) -+ if [ -z "$OPTION_NAME" ]; then -+ usage -+ exit 1 -+ fi -+ shift 2 -+ else -+ usage -+ exit 1 -+ fi -+ ;; - --enable_foreign) - if [ -n "$2" ]; then - FOREIGN=$2 -@@ -208,12 +223,15 @@ function parse_args - - function validate_args - { -- if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$PROPERTY" -o -n "$MODULE" ]; then -+ if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$PROPERTY" -o -n "$MODULE" -o -n "$FOREIGN" -o -n "$OPTION_NAME" ]; then - echo "ignoring extra parameters on disable" - FRIENDLY="" - FIND="" - PROPERTY="" - MODULE="" -+ FOREIGN="" -+ OPTION_NAME="" -+ OPTION_VALUE="" - fi - if [ -n "$FRIENDLY" ] && [ "$FRIENDLY" != "y" -a "$FRIENDLY" != "n" ]; then - echo "--user_friendly_names must be either 'y' or 'n'" -@@ -235,7 +253,19 @@ function validate_args - echo "--enable_foreign must be either 'y' or 'n'" - exit 1 - fi -- if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" -a -z "$PROPERTY" -a -z "$FOREIGN" ]; then -+ if [ -n "$OPTION_NAME" ]; then -+ if [[ $OPTION_NAME =~ [[:space:]]|#|\"|!|\{|\} ]]; then -+ echo "--option name \"$OPTION_NAME\" is invalid" -+ exit 1 -+ elif [[ $OPTION_VALUE =~ \"|#|!|\{|\} ]]; then -+ echo "--option value \"$OPTION_VALUE\" is invalid" -+ exit 1 -+ fi -+ if [[ $OPTION_VALUE =~ [[:space:]] ]]; then -+ OPTION_VALUE=\"$OPTION_VALUE\" -+ fi -+ fi -+ if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" -a -z "$PROPERTY" -a -z "$FOREIGN" -a -z "$OPTION_NAME" ]; then - SHOW_STATUS=1 - fi - if [ -n "$MODULE" ] && [ "$MODULE" != "y" -a "$MODULE" != "n" ]; then -@@ -348,6 +378,13 @@ if [ "$HAVE_DEFAULTS" = "1" ]; then - elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign" ; then - HAVE_FOREIGN=3 - fi -+ if [ -n "$OPTION_NAME" ]; then -+ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q '^[[:space:]]*'"$OPTION_NAME"'[[:space:]][[:space:]]*'"$OPTION_VALUE" ; then -+ HAVE_OPTION=1 -+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q '^[[:space:]]*'"$OPTION_NAME"'\([[:space:]].*\)\?$' ; then -+ HAVE_OPTION=0 -+ fi -+ fi - fi - - if [ "$HAVE_EXCEPTIONS" = "1" ]; then -@@ -532,6 +569,21 @@ elif [ "$FOREIGN" = "y" ]; then - fi - fi - -+if [ -n "$OPTION_NAME" -a -n "$OPTION_VALUE" ]; then -+ if [ -z "$HAVE_OPTION" ]; then -+ sed -i '/^defaults[[:space:]]*{/ a\ -+ '"$OPTION_NAME"' '"$OPTION_VALUE"' -+' $TMPFILE -+ CHANGED_CONFIG=1 -+ elif [ "$HAVE_OPTION" = 0 ]; then -+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*'"$OPTION_NAME"'\([[:space:]].*\)\?$/ '"$OPTION_NAME"' '"$OPTION_VALUE"'/' $TMPFILE -+ CHANGED_CONFIG=1 -+ fi -+elif [ -n "$OPTION_NAME" -a -n "$HAVE_OPTION" ]; then -+ sed -i '/^defaults[[:space:]]*{/,/^}/{/^[[:space:]]*'"$OPTION_NAME"'\([[:space:]].*\)\?$/d}' $TMPFILE -+ CHANGED_CONFIG=1 -+fi -+ - if [ -f "$OUTPUTFILE" ]; then - cp $OUTPUTFILE $OUTPUTFILE.old - if [ $? != 0 ]; then -diff --git a/multipath/mpathconf.8 b/multipath/mpathconf.8 -index a14d831e..496383b7 100644 ---- a/multipath/mpathconf.8 -+++ b/multipath/mpathconf.8 -@@ -101,6 +101,13 @@ to the - defaults section. if set to \fBn\fP, this removes the line, if present. This - command can be used along with any other command. - .TP -+.B --option \fB:[]\fP -+Sets the defaults section option \fB\fP to \fB\fP. If the -+option was not previously set in the defaults section, it is added. If it was -+set, its value is changed to \fB\fP. If \fB\fP is left blank, -+then the option is removed from the defaults section, if was set there. This -+command can be used along with any other command. -+.TP - .B --outfile \fB\fP - Write the resulting multipath configuration to \fB\fP instead of - \fB/etc/multipath.conf\fP. diff --git a/0037-RH-add-support-to-mpathconf-for-setting-recheck_wwid.patch b/0037-RH-add-support-to-mpathconf-for-setting-recheck_wwid.patch deleted file mode 100644 index 5330d38..0000000 --- a/0037-RH-add-support-to-mpathconf-for-setting-recheck_wwid.patch +++ /dev/null @@ -1,154 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 3 Feb 2022 13:26:18 -0600 -Subject: [PATCH] RH: add support to mpathconf for setting recheck_wwid - -mpathconf now supports --recheck_wwid for setthing the -recheck_wwid option - -Signed-off-by: Benjamin Marzinski ---- - multipath/mpathconf | 48 ++++++++++++++++++++++++++++++++++++++++--- - multipath/mpathconf.8 | 9 ++++++++ - 2 files changed, 54 insertions(+), 3 deletions(-) - -diff --git a/multipath/mpathconf b/multipath/mpathconf -index 6e33fb99..319664b1 100644 ---- a/multipath/mpathconf -+++ b/multipath/mpathconf -@@ -17,7 +17,7 @@ - # This program was largely ripped off from lvmconf - # - --unset ENABLE FIND FRIENDLY PROPERTY FOREIGN MODULE MULTIPATHD HAVE_DISABLE HAVE_WWID_DISABLE HAVE_FIND HAVE_BLACKLIST HAVE_EXCEPTIONS HAVE_DEFAULTS HAVE_FRIENDLY HAVE_PROPERTY HAVE_FOREIGN HAVE_MULTIPATHD HAVE_MODULE HAVE_OUTFILE SHOW_STATUS CHANGED_CONFIG WWID_LIST HAVE_OPTION OPTION_NAME OPTION_VALUE -+unset ENABLE FIND FRIENDLY PROPERTY FOREIGN MODULE MULTIPATHD HAVE_DISABLE HAVE_WWID_DISABLE HAVE_FIND HAVE_BLACKLIST HAVE_EXCEPTIONS HAVE_DEFAULTS HAVE_FRIENDLY HAVE_PROPERTY HAVE_FOREIGN HAVE_MULTIPATHD HAVE_MODULE HAVE_OUTFILE SHOW_STATUS CHANGED_CONFIG WWID_LIST HAVE_OPTION OPTION_NAME OPTION_VALUE HAVE_RECHECK_WWID RECHECK_WWID - - DEFAULT_CONFIG="# device-mapper-multipath configuration file - -@@ -52,6 +52,7 @@ function usage - echo "Set find_multipaths (Default y): --find_multipaths " - echo "Set default property blacklist (Default n): --property_blacklist " - echo "Set enable_foreign to show foreign devices (Default n): --enable_foreign " -+ echo "Set recheck_wwid (Defaut n): --recheck_wwid " - echo "Add/Change/Remove option in defaults section: --option :" - echo "Load the dm-multipath modules on enable (Default y): --with_module " - echo "start/stop/reload multipathd (Default n): --with_multipathd " -@@ -145,6 +146,15 @@ function parse_args - exit 1 - fi - ;; -+ --recheck_wwid) -+ if [ -n "$2" ]; then -+ RECHECK_WWID=$2 -+ shift 2 -+ else -+ usage -+ exit 1 -+ fi -+ ;; - --find_multipaths) - if [ -n "$2" ]; then - FIND=$2 -@@ -223,7 +233,7 @@ function parse_args - - function validate_args - { -- if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$PROPERTY" -o -n "$MODULE" -o -n "$FOREIGN" -o -n "$OPTION_NAME" ]; then -+ if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$PROPERTY" -o -n "$MODULE" -o -n "$FOREIGN" -o -n "$OPTION_NAME" -o -n "$RECHECK_WWID" ]; then - echo "ignoring extra parameters on disable" - FRIENDLY="" - FIND="" -@@ -232,11 +242,16 @@ function validate_args - FOREIGN="" - OPTION_NAME="" - OPTION_VALUE="" -+ RECHECK_WWID="" - fi - if [ -n "$FRIENDLY" ] && [ "$FRIENDLY" != "y" -a "$FRIENDLY" != "n" ]; then - echo "--user_friendly_names must be either 'y' or 'n'" - exit 1 - fi -+ if [ -n "$RECHECK_WWID" ] && [ "$RECHECK_WWID" != "y" -a "$RECHECK_WWID" != "n" ]; then -+ echo "--recheck_wwid must be either 'y' or 'n'" -+ exit 1 -+ fi - if [ "$FIND" = "y" ]; then - FIND="yes" - elif [ "$FIND" = "n" ]; then -@@ -265,7 +280,7 @@ function validate_args - OPTION_VALUE=\"$OPTION_VALUE\" - fi - fi -- if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" -a -z "$PROPERTY" -a -z "$FOREIGN" -a -z "$OPTION_NAME" ]; then -+ if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" -a -z "$PROPERTY" -a -z "$FOREIGN" -a -z "$OPTION_NAME" -a -z "$RECHECK_WWID" ]; then - SHOW_STATUS=1 - fi - if [ -n "$MODULE" ] && [ "$MODULE" != "y" -a "$MODULE" != "n" ]; then -@@ -367,6 +382,11 @@ if [ "$HAVE_DEFAULTS" = "1" ]; then - elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]][[:space:]]*\(no\|0\)" ; then - HAVE_FRIENDLY=0 - fi -+ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*recheck_wwid[[:space:]][[:space:]]*\(yes\|1\)" ; then -+ HAVE_RECHECK_WWID=1 -+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*recheck_wwid[[:space:]][[:space:]]*\(no\|0\)" ; then -+ HAVE_RECHECK_WWID=0 -+ fi - if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*enable_foreign" ; then - HAVE_FOREIGN=0 - elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]][[:space:]]*\"\.\*\"" ; then -@@ -411,6 +431,11 @@ if [ -n "$SHOW_STATUS" ]; then - else - echo "user_friendly_names is enabled" - fi -+ if [ -z "$HAVE_RECHECK_WWID" -o "$HAVE_RECHECK_WWID" = 0 ]; then -+ echo "recheck_wwid is disabled" -+ else -+ echo "recheck_wwid is enabled" -+ fi - if [ -z "$HAVE_PROPERTY" -o "$HAVE_PROPERTY" = 0 ]; then - echo "default property blacklist is disabled" - else -@@ -527,6 +552,23 @@ elif [ "$FRIENDLY" = "y" ]; then - fi - fi - -+if [ "$RECHECK_WWID" = "n" ]; then -+ if [ "$HAVE_RECHECK_WWID" = 1 ]; then -+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*recheck_wwid[[:space:]][[:space:]]*\(yes\|1\)/ recheck_wwid no/' $TMPFILE -+ CHANGED_CONFIG=1 -+ fi -+elif [ "$RECHECK_WWID" = "y" ]; then -+ if [ -z "$HAVE_RECHECK_WWID" ]; then -+ sed -i '/^defaults[[:space:]]*{/ a\ -+ recheck_wwid yes -+' $TMPFILE -+ CHANGED_CONFIG=1 -+ elif [ "$HAVE_RECHECK_WWID" = 0 ]; then -+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*recheck_wwid[[:space:]][[:space:]]*\(no\|0\)/ recheck_wwid yes/' $TMPFILE -+ CHANGED_CONFIG=1 -+ fi -+fi -+ - if [ "$PROPERTY" = "n" ]; then - if [ "$HAVE_PROPERTY" = 1 ]; then - sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*property[[:space:]][[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/# property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE -diff --git a/multipath/mpathconf.8 b/multipath/mpathconf.8 -index 496383b7..9c2fb835 100644 ---- a/multipath/mpathconf.8 -+++ b/multipath/mpathconf.8 -@@ -77,6 +77,15 @@ to the - defaults section. If set to \fBn\fP, this removes the line, if present. This - command can be used along with any other command. - .TP -+.B --recheck_wwid \fP { \fBy\fP | \fBn\fP } -+If set to \fBy\fP, this adds the line -+.B recheck_wwid yes -+to the -+.B /etc/multipath.conf -+defaults section, or sets an existing line to \fByes\fP. If set to \fBn\fP, this -+sets an existing \fBrecheck_wwid\fP line to \fBno\fP. This command can be used -+along with any other command. -+.TP - .B --find_multipaths\fP { \fByes\fP | \fBno\fP | \fBstrict\fP | \fBgreedy\fP | \fBsmart\fP } - If set to \fB\fP, this adds the line - .B find_multipaths diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 195cd07..97d7dfc 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,52 +1,31 @@ Name: device-mapper-multipath -Version: 0.8.7 -Release: 8%{?dist} +Version: 0.8.9 +Release: 1%{?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 -L https://github.com/opensvc/multipath-tools/archive/0.8.7.tar.gz -o multipath-tools-0.8.7.tgz -Source0: multipath-tools-0.8.7.tgz +# curl -L https://github.com/opensvc/multipath-tools/archive/0.8.9.tar.gz -o multipath-tools-0.8.9.tgz +Source0: multipath-tools-0.8.9.tgz Source1: multipath.conf -Patch0001: 0001-multipath-tools-add-info-about-IO-affinity-path-sele.patch -Patch0002: 0002-multipathd-fix-missing-persistent-reseravtion-for-ac.patch -Patch0003: 0003-multipath-tools-minor-fixes-to-multipath.conf.5-man-.patch -Patch0004: 0004-multipath-tools-make-IBM-XIV-config-work-with-alua-a.patch -Patch0005: 0005-multipathd.socket-add-missing-conditions-from-servic.patch -Patch0006: 0006-multipath-tools-make-IBM-2107900-DS8000-config-work-.patch -Patch0007: 0007-multipath-tools-make-EMC-SYMMETRIX-config-work-with-.patch -Patch0008: 0008-multipath-tools-make-EMC-Invista-config-work-with-al.patch -Patch0009: 0009-multipath-tools-make-COMPELNT-Compellent-Vol-config-.patch -Patch0010: 0010-multipath-tools-remove-Compellent-maintainer.patch -Patch0011: 0011-Revert-multipath-tools-make-EMC-Invista-config-work-.patch -Patch0012: 0012-Revert-multipath-tools-make-EMC-SYMMETRIX-config-wor.patch -Patch0013: 0013-multipath-fix-exit-status-of-multipath-T.patch -Patch0014: 0014-libmultipath-add-section-name-to-invalid-keyword-out.patch -Patch0015: 0015-libmultipath-use-typedef-for-keyword-handler-functio.patch -Patch0016: 0016-libmultipath-print-the-correct-file-when-parsing-fai.patch -Patch0017: 0017-libmultipath-pass-file-and-line-number-to-keyword-ha.patch -Patch0018: 0018-libmultipath-make-set_int-take-a-range-for-valid-val.patch -Patch0019: 0019-libmultipath-improve-checks-for-set_str.patch -Patch0020: 0020-libmultipath-deprecate-file-and-directory-config-opt.patch -Patch0021: 0021-libmultipath-split-set_int-to-enable-reuse.patch -Patch0022: 0022-libmultipath-cleanup-invalid-config-handling.patch -Patch0023: 0023-libmultipath-don-t-return-error-on-invalid-values.patch -Patch0024: 0024-multipathd-avoid-unnecessary-path-read-only-reloads.patch -Patch0025: 0025-RH-fixup-udev-rules-for-redhat.patch -Patch0026: 0026-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0027: 0027-RH-don-t-start-without-a-config-file.patch -Patch0028: 0028-RH-Fix-nvme-function-missing-argument.patch -Patch0029: 0029-RH-use-rpm-optflags-if-present.patch -Patch0030: 0030-RH-add-mpathconf.patch -Patch0031: 0031-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0032: 0032-RH-reset-default-find_mutipaths-value-to-off.patch -Patch0033: 0033-RH-attempt-to-get-ANA-info-via-sysfs-first.patch -Patch0034: 0034-RH-make-parse_vpd_pg83-match-scsi_id-output.patch -Patch0035: 0035-libmultipath-use-asprintf-to-allocate-prefixed_uuid.patch -Patch0036: 0036-RH-add-support-to-mpathconf-for-setting-arbitrary-de.patch -Patch0037: 0037-RH-add-support-to-mpathconf-for-setting-recheck_wwid.patch +Patch0001: 0001-multipath-tools-identify-more-arrays-under-IBM-2145-.patch +Patch0002: 0002-multipath-tools-add-HPE-as-vendor-for-OPEN-XP8-array.patch +Patch0003: 0003-multipath-tools-add-HP-HSVX740-to-hwtable.patch +Patch0004: 0004-multipath-tools-add-DellEMC-ME5-PowerVault-ME5-to-ha.patch +Patch0005: 0005-multipath-tools-update-mpp-force_readonly-in-ev_add_.patch +Patch0006: 0006-RH-fixup-udev-rules-for-redhat.patch +Patch0007: 0007-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0008: 0008-RH-don-t-start-without-a-config-file.patch +Patch0009: 0009-RH-Fix-nvme-function-missing-argument.patch +Patch0010: 0010-RH-use-rpm-optflags-if-present.patch +Patch0011: 0011-RH-add-mpathconf.patch +Patch0012: 0012-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0013: 0013-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0014: 0014-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0015: 0015-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +Patch0016: 0016-RH-add-scsi-device-handlers-to-modules-load.d.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -130,7 +109,7 @@ This package contains the files needed to develop applications that use device-mapper-multipath's libdmmp C API library %prep -%autosetup -n multipath-tools-0.8.7 -p1 +%autosetup -n multipath-tools-0.8.9 -p1 cp %{SOURCE1} . %build @@ -188,6 +167,9 @@ fi %{_mandir}/man8/mpathpersist.8.gz %config /usr/lib/udev/rules.d/62-multipath.rules %config /usr/lib/udev/rules.d/11-dm-mpath.rules +%dir /usr/lib/modules-load.d +/usr/lib/modules-load.d/multipath.conf +/usr/lib/modules-load.d/scsi_dh.conf %doc README.md %doc README.alua %doc multipath.conf @@ -244,6 +226,19 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Mon Mar 28 2022 Benjamin Marzinski - 0.8.9-1 +- Update source to upstream version 0.8.9 + * Previous patches 0001-0024 & 0035 are included in the commit. +- Add patches from upstream staging branch + * Patches 0001-0005 are from the upstream staging branch +- Rename redhat patches + * Previous patches 0025-0034 are now patches 0006-0015 +- Combine redhat patches + * Previous patches 0036 & 0037 are now part of patch 0011 +- Add 0016-RH-add-scsi-device-handlers-to-modules-load.d.patch +- Spec file changes + * Install multipath.conf and scsi_dh.conf to /usr/lib/modules-load.d + * Mon Feb 7 2022 Benjamin Marzinski - 0.8.7-8 - Add 0036-RH-add-support-to-mpathconf-for-setting-arbitrary-de.patch * add the ability for mpathconf to set arbitray options with --option diff --git a/sources b/sources index ba0504a..7a7f2cd 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (multipath-tools-0.8.7.tgz) = c01aea837b13429d17688455b813947342ca1cabba19b22e13ce640c77e68335a6d410280a8298595e239131e6fcbb655fa6de5ff9857eac99aa175046a450cd +SHA512 (multipath-tools-0.8.9.tgz) = 25f2a5d436af6a343804988cef45ca1574d4a981655a2b91563ddb89138619158befdf5af92d836a17c95d6dcf901072b614473c2129274e5dcdb1a1d64edb4d SHA512 (multipath.conf) = 71953dce5a68adcf60a942305f5a66023e6f4c4baf53b1bfdb4edf65ed5b8e03db804363c36d1dcfd85591f4766f52b515269904c53b84d7b076da0b80b09942 From 652daa1a21de278169ef96a967b720d2aa967479 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Wed, 13 Jul 2022 16:51:42 -0500 Subject: [PATCH 32/67] device-mapper-multipath-0.9.0-1 Update source to upstream version 0.9.0 * Previous patches 0001-0005 are included in the commit. * This version deprecates multiple options: mutlipath_dir, config_dir, and getuid_callout, along with the "default_" prefixed alternate names for the default section parameters. Add patches from upstream staging branch * Patches 0001-0006 are from the upstream staging branch Rename redhat patches * Previous patches 0006-0016 are now patches 0007-0017 --- .gitignore | 1 + ...github-workflows-switch-to-fedora-36.patch | 29 ++++ ...add-HPE-as-vendor-for-OPEN-XP8-array.patch | 32 ----- ...fix-multipath-ll-bug-for-Native-NVME.patch | 103 +++++++++++++ ...path-tools-add-HP-HSVX740-to-hwtable.patch | 31 ---- ...update-Huawei-OceanStor-NVMe-vendor-.patch | 39 +++++ ...add-DellEMC-ME5-PowerVault-ME5-to-ha.patch | 37 ----- ...update-Generic-NVMe-vendor-regex-in-.patch | 25 ++-- ...et-detect_checker-for-clariion-Unity.patch | 30 ++++ ...update-mpp-force_readonly-in-ev_add_.patch | 136 ------------------ ...-find_multipaths_timeout-for-unknown.patch | 27 ++++ ... 0007-RH-fixup-udev-rules-for-redhat.patch | 10 +- ...property-blacklist-exception-builtin.patch | 6 +- ...RH-don-t-start-without-a-config-file.patch | 8 +- ...H-Fix-nvme-function-missing-argument.patch | 0 ... 0011-RH-use-rpm-optflags-if-present.patch | 38 ++--- ...hconf.patch => 0012-RH-add-mpathconf.patch | 14 +- ...om-kernel-cmdline-mpath.wwids-with-A.patch | 2 +- ...-default-find_mutipaths-value-to-off.patch | 4 +- ...empt-to-get-ANA-info-via-sysfs-first.patch | 0 ...-parse_vpd_pg83-match-scsi_id-output.patch | 6 +- ...si-device-handlers-to-modules-load.d.patch | 4 +- device-mapper-multipath.spec | 52 ++++--- sources | 2 +- 24 files changed, 315 insertions(+), 321 deletions(-) create mode 100644 0001-github-workflows-switch-to-fedora-36.patch delete mode 100644 0002-multipath-tools-add-HPE-as-vendor-for-OPEN-XP8-array.patch create mode 100644 0002-multipath-tools-fix-multipath-ll-bug-for-Native-NVME.patch delete mode 100644 0003-multipath-tools-add-HP-HSVX740-to-hwtable.patch create mode 100644 0003-multipath-tools-update-Huawei-OceanStor-NVMe-vendor-.patch delete mode 100644 0004-multipath-tools-add-DellEMC-ME5-PowerVault-ME5-to-ha.patch rename 0001-multipath-tools-identify-more-arrays-under-IBM-2145-.patch => 0004-multipath-tools-update-Generic-NVMe-vendor-regex-in-.patch (55%) create mode 100644 0005-libmultipath-unset-detect_checker-for-clariion-Unity.patch delete mode 100644 0005-multipath-tools-update-mpp-force_readonly-in-ev_add_.patch create mode 100644 0006-libmultipath-fix-find_multipaths_timeout-for-unknown.patch rename 0006-RH-fixup-udev-rules-for-redhat.patch => 0007-RH-fixup-udev-rules-for-redhat.patch (94%) rename 0007-RH-Remove-the-property-blacklist-exception-builtin.patch => 0008-RH-Remove-the-property-blacklist-exception-builtin.patch (96%) rename 0008-RH-don-t-start-without-a-config-file.patch => 0009-RH-don-t-start-without-a-config-file.patch (95%) rename 0009-RH-Fix-nvme-function-missing-argument.patch => 0010-RH-Fix-nvme-function-missing-argument.patch (100%) rename 0010-RH-use-rpm-optflags-if-present.patch => 0011-RH-use-rpm-optflags-if-present.patch (66%) rename 0011-RH-add-mpathconf.patch => 0012-RH-add-mpathconf.patch (98%) rename 0012-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch => 0013-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch (99%) rename 0013-RH-reset-default-find_mutipaths-value-to-off.patch => 0014-RH-reset-default-find_mutipaths-value-to-off.patch (94%) rename 0014-RH-attempt-to-get-ANA-info-via-sysfs-first.patch => 0015-RH-attempt-to-get-ANA-info-via-sysfs-first.patch (100%) rename 0015-RH-make-parse_vpd_pg83-match-scsi_id-output.patch => 0016-RH-make-parse_vpd_pg83-match-scsi_id-output.patch (94%) rename 0016-RH-add-scsi-device-handlers-to-modules-load.d.patch => 0017-RH-add-scsi-device-handlers-to-modules-load.d.patch (85%) diff --git a/.gitignore b/.gitignore index d5360ef..7a13460 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,4 @@ multipath-tools-091027.tar.gz /multipath-tools-0.8.6.tgz /multipath-tools-0.8.7.tgz /multipath-tools-0.8.9.tgz +/multipath-tools-0.9.0.tgz diff --git a/0001-github-workflows-switch-to-fedora-36.patch b/0001-github-workflows-switch-to-fedora-36.patch new file mode 100644 index 0000000..1583fd8 --- /dev/null +++ b/0001-github-workflows-switch-to-fedora-36.patch @@ -0,0 +1,29 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 10 Jun 2022 22:44:11 +0200 +Subject: [PATCH] github workflows: switch to fedora 36 + +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/native.yaml | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml +index 19c9e297..ddfd4a09 100644 +--- a/.github/workflows/native.yaml ++++ b/.github/workflows/native.yaml +@@ -12,12 +12,10 @@ jobs: + runs-on: ubuntu-20.04 + strategy: + matrix: +- os: [buster, jessie, bullseye, fedora-35] ++ os: [buster, jessie, bullseye, fedora-36] + arch: ['', '-i386'] + exclude: +- - os: fedora-34 +- arch: '-i386' +- - os: fedora-35 ++ - os: fedora-36 + arch: '-i386' + container: mwilck/multipath-build-${{ matrix.os }}${{ matrix.arch }} + steps: diff --git a/0002-multipath-tools-add-HPE-as-vendor-for-OPEN-XP8-array.patch b/0002-multipath-tools-add-HPE-as-vendor-for-OPEN-XP8-array.patch deleted file mode 100644 index 7df0d4b..0000000 --- a/0002-multipath-tools-add-HPE-as-vendor-for-OPEN-XP8-array.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Thu, 24 Feb 2022 22:23:34 +0100 -Subject: [PATCH] multipath-tools: add HPE as vendor for OPEN- (XP8 arrays) - -Cc: Matthias Rudolph -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/hwtable.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index 643caa32..3b9e0e0f 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -467,8 +467,8 @@ static struct hwentry default_hw[] = { - * Maintainer: Matthias Rudolph - */ - { -- /* USP-V, HUS VM, VSP, VSP G1X00 and VSP GX00 families / HP XP */ -- .vendor = "(HITACHI|HP)", -+ /* USP-V, HUS VM, VSP, VSP G1X00 and VSP GX00 families / HPE XP */ -+ .vendor = "(HITACHI|HP|HPE)", - .product = "^OPEN-", - .pgpolicy = MULTIBUS, - }, diff --git a/0002-multipath-tools-fix-multipath-ll-bug-for-Native-NVME.patch b/0002-multipath-tools-fix-multipath-ll-bug-for-Native-NVME.patch new file mode 100644 index 0000000..c54b4cd --- /dev/null +++ b/0002-multipath-tools-fix-multipath-ll-bug-for-Native-NVME.patch @@ -0,0 +1,103 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: chengjike +Date: Fri, 8 Oct 2021 20:24:49 +0800 +Subject: [PATCH] multipath-tools: fix "multipath -ll" bug for Native NVME + Multipath devices + +After "Native NVME Multipath" is configured, +the content displayed is incorrect when you run "multipath -ll" command. +Each NVME devices have the same path name. For example: + +[root@localhost home]# multipath -ll +eui.710032e8fb22a86c24a52c1000000db8 [nvme]:nvme1n1 NVMe,Huawei-XSG1,1000001 +size=10485760 features='n/a' hwhandler='ANA' wp=rw +|-+- policy='n/a' prio=50 status=optimized +| `- 1:4:1 nvme1c4n1 0:0 n/a optimized live +`-+- policy='n/a' prio=50 status=optimized + `- 1:9:1 nvme1c9n1 0:0 n/a optimized live +eui.710032e8fb22a86b24a52c7c00000db7 [nvme]:nvme1n2 NVMe,Huawei-XSG1,1000001 +size=10485760 features='n/a' hwhandler='ANA' wp=rw +|-+- policy='n/a' prio=50 status=optimized +| `- 1:4:1 nvme1c4n1 0:0 n/a optimized live +`-+- policy='n/a' prio=50 status=optimized + `- 1:9:1 nvme1c9n1 0:0 n/a optimized live +[root@localhost home]# + +The logical paths of "nvme1n1" and "nvme1n2" are both "nvme1c4n1" and "nvme1c9n1". +So when multipath-tools aggregates disks, use "nvme_ns_head->instance" for matching. +such as ,Use "b" in "nvmeanb" string to match "z" in "nvmexcynz"(a,b,x,y,z can be any number), +and if "b" and "z" are the same, they are related. + +Signed-off-by: chengjike +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/foreign/nvme.c | 26 ++++++++++++++++++++------ + 1 file changed, 20 insertions(+), 6 deletions(-) + +diff --git a/libmultipath/foreign/nvme.c b/libmultipath/foreign/nvme.c +index 52ca56d8..9a05b333 100644 +--- a/libmultipath/foreign/nvme.c ++++ b/libmultipath/foreign/nvme.c +@@ -531,14 +531,18 @@ static int _dirent_controller(const struct dirent *di) + + /* Find the block device for a given nvme controller */ + struct udev_device *get_ctrl_blkdev(const struct context *ctx, +- struct udev_device *ctrl) ++ struct udev_device *ctrl, const char *ctrl_name) + { ++ int ctrl_num, ns_num; + struct udev_list_entry *item; + struct udev_device *blkdev = NULL; + struct udev_enumerate *enm = udev_enumerate_new(ctx->udev); + const char *devtype; + +- if (enm == NULL) ++ if (enm == NULL || ctrl_name == NULL) ++ return NULL; ++ ++ if (sscanf(ctrl_name, "nvme%dn%d", &ctrl_num, &ns_num) != 2) + return NULL; + + pthread_cleanup_push(_udev_enumerate_unref, enm); +@@ -556,6 +560,8 @@ struct udev_device *get_ctrl_blkdev(const struct context *ctx, + item != NULL; + item = udev_list_entry_get_next(item)) { + struct udev_device *tmp; ++ const char *name = NULL ; ++ int m, n, l; + + tmp = udev_device_new_from_syspath(ctx->udev, + udev_list_entry_get_name(item)); +@@ -563,11 +569,19 @@ struct udev_device *get_ctrl_blkdev(const struct context *ctx, + continue; + + devtype = udev_device_get_devtype(tmp); +- if (devtype && !strcmp(devtype, "disk")) { ++ if (devtype == NULL || strcmp(devtype, "disk")) { ++ udev_device_unref(tmp); ++ continue; ++ } ++ ++ name = udev_device_get_sysname(tmp); ++ if (name != NULL && ++ sscanf(name, "nvme%dc%dn%d", &m, &n, &l) == 3 && ++ l == ns_num) { + blkdev = tmp; + break; +- } else +- udev_device_unref(tmp); ++ } ++ udev_device_unref(tmp); + } + + if (blkdev == NULL) +@@ -680,7 +694,7 @@ static void _find_controllers(struct context *ctx, struct nvme_map *map) + } + + pthread_cleanup_push(_udev_device_unref, ctrl); +- udev = get_ctrl_blkdev(ctx, ctrl); ++ udev = get_ctrl_blkdev(ctx, ctrl, udev_device_get_sysname(map->udev)); + /* + * We give up the reference to the nvme device here and get + * it back from the child below. diff --git a/0003-multipath-tools-add-HP-HSVX740-to-hwtable.patch b/0003-multipath-tools-add-HP-HSVX740-to-hwtable.patch deleted file mode 100644 index b950020..0000000 --- a/0003-multipath-tools-add-HP-HSVX740-to-hwtable.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Thu, 24 Feb 2022 22:24:39 +0100 -Subject: [PATCH] multipath-tools: add HP/HSVX740 to hwtable - -Info from: https://community.hpe.com/hpeb/attachments/hpeb/itrc-248/61618/1/HP_DM_MP_Guide.pdf - -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/hwtable.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index 3b9e0e0f..ff8ed036 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -192,7 +192,7 @@ static struct hwentry default_hw[] = { - { - /* SAN Virtualization Services Platform */ - .vendor = "HP", -- .product = "HSVX700", -+ .product = "(HSVX700|HSVX740)", - .hwhandler = "1 alua", - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, diff --git a/0003-multipath-tools-update-Huawei-OceanStor-NVMe-vendor-.patch b/0003-multipath-tools-update-Huawei-OceanStor-NVMe-vendor-.patch new file mode 100644 index 0000000..6bb4ab0 --- /dev/null +++ b/0003-multipath-tools-update-Huawei-OceanStor-NVMe-vendor-.patch @@ -0,0 +1,39 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Sun, 10 Jul 2022 01:07:08 +0200 +Subject: [PATCH] multipath-tools: update Huawei OceanStor NVMe vendor id + +"NVME" in the doc, but "NVMe" is the real output: +(page 61-62): https://drive.google.com/file/d/1c5RK4GXX7ofZBFxTtZ_IN1qHyIjw5eR1 +https://marc.info/?l=dm-devel&m=163393151312418 +Use both, just in case. + +Cc: +Cc: +Cc: +Cc: Zhouweigang (Jack) +Cc: Zou Ming +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/hwtable.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index 513fa679..fc0252ba 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -1116,7 +1116,7 @@ static struct hwentry default_hw[] = { + }, + { + /* OceanStor NVMe */ +- .vendor = "NVME", ++ .vendor = "NVM[eE]", + .product = "Huawei-XSG1", + .checker_name = DIRECTIO, + .no_path_retry = 12, diff --git a/0004-multipath-tools-add-DellEMC-ME5-PowerVault-ME5-to-ha.patch b/0004-multipath-tools-add-DellEMC-ME5-PowerVault-ME5-to-ha.patch deleted file mode 100644 index 8834238..0000000 --- a/0004-multipath-tools-add-DellEMC-ME5-PowerVault-ME5-to-ha.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Wed, 23 Feb 2022 23:16:44 +0100 -Subject: [PATCH] multipath-tools: add DellEMC/ME5 (PowerVault ME5) to hardware - table - -Convert PowerVault ME4 template for all ME series. - -[MW] https://dl.dell.com/content/manual51886263-dell-powervault-me5-series-administrator's-guide.pdf - -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/hwtable.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index ff8ed036..0e1c0a41 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -397,9 +397,9 @@ static struct hwentry default_hw[] = { - .fast_io_fail = 15, - }, - { -- /* PowerVault ME4 */ -+ /* PowerVault ME 4/5 families */ - .vendor = "DellEMC", -- .product = "ME4", -+ .product = "^ME", - .pgpolicy = GROUP_BY_PRIO, - .prio_name = PRIO_ALUA, - .hwhandler = "1 alua", diff --git a/0001-multipath-tools-identify-more-arrays-under-IBM-2145-.patch b/0004-multipath-tools-update-Generic-NVMe-vendor-regex-in-.patch similarity index 55% rename from 0001-multipath-tools-identify-more-arrays-under-IBM-2145-.patch rename to 0004-multipath-tools-update-Generic-NVMe-vendor-regex-in-.patch index c34345e..e70f088 100644 --- a/0001-multipath-tools-identify-more-arrays-under-IBM-2145-.patch +++ b/0004-multipath-tools-update-Generic-NVMe-vendor-regex-in-.patch @@ -1,7 +1,10 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Xose Vazquez Perez -Date: Thu, 24 Feb 2022 22:06:08 +0100 -Subject: [PATCH] multipath-tools: identify more arrays under IBM/2145 ID +Date: Sun, 10 Jul 2022 01:07:09 +0200 +Subject: [PATCH] multipath-tools: update "Generic NVMe" vendor regex in + hwtable + +to accept NVME and NVMe Cc: Martin Wilck Cc: Benjamin Marzinski @@ -15,15 +18,15 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index bd157103..643caa32 100644 +index fc0252ba..c88fa09a 100644 --- a/libmultipath/hwtable.c +++ b/libmultipath/hwtable.c -@@ -665,7 +665,7 @@ static struct hwentry default_hw[] = { - }, +@@ -86,7 +86,7 @@ static struct hwentry default_hw[] = { + */ { - // Storwize V5000 and V7000 lines / SAN Volume Controller (SVC) / Flex System V7000 / -- // FlashSystem V840/V9000/5000/5100/5200/7200/9100/9200/9200R -+ // FlashSystem V840/V9000/5000/5100/5200/7200/7300/9100/9200/9200R/9500 - .vendor = "IBM", - .product = "^2145", - .no_path_retry = NO_PATH_RETRY_QUEUE, + /* Generic NVMe */ +- .vendor = "NVME", ++ .vendor = "NVM[eE]", + .product = ".*", + .uid_attribute = DEFAULT_NVME_UID_ATTRIBUTE, + .checker_name = NONE, diff --git a/0005-libmultipath-unset-detect_checker-for-clariion-Unity.patch b/0005-libmultipath-unset-detect_checker-for-clariion-Unity.patch new file mode 100644 index 0000000..d80c1cf --- /dev/null +++ b/0005-libmultipath-unset-detect_checker-for-clariion-Unity.patch @@ -0,0 +1,30 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 10 May 2022 14:17:22 -0500 +Subject: [PATCH] libmultipath: unset detect_checker for clariion / Unity + arrays + +Dell EMC would like to always use the emc_clariion checker. Currently +detect_checker will switch the checker to TUR for Unity arrays. +This can cause problems on some setups with replicated Unity LUNs, +which are handled correctly the the emc_checker, but not the TUR +checker. + +Cc: vincent.chen1@dell.com +Signed-off-by: Benjamin Marzinski +--- + libmultipath/hwtable.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index c88fa09a..2085aba5 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -350,6 +350,7 @@ static struct hwentry default_hw[] = { + .no_path_retry = (300 / DEFAULT_CHECKINT), + .checker_name = EMC_CLARIION, + .prio_name = PRIO_EMC, ++ .detect_checker = DETECT_CHECKER_OFF, + }, + { + /* Invista / VPLEX */ diff --git a/0005-multipath-tools-update-mpp-force_readonly-in-ev_add_.patch b/0005-multipath-tools-update-mpp-force_readonly-in-ev_add_.patch deleted file mode 100644 index a2538e4..0000000 --- a/0005-multipath-tools-update-mpp-force_readonly-in-ev_add_.patch +++ /dev/null @@ -1,136 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Uday Shankar -Date: Wed, 9 Mar 2022 13:03:26 -0700 -Subject: [PATCH] multipath-tools: update mpp->force_readonly in ev_add_path - -When NVMe disks are added to the system, no uevent containing the -DISK_RO property is generated. As a result, dm-* nodes backed by -readonly NVMe disks will not have their RO state set properly. The -result looks like this: - -$ multipath -l -eui.00c92c091fd6564424a9376600011bd1 dm-3 NVME,Pure Storage FlashArray -size=1.0T features='0' hwhandler='0' wp=rw -|-+- policy='service-time 0' prio=0 status=active -| `- 0:2:2:72657 nvme0n2 259:4 active undef running -`-+- policy='service-time 0' prio=0 status=enabled - `- 1:0:2:72657 nvme1n2 259:1 active undef running -$ cat /sys/block/dm-3/ro -0 -$ cat /sys/block/nvme*n2/ro -1 -1 - -This is not a problem for SCSI disks, since the kernel will emit change -uevents containing the DISK_RO property when the disk is added to the -system. See the following thread for my initial attempt to fix this -issue at the kernel level: -https://lore.kernel.org/linux-block/Yib8GqCA5e3SQYty@infradead.org/T/#t - -Fix the issue by picking up the path ro state from sysfs in ev_add_path, -setting the mpp->force_readonly accordingly, and changing -dm_addmap_create to be aware of mpp->force_readonly. - -Signed-off-by: Uday Shankar -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/devmapper.c | 2 +- - multipathd/main.c | 50 ++++++++++++++++++++++------------------ - 2 files changed, 29 insertions(+), 23 deletions(-) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index 2507f77f..9819e29b 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -540,7 +540,7 @@ int dm_addmap_create (struct multipath *mpp, char * params) - int ro; - uint16_t udev_flags = build_udev_flags(mpp, 0); - -- for (ro = 0; ro <= 1; ro++) { -+ for (ro = mpp->force_readonly ? 1 : 0; ro <= 1; ro++) { - int err; - - if (dm_addmap(DM_DEVICE_CREATE, TGT_MPATH, mpp, params, ro, -diff --git a/multipathd/main.c b/multipathd/main.c -index f2c0b280..a67865df 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -1130,6 +1130,28 @@ out: - return ret; - } - -+static int -+sysfs_get_ro (struct path *pp) -+{ -+ int ro; -+ char buff[3]; /* Either "0\n\0" or "1\n\0" */ -+ -+ if (!pp->udev) -+ return -1; -+ -+ if (sysfs_attr_get_value(pp->udev, "ro", buff, sizeof(buff)) <= 0) { -+ condlog(3, "%s: Cannot read ro attribute in sysfs", pp->dev); -+ return -1; -+ } -+ -+ if (sscanf(buff, "%d\n", &ro) != 1 || ro < 0 || ro > 1) { -+ condlog(3, "%s: Cannot parse ro attribute", pp->dev); -+ return -1; -+ } -+ -+ return ro; -+} -+ - /* - * returns: - * 0: added -@@ -1143,6 +1165,7 @@ ev_add_path (struct path * pp, struct vectors * vecs, int need_do_map) - int retries = 3; - int start_waiter = 0; - int ret; -+ int ro; - - /* - * need path UID to go any further -@@ -1207,6 +1230,11 @@ rescan: - /* persistent reservation check*/ - mpath_pr_event_handle(pp); - -+ /* ro check - if new path is ro, force map to be ro as well */ -+ ro = sysfs_get_ro(pp); -+ if (ro == 1) -+ mpp->force_readonly = 1; -+ - if (!need_do_map) - return 0; - -@@ -1446,28 +1474,6 @@ finish_path_init(struct path *pp, struct vectors * vecs) - return -1; - } - --static int --sysfs_get_ro (struct path *pp) --{ -- int ro; -- char buff[3]; /* Either "0\n\0" or "1\n\0" */ -- -- if (!pp->udev) -- return -1; -- -- if (sysfs_attr_get_value(pp->udev, "ro", buff, sizeof(buff)) <= 0) { -- condlog(3, "%s: Cannot read ro attribute in sysfs", pp->dev); -- return -1; -- } -- -- if (sscanf(buff, "%d\n", &ro) != 1 || ro < 0 || ro > 1) { -- condlog(3, "%s: Cannot parse ro attribute", pp->dev); -- return -1; -- } -- -- return ro; --} -- - static bool - needs_ro_update(struct multipath *mpp, int ro) - { diff --git a/0006-libmultipath-fix-find_multipaths_timeout-for-unknown.patch b/0006-libmultipath-fix-find_multipaths_timeout-for-unknown.patch new file mode 100644 index 0000000..96b7260 --- /dev/null +++ b/0006-libmultipath-fix-find_multipaths_timeout-for-unknown.patch @@ -0,0 +1,27 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 28 Jun 2022 15:38:28 -0500 +Subject: [PATCH] libmultipath: fix find_multipaths_timeout for unknown + hardware + +pp->hwe is now a vector that will always be allocated for all path +devices. Instead of checking if it is NULL, check if it is empty. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/propsel.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c +index 50d0b5c8..f782f251 100644 +--- a/libmultipath/propsel.c ++++ b/libmultipath/propsel.c +@@ -1293,7 +1293,7 @@ out: + */ + if (pp->find_multipaths_timeout < 0) { + pp->find_multipaths_timeout = -pp->find_multipaths_timeout; +- if (!pp->hwe) { ++ if (VECTOR_SIZE(pp->hwe) == 0) { + pp->find_multipaths_timeout = + DEFAULT_UNKNOWN_FIND_MULTIPATHS_TIMEOUT; + origin = "(default for unknown hardware)"; diff --git a/0006-RH-fixup-udev-rules-for-redhat.patch b/0007-RH-fixup-udev-rules-for-redhat.patch similarity index 94% rename from 0006-RH-fixup-udev-rules-for-redhat.patch rename to 0007-RH-fixup-udev-rules-for-redhat.patch index 6153d90..f24e8db 100644 --- a/0006-RH-fixup-udev-rules-for-redhat.patch +++ b/0007-RH-fixup-udev-rules-for-redhat.patch @@ -15,10 +15,10 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index d24da43e..fb23635c 100644 +index bcd2212a..40cfbd0c 100644 --- a/Makefile.inc +++ b/Makefile.inc -@@ -75,7 +75,7 @@ endif +@@ -76,7 +76,7 @@ endif prefix = exec_prefix = $(prefix) usr_prefix = $(prefix) @@ -40,10 +40,10 @@ index 1969dee0..d2b28233 100644 LABEL="kpartx_end" diff --git a/multipath/Makefile b/multipath/Makefile -index c930499d..2059a4f4 100644 +index bcb04533..d2b3fd82 100644 --- a/multipath/Makefile +++ b/multipath/Makefile -@@ -22,7 +22,7 @@ install: +@@ -23,7 +23,7 @@ install: $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ $(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) $(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) @@ -52,7 +52,7 @@ index c930499d..2059a4f4 100644 $(INSTALL_PROGRAM) -d $(DESTDIR)$(modulesloaddir) $(INSTALL_PROGRAM) -m 644 modules-load.conf $(DESTDIR)$(modulesloaddir)/multipath.conf $(INSTALL_PROGRAM) -d $(DESTDIR)$(man8dir) -@@ -40,7 +40,7 @@ uninstall: +@@ -41,7 +41,7 @@ uninstall: $(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules $(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf $(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf diff --git a/0007-RH-Remove-the-property-blacklist-exception-builtin.patch b/0008-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 96% rename from 0007-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0008-RH-Remove-the-property-blacklist-exception-builtin.patch index edc8dc1..3bf0684 100644 --- a/0007-RH-Remove-the-property-blacklist-exception-builtin.patch +++ b/0008-RH-Remove-the-property-blacklist-exception-builtin.patch @@ -43,10 +43,10 @@ index 8d15d2ea..eff690fd 100644 udev_device_get_properties_list_entry(udev)) { diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 605b46e0..1844a250 100644 +index c2d34f18..18a55b70 100644 --- a/multipath/multipath.conf.5 +++ b/multipath/multipath.conf.5 -@@ -1365,9 +1365,14 @@ keywords. Both are regular expressions. For a full description of these keywords +@@ -1348,9 +1348,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, @@ -62,7 +62,7 @@ index 605b46e0..1844a250 100644 . .RS .PP -@@ -1378,10 +1383,6 @@ Blacklisting by missing properties is only applied to devices which do have the +@@ -1361,10 +1366,6 @@ Blacklisting by missing properties is only applied to devices which do have the property specified by \fIuid_attribute\fR (e.g. \fIID_SERIAL\fR) set. Previously, it was applied to every device, possibly causing devices to be blacklisted because of temporary I/O error conditions. diff --git a/0008-RH-don-t-start-without-a-config-file.patch b/0009-RH-don-t-start-without-a-config-file.patch similarity index 95% rename from 0008-RH-don-t-start-without-a-config-file.patch rename to 0009-RH-don-t-start-without-a-config-file.patch index 82bf02f..77f2958 100644 --- a/0008-RH-don-t-start-without-a-config-file.patch +++ b/0009-RH-don-t-start-without-a-config-file.patch @@ -21,13 +21,13 @@ Signed-off-by: Benjamin Marzinski 6 files changed, 19 insertions(+) diff --git a/libmultipath/config.c b/libmultipath/config.c -index c595e768..b193de5c 100644 +index ab8b26e7..f06fcbf9 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c -@@ -894,6 +894,19 @@ int _init_config (const char *file, struct config *conf) - goto out; +@@ -955,6 +955,19 @@ int _init_config (const char *file, struct config *conf) } factorize_hwtable(conf->hwtable, builtin_hwtable_size, file); + validate_pctable(conf->overrides, 0, file); + } else { + condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices."); + if (conf->blist_devnode == NULL) { @@ -45,7 +45,7 @@ index c595e768..b193de5c 100644 conf->processed_main_config = 1; diff --git a/libmultipath/config.h b/libmultipath/config.h -index c73389b5..69a01cb7 100644 +index 36d40157..115b463b 100644 --- a/libmultipath/config.h +++ b/libmultipath/config.h @@ -9,6 +9,7 @@ diff --git a/0009-RH-Fix-nvme-function-missing-argument.patch b/0010-RH-Fix-nvme-function-missing-argument.patch similarity index 100% rename from 0009-RH-Fix-nvme-function-missing-argument.patch rename to 0010-RH-Fix-nvme-function-missing-argument.patch diff --git a/0010-RH-use-rpm-optflags-if-present.patch b/0011-RH-use-rpm-optflags-if-present.patch similarity index 66% rename from 0010-RH-use-rpm-optflags-if-present.patch rename to 0011-RH-use-rpm-optflags-if-present.patch index 7436fd0..5b0ed18 100644 --- a/0010-RH-use-rpm-optflags-if-present.patch +++ b/0011-RH-use-rpm-optflags-if-present.patch @@ -9,27 +9,21 @@ still being generic. Signed-off-by: Benjamin Marzinski --- - Makefile.inc | 26 +++++++++++++++++++------- - 1 file changed, 19 insertions(+), 7 deletions(-) + Makefile.inc | 24 ++++++++++++++++++------ + 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index fb23635c..4511ab1f 100644 +index 40cfbd0c..307b6b4d 100644 --- a/Makefile.inc +++ b/Makefile.inc -@@ -114,23 +114,35 @@ TEST_CC_OPTION = $(shell \ - echo "$(2)"; \ - fi) - --STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector) - ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers,) +@@ -136,18 +136,30 @@ ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered -Wno-error=clobbered,) WFORMATOVERFLOW := $(call TEST_CC_OPTION,-Wformat-overflow=2,) -OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 -WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int \ +ifndef RPM_OPT_FLAGS -+ STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector) -+ OPTFLAGS := -O2 -g -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions \ ++ OPTFLAGS := -O2 -g -Wall $(FORTIFY_OPT) -fexceptions \ + $(STACKPROT) -grecord-gcc-switches \ + -fasynchronous-unwind-tables --param=ssp-buffer-size=4 + ifeq ($(shell test -f /usr/lib/rpm/redhat/redhat-hardened-cc1 && echo 1),1) @@ -44,12 +38,13 @@ index fb23635c..4511ab1f 100644 +WARNFLAGS := -Werror -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int \ -Werror=implicit-function-declaration -Werror=format-security \ - $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) --CPPFLAGS := -Wp,-D_FORTIFY_SOURCE=2 -+ $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) \ -+ -Wstrict-prototypes - CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ - -DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" \ - -MMD -MP +-CPPFLAGS := $(FORTIFY_OPT) \ +- -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" -DRUN_DIR=\"${RUN}\" \ ++ $(WNOCLOBBERED) -Werror=cast-qual \ ++ $(ERROR_DISCARDED_QUALIFIERS) -Wstrict-prototypes ++CPPFLAGS := -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" -DRUN_DIR=\"${RUN}\" \ + -DCONFIG_DIR=\"$(configdir)\" -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP + CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe BIN_CFLAGS = -fPIE -DPIE LIB_CFLAGS = -fPIC SHARED_FLAGS = -shared @@ -58,12 +53,3 @@ index fb23635c..4511ab1f 100644 BIN_LDFLAGS = -pie # Check whether a function with name $1 has been declared in header file $2. -@@ -174,7 +186,7 @@ check_var = $(shell \ - - %.o: %.c - @echo building $@ because of $? -- $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< -+ $(CC) $(CFLAGS) -c -o $@ $< - - %.abi: %.so.0 - abidw $< >$@ diff --git a/0011-RH-add-mpathconf.patch b/0012-RH-add-mpathconf.patch similarity index 98% rename from 0011-RH-add-mpathconf.patch rename to 0012-RH-add-mpathconf.patch index 80b882a..ff2487f 100644 --- a/0011-RH-add-mpathconf.patch +++ b/0012-RH-add-mpathconf.patch @@ -21,11 +21,11 @@ Signed-off-by: Benjamin Marzinski create mode 100644 multipath/mpathconf.8 diff --git a/libmultipath/config.c b/libmultipath/config.c -index b193de5c..a8ec3bf4 100644 +index f06fcbf9..e2840839 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c -@@ -896,6 +896,8 @@ int _init_config (const char *file, struct config *conf) - factorize_hwtable(conf->hwtable, builtin_hwtable_size, file); +@@ -957,6 +957,8 @@ int _init_config (const char *file, struct config *conf) + validate_pctable(conf->overrides, 0, file); } else { condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices."); + condlog(0, "You can run \"/sbin/mpathconf --enable\" to create"); @@ -34,10 +34,10 @@ index b193de5c..a8ec3bf4 100644 conf->blist_devnode = vector_alloc(); if (!conf->blist_devnode) { diff --git a/multipath/Makefile b/multipath/Makefile -index 2059a4f4..e2ebe431 100644 +index d2b3fd82..00e46a0d 100644 --- a/multipath/Makefile +++ b/multipath/Makefile -@@ -20,6 +20,7 @@ $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so +@@ -21,6 +21,7 @@ $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so install: $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ @@ -45,7 +45,7 @@ index 2059a4f4..e2ebe431 100644 $(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) $(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) $(INSTALL_PROGRAM) -m 644 $(EXEC).rules $(DESTDIR)$(udevrulesdir)/62-multipath.rules -@@ -29,6 +30,7 @@ install: +@@ -30,6 +31,7 @@ install: $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(man8dir) $(INSTALL_PROGRAM) -d $(DESTDIR)$(man5dir) $(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5 $(DESTDIR)$(man5dir) @@ -53,7 +53,7 @@ index 2059a4f4..e2ebe431 100644 ifneq ($(SCSI_DH_MODULES_PRELOAD),) $(INSTALL_PROGRAM) -m 644 scsi_dh.conf $(DESTDIR)$(modulesloaddir)/scsi_dh.conf for _x in $(SCSI_DH_MODULES_PRELOAD); do echo "$$_x"; done \ -@@ -41,8 +43,10 @@ uninstall: +@@ -42,8 +44,10 @@ uninstall: $(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf $(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf $(RM) $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules diff --git a/0012-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0013-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 99% rename from 0012-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0013-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch index c133e00..fbf22db 100644 --- a/0012-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +++ b/0013-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch @@ -20,7 +20,7 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/multipath/main.c b/multipath/main.c -index d09f62db..0d786ee5 100644 +index 034dd2f4..4c31820b 100644 --- a/multipath/main.c +++ b/multipath/main.c @@ -120,7 +120,7 @@ usage (char * progname) diff --git a/0013-RH-reset-default-find_mutipaths-value-to-off.patch b/0014-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 94% rename from 0013-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0014-RH-reset-default-find_mutipaths-value-to-off.patch index f1e8c33..9b6b7bb 100644 --- a/0013-RH-reset-default-find_mutipaths-value-to-off.patch +++ b/0014-RH-reset-default-find_mutipaths-value-to-off.patch @@ -12,10 +12,10 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h -index 7d95413d..4fe08991 100644 +index 7979f208..78b3d938 100644 --- a/libmultipath/defaults.h +++ b/libmultipath/defaults.h -@@ -24,7 +24,7 @@ +@@ -23,7 +23,7 @@ #define DEFAULT_NO_PATH_RETRY NO_PATH_RETRY_UNDEF #define DEFAULT_VERBOSITY 2 #define DEFAULT_REASSIGN_MAPS 0 diff --git a/0014-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0015-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 100% rename from 0014-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0015-RH-attempt-to-get-ANA-info-via-sysfs-first.patch diff --git a/0015-RH-make-parse_vpd_pg83-match-scsi_id-output.patch b/0016-RH-make-parse_vpd_pg83-match-scsi_id-output.patch similarity index 94% rename from 0015-RH-make-parse_vpd_pg83-match-scsi_id-output.patch rename to 0016-RH-make-parse_vpd_pg83-match-scsi_id-output.patch index bbc0212..619ce7d 100644 --- a/0015-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +++ b/0016-RH-make-parse_vpd_pg83-match-scsi_id-output.patch @@ -14,10 +14,10 @@ Signed-off-by: Benjamin Marzinski 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index b969fba1..d2f2a8cf 100644 +index 0d8a558c..0c73b754 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c -@@ -1156,13 +1156,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, +@@ -1177,13 +1177,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, good_len = 8; break; case 2: @@ -33,7 +33,7 @@ index b969fba1..d2f2a8cf 100644 good_len = 8; break; default: -@@ -1180,10 +1176,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, +@@ -1201,10 +1197,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, break; case 0x8: /* SCSI Name: Prio 3 */ diff --git a/0016-RH-add-scsi-device-handlers-to-modules-load.d.patch b/0017-RH-add-scsi-device-handlers-to-modules-load.d.patch similarity index 85% rename from 0016-RH-add-scsi-device-handlers-to-modules-load.d.patch rename to 0017-RH-add-scsi-device-handlers-to-modules-load.d.patch index 07f921f..d86e03b 100644 --- a/0016-RH-add-scsi-device-handlers-to-modules-load.d.patch +++ b/0017-RH-add-scsi-device-handlers-to-modules-load.d.patch @@ -11,7 +11,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc -index 4511ab1f..fec82b00 100644 +index 307b6b4d..8f64c700 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -11,7 +11,7 @@ @@ -21,5 +21,5 @@ index 4511ab1f..fec82b00 100644 -SCSI_DH_MODULES_PRELOAD := +SCSI_DH_MODULES_PRELOAD := scsi_dh_alua scsi_dh_emc scsi_dh_rdac + EXTRAVERSION := $(shell rev=$$(git rev-parse --short=7 HEAD 2>/dev/null); echo $${rev:+-g$$rev}) - PKGCONFIG ?= pkg-config diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 97d7dfc..23dcdc9 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,5 +1,5 @@ Name: device-mapper-multipath -Version: 0.8.9 +Version: 0.9.0 Release: 1%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 @@ -7,25 +7,26 @@ 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 -L https://github.com/opensvc/multipath-tools/archive/0.8.9.tar.gz -o multipath-tools-0.8.9.tgz -Source0: multipath-tools-0.8.9.tgz +# curl -L https://github.com/opensvc/multipath-tools/archive/0.9.0.tar.gz -o multipath-tools-0.9.0.tgz +Source0: multipath-tools-0.9.0.tgz Source1: multipath.conf -Patch0001: 0001-multipath-tools-identify-more-arrays-under-IBM-2145-.patch -Patch0002: 0002-multipath-tools-add-HPE-as-vendor-for-OPEN-XP8-array.patch -Patch0003: 0003-multipath-tools-add-HP-HSVX740-to-hwtable.patch -Patch0004: 0004-multipath-tools-add-DellEMC-ME5-PowerVault-ME5-to-ha.patch -Patch0005: 0005-multipath-tools-update-mpp-force_readonly-in-ev_add_.patch -Patch0006: 0006-RH-fixup-udev-rules-for-redhat.patch -Patch0007: 0007-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0008: 0008-RH-don-t-start-without-a-config-file.patch -Patch0009: 0009-RH-Fix-nvme-function-missing-argument.patch -Patch0010: 0010-RH-use-rpm-optflags-if-present.patch -Patch0011: 0011-RH-add-mpathconf.patch -Patch0012: 0012-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0013: 0013-RH-reset-default-find_mutipaths-value-to-off.patch -Patch0014: 0014-RH-attempt-to-get-ANA-info-via-sysfs-first.patch -Patch0015: 0015-RH-make-parse_vpd_pg83-match-scsi_id-output.patch -Patch0016: 0016-RH-add-scsi-device-handlers-to-modules-load.d.patch +Patch0001: 0001-github-workflows-switch-to-fedora-36.patch +Patch0002: 0002-multipath-tools-fix-multipath-ll-bug-for-Native-NVME.patch +Patch0003: 0003-multipath-tools-update-Huawei-OceanStor-NVMe-vendor-.patch +Patch0004: 0004-multipath-tools-update-Generic-NVMe-vendor-regex-in-.patch +Patch0005: 0005-libmultipath-unset-detect_checker-for-clariion-Unity.patch +Patch0006: 0006-libmultipath-fix-find_multipaths_timeout-for-unknown.patch +Patch0007: 0007-RH-fixup-udev-rules-for-redhat.patch +Patch0008: 0008-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0009: 0009-RH-don-t-start-without-a-config-file.patch +Patch0010: 0010-RH-Fix-nvme-function-missing-argument.patch +Patch0011: 0011-RH-use-rpm-optflags-if-present.patch +Patch0012: 0012-RH-add-mpathconf.patch +Patch0013: 0013-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0014: 0014-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0015: 0015-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0016: 0016-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +Patch0017: 0017-RH-add-scsi-device-handlers-to-modules-load.d.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -109,7 +110,7 @@ This package contains the files needed to develop applications that use device-mapper-multipath's libdmmp C API library %prep -%autosetup -n multipath-tools-0.8.9 -p1 +%autosetup -n multipath-tools-0.9.0 -p1 cp %{SOURCE1} . %build @@ -226,6 +227,17 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Wed Jul 13 2022 Benjamin Marzinski - 0.9.0-1 +- Update source to upstream version 0.9.0 + * Previous patches 0001-0005 are included in the commit. + * This version deprecates multiple options: mutlipath_dir, config_dir, and + getuid_callout, along with the "default_" prefixed alternate names for the + default section parameters. +- Add patches from upstream staging branch + * Patches 0001-0006 are from the upstream staging branch +- Rename redhat patches + * Previous patches 0006-0016 are now patches 0007-0017 + * Mon Mar 28 2022 Benjamin Marzinski - 0.8.9-1 - Update source to upstream version 0.8.9 * Previous patches 0001-0024 & 0035 are included in the commit. diff --git a/sources b/sources index 7a7f2cd..14c7342 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (multipath-tools-0.8.9.tgz) = 25f2a5d436af6a343804988cef45ca1574d4a981655a2b91563ddb89138619158befdf5af92d836a17c95d6dcf901072b614473c2129274e5dcdb1a1d64edb4d +SHA512 (multipath-tools-0.9.0.tgz) = 6c417f6d1d116fa43bedb9f77769ece9cbb7b35b78a9b3558c41df2360e52a65a07314b12ab7e4a7bbc867b9755250de9db96a2f7eb4a6a37f0b0b3f0bbc840e SHA512 (multipath.conf) = 71953dce5a68adcf60a942305f5a66023e6f4c4baf53b1bfdb4edf65ed5b8e03db804363c36d1dcfd85591f4766f52b515269904c53b84d7b076da0b80b09942 From ca605574d1f061247ed63000e4dd03d6a3adcbd4 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 21 Jul 2022 00:20:57 +0000 Subject: [PATCH 33/67] Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- device-mapper-multipath.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 23dcdc9..84d0472 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.9.0 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -227,6 +227,9 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Thu Jul 21 2022 Fedora Release Engineering - 0.9.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild + * Wed Jul 13 2022 Benjamin Marzinski - 0.9.0-1 - Update source to upstream version 0.9.0 * Previous patches 0001-0005 are included in the commit. From ef9089f4e85187f88688b4d6c3d3d1ccf9a13e9f Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Fri, 19 Aug 2022 12:48:04 -0500 Subject: [PATCH 34/67] device-mapper-multipath-0.9.0-3 Update to the head of the upstream staging branch * Patches 0005-0042 are from the upstream staging branch * Previous patches 0005 & 0006 are now patches 0023 & 0005 Rename redhat patches * Previous patches 0007-0017 are now patches 0043-0053 Change from using readline to libedit * readline is licensed GPL v3, and multipathd includes code licensed gpl v2. Remove README.alua * information moved to README.md --- ...update-Huawei-OceanStor-NVMe-vendor-.patch | 1 + ...update-Generic-NVMe-vendor-regex-in-.patch | 1 + ...-find_multipaths_timeout-for-unknown.patch | 4 +- ...-update-devel-repo-info-in-README.md.patch | 52 ++ 0007-multipath-tools-delete-README.alua.patch | 48 ++ ...ath-tools-add-ALUA-info-to-README.md.patch | 53 ++ ...multipath-alua-remove-get_sysfs_pg83.patch | 95 +++ ...libmultipath-remove-sysfs_get_binary.patch | 77 +++ ...fs_bin_attr_get_value-no-error-if-bu.patch | 65 ++ ...mon-code-path-for-sysfs_attr_get_val.patch | 115 ++++ ...itize-error-checking-in-sysfs-access.patch | 165 +++++ 0014-libmultipath-get-rid-of-PATH_SIZE.patch | 115 ++++ ...fs_attr_get_value-don-t-return-0-if-.patch | 172 +++++ ...fs_attr_set_value-don-t-return-0-on-.patch | 251 ++++++++ ...fs-cleanup-file-descriptors-on-pthre.patch | 71 +++ ...tipathd-log-failure-setting-sysfs-at.patch | 168 +++++ ...expect_condlog-skip-depending-on-ver.patch | 37 ++ ...-tests-__wrap_dlog-print-log-message.patch | 27 + 0021-multipath-tests-add-sysfs-test.patch | 538 ++++++++++++++++ ...sion-bump-version-for-sysfs-accessor.patch | 43 ++ ...et-detect_checker-for-clariion-Unity.patch | 3 +- 0024-libmultipath-spelling-cplusplus.patch | 26 + 0025-libmultipath-spelling-ascii.patch | 25 + 0026-libmultipath-spelling-progress.patch | 25 + 0027-multipath-tools-spelling-fixes.patch | 599 ++++++++++++++++++ ...remove-list-of-rebranded-arrays-vend.patch | 57 ++ ...correct-CLARiiON-info-from-multipath.patch | 47 ++ ...add-basic-info-on-how-to-use-multipa.patch | 41 ++ ...r-out-the-code-to-flush-a-map-with-n.patch | 90 +++ ...urn-success-if-we-raced-to-remove-a-.patch | 47 ++ ...Handle-losing-all-path-in-update_map.patch | 36 ++ ...-fix-systemd-timers-in-the-initramfs.patch | 35 + ...multipathd-Add-missing-ctype-include.patch | 26 + ...thd-replace-libreadline-with-libedit.patch | 102 +++ ...vert-license-of-strbuf-code-to-GPL-2.patch | 42 ++ ...-build-and-unittest.yaml-add-libedit.patch | 44 ++ ...kflows-coverity.yaml-add-libedit-dev.patch | 26 + ...b-workflows-abi.yaml-add-libedit-dev.patch | 26 + ...-native.yaml-add-libedit-dev-except-.patch | 71 +++ ...-foreign.yaml-switch-to-Debian-11-bu.patch | 40 ++ ... 0043-RH-fixup-udev-rules-for-redhat.patch | 4 +- ...property-blacklist-exception-builtin.patch | 2 +- ...RH-don-t-start-without-a-config-file.patch | 4 +- ...H-Fix-nvme-function-missing-argument.patch | 0 ... 0047-RH-use-rpm-optflags-if-present.patch | 4 +- ...hconf.patch => 0048-RH-add-mpathconf.patch | 0 ...om-kernel-cmdline-mpath.wwids-with-A.patch | 0 ...-default-find_mutipaths-value-to-off.patch | 0 ...empt-to-get-ANA-info-via-sysfs-first.patch | 0 ...-parse_vpd_pg83-match-scsi_id-output.patch | 6 +- ...si-device-handlers-to-modules-load.d.patch | 4 +- device-mapper-multipath.spec | 80 ++- 52 files changed, 3580 insertions(+), 30 deletions(-) rename 0006-libmultipath-fix-find_multipaths_timeout-for-unknown.patch => 0005-libmultipath-fix-find_multipaths_timeout-for-unknown.patch (85%) create mode 100644 0006-multipath-tools-update-devel-repo-info-in-README.md.patch create mode 100644 0007-multipath-tools-delete-README.alua.patch create mode 100644 0008-multipath-tools-add-ALUA-info-to-README.md.patch create mode 100644 0009-libmultipath-alua-remove-get_sysfs_pg83.patch create mode 100644 0010-libmultipath-remove-sysfs_get_binary.patch create mode 100644 0011-libmultipath-sysfs_bin_attr_get_value-no-error-if-bu.patch create mode 100644 0012-libmultipath-common-code-path-for-sysfs_attr_get_val.patch create mode 100644 0013-libmultipath-sanitize-error-checking-in-sysfs-access.patch create mode 100644 0014-libmultipath-get-rid-of-PATH_SIZE.patch create mode 100644 0015-libmultipath-sysfs_attr_get_value-don-t-return-0-if-.patch create mode 100644 0016-libmultipath-sysfs_attr_set_value-don-t-return-0-on-.patch create mode 100644 0017-libmultipath-sysfs-cleanup-file-descriptors-on-pthre.patch create mode 100644 0018-libmultipath-multipathd-log-failure-setting-sysfs-at.patch create mode 100644 0019-multipath-tests-expect_condlog-skip-depending-on-ver.patch create mode 100644 0020-multipath-tests-__wrap_dlog-print-log-message.patch create mode 100644 0021-multipath-tests-add-sysfs-test.patch create mode 100644 0022-libmultipath.version-bump-version-for-sysfs-accessor.patch rename 0005-libmultipath-unset-detect_checker-for-clariion-Unity.patch => 0023-libmultipath-unset-detect_checker-for-clariion-Unity.patch (92%) create mode 100644 0024-libmultipath-spelling-cplusplus.patch create mode 100644 0025-libmultipath-spelling-ascii.patch create mode 100644 0026-libmultipath-spelling-progress.patch create mode 100644 0027-multipath-tools-spelling-fixes.patch create mode 100644 0028-multipath-tools-remove-list-of-rebranded-arrays-vend.patch create mode 100644 0029-multipath-tools-correct-CLARiiON-info-from-multipath.patch create mode 100644 0030-multipath-tools-add-basic-info-on-how-to-use-multipa.patch create mode 100644 0031-multipathd-factor-out-the-code-to-flush-a-map-with-n.patch create mode 100644 0032-libmultipath-return-success-if-we-raced-to-remove-a-.patch create mode 100644 0033-multipathd-Handle-losing-all-path-in-update_map.patch create mode 100644 0034-multipath-fix-systemd-timers-in-the-initramfs.patch create mode 100644 0035-multipathd-Add-missing-ctype-include.patch create mode 100644 0036-multipathd-replace-libreadline-with-libedit.patch create mode 100644 0037-libmultipath-convert-license-of-strbuf-code-to-GPL-2.patch create mode 100644 0038-github-workflows-build-and-unittest.yaml-add-libedit.patch create mode 100644 0039-github-workflows-coverity.yaml-add-libedit-dev.patch create mode 100644 0040-github-workflows-abi.yaml-add-libedit-dev.patch create mode 100644 0041-GitHub-workflows-native.yaml-add-libedit-dev-except-.patch create mode 100644 0042-GitHub-workflows-foreign.yaml-switch-to-Debian-11-bu.patch rename 0007-RH-fixup-udev-rules-for-redhat.patch => 0043-RH-fixup-udev-rules-for-redhat.patch (97%) rename 0008-RH-Remove-the-property-blacklist-exception-builtin.patch => 0044-RH-Remove-the-property-blacklist-exception-builtin.patch (99%) rename 0009-RH-don-t-start-without-a-config-file.patch => 0045-RH-don-t-start-without-a-config-file.patch (98%) rename 0010-RH-Fix-nvme-function-missing-argument.patch => 0046-RH-Fix-nvme-function-missing-argument.patch (100%) rename 0011-RH-use-rpm-optflags-if-present.patch => 0047-RH-use-rpm-optflags-if-present.patch (96%) rename 0012-RH-add-mpathconf.patch => 0048-RH-add-mpathconf.patch (100%) rename 0013-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch => 0049-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch (100%) rename 0014-RH-reset-default-find_mutipaths-value-to-off.patch => 0050-RH-reset-default-find_mutipaths-value-to-off.patch (100%) rename 0015-RH-attempt-to-get-ANA-info-via-sysfs-first.patch => 0051-RH-attempt-to-get-ANA-info-via-sysfs-first.patch (100%) rename 0016-RH-make-parse_vpd_pg83-match-scsi_id-output.patch => 0052-RH-make-parse_vpd_pg83-match-scsi_id-output.patch (94%) rename 0017-RH-add-scsi-device-handlers-to-modules-load.d.patch => 0053-RH-add-scsi-device-handlers-to-modules-load.d.patch (92%) diff --git a/0003-multipath-tools-update-Huawei-OceanStor-NVMe-vendor-.patch b/0003-multipath-tools-update-Huawei-OceanStor-NVMe-vendor-.patch index 6bb4ab0..9643721 100644 --- a/0003-multipath-tools-update-Huawei-OceanStor-NVMe-vendor-.patch +++ b/0003-multipath-tools-update-Huawei-OceanStor-NVMe-vendor-.patch @@ -19,6 +19,7 @@ Cc: Christophe Varoqui Cc: DM-DEVEL ML Signed-off-by: Xose Vazquez Perez Reviewed-by: Martin Wilck +Reviewed-by: Benjamin Marzinski Signed-off-by: Benjamin Marzinski --- libmultipath/hwtable.c | 2 +- diff --git a/0004-multipath-tools-update-Generic-NVMe-vendor-regex-in-.patch b/0004-multipath-tools-update-Generic-NVMe-vendor-regex-in-.patch index e70f088..4ef193d 100644 --- a/0004-multipath-tools-update-Generic-NVMe-vendor-regex-in-.patch +++ b/0004-multipath-tools-update-Generic-NVMe-vendor-regex-in-.patch @@ -12,6 +12,7 @@ Cc: Christophe Varoqui Cc: DM-DEVEL ML Signed-off-by: Xose Vazquez Perez Reviewed-by: Martin Wilck +Reviewed-by: Benjamin Marzinski Signed-off-by: Benjamin Marzinski --- libmultipath/hwtable.c | 2 +- diff --git a/0006-libmultipath-fix-find_multipaths_timeout-for-unknown.patch b/0005-libmultipath-fix-find_multipaths_timeout-for-unknown.patch similarity index 85% rename from 0006-libmultipath-fix-find_multipaths_timeout-for-unknown.patch rename to 0005-libmultipath-fix-find_multipaths_timeout-for-unknown.patch index 96b7260..c2abfaa 100644 --- a/0006-libmultipath-fix-find_multipaths_timeout-for-unknown.patch +++ b/0005-libmultipath-fix-find_multipaths_timeout-for-unknown.patch @@ -1,13 +1,15 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski -Date: Tue, 28 Jun 2022 15:38:28 -0500 +Date: Tue, 12 Jul 2022 17:02:51 -0500 Subject: [PATCH] libmultipath: fix find_multipaths_timeout for unknown hardware pp->hwe is now a vector that will always be allocated for all path devices. Instead of checking if it is NULL, check if it is empty. +Fixes: f0462f0 ("libmultipath: use vector for for pp->hwe and mp->hwe") Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck --- libmultipath/propsel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/0006-multipath-tools-update-devel-repo-info-in-README.md.patch b/0006-multipath-tools-update-devel-repo-info-in-README.md.patch new file mode 100644 index 0000000..3eaf2c0 --- /dev/null +++ b/0006-multipath-tools-update-devel-repo-info-in-README.md.patch @@ -0,0 +1,52 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Thu, 14 Jul 2022 21:05:39 +0200 +Subject: [PATCH] multipath-tools: update devel repo info in README.md + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + README.md | 10 +++------- + 1 file changed, 3 insertions(+), 7 deletions(-) + +diff --git a/README.md b/README.md +index f06f8cea..dcf51f20 100644 +--- a/README.md ++++ b/README.md +@@ -3,7 +3,6 @@ + multipath-tools for Linux + ========================= + +- + https://github.com/opensvc/multipath-tools + + This package provides the following binaries to drive the Device Mapper multipathing driver: +@@ -42,14 +41,12 @@ Go to: https://github.com/opensvc/multipath-tools/tags + Select a release-tag and then click on "zip" or "tar.gz". + + +-Source code +-=========== ++Devel code ++========== + + To get latest devel code: + +- git clone https://github.com/opensvc/multipath-tools.git +- +-Github page: https://github.com/opensvc/multipath-tools ++ git clone -b queue https://github.com/openSUSE/multipath-tools + + + Building multipath-tools +@@ -149,4 +146,3 @@ The multipath-tools source code is covered by several different licences. + Refer to the individual source files for details. + Source files which do not specify a licence are shipped under LGPL-2.0 + (see `LICENSES/LGPL-2.0`). +- diff --git a/0007-multipath-tools-delete-README.alua.patch b/0007-multipath-tools-delete-README.alua.patch new file mode 100644 index 0000000..8682745 --- /dev/null +++ b/0007-multipath-tools-delete-README.alua.patch @@ -0,0 +1,48 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Thu, 14 Jul 2022 21:05:40 +0200 +Subject: [PATCH] multipath-tools: delete README.alua + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + README.alua | 24 ------------------------ + 1 file changed, 24 deletions(-) + delete mode 100644 README.alua + +diff --git a/README.alua b/README.alua +deleted file mode 100644 +index 5d2b1c64..00000000 +--- a/README.alua ++++ /dev/null +@@ -1,24 +0,0 @@ +-This is a rough guide, consult your storage device manufacturer documentation. +- +-ALUA is supported in some devices, but usually it's disabled by default. +-To enable ALUA, the following options should be changed: +- +-- EMC CLARiiON/VNX: +- "Failover Mode" should be changed to "4" or "Active-Active mode(ALUA)-failover mode 4" +- +-- HPE 3PAR, Primera, and Alletra 9000: +- "Host:" should be changed to "Generic-ALUA Persona 2 (UARepLun, SESLun, ALUA)". +- +-- Promise VTrak/Vess: +- "LUN Affinity" and "ALUA" should be changed to "Enable", "Redundancy Type" +- must be "Active-Active". +- +-- LSI/Engenio/NetApp RDAC class, as NetApp SANtricity E/EF Series and OEM arrays: +- "Select operating system:" should be changed to "Linux DM-MP (Kernel 3.10 or later)". +- +-- NetApp ONTAP: +- To check ALUA state: "igroup show -v ", and to enable ALUA: +- "igroup set alua yes". +- +-- Huawei OceanStor: +- "Host Access Mode" should be changed to "Asymmetric". diff --git a/0008-multipath-tools-add-ALUA-info-to-README.md.patch b/0008-multipath-tools-add-ALUA-info-to-README.md.patch new file mode 100644 index 0000000..2a11fce --- /dev/null +++ b/0008-multipath-tools-add-ALUA-info-to-README.md.patch @@ -0,0 +1,53 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Thu, 14 Jul 2022 23:14:31 +0200 +Subject: [PATCH] multipath-tools: add ALUA info to README.md + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + README.md | 28 ++++++++++++++++++++++++++++ + 1 file changed, 28 insertions(+) + +diff --git a/README.md b/README.md +index dcf51f20..2322082c 100644 +--- a/README.md ++++ b/README.md +@@ -146,3 +146,31 @@ The multipath-tools source code is covered by several different licences. + Refer to the individual source files for details. + Source files which do not specify a licence are shipped under LGPL-2.0 + (see `LICENSES/LGPL-2.0`). ++ ++ ++ALUA ++==== ++This is a rough guide, consult your storage device manufacturer documentation. ++ ++ALUA is supported in some devices, but usually it's disabled by default. ++To enable ALUA, the following options should be changed: ++ ++- EMC CLARiiON/VNX: ++ "Failover Mode" should be changed to "4" or "Active-Active mode(ALUA)-failover mode 4" ++ ++- HPE 3PAR, Primera, and Alletra 9000: ++ "Host:" should be changed to "Generic-ALUA Persona 2 (UARepLun, SESLun, ALUA)". ++ ++- Promise VTrak/Vess: ++ "LUN Affinity" and "ALUA" should be changed to "Enable", "Redundancy Type" ++ must be "Active-Active". ++ ++- LSI/Engenio/NetApp RDAC class, as NetApp SANtricity E/EF Series and OEM arrays: ++ "Select operating system:" should be changed to "Linux DM-MP (Kernel 3.10 or later)". ++ ++- NetApp ONTAP: ++ To check ALUA state: "igroup show -v ", and to enable ALUA: ++ "igroup set alua yes". ++ ++- Huawei OceanStor: ++ "Host Access Mode" should be changed to "Asymmetric". diff --git a/0009-libmultipath-alua-remove-get_sysfs_pg83.patch b/0009-libmultipath-alua-remove-get_sysfs_pg83.patch new file mode 100644 index 0000000..4aa92fc --- /dev/null +++ b/0009-libmultipath-alua-remove-get_sysfs_pg83.patch @@ -0,0 +1,95 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 6 Jul 2022 15:57:21 +0200 +Subject: [PATCH] libmultipath: alua: remove get_sysfs_pg83() + +Since b72e753 ("libmultipath: alua: try to retrieve inquiry data from sysfs"), +we fetch inquiry and VPD data from sysfs anyway. No need to do this twice. + +Signed-off-by: Martin Wilck + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/prioritizers/alua_rtpg.c | 57 ++++++++------------------- + 1 file changed, 16 insertions(+), 41 deletions(-) + +diff --git a/libmultipath/prioritizers/alua_rtpg.c b/libmultipath/prioritizers/alua_rtpg.c +index 3f9c0e73..4db13c20 100644 +--- a/libmultipath/prioritizers/alua_rtpg.c ++++ b/libmultipath/prioritizers/alua_rtpg.c +@@ -228,25 +228,6 @@ get_target_port_group_support(const struct path *pp, unsigned int timeout) + return rc; + } + +-static int +-get_sysfs_pg83(const struct path *pp, unsigned char *buff, int buflen) +-{ +- struct udev_device *parent = pp->udev; +- +- while (parent) { +- const char *subsys = udev_device_get_subsystem(parent); +- if (subsys && !strncmp(subsys, "scsi", 4)) +- break; +- parent = udev_device_get_parent(parent); +- } +- +- if (!parent || sysfs_get_vpd(parent, 0x83, buff, buflen) <= 0) { +- PRINT_DEBUG("failed to read sysfs vpd pg83"); +- return -1; +- } +- return 0; +-} +- + int + get_target_port_group(const struct path * pp, unsigned int timeout) + { +@@ -265,32 +246,26 @@ get_target_port_group(const struct path * pp, unsigned int timeout) + } + + memset(buf, 0, buflen); ++ rc = do_inquiry(pp, 1, 0x83, buf, buflen, timeout); ++ if (rc < 0) ++ goto out; + +- rc = get_sysfs_pg83(pp, buf, buflen); +- +- if (rc < 0) { ++ scsi_buflen = get_unaligned_be16(&buf[2]) + 4; ++ if (scsi_buflen >= USHRT_MAX) ++ scsi_buflen = USHRT_MAX; ++ if (buflen < scsi_buflen) { ++ free(buf); ++ buf = (unsigned char *)malloc(scsi_buflen); ++ if (!buf) { ++ PRINT_DEBUG("malloc failed: could not allocate" ++ "%u bytes", scsi_buflen); ++ return -RTPG_RTPG_FAILED; ++ } ++ buflen = scsi_buflen; ++ memset(buf, 0, buflen); + rc = do_inquiry(pp, 1, 0x83, buf, buflen, timeout); + if (rc < 0) + goto out; +- +- scsi_buflen = get_unaligned_be16(&buf[2]) + 4; +- /* Paranoia */ +- if (scsi_buflen >= USHRT_MAX) +- scsi_buflen = USHRT_MAX; +- if (buflen < scsi_buflen) { +- free(buf); +- buf = (unsigned char *)malloc(scsi_buflen); +- if (!buf) { +- PRINT_DEBUG("malloc failed: could not allocate" +- "%u bytes", scsi_buflen); +- return -RTPG_RTPG_FAILED; +- } +- buflen = scsi_buflen; +- memset(buf, 0, buflen); +- rc = do_inquiry(pp, 1, 0x83, buf, buflen, timeout); +- if (rc < 0) +- goto out; +- } + } + + vpd83 = (struct vpd83_data *) buf; diff --git a/0010-libmultipath-remove-sysfs_get_binary.patch b/0010-libmultipath-remove-sysfs_get_binary.patch new file mode 100644 index 0000000..c2661ed --- /dev/null +++ b/0010-libmultipath-remove-sysfs_get_binary.patch @@ -0,0 +1,77 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 5 Jul 2022 10:54:02 +0200 +Subject: [PATCH] libmultipath: remove sysfs_get_binary() + +This function adds no value on top of sysfs_bin_attr_get_value(). +Remove it. + +Signed-off-by: Martin Wilck + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/discovery.c | 26 ++------------------------ + tests/test-lib.c | 1 - + 2 files changed, 2 insertions(+), 25 deletions(-) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index 0d8a558c..7e09e4e2 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -263,41 +263,19 @@ declare_sysfs_get_str(vendor); + declare_sysfs_get_str(model); + declare_sysfs_get_str(rev); + +-static ssize_t +-sysfs_get_binary (struct udev_device * udev, const char *attrname, +- unsigned char *buff, size_t len) +-{ +- ssize_t attr_len; +- const char * devname; +- +- if (!udev) { +- condlog(3, "No udev device given\n"); +- return -ENOSYS; +- } +- +- devname = udev_device_get_sysname(udev); +- attr_len = sysfs_bin_attr_get_value(udev, attrname, buff, len); +- if (attr_len < 0) { +- condlog(3, "%s: attribute %s not found in sysfs", +- devname, attrname); +- return attr_len; +- } +- return attr_len; +-} +- + ssize_t sysfs_get_vpd(struct udev_device * udev, unsigned char pg, + unsigned char *buff, size_t len) + { + char attrname[9]; + + snprintf(attrname, sizeof(attrname), "vpd_pg%02x", pg); +- return sysfs_get_binary(udev, attrname, buff, len); ++ return sysfs_bin_attr_get_value(udev, attrname, buff, len); + } + + ssize_t sysfs_get_inquiry(struct udev_device * udev, + unsigned char *buff, size_t len) + { +- return sysfs_get_binary(udev, "inquiry", buff, len); ++ return sysfs_bin_attr_get_value(udev, "inquiry", buff, len); + } + + int +diff --git a/tests/test-lib.c b/tests/test-lib.c +index 6dd3ee88..0bc49d53 100644 +--- a/tests/test-lib.c ++++ b/tests/test-lib.c +@@ -334,7 +334,6 @@ void mock_pathinfo(int mask, const struct mocked_path *mp) + if (mask & DI_SERIAL) { + will_return(__wrap_udev_device_get_subsystem, "scsi"); + will_return(__wrap_udev_device_get_sysname, hbtl); +- will_return(__wrap_udev_device_get_sysname, hbtl); + } + + if (mask & DI_WWID) { diff --git a/0011-libmultipath-sysfs_bin_attr_get_value-no-error-if-bu.patch b/0011-libmultipath-sysfs_bin_attr_get_value-no-error-if-bu.patch new file mode 100644 index 0000000..787d230 --- /dev/null +++ b/0011-libmultipath-sysfs_bin_attr_get_value-no-error-if-bu.patch @@ -0,0 +1,65 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 5 Jul 2022 10:47:51 +0200 +Subject: [PATCH] libmultipath: sysfs_bin_attr_get_value(): no error if buffer + is filled + +sysfs_bin_attr_get_value() sets the length of bytes read to 0 +when the provided buffer was too small, truncating potentially +useful data. This is harmful e.g. in do_inquiry(), if the "inquiry" +sysfs attribute contains more than 96 bytes (which is possible). + +Actually, binary attributes don't need to be 0-terminated. Thus, +unlike for string attributes, it's not an error if the requested number of +bytes is exactly equal to the number of bytes read. We expect that +the caller knows how many bytes it needs to read. + +Signed-off-by: Martin Wilck + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/discovery.c | 10 ++++++---- + libmultipath/sysfs.c | 5 +---- + 2 files changed, 7 insertions(+), 8 deletions(-) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index 7e09e4e2..f5b8401c 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -1341,13 +1341,15 @@ static int + get_vpd_sysfs (struct udev_device *parent, int pg, char * str, int maxlen) + { + int len; +- size_t buff_len; ++ ssize_t buff_len; + unsigned char buff[VPD_BUFLEN]; + + memset(buff, 0x0, VPD_BUFLEN); +- if (!parent || sysfs_get_vpd(parent, pg, buff, VPD_BUFLEN) <= 0) { +- condlog(3, "failed to read sysfs vpd pg%02x", pg); +- return -EINVAL; ++ buff_len = sysfs_get_vpd(parent, pg, buff, VPD_BUFLEN); ++ if (buff_len < 0) { ++ condlog(3, "failed to read sysfs vpd pg%02x: %s", ++ pg, strerror(-buff_len)); ++ return buff_len; + } + + if (buff[1] != pg) { +diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c +index f45dbee1..3ec92512 100644 +--- a/libmultipath/sysfs.c ++++ b/libmultipath/sysfs.c +@@ -146,10 +146,7 @@ ssize_t sysfs_bin_attr_get_value(struct udev_device *dev, const char *attr_name, + if (size < 0) { + condlog(4, "read from %s failed: %s", devpath, strerror(errno)); + size = -errno; +- } else if (size == (ssize_t)value_len) { +- condlog(4, "overflow while reading from %s", devpath); +- size = 0; +- } ++ }; + + close(fd); + return size; diff --git a/0012-libmultipath-common-code-path-for-sysfs_attr_get_val.patch b/0012-libmultipath-common-code-path-for-sysfs_attr_get_val.patch new file mode 100644 index 0000000..d09cd8a --- /dev/null +++ b/0012-libmultipath-common-code-path-for-sysfs_attr_get_val.patch @@ -0,0 +1,115 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 5 Jul 2022 11:14:30 +0200 +Subject: [PATCH] libmultipath: common code path for sysfs_attr_get_value() + +The code for sysfs_attr_get_value and sysfs_bin_attr_get_value() was +almost identical. Use a common code path. + +Signed-off-by: Martin Wilck + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/sysfs.c | 70 +++++++++++--------------------------------- + 1 file changed, 17 insertions(+), 53 deletions(-) + +diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c +index 3ec92512..4db911cc 100644 +--- a/libmultipath/sysfs.c ++++ b/libmultipath/sysfs.c +@@ -44,8 +44,8 @@ + * as libudev lacks the capability to update an attribute value. + * So for modified attributes we need to implement our own function. + */ +-ssize_t sysfs_attr_get_value(struct udev_device *dev, const char *attr_name, +- char * value, size_t value_len) ++static ssize_t __sysfs_attr_get_value(struct udev_device *dev, const char *attr_name, ++ char *value, size_t value_len, bool binary) + { + char devpath[PATH_SIZE]; + struct stat statbuf; +@@ -87,12 +87,14 @@ ssize_t sysfs_attr_get_value(struct udev_device *dev, const char *attr_name, + if (size < 0) { + condlog(4, "read from %s failed: %s", devpath, strerror(errno)); + size = -errno; +- value[0] = '\0'; +- } else if (size == (ssize_t)value_len) { ++ if (!binary) ++ value[0] = '\0'; ++ } else if (!binary && size == (ssize_t)value_len) { ++ condlog(3, "%s: overflow reading from %s (required len: %zu)", ++ __func__, devpath, size); + value[size - 1] = '\0'; +- condlog(4, "overflow while reading from %s", devpath); + size = 0; +- } else { ++ } else if (!binary) { + value[size] = '\0'; + size = strchop(value); + } +@@ -101,55 +103,17 @@ ssize_t sysfs_attr_get_value(struct udev_device *dev, const char *attr_name, + return size; + } + +-ssize_t sysfs_bin_attr_get_value(struct udev_device *dev, const char *attr_name, +- unsigned char * value, size_t value_len) ++ssize_t sysfs_attr_get_value(struct udev_device *dev, const char *attr_name, ++ char *value, size_t value_len) + { +- char devpath[PATH_SIZE]; +- struct stat statbuf; +- int fd; +- ssize_t size = -1; +- +- if (!dev || !attr_name || !value) +- return 0; +- +- snprintf(devpath, PATH_SIZE, "%s/%s", udev_device_get_syspath(dev), +- attr_name); +- condlog(4, "open '%s'", devpath); +- /* read attribute value */ +- fd = open(devpath, O_RDONLY); +- if (fd < 0) { +- condlog(4, "attribute '%s' can not be opened: %s", +- devpath, strerror(errno)); +- return -errno; +- } +- if (fstat(fd, &statbuf) != 0) { +- condlog(4, "stat '%s' failed: %s", devpath, strerror(errno)); +- close(fd); +- return -ENXIO; +- } +- +- /* skip directories */ +- if (S_ISDIR(statbuf.st_mode)) { +- condlog(4, "%s is a directory", devpath); +- close(fd); +- return -EISDIR; +- } +- +- /* skip non-writeable files */ +- if ((statbuf.st_mode & S_IRUSR) == 0) { +- condlog(4, "%s is not readable", devpath); +- close(fd); +- return -EPERM; +- } +- +- size = read(fd, value, value_len); +- if (size < 0) { +- condlog(4, "read from %s failed: %s", devpath, strerror(errno)); +- size = -errno; +- }; ++ return __sysfs_attr_get_value(dev, attr_name, value, value_len, false); ++} + +- close(fd); +- return size; ++ssize_t sysfs_bin_attr_get_value(struct udev_device *dev, const char *attr_name, ++ unsigned char *value, size_t value_len) ++{ ++ return __sysfs_attr_get_value(dev, attr_name, (char *)value, ++ value_len, true); + } + + ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, diff --git a/0013-libmultipath-sanitize-error-checking-in-sysfs-access.patch b/0013-libmultipath-sanitize-error-checking-in-sysfs-access.patch new file mode 100644 index 0000000..9dc3dc5 --- /dev/null +++ b/0013-libmultipath-sanitize-error-checking-in-sysfs-access.patch @@ -0,0 +1,165 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 5 Jul 2022 11:41:40 +0200 +Subject: [PATCH] libmultipath: sanitize error checking in sysfs accessors + +udev_device_get_syspath() may return NULL; check for it, and check +for pathname overflow. Disallow a zero buffer length. The fstat() +calls were superfluous, as a read() or write() on the fd would +return the respective error codes depending on file type or permissions, +the extra system call and code complexity adds no value. + +Log levels should be moderate in sysfs.c, because it depends +on the caller whether errors getting/setting certain attributes are +fatal. + +Signed-off-by: Martin Wilck + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/sysfs.c | 94 ++++++++++++++++++-------------------------- + 1 file changed, 39 insertions(+), 55 deletions(-) + +diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c +index 4db911cc..1f0f2074 100644 +--- a/libmultipath/sysfs.c ++++ b/libmultipath/sysfs.c +@@ -47,46 +47,38 @@ + static ssize_t __sysfs_attr_get_value(struct udev_device *dev, const char *attr_name, + char *value, size_t value_len, bool binary) + { ++ const char *syspath; + char devpath[PATH_SIZE]; +- struct stat statbuf; + int fd; + ssize_t size = -1; + +- if (!dev || !attr_name || !value) +- return 0; ++ if (!dev || !attr_name || !value || !value_len) { ++ condlog(1, "%s: invalid parameters", __func__); ++ return -EINVAL; ++ } + +- snprintf(devpath, PATH_SIZE, "%s/%s", udev_device_get_syspath(dev), +- attr_name); ++ syspath = udev_device_get_syspath(dev); ++ if (!syspath) { ++ condlog(3, "%s: invalid udevice", __func__); ++ return -EINVAL; ++ } ++ if (safe_sprintf(devpath, "%s/%s", syspath, attr_name)) { ++ condlog(3, "%s: devpath overflow", __func__); ++ return -EOVERFLOW; ++ } + condlog(4, "open '%s'", devpath); + /* read attribute value */ + fd = open(devpath, O_RDONLY); + if (fd < 0) { +- condlog(4, "attribute '%s' can not be opened: %s", +- devpath, strerror(errno)); ++ condlog(3, "%s: attribute '%s' can not be opened: %s", ++ __func__, devpath, strerror(errno)); + return -errno; + } +- if (fstat(fd, &statbuf) < 0) { +- condlog(4, "stat '%s' failed: %s", devpath, strerror(errno)); +- close(fd); +- return -ENXIO; +- } +- /* skip directories */ +- if (S_ISDIR(statbuf.st_mode)) { +- condlog(4, "%s is a directory", devpath); +- close(fd); +- return -EISDIR; +- } +- /* skip non-writeable files */ +- if ((statbuf.st_mode & S_IRUSR) == 0) { +- condlog(4, "%s is not readable", devpath); +- close(fd); +- return -EPERM; +- } +- + size = read(fd, value, value_len); + if (size < 0) { +- condlog(4, "read from %s failed: %s", devpath, strerror(errno)); + size = -errno; ++ condlog(3, "%s: read from %s failed: %s", __func__, devpath, ++ strerror(errno)); + if (!binary) + value[0] = '\0'; + } else if (!binary && size == (ssize_t)value_len) { +@@ -119,51 +111,43 @@ ssize_t sysfs_bin_attr_get_value(struct udev_device *dev, const char *attr_name, + ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, + const char * value, size_t value_len) + { ++ const char *syspath; + char devpath[PATH_SIZE]; +- struct stat statbuf; + int fd; + ssize_t size = -1; + +- if (!dev || !attr_name || !value || !value_len) +- return 0; ++ if (!dev || !attr_name || !value || !value_len) { ++ condlog(1, "%s: invalid parameters", __func__); ++ return -EINVAL; ++ } ++ ++ syspath = udev_device_get_syspath(dev); ++ if (!syspath) { ++ condlog(3, "%s: invalid udevice", __func__); ++ return -EINVAL; ++ } ++ if (safe_sprintf(devpath, "%s/%s", syspath, attr_name)) { ++ condlog(3, "%s: devpath overflow", __func__); ++ return -EOVERFLOW; ++ } + +- snprintf(devpath, PATH_SIZE, "%s/%s", udev_device_get_syspath(dev), +- attr_name); + condlog(4, "open '%s'", devpath); + /* write attribute value */ + fd = open(devpath, O_WRONLY); + if (fd < 0) { +- condlog(4, "attribute '%s' can not be opened: %s", +- devpath, strerror(errno)); +- return -errno; +- } +- if (fstat(fd, &statbuf) != 0) { +- condlog(4, "stat '%s' failed: %s", devpath, strerror(errno)); +- close(fd); ++ condlog(2, "%s: attribute '%s' can not be opened: %s", ++ __func__, devpath, strerror(errno)); + return -errno; + } + +- /* skip directories */ +- if (S_ISDIR(statbuf.st_mode)) { +- condlog(4, "%s is a directory", devpath); +- close(fd); +- return -EISDIR; +- } +- +- /* skip non-writeable files */ +- if ((statbuf.st_mode & S_IWUSR) == 0) { +- condlog(4, "%s is not writeable", devpath); +- close(fd); +- return -EPERM; +- } +- + size = write(fd, value, value_len); + if (size < 0) { +- condlog(4, "write to %s failed: %s", devpath, strerror(errno)); + size = -errno; ++ condlog(3, "%s: write to %s failed: %s", __func__, ++ devpath, strerror(errno)); + } else if (size < (ssize_t)value_len) { +- condlog(4, "tried to write %ld to %s. Wrote %ld", +- (long)value_len, devpath, (long)size); ++ condlog(3, "%s: underflow writing %zu bytes to %s. Wrote %zd bytes", ++ __func__, value_len, devpath, size); + size = 0; + } + diff --git a/0014-libmultipath-get-rid-of-PATH_SIZE.patch b/0014-libmultipath-get-rid-of-PATH_SIZE.patch new file mode 100644 index 0000000..a080792 --- /dev/null +++ b/0014-libmultipath-get-rid-of-PATH_SIZE.patch @@ -0,0 +1,115 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 5 Jul 2022 11:52:42 +0200 +Subject: [PATCH] libmultipath: get rid of PATH_SIZE + +replace PATH_SIZE with the system limit PATH_MAX. In some places, +PATH_SIZE was used for file names. Use FILE_NAME_SIZE in these cases. +Also, use a constant for "multipathd.service" in systemd_service_enabled_in(). + +Signed-off-by: Martin Wilck + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/structs.h | 3 --- + libmultipath/sysfs.c | 8 ++++---- + libmultipath/util.c | 8 +++++--- + multipathd/cli_handlers.c | 2 +- + 4 files changed, 10 insertions(+), 11 deletions(-) + +diff --git a/libmultipath/structs.h b/libmultipath/structs.h +index a6a09441..dfa12ff9 100644 +--- a/libmultipath/structs.h ++++ b/libmultipath/structs.h +@@ -17,7 +17,6 @@ + #define FILE_NAME_SIZE 256 + #define CALLOUT_MAX_SIZE 256 + #define BLK_DEV_SIZE 33 +-#define PATH_SIZE 512 + #define NAME_SIZE 512 + #define HOST_NAME_LEN 16 + #define SLOT_NAME_SIZE 40 +@@ -519,6 +518,4 @@ int pathcmp (const struct pathgroup *, const struct pathgroup *); + int add_feature (char **, const char *); + int remove_feature (char **, const char *); + +-extern char sysfs_path[PATH_SIZE]; +- + #endif /* _STRUCTS_H */ +diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c +index 1f0f2074..e48b05ec 100644 +--- a/libmultipath/sysfs.c ++++ b/libmultipath/sysfs.c +@@ -48,7 +48,7 @@ static ssize_t __sysfs_attr_get_value(struct udev_device *dev, const char *attr_ + char *value, size_t value_len, bool binary) + { + const char *syspath; +- char devpath[PATH_SIZE]; ++ char devpath[PATH_MAX]; + int fd; + ssize_t size = -1; + +@@ -112,7 +112,7 @@ ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, + const char * value, size_t value_len) + { + const char *syspath; +- char devpath[PATH_SIZE]; ++ char devpath[PATH_MAX]; + int fd; + ssize_t size = -1; + +@@ -184,7 +184,7 @@ sysfs_get_size (struct path *pp, unsigned long long * size) + int sysfs_check_holders(char * check_devt, char * new_devt) + { + unsigned int major, new_minor, table_minor; +- char path[PATH_MAX], check_dev[PATH_SIZE]; ++ char path[PATH_MAX], check_dev[FILE_NAME_SIZE]; + char * table_name; + DIR *dirfd; + struct dirent *holder; +@@ -194,7 +194,7 @@ int sysfs_check_holders(char * check_devt, char * new_devt) + return 0; + } + +- if (devt2devname(check_dev, PATH_SIZE, check_devt)) { ++ if (devt2devname(check_dev, sizeof(check_dev), check_devt)) { + condlog(1, "can't get devname for %s", check_devt); + return 0; + } +diff --git a/libmultipath/util.c b/libmultipath/util.c +index ce5ea73e..e7e7d4c1 100644 +--- a/libmultipath/util.c ++++ b/libmultipath/util.c +@@ -242,13 +242,15 @@ setup_thread_attr(pthread_attr_t *attr, size_t stacksize, int detached) + + int systemd_service_enabled_in(const char *dev, const char *prefix) + { +- char path[PATH_SIZE], file[PATH_MAX], service[PATH_SIZE]; ++ static const char service[] = "multipathd.service"; ++ char path[PATH_MAX], file[PATH_MAX]; + DIR *dirfd; + struct dirent *d; + int found = 0; + +- snprintf(service, PATH_SIZE, "multipathd.service"); +- snprintf(path, PATH_SIZE, "%s/systemd/system", prefix); ++ if (safe_sprintf(path, "%s/systemd/system", prefix)) ++ return 0; ++ + condlog(3, "%s: checking for %s in %s", dev, service, path); + + dirfd = opendir(path); +diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c +index d79cdd7c..db4d4412 100644 +--- a/multipathd/cli_handlers.c ++++ b/multipathd/cli_handlers.c +@@ -688,7 +688,7 @@ cli_add_map (void * v, struct strbuf *reply, void * data) + struct vectors * vecs = (struct vectors *)data; + char * param = get_keyparam(v, MAP); + int major = -1, minor = -1; +- char dev_path[PATH_SIZE]; ++ char dev_path[FILE_NAME_SIZE]; + char *refwwid, *alias = NULL; + int rc, count = 0; + struct config *conf; diff --git a/0015-libmultipath-sysfs_attr_get_value-don-t-return-0-if-.patch b/0015-libmultipath-sysfs_attr_get_value-don-t-return-0-if-.patch new file mode 100644 index 0000000..d58b785 --- /dev/null +++ b/0015-libmultipath-sysfs_attr_get_value-don-t-return-0-if-.patch @@ -0,0 +1,172 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 5 Jul 2022 13:33:51 +0200 +Subject: [PATCH] libmultipath: sysfs_attr_get_value(): don't return 0 if + buffer too small + +If the passed read buffer is too small to hold the value read plus +terminating 0 byte, return the given size value rather than 0. + +This way we get similar semantics as for sysfs_bin_attr_get_get_value(), +except that sysfs_attr_get_value() must always 0-terminate the value; +thus a return value equal to the length parameter is an error for +the non-binary case. + +Provide a helper macro to test this "overflow" condition. + +Signed-off-by: Martin Wilck + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/configure.c | 2 +- + libmultipath/discovery.c | 14 +++++++------- + libmultipath/propsel.c | 6 +++++- + libmultipath/sysfs.c | 3 +-- + libmultipath/sysfs.h | 13 +++++++++++++ + multipathd/main.c | 2 +- + 6 files changed, 28 insertions(+), 12 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index 09ae708d..467bbaa6 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -589,7 +589,7 @@ sysfs_set_max_sectors_kb(struct multipath *mpp, int is_reload) + ret = sysfs_attr_get_value(udd, "queue/max_sectors_kb", buff, + sizeof(buff)); + udev_device_unref(udd); +- if (ret <= 0) { ++ if (!sysfs_attr_value_ok(ret, sizeof(buff))) { + condlog(1, "failed to get current max_sectors_kb from %s", mpp->alias); + return 1; + } +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index f5b8401c..54b1caf0 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -560,10 +560,10 @@ sysfs_get_asymmetric_access_state(struct path *pp, char *buff, int buflen) + if (!parent) + return -1; + +- if (sysfs_attr_get_value(parent, "access_state", buff, buflen) <= 0) ++ if (!sysfs_attr_get_value_ok(parent, "access_state", buff, buflen)) + return -1; + +- if (sysfs_attr_get_value(parent, "preferred_path", value, 16) <= 0) ++ if (!sysfs_attr_get_value_ok(parent, "preferred_path", value, sizeof(value))) + return 0; + + preferred = strtoul(value, &eptr, 0); +@@ -638,8 +638,8 @@ sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp) + /* + * read the current dev_loss_tmo value from sysfs + */ +- ret = sysfs_attr_get_value(rport_dev, "dev_loss_tmo", value, 16); +- if (ret <= 0) { ++ ret = sysfs_attr_get_value(rport_dev, "dev_loss_tmo", value, sizeof(value)); ++ if (!sysfs_attr_value_ok(ret, sizeof(value))) { + condlog(0, "%s: failed to read dev_loss_tmo value, " + "error %d", rport_id, -ret); + goto out; +@@ -1737,8 +1737,8 @@ path_offline (struct path * pp) + } + + memset(buff, 0x0, SCSI_STATE_SIZE); +- err = sysfs_attr_get_value(parent, "state", buff, SCSI_STATE_SIZE); +- if (err <= 0) { ++ err = sysfs_attr_get_value(parent, "state", buff, sizeof(buff)); ++ if (!sysfs_attr_value_ok(err, sizeof(buff))) { + if (err == -ENXIO) + return PATH_REMOVED; + else +@@ -2142,7 +2142,7 @@ static ssize_t uid_fallback(struct path *pp, int path_state, + return -1; + len = sysfs_attr_get_value(pp->udev, "wwid", value, + sizeof(value)); +- if (len <= 0) ++ if (!sysfs_attr_value_ok(len, sizeof(value))) + return -1; + len = strlcpy(pp->wwid, value, WWID_SIZE); + if (len >= WWID_SIZE) { +diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c +index f782f251..98e3aad1 100644 +--- a/libmultipath/propsel.c ++++ b/libmultipath/propsel.c +@@ -435,6 +435,7 @@ out: + static int get_dh_state(struct path *pp, char *value, size_t value_len) + { + struct udev_device *ud; ++ ssize_t rc; + + if (pp->udev == NULL) + return -1; +@@ -444,7 +445,10 @@ static int get_dh_state(struct path *pp, char *value, size_t value_len) + if (ud == NULL) + return -1; + +- return sysfs_attr_get_value(ud, "dh_state", value, value_len); ++ rc = sysfs_attr_get_value(ud, "dh_state", value, value_len); ++ if (!sysfs_attr_value_ok(rc, value_len)) ++ return -1; ++ return rc; + } + + int select_hwhandler(struct config *conf, struct multipath *mp) +diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c +index e48b05ec..125f1c2b 100644 +--- a/libmultipath/sysfs.c ++++ b/libmultipath/sysfs.c +@@ -85,7 +85,6 @@ static ssize_t __sysfs_attr_get_value(struct udev_device *dev, const char *attr_ + condlog(3, "%s: overflow reading from %s (required len: %zu)", + __func__, devpath, size); + value[size - 1] = '\0'; +- size = 0; + } else if (!binary) { + value[size] = '\0'; + size = strchop(value); +@@ -165,7 +164,7 @@ sysfs_get_size (struct path *pp, unsigned long long * size) + return 1; + + attr[0] = '\0'; +- if (sysfs_attr_get_value(pp->udev, "size", attr, 255) <= 0) { ++ if (!sysfs_attr_get_value_ok(pp->udev, "size", attr, sizeof(attr))) { + condlog(3, "%s: No size attribute in sysfs", pp->dev); + return 1; + } +diff --git a/libmultipath/sysfs.h b/libmultipath/sysfs.h +index 72b39ab2..cdc84e40 100644 +--- a/libmultipath/sysfs.h ++++ b/libmultipath/sysfs.h +@@ -12,6 +12,19 @@ ssize_t sysfs_attr_get_value(struct udev_device *dev, const char *attr_name, + char * value, size_t value_len); + ssize_t sysfs_bin_attr_get_value(struct udev_device *dev, const char *attr_name, + unsigned char * value, size_t value_len); ++#define sysfs_attr_value_ok(rc, value_len) \ ++ ({ \ ++ ssize_t __r = rc; \ ++ __r >= 0 && (size_t)__r < (size_t)value_len; \ ++ }) ++ ++#define sysfs_attr_get_value_ok(dev, attr, val, len) \ ++ ({ \ ++ size_t __l = (len); \ ++ ssize_t __rc = sysfs_attr_get_value(dev, attr, val, __l); \ ++ sysfs_attr_value_ok(__rc, __l); \ ++ }) ++ + int sysfs_get_size (struct path *pp, unsigned long long * size); + int sysfs_check_holders(char * check_devt, char * new_devt); + bool sysfs_is_multipathed(struct path *pp, bool set_wwid); +diff --git a/multipathd/main.c b/multipathd/main.c +index 2f2b9d4c..68eca925 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -1126,7 +1126,7 @@ sysfs_get_ro (struct path *pp) + if (!pp->udev) + return -1; + +- if (sysfs_attr_get_value(pp->udev, "ro", buff, sizeof(buff)) <= 0) { ++ if (!sysfs_attr_get_value_ok(pp->udev, "ro", buff, sizeof(buff))) { + condlog(3, "%s: Cannot read ro attribute in sysfs", pp->dev); + return -1; + } diff --git a/0016-libmultipath-sysfs_attr_set_value-don-t-return-0-on-.patch b/0016-libmultipath-sysfs_attr_set_value-don-t-return-0-on-.patch new file mode 100644 index 0000000..e9bc0c8 --- /dev/null +++ b/0016-libmultipath-sysfs_attr_set_value-don-t-return-0-on-.patch @@ -0,0 +1,251 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 5 Jul 2022 17:51:41 +0200 +Subject: [PATCH] libmultipath: sysfs_attr_set_value(): don't return 0 on + partial write + +sysfs_attr_set_value() returned 0 if not all requested bytes were written. +Change this to return the number of bytes written. Error checking is now +somewhat more involved; provide a helper macro for it. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/configure.c | 10 ++++-- + libmultipath/discovery.c | 74 +++++++++++++++++++++++++--------------- + libmultipath/sysfs.c | 6 ++-- + libmultipath/sysfs.h | 10 ++++++ + 4 files changed, 66 insertions(+), 34 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index 467bbaa6..0607dbac 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -568,6 +568,7 @@ sysfs_set_max_sectors_kb(struct multipath *mpp, int is_reload) + struct pathgroup * pgp; + struct path *pp; + char buff[11]; ++ ssize_t len; + int i, j, ret, err = 0; + struct udev_device *udd; + int max_sectors_kb; +@@ -600,14 +601,17 @@ sysfs_set_max_sectors_kb(struct multipath *mpp, int is_reload) + } + } + snprintf(buff, 11, "%d", max_sectors_kb); ++ len = strlen(buff); + + vector_foreach_slot (mpp->pg, pgp, i) { + vector_foreach_slot(pgp->paths, pp, j) { + ret = sysfs_attr_set_value(pp->udev, + "queue/max_sectors_kb", +- buff, strlen(buff)); +- if (ret < 0) { +- condlog(1, "failed setting max_sectors_kb on %s : %s", pp->dev, strerror(-ret)); ++ buff, len); ++ if (ret != len) { ++ log_sysfs_attr_set_value(1, ret, ++ "failed setting max_sectors_kb on %s", ++ pp->dev); + err = 1; + } + } +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index 54b1caf0..ee290093 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -598,13 +598,15 @@ sysfs_set_eh_deadline(struct path *pp) + len = sprintf(value, "%d", pp->eh_deadline); + + ret = sysfs_attr_set_value(hostdev, "eh_deadline", +- value, len + 1); ++ value, len); + /* + * not all scsi drivers support setting eh_deadline, so failing + * is totally reasonable + */ +- if (ret <= 0) +- condlog(3, "%s: failed to set eh_deadline to %s, error %d", udev_device_get_sysname(hostdev), value, -ret); ++ if (ret != len) ++ log_sysfs_attr_set_value(3, ret, ++ "%s: failed to set eh_deadline to %s", ++ udev_device_get_sysname(hostdev), value); + + udev_device_unref(hostdev); + return (ret <= 0); +@@ -667,19 +669,22 @@ sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp) + pp->fast_io_fail != MP_FAST_IO_FAIL_OFF) { + /* Check if we need to temporarily increase dev_loss_tmo */ + if ((unsigned int)pp->fast_io_fail >= tmo) { ++ ssize_t len; ++ + /* Increase dev_loss_tmo temporarily */ + snprintf(value, sizeof(value), "%u", + (unsigned int)pp->fast_io_fail + 1); ++ len = strlen(value); + ret = sysfs_attr_set_value(rport_dev, "dev_loss_tmo", +- value, strlen(value)); +- if (ret <= 0) { ++ value, len); ++ if (ret != len) { + if (ret == -EBUSY) + condlog(3, "%s: rport blocked", + rport_id); + else +- condlog(0, "%s: failed to set " +- "dev_loss_tmo to %s, error %d", +- rport_id, value, -ret); ++ log_sysfs_attr_set_value(0, ret, ++ "%s: failed to set dev_loss_tmo to %s", ++ rport_id, value); + goto out; + } + } +@@ -691,32 +696,39 @@ sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp) + pp->dev_loss = DEFAULT_DEV_LOSS_TMO; + } + if (pp->fast_io_fail != MP_FAST_IO_FAIL_UNSET) { ++ ssize_t len; ++ + if (pp->fast_io_fail == MP_FAST_IO_FAIL_OFF) + sprintf(value, "off"); + else if (pp->fast_io_fail == MP_FAST_IO_FAIL_ZERO) + sprintf(value, "0"); + else + snprintf(value, 16, "%u", pp->fast_io_fail); ++ len = strlen(value); + ret = sysfs_attr_set_value(rport_dev, "fast_io_fail_tmo", +- value, strlen(value)); +- if (ret <= 0) { ++ value, len); ++ if (ret != len) { + if (ret == -EBUSY) + condlog(3, "%s: rport blocked", rport_id); + else +- condlog(0, "%s: failed to set fast_io_fail_tmo to %s, error %d", +- rport_id, value, -ret); ++ log_sysfs_attr_set_value(0, ret, ++ "%s: failed to set fast_io_fail_tmo to %s", ++ rport_id, value); + } + } + if (pp->dev_loss != DEV_LOSS_TMO_UNSET) { ++ ssize_t len; ++ + snprintf(value, 16, "%u", pp->dev_loss); +- ret = sysfs_attr_set_value(rport_dev, "dev_loss_tmo", +- value, strlen(value)); +- if (ret <= 0) { ++ len = strlen(value); ++ ret = sysfs_attr_set_value(rport_dev, "dev_loss_tmo", value, len); ++ if (ret != len) { + if (ret == -EBUSY) + condlog(3, "%s: rport blocked", rport_id); + else +- condlog(0, "%s: failed to set dev_loss_tmo to %s, error %d", +- rport_id, value, -ret); ++ log_sysfs_attr_set_value(0, ret, ++ "%s: failed to set dev_loss_tmo to %s", ++ rport_id, value); + } + } + out: +@@ -754,12 +766,16 @@ sysfs_set_session_tmo(struct path *pp) + condlog(3, "%s: can't set fast_io_fail_tmo to '0'" + "on iSCSI", pp->dev); + } else { ++ ssize_t len, ret; ++ + snprintf(value, 11, "%u", pp->fast_io_fail); +- if (sysfs_attr_set_value(session_dev, "recovery_tmo", +- value, strlen(value)) <= 0) { +- condlog(3, "%s: Failed to set recovery_tmo, " +- " error %d", pp->dev, errno); +- } ++ len = strlen(value); ++ ret = sysfs_attr_set_value(session_dev, "recovery_tmo", ++ value, len); ++ if (ret != len) ++ log_sysfs_attr_set_value(3, ret, ++ "%s: Failed to set recovery_tmo to %s", ++ pp->dev, value); + } + } + udev_device_unref(session_dev); +@@ -802,12 +818,16 @@ sysfs_set_nexus_loss_tmo(struct path *pp) + pp->sg_id.channel, pp->sg_id.scsi_id, end_dev_id); + + if (pp->dev_loss != DEV_LOSS_TMO_UNSET) { ++ ssize_t len, ret; ++ + snprintf(value, 11, "%u", pp->dev_loss); +- if (sysfs_attr_set_value(sas_dev, "I_T_nexus_loss_timeout", +- value, strlen(value)) <= 0) +- condlog(3, "%s: failed to update " +- "I_T Nexus loss timeout, error %d", +- pp->dev, errno); ++ len = strlen(value); ++ ret = sysfs_attr_set_value(sas_dev, "I_T_nexus_loss_timeout", ++ value, len); ++ if (ret != len) ++ log_sysfs_attr_set_value(3, ret, ++ "%s: failed to update I_T Nexus loss timeout", ++ pp->dev); + } + udev_device_unref(sas_dev); + return; +diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c +index 125f1c2b..9c84af70 100644 +--- a/libmultipath/sysfs.c ++++ b/libmultipath/sysfs.c +@@ -134,7 +134,7 @@ ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, + /* write attribute value */ + fd = open(devpath, O_WRONLY); + if (fd < 0) { +- condlog(2, "%s: attribute '%s' can not be opened: %s", ++ condlog(3, "%s: attribute '%s' can not be opened: %s", + __func__, devpath, strerror(errno)); + return -errno; + } +@@ -144,11 +144,9 @@ ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, + size = -errno; + condlog(3, "%s: write to %s failed: %s", __func__, + devpath, strerror(errno)); +- } else if (size < (ssize_t)value_len) { ++ } else if (size < (ssize_t)value_len) + condlog(3, "%s: underflow writing %zu bytes to %s. Wrote %zd bytes", + __func__, value_len, devpath, size); +- size = 0; +- } + + close(fd); + return size; +diff --git a/libmultipath/sysfs.h b/libmultipath/sysfs.h +index cdc84e40..799f68e9 100644 +--- a/libmultipath/sysfs.h ++++ b/libmultipath/sysfs.h +@@ -5,6 +5,7 @@ + #ifndef _LIBMULTIPATH_SYSFS_H + #define _LIBMULTIPATH_SYSFS_H + #include ++#include "strbuf.h" + + ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, + const char * value, size_t value_len); +@@ -25,6 +26,15 @@ ssize_t sysfs_bin_attr_get_value(struct udev_device *dev, const char *attr_name, + sysfs_attr_value_ok(__rc, __l); \ + }) + ++#define log_sysfs_attr_set_value(prio, rc, fmt, __args...) \ ++do { \ ++ STRBUF_ON_STACK(__buf); \ ++ if (print_strbuf(&__buf, fmt, ##__args) >= 0 && \ ++ print_strbuf(&__buf, ": %s", rc < 0 ? strerror(-rc) : \ ++ "write underflow") >= 0) \ ++ condlog(prio, "%s", get_strbuf_str(&__buf)); \ ++} while(0) ++ + int sysfs_get_size (struct path *pp, unsigned long long * size); + int sysfs_check_holders(char * check_devt, char * new_devt); + bool sysfs_is_multipathed(struct path *pp, bool set_wwid); diff --git a/0017-libmultipath-sysfs-cleanup-file-descriptors-on-pthre.patch b/0017-libmultipath-sysfs-cleanup-file-descriptors-on-pthre.patch new file mode 100644 index 0000000..90fbfdf --- /dev/null +++ b/0017-libmultipath-sysfs-cleanup-file-descriptors-on-pthre.patch @@ -0,0 +1,71 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 5 Jul 2022 18:07:57 +0200 +Subject: [PATCH] libmultipath: sysfs: cleanup file descriptors on + pthread_cancel() + +Signed-off-by: Martin Wilck + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/sysfs.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c +index 9c84af70..64946385 100644 +--- a/libmultipath/sysfs.c ++++ b/libmultipath/sysfs.c +@@ -49,7 +49,7 @@ static ssize_t __sysfs_attr_get_value(struct udev_device *dev, const char *attr_ + { + const char *syspath; + char devpath[PATH_MAX]; +- int fd; ++ long fd; + ssize_t size = -1; + + if (!dev || !attr_name || !value || !value_len) { +@@ -74,6 +74,8 @@ static ssize_t __sysfs_attr_get_value(struct udev_device *dev, const char *attr_ + __func__, devpath, strerror(errno)); + return -errno; + } ++ pthread_cleanup_push(close_fd, (void *)fd); ++ + size = read(fd, value, value_len); + if (size < 0) { + size = -errno; +@@ -90,7 +92,7 @@ static ssize_t __sysfs_attr_get_value(struct udev_device *dev, const char *attr_ + size = strchop(value); + } + +- close(fd); ++ pthread_cleanup_pop(1); + return size; + } + +@@ -112,7 +114,7 @@ ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, + { + const char *syspath; + char devpath[PATH_MAX]; +- int fd; ++ long fd; + ssize_t size = -1; + + if (!dev || !attr_name || !value || !value_len) { +@@ -138,6 +140,7 @@ ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, + __func__, devpath, strerror(errno)); + return -errno; + } ++ pthread_cleanup_push(close_fd, (void *)fd); + + size = write(fd, value, value_len); + if (size < 0) { +@@ -148,7 +151,7 @@ ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, + condlog(3, "%s: underflow writing %zu bytes to %s. Wrote %zd bytes", + __func__, value_len, devpath, size); + +- close(fd); ++ pthread_cleanup_pop(1); + return size; + } + diff --git a/0018-libmultipath-multipathd-log-failure-setting-sysfs-at.patch b/0018-libmultipath-multipathd-log-failure-setting-sysfs-at.patch new file mode 100644 index 0000000..710f633 --- /dev/null +++ b/0018-libmultipath-multipathd-log-failure-setting-sysfs-at.patch @@ -0,0 +1,168 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 5 Jul 2022 18:45:11 +0200 +Subject: [PATCH] libmultipath, multipathd: log failure setting sysfs + attributes + +Failure to set a sysfs attribute is worth noting, normally. + +Signed-off-by: Martin Wilck + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/configure.c | 18 ++++++++++++++--- + multipathd/fpin_handlers.c | 11 +++++++++-- + multipathd/main.c | 40 ++++++++++++++++++++++++++++++-------- + 3 files changed, 56 insertions(+), 13 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index 0607dbac..4427f910 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -489,9 +489,15 @@ void trigger_partitions_udev_change(struct udev_device *dev, + + devtype = udev_device_get_devtype(part); + if (devtype && !strcmp("partition", devtype)) { ++ ssize_t ret; ++ + condlog(4, "%s: triggering %s event for %s", __func__, + action, syspath); +- sysfs_attr_set_value(part, "uevent", action, len); ++ ret = sysfs_attr_set_value(part, "uevent", action, len); ++ if (ret != len) ++ log_sysfs_attr_set_value(2, ret, ++ "%s: failed to trigger %s uevent", ++ syspath, action); + } + udev_device_unref(part); + } +@@ -510,6 +516,7 @@ trigger_path_udev_change(struct path *pp, bool is_mpath) + */ + const char *action = is_mpath ? "change" : "add"; + const char *env; ++ ssize_t len, ret; + + if (!pp->udev) + return; +@@ -536,8 +543,13 @@ trigger_path_udev_change(struct path *pp, bool is_mpath) + + condlog(3, "triggering %s uevent for %s (is %smultipath member)", + action, pp->dev, is_mpath ? "" : "no "); +- sysfs_attr_set_value(pp->udev, "uevent", +- action, strlen(action)); ++ ++ len = strlen(action); ++ ret = sysfs_attr_set_value(pp->udev, "uevent", action, len); ++ if (ret != len) ++ log_sysfs_attr_set_value(2, ret, ++ "%s: failed to trigger %s uevent", ++ pp->dev, action); + trigger_partitions_udev_change(pp->udev, action, + strlen(action)); + } +diff --git a/multipathd/fpin_handlers.c b/multipathd/fpin_handlers.c +index 384ae318..00195721 100644 +--- a/multipathd/fpin_handlers.c ++++ b/multipathd/fpin_handlers.c +@@ -172,8 +172,15 @@ fpin_els_add_li_frame(struct fc_nl_event *fc_event) + /*Sets the rport port_state to marginal*/ + static void fpin_set_rport_marginal(struct udev_device *rport_dev) + { +- sysfs_attr_set_value(rport_dev, "port_state", +- "Marginal", strlen("Marginal")); ++ static const char marginal[] = "Marginal"; ++ ssize_t ret; ++ ++ ret = sysfs_attr_set_value(rport_dev, "port_state", ++ marginal, sizeof(marginal) - 1); ++ if (ret != sizeof(marginal) - 1) ++ log_sysfs_attr_set_value(2, ret, ++ "%s: failed to set port_state to marginal", ++ udev_device_get_syspath(rport_dev)); + } + + /*Add the marginal devices info into the list*/ +diff --git a/multipathd/main.c b/multipathd/main.c +index 68eca925..a160c824 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -911,14 +911,22 @@ rescan_path(struct udev_device *ud) + { + ud = udev_device_get_parent_with_subsystem_devtype(ud, "scsi", + "scsi_device"); +- if (ud) +- sysfs_attr_set_value(ud, "rescan", "1", strlen("1")); ++ if (ud) { ++ ssize_t ret = ++ sysfs_attr_set_value(ud, "rescan", "1", strlen("1")); ++ if (ret != strlen("1")) ++ log_sysfs_attr_set_value(1, ret, ++ "%s: failed to trigger rescan", ++ udev_device_get_syspath(ud)); ++ } + } + + void + handle_path_wwid_change(struct path *pp, struct vectors *vecs) + { + struct udev_device *udd; ++ static const char add[] = "add"; ++ ssize_t ret; + + if (!pp || !pp->udev) + return; +@@ -929,8 +937,12 @@ handle_path_wwid_change(struct path *pp, struct vectors *vecs) + dm_fail_path(pp->mpp->alias, pp->dev_t); + } + rescan_path(udd); +- sysfs_attr_set_value(udd, "uevent", "add", strlen("add")); ++ ret = sysfs_attr_set_value(udd, "uevent", add, sizeof(add) - 1); + udev_device_unref(udd); ++ if (ret != sizeof(add) - 1) ++ log_sysfs_attr_set_value(1, ret, ++ "%s: failed to trigger add event", ++ pp->dev); + } + + bool +@@ -2003,9 +2015,14 @@ partial_retrigger_tick(vector pathvec) + --pp->partial_retrigger_delay == 0) { + const char *msg = udev_device_get_is_initialized(pp->udev) ? + "change" : "add"; +- +- sysfs_attr_set_value(pp->udev, "uevent", msg, +- strlen(msg)); ++ ssize_t len = strlen(msg); ++ ssize_t ret = sysfs_attr_set_value(pp->udev, "uevent", msg, ++ len); ++ ++ if (len != ret) ++ log_sysfs_attr_set_value(2, ret, ++ "%s: failed to trigger %s event", ++ pp->dev, msg); + } + } + } +@@ -2245,12 +2262,19 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) + + if (!pp->mpp && pp->initialized == INIT_MISSING_UDEV) { + if (pp->retriggers < retrigger_tries) { ++ static const char change[] = "change"; ++ ssize_t ret; ++ + condlog(2, "%s: triggering change event to reinitialize", + pp->dev); + pp->initialized = INIT_REQUESTED_UDEV; + pp->retriggers++; +- sysfs_attr_set_value(pp->udev, "uevent", "change", +- strlen("change")); ++ ret = sysfs_attr_set_value(pp->udev, "uevent", change, ++ sizeof(change) - 1); ++ if (ret != sizeof(change) - 1) ++ log_sysfs_attr_set_value(1, ret, ++ "%s: failed to trigger change event", ++ pp->dev); + return 0; + } else { + condlog(1, "%s: not initialized after %d udev retriggers", diff --git a/0019-multipath-tests-expect_condlog-skip-depending-on-ver.patch b/0019-multipath-tests-expect_condlog-skip-depending-on-ver.patch new file mode 100644 index 0000000..6b7c06b --- /dev/null +++ b/0019-multipath-tests-expect_condlog-skip-depending-on-ver.patch @@ -0,0 +1,37 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 5 Jul 2022 23:18:07 +0200 +Subject: [PATCH] multipath tests: expect_condlog: skip depending on verbosity + +otherwise we'll get failures if verbosity level is low. + +Signed-off-by: Martin Wilck + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + tests/test-log.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/tests/test-log.c b/tests/test-log.c +index 14f25b9b..0c17cd96 100644 +--- a/tests/test-log.c ++++ b/tests/test-log.c +@@ -6,6 +6,8 @@ + #include + #include "log.h" + #include "test-log.h" ++#include "debug.h" ++ + + __attribute__((format(printf, 2, 0))) + void __wrap_dlog (int prio, const char * fmt, ...) +@@ -24,6 +26,8 @@ void __wrap_dlog (int prio, const char * fmt, ...) + + void expect_condlog(int prio, char *string) + { ++ if (prio > MAX_VERBOSITY || prio > libmp_verbosity) ++ return; + expect_value(__wrap_dlog, prio, prio); + will_return(__wrap_dlog, string); + } diff --git a/0020-multipath-tests-__wrap_dlog-print-log-message.patch b/0020-multipath-tests-__wrap_dlog-print-log-message.patch new file mode 100644 index 0000000..216e5a2 --- /dev/null +++ b/0020-multipath-tests-__wrap_dlog-print-log-message.patch @@ -0,0 +1,27 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 6 Jul 2022 11:15:27 +0200 +Subject: [PATCH] multipath tests: __wrap_dlog: print log message + +This makes it easier to analyze errors from __wrap_dlog(). + +Signed-off-by: Martin Wilck + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + tests/test-log.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tests/test-log.c b/tests/test-log.c +index 0c17cd96..c1745872 100644 +--- a/tests/test-log.c ++++ b/tests/test-log.c +@@ -20,6 +20,7 @@ void __wrap_dlog (int prio, const char * fmt, ...) + va_start(ap, fmt); + vsnprintf(buff, MAX_MSG_SIZE, fmt, ap); + va_end(ap); ++ fprintf(stderr, "%s(%d): %s", __func__, prio, buff); + expected = mock_ptr_type(char *); + assert_memory_equal(buff, expected, strlen(expected)); + } diff --git a/0021-multipath-tests-add-sysfs-test.patch b/0021-multipath-tests-add-sysfs-test.patch new file mode 100644 index 0000000..b02a055 --- /dev/null +++ b/0021-multipath-tests-add-sysfs-test.patch @@ -0,0 +1,538 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 5 Jul 2022 23:19:30 +0200 +Subject: [PATCH] multipath tests: add sysfs test + +Signed-off-by: Martin Wilck + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + tests/Makefile | 5 +- + tests/sysfs.c | 494 +++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 498 insertions(+), 1 deletion(-) + create mode 100644 tests/sysfs.c + +diff --git a/tests/Makefile b/tests/Makefile +index d20ef236..95a99908 100644 +--- a/tests/Makefile ++++ b/tests/Makefile +@@ -16,7 +16,7 @@ CFLAGS += $(BIN_CFLAGS) -Wno-unused-parameter $(W_MISSING_INITIALIZERS) + LIBDEPS += -L. -L$(mpathcmddir) -lmultipath -lmpathcmd -lcmocka + + TESTS := uevent parser util dmevents hwtable blacklist unaligned vpd pgpolicy \ +- alias directio valid devt mpathvalid strbuf ++ alias directio valid devt mpathvalid strbuf sysfs + HELPERS := test-lib.o test-log.o + + .SILENT: $(TESTS:%=%.o) +@@ -70,6 +70,9 @@ ifneq ($(DIO_TEST_DEV),) + directio-test_LIBDEPS := -laio + endif + strbuf-test_OBJDEPS := ../libmultipath/strbuf.o ++sysfs-test_TESTDEPS := test-log.o ++sysfs-test_OBJDEPS := ../libmultipath/sysfs.o ../libmultipath/util.o ++sysfs-test_LIBDEPS := -ludev -lpthread -ldl + + %.o: %.c + $(CC) $(CPPFLAGS) $(CFLAGS) $($*-test_FLAGS) -c -o $@ $< +diff --git a/tests/sysfs.c b/tests/sysfs.c +new file mode 100644 +index 00000000..0ec135bf +--- /dev/null ++++ b/tests/sysfs.c +@@ -0,0 +1,494 @@ ++/* ++ * Copyright (c) 2021 SUSE LLC ++ * SPDX-License-Identifier: GPL-2.0-only ++ */ ++ ++#define _GNU_SOURCE ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "debug.h" ++#include "globals.c" ++#include "test-log.h" ++#include "sysfs.h" ++#include "util.h" ++ ++#define TEST_FD 123 ++ ++char *__wrap_udev_device_get_syspath(struct udev_device *ud) ++{ ++ char *val = mock_ptr_type(char *); ++ ++ return val; ++} ++ ++int __wrap_open(const char *pathname, int flags) ++{ ++ int ret; ++ ++ check_expected(pathname); ++ check_expected(flags); ++ ret = mock_type(int); ++ return ret; ++} ++ ++ssize_t __wrap_read(int fd, void *buf, size_t count) ++{ ++ ssize_t ret; ++ char *val; ++ ++ check_expected(fd); ++ check_expected(count); ++ ret = mock_type(int); ++ val = mock_ptr_type(char *); ++ if (ret >= (ssize_t)count) ++ ret = count; ++ if (ret >= 0 && val) { ++ fprintf(stderr, "%s: '%s' -> %zd\n", __func__, val, ret); ++ memcpy(buf, val, ret); ++ } ++ return ret; ++} ++ ++ssize_t __wrap_write(int fd, void *buf, size_t count) ++{ ++ ssize_t ret; ++ ++ check_expected(fd); ++ check_expected(count); ++ ret = mock_type(int); ++ if (ret >= (ssize_t)count) ++ ret = count; ++ return ret; ++} ++ ++int __real_close(int fd); ++int __wrap_close(int fd) { ++ if (fd != TEST_FD) ++ return __real_close(fd); ++ return mock_type(int); ++} ++ ++static int setup(void **state) ++{ ++ udev = udev_new(); ++ return 0; ++} ++ ++static int teardown(void **state) ++{ ++ udev_unref(udev); ++ return 0; ++} ++ ++static void expect_sagv_invalid(void) ++{ ++ expect_condlog(1, "__sysfs_attr_get_value: invalid parameters"); ++} ++ ++static void test_sagv_invalid(void **state) ++{ ++ expect_sagv_invalid(); ++ assert_int_equal(sysfs_attr_get_value(NULL, NULL, NULL, 0), -EINVAL); ++ expect_sagv_invalid(); ++ assert_int_equal(sysfs_bin_attr_get_value(NULL, NULL, NULL, 0), -EINVAL); ++ ++ expect_sagv_invalid(); ++ assert_int_equal(sysfs_attr_get_value(NULL, (void *)state, (void *)state, 1), ++ -EINVAL); ++ expect_sagv_invalid(); ++ assert_int_equal(sysfs_bin_attr_get_value(NULL, (void *)state, (void *)state, 1), ++ -EINVAL); ++ ++ expect_sagv_invalid(); ++ assert_int_equal(sysfs_attr_get_value((void *)state, NULL, (void *)state, 1), ++ -EINVAL); ++ expect_sagv_invalid(); ++ assert_int_equal(sysfs_bin_attr_get_value((void *)state, NULL, (void *)state, 1), ++ -EINVAL); ++ ++ expect_sagv_invalid(); ++ assert_int_equal(sysfs_attr_get_value((void *)state, (void *)state, NULL, 1), ++ -EINVAL); ++ expect_sagv_invalid(); ++ assert_int_equal(sysfs_bin_attr_get_value((void *)state, (void *)state, NULL, 1), ++ -EINVAL); ++ ++ expect_sagv_invalid(); ++ assert_int_equal(sysfs_attr_get_value((void *)state, (void *)state, ++ (void *)state, 0), -EINVAL); ++ expect_sagv_invalid(); ++ assert_int_equal(sysfs_bin_attr_get_value((void *)state, (void *)state, ++ (void *)state, 0), -EINVAL); ++} ++ ++static void test_sagv_bad_udev(void **state) ++{ ++ will_return(__wrap_udev_device_get_syspath, NULL); ++ expect_condlog(3, "__sysfs_attr_get_value: invalid udevice"); ++ assert_int_equal(sysfs_attr_get_value((void *)state, (void *)state, ++ (void *)state, 1), -EINVAL); ++ ++ will_return(__wrap_udev_device_get_syspath, NULL); ++ expect_condlog(3, "__sysfs_attr_get_value: invalid udevice"); ++ assert_int_equal(sysfs_bin_attr_get_value((void *)state, (void *)state, ++ (void *)state, 1), -EINVAL); ++} ++ ++static void test_sagv_bad_snprintf(void **state) ++{ ++ char longstr[PATH_MAX + 1]; ++ char buf[1]; ++ ++ memset(longstr, 'a', sizeof(longstr) - 1); ++ longstr[sizeof(longstr) - 1] = '\0'; ++ ++ will_return(__wrap_udev_device_get_syspath, "/foo"); ++ expect_condlog(3, "__sysfs_attr_get_value: devpath overflow"); ++ assert_int_equal(sysfs_attr_get_value((void *)state, longstr, ++ buf, sizeof(buf)), -EOVERFLOW); ++ will_return(__wrap_udev_device_get_syspath, "/foo"); ++ expect_condlog(3, "__sysfs_attr_get_value: devpath overflow"); ++ assert_int_equal(sysfs_bin_attr_get_value((void *)state, longstr, ++ (unsigned char *)buf, sizeof(buf)), ++ -EOVERFLOW); ++} ++ ++static void test_sagv_open_fail(void **state) ++{ ++ char buf[1]; ++ ++ will_return(__wrap_udev_device_get_syspath, "/foo"); ++ expect_condlog(4, "open '/foo/bar'"); ++ expect_string(__wrap_open, pathname, "/foo/bar"); ++ expect_value(__wrap_open, flags, O_RDONLY); ++ errno = ENOENT; ++ will_return(__wrap_open, -1); ++ expect_condlog(3, "__sysfs_attr_get_value: attribute '/foo/bar' can not be opened"); ++ assert_int_equal(sysfs_attr_get_value((void *)state, "bar", ++ buf, sizeof(buf)), -ENOENT); ++} ++ ++static void test_sagv_read_fail(void **state) ++{ ++ char buf[1]; ++ ++ will_return(__wrap_udev_device_get_syspath, "/foo"); ++ expect_condlog(4, "open '/foo/bar'"); ++ expect_string(__wrap_open, pathname, "/foo/bar"); ++ expect_value(__wrap_open, flags, O_RDONLY); ++ will_return(__wrap_open, TEST_FD); ++ expect_value(__wrap_read, fd, TEST_FD); ++ expect_value(__wrap_read, count, sizeof(buf)); ++ errno = EISDIR; ++ will_return(__wrap_read, -1); ++ will_return(__wrap_read, NULL); ++ expect_condlog(3, "__sysfs_attr_get_value: read from /foo/bar failed:"); ++ will_return(__wrap_close, 0); ++ assert_int_equal(sysfs_attr_get_value((void *)state, "bar", ++ buf, sizeof(buf)), -EISDIR); ++ ++ will_return(__wrap_udev_device_get_syspath, "/foo"); ++ expect_condlog(4, "open '/foo/baz'"); ++ expect_string(__wrap_open, pathname, "/foo/baz"); ++ expect_value(__wrap_open, flags, O_RDONLY); ++ will_return(__wrap_open, TEST_FD); ++ expect_value(__wrap_read, fd, TEST_FD); ++ expect_value(__wrap_read, count, sizeof(buf)); ++ errno = EPERM; ++ will_return(__wrap_read, -1); ++ will_return(__wrap_read, NULL); ++ expect_condlog(3, "__sysfs_attr_get_value: read from /foo/baz failed:"); ++ will_return(__wrap_close, 0); ++ assert_int_equal(sysfs_bin_attr_get_value((void *)state, "baz", ++ (unsigned char *)buf, sizeof(buf)), ++ -EPERM); ++ ++} ++ ++static void _test_sagv_read(void **state, unsigned int bufsz) ++{ ++ char buf[16]; ++ char input[] = "01234567"; ++ unsigned int n, trunc; ++ ++ assert_in_range(bufsz, 1, sizeof(buf)); ++ memset(buf, '.', sizeof(buf)); ++ will_return(__wrap_udev_device_get_syspath, "/foo"); ++ expect_condlog(4, "open '/foo/bar'"); ++ expect_string(__wrap_open, pathname, "/foo/bar"); ++ expect_value(__wrap_open, flags, O_RDONLY); ++ will_return(__wrap_open, TEST_FD); ++ expect_value(__wrap_read, fd, TEST_FD); ++ expect_value(__wrap_read, count, bufsz); ++ will_return(__wrap_read, sizeof(input) - 1); ++ will_return(__wrap_read, input); ++ ++ /* If the buffer is too small, input will be truncated by a 0 byte */ ++ if (bufsz <= sizeof(input) - 1) { ++ n = bufsz; ++ trunc = 1; ++ expect_condlog(3, "__sysfs_attr_get_value: overflow reading from /foo/bar"); ++ } else { ++ n = sizeof(input) - 1; ++ trunc = 0; ++ } ++ will_return(__wrap_close, 0); ++ assert_int_equal(sysfs_attr_get_value((void *)state, "bar", ++ buf, bufsz), n); ++ assert_memory_equal(buf, input, n - trunc); ++ assert_int_equal(buf[n - trunc], '\0'); ++ ++ /* Binary input is not truncated */ ++ memset(buf, '.', sizeof(buf)); ++ will_return(__wrap_udev_device_get_syspath, "/foo"); ++ expect_condlog(4, "open '/foo/baz'"); ++ expect_string(__wrap_open, pathname, "/foo/baz"); ++ expect_value(__wrap_open, flags, O_RDONLY); ++ will_return(__wrap_open, TEST_FD); ++ expect_value(__wrap_read, fd, TEST_FD); ++ expect_value(__wrap_read, count, bufsz); ++ will_return(__wrap_read, sizeof(input) - 1); ++ will_return(__wrap_read, input); ++ will_return(__wrap_close, 0); ++ n = bufsz < sizeof(input) - 1 ? bufsz : sizeof(input) - 1; ++ assert_int_equal(sysfs_bin_attr_get_value((void *)state, "baz", ++ (unsigned char *)buf, ++ bufsz), ++ n); ++ assert_memory_equal(buf, input, n); ++} ++ ++static void test_sagv_read_overflow_8(void **state) ++{ ++ _test_sagv_read(state, 8); ++} ++ ++static void test_sagv_read_overflow_4(void **state) ++{ ++ _test_sagv_read(state, 4); ++} ++ ++static void test_sagv_read_overflow_1(void **state) ++{ ++ _test_sagv_read(state, 1); ++} ++ ++static void test_sagv_read_good_9(void **state) ++{ ++ _test_sagv_read(state, 9); ++} ++ ++static void test_sagv_read_good_15(void **state) ++{ ++ _test_sagv_read(state, 15); ++} ++ ++static void _test_sagv_read_zeroes(void **state, unsigned int bufsz) ++{ ++ char buf[16]; ++ char input[] = { '\0','\0','\0','\0','\0','\0','\0','\0' }; ++ unsigned int n; ++ ++ assert_in_range(bufsz, 1, sizeof(buf)); ++ memset(buf, '.', sizeof(buf)); ++ will_return(__wrap_udev_device_get_syspath, "/foo"); ++ expect_condlog(4, "open '/foo/bar'"); ++ expect_string(__wrap_open, pathname, "/foo/bar"); ++ expect_value(__wrap_open, flags, O_RDONLY); ++ will_return(__wrap_open, TEST_FD); ++ expect_value(__wrap_read, fd, TEST_FD); ++ expect_value(__wrap_read, count, bufsz); ++ will_return(__wrap_read, sizeof(input) - 1); ++ will_return(__wrap_read, input); ++ ++ if (bufsz <= sizeof(input) - 1) { ++ n = bufsz; ++ expect_condlog(3, "__sysfs_attr_get_value: overflow reading from /foo/bar"); ++ } else ++ n = 0; ++ ++ will_return(__wrap_close, 0); ++ assert_int_equal(sysfs_attr_get_value((void *)state, "bar", ++ buf, bufsz), n); ++ ++ /* ++ * The return value of sysfs_attr_get_value ignores zero bytes, ++ * but the read data should have been copied to the buffer ++ */ ++ assert_memory_equal(buf, input, n == 0 ? bufsz : n); ++} ++ ++static void test_sagv_read_zeroes_4(void **state) ++{ ++ _test_sagv_read_zeroes(state, 4); ++} ++ ++static void expect_sasv_invalid(void) ++{ ++ expect_condlog(1, "sysfs_attr_set_value: invalid parameters"); ++} ++ ++static void test_sasv_invalid(void **state) ++{ ++ expect_sasv_invalid(); ++ assert_int_equal(sysfs_attr_set_value(NULL, NULL, NULL, 0), -EINVAL); ++ ++ expect_sasv_invalid(); ++ assert_int_equal(sysfs_attr_set_value(NULL, (void *)state, (void *)state, 1), ++ -EINVAL); ++ ++ expect_sasv_invalid(); ++ assert_int_equal(sysfs_attr_set_value((void *)state, NULL, (void *)state, 1), ++ -EINVAL); ++ ++ expect_sasv_invalid(); ++ assert_int_equal(sysfs_attr_set_value((void *)state, (void *)state, NULL, 1), ++ -EINVAL); ++ ++ expect_sasv_invalid(); ++ assert_int_equal(sysfs_attr_set_value((void *)state, (void *)state, ++ (void *)state, 0), -EINVAL); ++} ++ ++static void test_sasv_bad_udev(void **state) ++{ ++ will_return(__wrap_udev_device_get_syspath, NULL); ++ expect_condlog(3, "sysfs_attr_set_value: invalid udevice"); ++ assert_int_equal(sysfs_attr_set_value((void *)state, (void *)state, ++ (void *)state, 1), -EINVAL); ++} ++ ++static void test_sasv_bad_snprintf(void **state) ++{ ++ char longstr[PATH_MAX + 1]; ++ char buf[1]; ++ ++ memset(longstr, 'a', sizeof(longstr) - 1); ++ longstr[sizeof(longstr) - 1] = '\0'; ++ ++ will_return(__wrap_udev_device_get_syspath, "/foo"); ++ expect_condlog(3, "sysfs_attr_set_value: devpath overflow"); ++ assert_int_equal(sysfs_attr_set_value((void *)state, longstr, ++ buf, sizeof(buf)), -EOVERFLOW); ++} ++ ++static void test_sasv_open_fail(void **state) ++{ ++ char buf[1]; ++ ++ will_return(__wrap_udev_device_get_syspath, "/foo"); ++ expect_condlog(4, "open '/foo/bar'"); ++ expect_string(__wrap_open, pathname, "/foo/bar"); ++ expect_value(__wrap_open, flags, O_WRONLY); ++ errno = EPERM; ++ will_return(__wrap_open, -1); ++ expect_condlog(3, "sysfs_attr_set_value: attribute '/foo/bar' can not be opened"); ++ assert_int_equal(sysfs_attr_set_value((void *)state, "bar", ++ buf, sizeof(buf)), -EPERM); ++} ++ ++static void test_sasv_write_fail(void **state) ++{ ++ char buf[1]; ++ ++ will_return(__wrap_udev_device_get_syspath, "/foo"); ++ expect_condlog(4, "open '/foo/bar'"); ++ expect_string(__wrap_open, pathname, "/foo/bar"); ++ expect_value(__wrap_open, flags, O_WRONLY); ++ will_return(__wrap_open, TEST_FD); ++ expect_value(__wrap_write, fd, TEST_FD); ++ expect_value(__wrap_write, count, sizeof(buf)); ++ errno = EISDIR; ++ will_return(__wrap_write, -1); ++ expect_condlog(3, "sysfs_attr_set_value: write to /foo/bar failed:"); ++ will_return(__wrap_close, 0); ++ assert_int_equal(sysfs_attr_set_value((void *)state, "bar", ++ buf, sizeof(buf)), -EISDIR); ++ ++} ++ ++static void _test_sasv_write(void **state, unsigned int n_written) ++{ ++ char buf[8]; ++ ++ assert_in_range(n_written, 0, sizeof(buf)); ++ will_return(__wrap_udev_device_get_syspath, "/foo"); ++ expect_condlog(4, "open '/foo/bar'"); ++ expect_string(__wrap_open, pathname, "/foo/bar"); ++ expect_value(__wrap_open, flags, O_WRONLY); ++ will_return(__wrap_open, TEST_FD); ++ expect_value(__wrap_write, fd, TEST_FD); ++ expect_value(__wrap_write, count, sizeof(buf)); ++ will_return(__wrap_write, n_written); ++ ++ if (n_written < sizeof(buf)) ++ expect_condlog(3, "sysfs_attr_set_value: underflow writing"); ++ will_return(__wrap_close, 0); ++ assert_int_equal(sysfs_attr_set_value((void *)state, "bar", ++ buf, sizeof(buf)), ++ n_written); ++} ++ ++static void test_sasv_write_0(void **state) ++{ ++ _test_sasv_write(state, 0); ++} ++ ++static void test_sasv_write_4(void **state) ++{ ++ _test_sasv_write(state, 4); ++} ++ ++static void test_sasv_write_7(void **state) ++{ ++ _test_sasv_write(state, 7); ++} ++ ++static void test_sasv_write_8(void **state) ++{ ++ _test_sasv_write(state, 8); ++} ++ ++static int test_sysfs(void) ++{ ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test(test_sagv_invalid), ++ cmocka_unit_test(test_sagv_bad_udev), ++ cmocka_unit_test(test_sagv_bad_snprintf), ++ cmocka_unit_test(test_sagv_open_fail), ++ cmocka_unit_test(test_sagv_read_fail), ++ cmocka_unit_test(test_sagv_read_overflow_1), ++ cmocka_unit_test(test_sagv_read_overflow_4), ++ cmocka_unit_test(test_sagv_read_overflow_8), ++ cmocka_unit_test(test_sagv_read_good_9), ++ cmocka_unit_test(test_sagv_read_good_15), ++ cmocka_unit_test(test_sagv_read_zeroes_4), ++ cmocka_unit_test(test_sasv_invalid), ++ cmocka_unit_test(test_sasv_bad_udev), ++ cmocka_unit_test(test_sasv_bad_snprintf), ++ cmocka_unit_test(test_sasv_open_fail), ++ cmocka_unit_test(test_sasv_write_fail), ++ cmocka_unit_test(test_sasv_write_0), ++ cmocka_unit_test(test_sasv_write_4), ++ cmocka_unit_test(test_sasv_write_7), ++ cmocka_unit_test(test_sasv_write_8), ++ }; ++ ++ return cmocka_run_group_tests(tests, setup, teardown); ++} ++ ++int main(void) ++{ ++ int ret = 0; ++ ++ init_test_verbosity(4); ++ ret += test_sysfs(); ++ return ret; ++} diff --git a/0022-libmultipath.version-bump-version-for-sysfs-accessor.patch b/0022-libmultipath.version-bump-version-for-sysfs-accessor.patch new file mode 100644 index 0000000..fdbb113 --- /dev/null +++ b/0022-libmultipath.version-bump-version-for-sysfs-accessor.patch @@ -0,0 +1,43 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 6 Jul 2022 12:45:33 +0200 +Subject: [PATCH] libmultipath.version: bump version for sysfs accessors + +Formally, the ABI is still the same, but the semantics of the +return value have changed. + +Signed-off-by: Martin Wilck + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/libmultipath.version | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version +index b3690ac0..c1d9b156 100644 +--- a/libmultipath/libmultipath.version ++++ b/libmultipath/libmultipath.version +@@ -207,7 +207,6 @@ global: + strchop; + strlcpy; + sync_map_state; +- sysfs_attr_set_value; + sysfs_get_size; + sysfs_is_multipathed; + timespeccmp; +@@ -264,8 +263,13 @@ global: + + /* foreign */ + free_scandir_result; +- sysfs_attr_get_value; + + local: + *; + }; ++ ++LIBMULTIPATH_16.0.0 { ++global: ++ sysfs_attr_set_value; ++ sysfs_attr_get_value; ++}; diff --git a/0005-libmultipath-unset-detect_checker-for-clariion-Unity.patch b/0023-libmultipath-unset-detect_checker-for-clariion-Unity.patch similarity index 92% rename from 0005-libmultipath-unset-detect_checker-for-clariion-Unity.patch rename to 0023-libmultipath-unset-detect_checker-for-clariion-Unity.patch index d80c1cf..b69f395 100644 --- a/0005-libmultipath-unset-detect_checker-for-clariion-Unity.patch +++ b/0023-libmultipath-unset-detect_checker-for-clariion-Unity.patch @@ -1,6 +1,6 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski -Date: Tue, 10 May 2022 14:17:22 -0500 +Date: Tue, 7 Jun 2022 17:45:01 -0500 Subject: [PATCH] libmultipath: unset detect_checker for clariion / Unity arrays @@ -12,6 +12,7 @@ checker. Cc: vincent.chen1@dell.com Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck --- libmultipath/hwtable.c | 1 + 1 file changed, 1 insertion(+) diff --git a/0024-libmultipath-spelling-cplusplus.patch b/0024-libmultipath-spelling-cplusplus.patch new file mode 100644 index 0000000..bf21a11 --- /dev/null +++ b/0024-libmultipath-spelling-cplusplus.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Josh Soref <2119212+jsoref@users.noreply.github.com> +Date: Sun, 31 Jul 2022 13:11:15 -0400 +Subject: [PATCH] libmultipath: spelling: cplusplus + +Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> +Reviewed-by: Xose Vazquez Perez +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmpathvalid/mpath_valid.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmpathvalid/mpath_valid.h b/libmpathvalid/mpath_valid.h +index ed06196e..ec2f9392 100644 +--- a/libmpathvalid/mpath_valid.h ++++ b/libmpathvalid/mpath_valid.h +@@ -20,7 +20,7 @@ + #ifndef LIB_MPATH_VALID_H + #define LIB_MPATH_VALID_H + +-#ifdef __cpluscplus ++#ifdef __cplusplus + extern "C" { + #endif + diff --git a/0025-libmultipath-spelling-ascii.patch b/0025-libmultipath-spelling-ascii.patch new file mode 100644 index 0000000..01e22e4 --- /dev/null +++ b/0025-libmultipath-spelling-ascii.patch @@ -0,0 +1,25 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Josh Soref <2119212+jsoref@users.noreply.github.com> +Date: Sun, 31 Jul 2022 13:11:12 -0400 +Subject: [PATCH] libmultipath: spelling: ascii + +Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/prioritizers/alua_spc3.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmultipath/prioritizers/alua_spc3.h b/libmultipath/prioritizers/alua_spc3.h +index 08e992bd..e1a6c071 100644 +--- a/libmultipath/prioritizers/alua_spc3.h ++++ b/libmultipath/prioritizers/alua_spc3.h +@@ -143,7 +143,7 @@ inquiry_data_get_tpgs(struct inquiry_data *id) + *----------------------------------------------------------------------------- + */ + #define CODESET_BINARY 0x1 +-#define CODESET_ACSII 0x2 ++#define CODESET_ASCII 0x2 + #define CODESET_UTF8 0x3 + + #define ASSOCIATION_UNIT 0x0 diff --git a/0026-libmultipath-spelling-progress.patch b/0026-libmultipath-spelling-progress.patch new file mode 100644 index 0000000..2984f31 --- /dev/null +++ b/0026-libmultipath-spelling-progress.patch @@ -0,0 +1,25 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Josh Soref <2119212+jsoref@users.noreply.github.com> +Date: Sun, 31 Jul 2022 13:11:22 -0400 +Subject: [PATCH] libmultipath: spelling: progress + +Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/nvme/linux/nvme.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmultipath/nvme/linux/nvme.h b/libmultipath/nvme/linux/nvme.h +index a6975549..9fc2ae7f 100644 +--- a/libmultipath/nvme/linux/nvme.h ++++ b/libmultipath/nvme/linux/nvme.h +@@ -1035,7 +1035,7 @@ enum { + NVME_SANITIZE_LOG_STATUS_MASK = 0x0007, + NVME_SANITIZE_LOG_NEVER_SANITIZED = 0x0000, + NVME_SANITIZE_LOG_COMPLETED_SUCCESS = 0x0001, +- NVME_SANITIZE_LOG_IN_PROGESS = 0x0002, ++ NVME_SANITIZE_LOG_IN_PROGRESS = 0x0002, + NVME_SANITIZE_LOG_COMPLETED_FAILED = 0x0003, + NVME_SANITIZE_LOG_ND_COMPLETED_SUCCESS = 0x0004, + }; diff --git a/0027-multipath-tools-spelling-fixes.patch b/0027-multipath-tools-spelling-fixes.patch new file mode 100644 index 0000000..c1e9468 --- /dev/null +++ b/0027-multipath-tools-spelling-fixes.patch @@ -0,0 +1,599 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Josh Soref <2119212+jsoref@users.noreply.github.com> +Date: Sun, 31 Jul 2022 13:17:53 -0400 +Subject: [PATCH] multipath-tools: spelling fixes + +Spelling errors detected by the GitHub check-spelling action: +https://github.com/marketplace/actions/check-spelling + +Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/foreign.yaml | 2 +- + kpartx/crc32.c | 2 +- + kpartx/gpt.c | 2 +- + libdmmp/libdmmp_path.c | 2 +- + libmpathcmd/mpath_cmd.h | 2 +- + libmpathpersist/mpath_persist_int.c | 2 +- + libmpathvalid/mpath_valid.h | 4 ++-- + libmultipath/checkers/directio.c | 2 +- + libmultipath/config.h | 2 +- + libmultipath/configure.c | 2 +- + libmultipath/discovery.c | 2 +- + libmultipath/nvme/nvme.h | 2 +- + libmultipath/prioritizers/datacore.c | 4 ++-- + libmultipath/prioritizers/hds.c | 2 +- + libmultipath/prioritizers/path_latency.c | 4 ++-- + libmultipath/strbuf.h | 4 ++-- + libmultipath/structs_vec.c | 2 +- + libmultipath/uevent.c | 2 +- + libmultipath/valid.h | 2 +- + mpathpersist/main.c | 2 +- + multipath/multipath.conf.5 | 14 +++++++------- + multipathd/main.c | 10 +++++----- + tests/directio.c | 2 +- + tests/hwtable.c | 10 +++++----- + tests/mpathvalid.c | 2 +- + tests/pgpolicy.c | 2 +- + tests/valid.c | 4 ++-- + third-party/valgrind/valgrind.h | 8 ++++---- + 28 files changed, 50 insertions(+), 50 deletions(-) + +diff --git a/.github/workflows/foreign.yaml b/.github/workflows/foreign.yaml +index e9ffd3d8..32915186 100644 +--- a/.github/workflows/foreign.yaml ++++ b/.github/workflows/foreign.yaml +@@ -56,7 +56,7 @@ jobs: + - name: enable foreign arch + run: sudo docker run --rm --privileged multiarch/qemu-user-static:register --reset + - name: run tests +- # Github actions doesn't support referencing docker images with ++ # GitHub actions doesn't support referencing docker images with + # context variables. Workaround: use mosteo-actions/docker-run action + # See https://github.community/t/expressions-in-docker-uri/16271 + uses: mosteo-actions/docker-run@v1 +diff --git a/kpartx/crc32.c b/kpartx/crc32.c +index e688f8e9..df6c6878 100644 +--- a/kpartx/crc32.c ++++ b/kpartx/crc32.c +@@ -290,7 +290,7 @@ uint32_t attribute((pure)) crc32_be(uint32_t crc, unsigned char const *p, size_t + * the end, so we have to add 32 extra cycles shifting in zeros at the + * end of every message, + * +- * So the standard trick is to rearrage merging in the next_input_bit() ++ * So the standard trick is to rearrange merging in the next_input_bit() + * until the moment it's needed. Then the first 32 cycles can be precomputed, + * and merging in the final 32 zero bits to make room for the CRC can be + * skipped entirely. +diff --git a/kpartx/gpt.c b/kpartx/gpt.c +index 34a910cf..47d8743e 100644 +--- a/kpartx/gpt.c ++++ b/kpartx/gpt.c +@@ -357,7 +357,7 @@ is_gpt_valid(int fd, uint64_t lba, + __le32_to_cpu((*gpt)->num_partition_entries) * + __le32_to_cpu((*gpt)->sizeof_partition_entry)); + if (crc != __le32_to_cpu((*gpt)->partition_entry_array_crc32)) { +- // printf("GUID Partitition Entry Array CRC check failed.\n"); ++ // printf("GUID Partition Entry Array CRC check failed.\n"); + free(*gpt); + *gpt = NULL; + free(*ptes); +diff --git a/libdmmp/libdmmp_path.c b/libdmmp/libdmmp_path.c +index 47a2162c..21714b15 100644 +--- a/libdmmp/libdmmp_path.c ++++ b/libdmmp/libdmmp_path.c +@@ -28,7 +28,7 @@ + #include "libdmmp_private.h" + + #define _DMMP_SHOW_PS_INDEX_BLK_NAME 0 +-#define _DMMP_SHOW_PS_INDEX_SATAUS 1 ++#define _DMMP_SHOW_PS_INDEX_STATUS 1 + #define _DMMP_SHOW_PS_INDEX_WWID 2 + #define _DMMP_SHOW_PS_INDEX_PGID 3 + +diff --git a/libmpathcmd/mpath_cmd.h b/libmpathcmd/mpath_cmd.h +index 30838b02..0c293c71 100644 +--- a/libmpathcmd/mpath_cmd.h ++++ b/libmpathcmd/mpath_cmd.h +@@ -65,7 +65,7 @@ int mpath_connect(void); + /* + * DESCRIPTION: + * Disconnect from the multipathd daemon. This function must be +- * run after after processing all the multipath commands. ++ * run after processing all the multipath commands. + * + * RETURNS: + * 0 on success. -1 on failure (with errno set). +diff --git a/libmpathpersist/mpath_persist_int.c b/libmpathpersist/mpath_persist_int.c +index e34fc32d..6924b379 100644 +--- a/libmpathpersist/mpath_persist_int.c ++++ b/libmpathpersist/mpath_persist_int.c +@@ -601,7 +601,7 @@ static int mpath_prout_rel(struct multipath *mpp,int rq_servact, int rq_scope, + if (get_be64(mpp->reservation_key) && + memcmp(pr_buff->prin_descriptor.prin_readfd.descriptors[i]->key, + &mpp->reservation_key, 8)){ +- /*register with tarnsport id*/ ++ /*register with transport id*/ + memset(pamp, 0, length); + pamp->trnptid_list[0] = pptr; + memset (pamp->trnptid_list[0], 0, sizeof (struct transportid)); +diff --git a/libmpathvalid/mpath_valid.h b/libmpathvalid/mpath_valid.h +index ec2f9392..3e34b1fd 100644 +--- a/libmpathvalid/mpath_valid.h ++++ b/libmpathvalid/mpath_valid.h +@@ -112,7 +112,7 @@ int mpathvalid_exit(void); + * RETURNS: + * MPATH_STRICT, MPATH_SMART, MPATH_GREEDY, or MPATH_MODE_ERROR + * +- * MPATH_STRICT = find_multiapths (yes|on|no|off) ++ * MPATH_STRICT = find_multipaths (yes|on|no|off) + * MPATH_SMART = find_multipaths smart + * MPATH_GREEDY = find_multipaths greedy + * MPATH_MODE_ERROR = multipath configuration not initialized +@@ -126,7 +126,7 @@ unsigned int mpathvalid_get_mode(void); + * potentially claimed (MPATH_IS_VALID, MPATH_IS_VALID_NO_CHECK, + * or MPATH_IS_MAYBE_VALID) and wwid is not NULL, then *wiid will + * be set to point to the wwid of device. If set, *wwid must be +- * freed by the caller. path_wwids is an obptional parameter that ++ * freed by the caller. path_wwids is an optional parameter that + * points to an array of wwids, that were returned from previous + * calls to mpathvalid_is_path(). These are wwids of existing + * devices that are or potentially are claimed by device-mapper +diff --git a/libmultipath/checkers/directio.c b/libmultipath/checkers/directio.c +index bc7b7be5..a326e37b 100644 +--- a/libmultipath/checkers/directio.c ++++ b/libmultipath/checkers/directio.c +@@ -124,7 +124,7 @@ remove_aio_group(struct aio_group *aio_grp) + + /* If an aio_group is completely full of orphans, then no checkers can + * use it, which means that no checkers can clear out the orphans. To +- * avoid keeping the useless group around, simply remove remove the ++ * avoid keeping the useless group around, simply remove the + * group */ + static void + check_orphaned_group(struct aio_group *aio_grp) +diff --git a/libmultipath/config.h b/libmultipath/config.h +index 36d40157..fdcdff0a 100644 +--- a/libmultipath/config.h ++++ b/libmultipath/config.h +@@ -248,7 +248,7 @@ struct config { + * libmultipath calls. If an application wants to keep using the + * udev variable after calling libmultipath_exit(), it should have taken + * an additional reference on it beforehand. This is the case e.g. +- * after initiazing udev with udev_new(). ++ * after initializing udev with udev_new(). + */ + extern struct udev *udev; + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index 4427f910..8af7cd79 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -397,7 +397,7 @@ int setup_map(struct multipath *mpp, char **params, struct vectors *vecs) + * into a mp->params strings to feed the device-mapper + */ + if (assemble_map(mpp, params)) { +- condlog(0, "%s: problem assembing map", mpp->alias); ++ condlog(0, "%s: problem assembling map", mpp->alias); + return 1; + } + return 0; +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index ee290093..15560f8c 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -1344,7 +1344,7 @@ parse_vpd_c0_hp3par(const unsigned char *in, size_t in_len, + condlog(3, "HP/3PAR vendor specific VPD page length too short: %zu", in_len); + return -EINVAL; + } +- if (in[4] <= 3) /* revision must be > 3 to have Vomlume Name */ ++ if (in[4] <= 3) /* revision must be > 3 to have Volume Name */ + return -ENODATA; + len = get_unaligned_be32(&in[40]); + if (len > out_len || len + 44 > in_len) { +diff --git a/libmultipath/nvme/nvme.h b/libmultipath/nvme/nvme.h +index 7e0278b5..57f82a31 100644 +--- a/libmultipath/nvme/nvme.h ++++ b/libmultipath/nvme/nvme.h +@@ -224,7 +224,7 @@ char *nvme_char_from_block(char *block); + * Notes: This function does not care about transport so that the offset is + * not going to be checked inside of this function for the unsupported fields + * in a specific transport. For example, BPMBL(Boot Partition Memory Buffer +- * Location) register is not supported by fabrics, but it can be chcked here. ++ * Location) register is not supported by fabrics, but it can be checked here. + */ + static inline bool is_64bit_reg(__u32 offset) + { +diff --git a/libmultipath/prioritizers/datacore.c b/libmultipath/prioritizers/datacore.c +index 02dc2e27..d1d473d4 100644 +--- a/libmultipath/prioritizers/datacore.c ++++ b/libmultipath/prioritizers/datacore.c +@@ -1,6 +1,6 @@ + /* + * (C) 2010 Christophe Varoqui +- * (C) 2009 Dembach Goo Infromatik GmbH & Co KG ++ * (C) 2009 Dembach Goo Informatik GmbH & Co KG + * Manon Goo + * + * datacore.c +@@ -10,7 +10,7 @@ + * Matthias Rudolph + * + * This work is made available on the basis of the +- * GPLv2 for detials see . ++ * GPLv2 for details see . + * + * Manon Goo 2009 + * +diff --git a/libmultipath/prioritizers/hds.c b/libmultipath/prioritizers/hds.c +index 88cac5f0..d569f2d7 100644 +--- a/libmultipath/prioritizers/hds.c ++++ b/libmultipath/prioritizers/hds.c +@@ -32,7 +32,7 @@ + * Half of the LUNs are accessed via one HBA/storage controller and the other + * half via the other HBA/storage controller. + * +- * In cluster environmemnts (RAC) it also guarantees that all cluster nodes have ++ * In cluster environments (RAC) it also guarantees that all cluster nodes have + * access to the LDEVs via the same controller. + * + * You can run the prioritizer manually in verbose mode: +diff --git a/libmultipath/prioritizers/path_latency.c b/libmultipath/prioritizers/path_latency.c +index e155f6dc..2f5be9b9 100644 +--- a/libmultipath/prioritizers/path_latency.c ++++ b/libmultipath/prioritizers/path_latency.c +@@ -64,7 +64,7 @@ static int prepare_directio_read(int fd, int *blksz, char **pbuf, + long flags; + + if (ioctl(fd, BLKBSZGET, blksz) < 0) { +- pp_pl_log(3,"catnnot get blocksize, set default"); ++ pp_pl_log(3,"cannot get blocksize, set default"); + *blksz = DEF_BLK_SIZE; + } + if (posix_memalign((void **)pbuf, pgsize, *blksz)) +@@ -193,7 +193,7 @@ out: + } + + /* +- * Do not scale the prioriy in a certain range such as [0, 1024] ++ * Do not scale the priority in a certain range such as [0, 1024] + * because scaling will eliminate the effect of base_num. + */ + int calcPrio(double lg_avglatency, double lg_maxavglatency, +diff --git a/libmultipath/strbuf.h b/libmultipath/strbuf.h +index 41d7d54f..31ab519a 100644 +--- a/libmultipath/strbuf.h ++++ b/libmultipath/strbuf.h +@@ -159,7 +159,7 @@ int fill_strbuf(struct strbuf *buf, char c, int slen); + * + * Appends the given string to @strbuf, with leading and trailing double + * quotes (") added, expanding @strbuf's size as necessary. Any double quote +- * characters (") in the string are transformed to double double quotes (""). ++ * characters (") in the string are transformed to a pair of double quotes (""). + * If the function returns an error, @strbuf is unchanged. + */ + int append_strbuf_quoted(struct strbuf *buf, const char *str); +@@ -171,7 +171,7 @@ int append_strbuf_quoted(struct strbuf *buf, const char *str); + * @returns: number of appended characters if successful, (excluding + * terminating '\0'); negative error code otherwise + * +- * Appends the the arguments following @fmt, formatted as in printf(), to ++ * Appends the arguments following @fmt, formatted as in printf(), to + * @strbuf, expanding @strbuf's size as necessary. The function makes sure that + * the output @strbuf is always 0-terminated. + * If the function returns an error, @strbuf is unchanged. +diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c +index a69f0643..645896c6 100644 +--- a/libmultipath/structs_vec.c ++++ b/libmultipath/structs_vec.c +@@ -205,7 +205,7 @@ static bool update_pathvec_from_dm(vector pathvec, struct multipath *mpp, + continue; + + /* +- * At this point, pp->udev is valid and and pp->wwid ++ * At this point, pp->udev is valid and pp->wwid + * is the best we could get + */ + if (*pp->wwid && strcmp(mpp->wwid, pp->wwid)) { +diff --git a/libmultipath/uevent.c b/libmultipath/uevent.c +index 5793af94..57447ca0 100644 +--- a/libmultipath/uevent.c ++++ b/libmultipath/uevent.c +@@ -373,7 +373,7 @@ uevent_filter(struct uevent *later, struct uevent_filter_state *st) + + list_for_some_entry_reverse_safe(earlier, tmp, &later->node, &st->uevq, node) { + /* +- * filter unnessary earlier uevents ++ * filter unnecessary earlier uevents + * by the later uevent + */ + if (!list_empty(&earlier->merge_node)) { +diff --git a/libmultipath/valid.h b/libmultipath/valid.h +index ce1c7cbf..731e6eff 100644 +--- a/libmultipath/valid.h ++++ b/libmultipath/valid.h +@@ -23,7 +23,7 @@ + * already. + * PATH_IS_VALID is returned by is_path_valid, when the path is + * valid only if it hasn't been released to systemd already. +- * PATH_IS_MAYBE_VALID is returned when the the path would be valid ++ * PATH_IS_MAYBE_VALID is returned when the path would be valid + * if other paths with the same wwid existed. It is up to the caller + * to check for these other paths. + */ +diff --git a/mpathpersist/main.c b/mpathpersist/main.c +index 4bdd55c2..894e8c94 100644 +--- a/mpathpersist/main.c ++++ b/mpathpersist/main.c +@@ -480,7 +480,7 @@ static int handle_args(int argc, char * argv[], int nline) + } + if ((verbose > 2) && num_transportids) + { +- fprintf (stderr, "number of tranport-ids decoded from " ++ fprintf (stderr, "number of transport-ids decoded from " + "command line : %d\n", num_transportids); + } + +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 +index c2d34f18..853e0feb 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5 +@@ -455,7 +455,7 @@ precedence. See KNOWN ISSUES. + (Since kernel 2.6.38) Number of msecs before pg_init retry, it must be between 0 and 60000. + .TP + .I queue_mode +-(Since kernel 4.8) Select the the queueing mode per multipath device. ++(Since kernel 4.8) Select the queueing mode per multipath device. + can be \fIbio\fR, \fIrq\fR or \fImq\fR, which corresponds to + bio-based, request-based, and block-multiqueue (blk-mq) request-based, + respectively. +@@ -935,7 +935,7 @@ This option is not supported any more. The value is ignored. + .B san_path_err_threshold + If set to a value greater than 0, multipathd will watch paths and check how many + times a path has been failed due to errors.If the number of failures on a particular +-path is greater then the san_path_err_threshold, then the path will not reinstate ++path is greater than the san_path_err_threshold, then the path will not reinstate + till san_path_err_recovery_time. These path failures should occur within a + san_path_err_forget_rate checks, if not we will consider the path is good enough + to reinstantate. See "Shaky paths detection" below. +@@ -949,7 +949,7 @@ The default is: \fBno\fR + .B san_path_err_forget_rate + If set to a value greater than 0, multipathd will check whether the path failures + has exceeded the san_path_err_threshold within this many checks i.e +-san_path_err_forget_rate . If so we will not reinstante the path till ++san_path_err_forget_rate . If so we will not reinstate the path till + san_path_err_recovery_time. See "Shaky paths detection" below. + .RS + .TP +@@ -962,7 +962,7 @@ The default is: \fBno\fR + If set to a value greater than 0, multipathd will make sure that when path failures + has exceeded the san_path_err_threshold within san_path_err_forget_rate then the path + will be placed in failed state for san_path_err_recovery_time duration.Once san_path_err_recovery_time +-has timeout we will reinstante the failed path . ++has timeout we will reinstate the failed path . + san_path_err_recovery_time value should be in secs. + See "Shaky paths detection" below. + .RS +@@ -1000,7 +1000,7 @@ If the rate of IO error on a particular path is greater than the + \fImarginal_path_err_rate_threshold\fR, then the path will not reinstate for + \fImarginal_path_err_recheck_gap_time\fR seconds unless there is only one + active path. After \fImarginal_path_err_recheck_gap_time\fR expires, the path +-will be requeueed for rechecking. If checking result is good enough, the ++will be requeued for rechecking. If checking result is good enough, the + path will be reinstated. See "Shaky paths detection" below. + .RS + .TP +@@ -1031,7 +1031,7 @@ value, the failed path of which the IO error rate is larger than + \fImarginal_path_err_rate_threshold\fR will be kept in failed state for + \fImarginal_path_err_recheck_gap_time\fR seconds. When + \fImarginal_path_err_recheck_gap_time\fR seconds expires, the path will be +-requeueed for checking. If checking result is good enough, the path will be ++requeued for checking. If checking result is good enough, the path will be + reinstated, or else it will keep failed. See "Shaky paths detection" below. + .RS + .TP +@@ -1379,7 +1379,7 @@ 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 5 blacklist criteria are evaluated in the the order ++For every device, these 5 blacklist criteria are evaluated in 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 +diff --git a/multipathd/main.c b/multipathd/main.c +index a160c824..defee10a 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -583,7 +583,7 @@ retry: + if (mpp->prflag) { + vector_foreach_slot(mpp->paths, pp, i) { + if ((pp->state == PATH_UP) || (pp->state == PATH_GHOST)) { +- /* persistent reseravtion check*/ ++ /* persistent reservation check*/ + mpath_pr_event_handle(pp); + } + } +@@ -1515,7 +1515,7 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) + condlog(3, "%s: error in change_foreign", __func__); + break; + default: +- condlog(1, "%s: return code %d of change_forein is unsupported", ++ condlog(1, "%s: return code %d of change_foreign is unsupported", + __func__, rc); + break; + } +@@ -1966,7 +1966,7 @@ ghost_delay_tick(struct vectors *vecs) + } + + static void +-defered_failback_tick (vector mpvec) ++deferred_failback_tick (vector mpvec) + { + struct multipath * mpp; + unsigned int i; +@@ -2186,7 +2186,7 @@ static int check_path_reinstate_state(struct path * pp) { + get_monotonic_time(&curr_time); + /* when path failures has exceeded the san_path_err_threshold + * place the path in delayed state till san_path_err_recovery_time +- * so that the cutomer can rectify the issue within this time. After ++ * so that the customer can rectify the issue within this time. After + * the completion of san_path_err_recovery_time it should + * automatically reinstate the path + * (note: we know that san_path_err_threshold > 0 here). +@@ -2647,7 +2647,7 @@ checkerloop (void *ap) + pthread_cleanup_push(cleanup_lock, &vecs->lock); + lock(&vecs->lock); + pthread_testcancel(); +- defered_failback_tick(vecs->mpvec); ++ deferred_failback_tick(vecs->mpvec); + retry_count_tick(vecs->mpvec); + missing_uev_wait_tick(vecs); + ghost_delay_tick(vecs); +diff --git a/tests/directio.c b/tests/directio.c +index 20ccc47a..01fdef28 100644 +--- a/tests/directio.c ++++ b/tests/directio.c +@@ -497,7 +497,7 @@ static void test_free_with_pending(void **state) + do_libcheck_reset(1); + } + +-/* test removing orpahed aio_group on free */ ++/* test removing orphaned aio_group on free */ + static void test_orphaned_aio_group(void **state) + { + struct checker c[AIO_GROUP_SIZE] = {{.cls = NULL}}; +diff --git a/tests/hwtable.c b/tests/hwtable.c +index bfaf613f..334b75e8 100644 +--- a/tests/hwtable.c ++++ b/tests/hwtable.c +@@ -29,7 +29,7 @@ + + #define N_CONF_FILES 2 + +-static const char tmplate[] = "/tmp/hwtable-XXXXXX"; ++static const char template[] = "/tmp/hwtable-XXXXXX"; + + struct key_value { + const char *key; +@@ -136,7 +136,7 @@ static int setup(void **state) + if (hwt == NULL) + return -1; + +- snprintf(buf, sizeof(buf), "%s", tmplate); ++ snprintf(buf, sizeof(buf), "%s", template); + if (mkdtemp(buf) == NULL) { + condlog(0, "mkdtemp: %s", strerror(errno)); + goto err; +@@ -255,7 +255,7 @@ static void write_defaults(const struct hwt_state *hwt) + { "detect_prio", "no" }, + { "detect_checker", "no" }, + }; +- char buf[sizeof(tmplate) + sizeof(bindings_name)]; ++ char buf[sizeof(template) + sizeof(bindings_name)]; + char dirbuf[PATH_MAX]; + + snprintf(buf, sizeof(buf), "%s/%s", hwt->tmpname, bindings_name); +@@ -308,7 +308,7 @@ static void write_device(FILE *ff, int nkv, const struct key_value *kv) + } + + /* +- * Some macros to avoid boilerplace code ++ * Some macros to avoid boilerplate code + */ + + #define CHECK_STATE(state) ({ \ +@@ -448,7 +448,7 @@ static const struct key_value npr_queue = { _no_path_retry, "queue" }; + /***** BEGIN TESTS SECTION *****/ + + /* +- * Dump the configuration, subistitute the dumped configuration ++ * Dump the configuration, substitute the dumped configuration + * for the current one, and verify that the result is identical. + */ + static void replicate_config(const struct hwt_state *hwt, bool local) +diff --git a/tests/mpathvalid.c b/tests/mpathvalid.c +index 0230a88f..df66ed6a 100644 +--- a/tests/mpathvalid.c ++++ b/tests/mpathvalid.c +@@ -399,7 +399,7 @@ static void test_mpathvalid_is_path_good3(void **state) + free(wwid); + } + +-/* mabybe valid with no matching paths */ ++/* maybe valid with no matching paths */ + static void test_mpathvalid_is_path_good4(void **state) + { + const char *wwids[] = { "WWID_A", "WWID_B", "WWID_C", "WWID_D" }; +diff --git a/tests/pgpolicy.c b/tests/pgpolicy.c +index f116d12c..43be831f 100644 +--- a/tests/pgpolicy.c ++++ b/tests/pgpolicy.c +@@ -191,7 +191,7 @@ verify_pathgroups(struct multipath *mp, struct path *pp, int **groups, + /* Test names instead of pointers to get a more + * useful error message */ + assert_string_equal(pgp_path->dev, pp_path->dev); +- /* This test is just a backkup in case the ++ /* This test is just a backup in case the + * something wenth wrong naming the paths */ + assert_ptr_equal(pgp_path, pp_path); + } +diff --git a/tests/valid.c b/tests/valid.c +index e7393a1c..398b771e 100644 +--- a/tests/valid.c ++++ b/tests/valid.c +@@ -293,7 +293,7 @@ static void test_sysfs_is_multipathed(void **state) + + memset(&pp, 0, sizeof(pp)); + conf.find_multipaths = FIND_MULTIPATHS_STRICT; +- /* test for already existing multiapthed device */ ++ /* test for already existing multipathed device */ + will_return(__wrap_sysfs_is_multipathed, true); + will_return(__wrap_sysfs_is_multipathed, wwid); + assert_int_equal(is_path_valid(name, &conf, &pp, true), +@@ -452,7 +452,7 @@ static void test_greedy(void **state) + assert_string_equal(pp.dev, name); + assert_ptr_equal(pp.udev, &test_udev); + assert_string_equal(pp.wwid, wwid); +- /* test greedy success without checking multiapthd */ ++ /* test greedy success without checking multipathd */ + memset(&pp, 0, sizeof(pp)); + setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_IS_FAILED); + assert_int_equal(is_path_valid(name, &conf, &pp, false), +diff --git a/third-party/valgrind/valgrind.h b/third-party/valgrind/valgrind.h +index 577c8f05..1633b318 100644 +--- a/third-party/valgrind/valgrind.h ++++ b/third-party/valgrind/valgrind.h +@@ -1075,7 +1075,7 @@ typedef + + /* Use these to write the name of your wrapper. NOTE: duplicates + VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h. NOTE also: inserts +- the default behaviour equivalance class tag "0000" into the name. ++ the default behaviour equivalence class tag "0000" into the name. + See pub_tool_redir.h for details -- normally you don't need to + think about this, though. */ + +@@ -1620,11 +1620,11 @@ typedef + and say that %r15 is trashed instead. gcc seems happy to go with + that. + +- Oh .. and this all needs to be conditionalised so that it is ++ Oh .. and this all needs to be conditionalized so that it is + unchanged from before this commit, when compiled with older gccs + that don't support __builtin_dwarf_cfa. Furthermore, since + this header file is freestanding, it has to be independent of +- config.h, and so the following conditionalisation cannot depend on ++ config.h, and so the following conditionalization cannot depend on + configure time checks. + + Although it's not clear from +@@ -1673,7 +1673,7 @@ typedef + /* NB 9 Sept 07. There is a nasty kludge here in all these CALL_FN_ + macros. In order not to trash the stack redzone, we need to drop + %rsp by 128 before the hidden call, and restore afterwards. The +- nastyness is that it is only by luck that the stack still appears ++ nastiness is that it is only by luck that the stack still appears + to be unwindable during the hidden call - since then the behaviour + of any routine using this macro does not match what the CFI data + says. Sigh. diff --git a/0028-multipath-tools-remove-list-of-rebranded-arrays-vend.patch b/0028-multipath-tools-remove-list-of-rebranded-arrays-vend.patch new file mode 100644 index 0000000..f2dbfce --- /dev/null +++ b/0028-multipath-tools-remove-list-of-rebranded-arrays-vend.patch @@ -0,0 +1,57 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Thu, 21 Jul 2022 19:22:04 +0200 +Subject: [PATCH] multipath-tools: remove list of rebranded arrays vendors from + man page + +It does not provide useful info, and it is incomplete. + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + multipath/multipath.conf.5 | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 +index 853e0feb..8b7dc511 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5 +@@ -315,12 +315,12 @@ accepts the optional prio_arg \fIexclusive_pref_bit\fR. + .TP + .I ontap + (Hardware-dependent) +-Generate the path priority for NetApp ONTAP class and OEM arrays as IBM NSeries. ++Generate the path priority for NetApp ONTAP class, and rebranded arrays. + .TP + .I rdac + (Hardware-dependent) + Generate the path priority for LSI/Engenio/NetApp RDAC class as NetApp SANtricity +-E/EF Series, and OEM arrays from IBM DELL SGI STK and SUN. ++E/EF Series, and rebranded arrays. + .TP + .I hp_sw + (Hardware-dependent) +@@ -496,7 +496,7 @@ Active/Standby mode exclusively. + .I rdac + (Hardware-dependent) + Check the path state for LSI/Engenio/NetApp RDAC class as NetApp SANtricity E/EF +-Series, and OEM arrays from IBM DELL SGI STK and SUN. ++Series, and rebranded arrays. + .TP + .I directio + Read the first sector with direct I/O. This checker could cause spurious path +@@ -1568,7 +1568,7 @@ families. + .I 1 rdac + (Hardware-dependent) + Hardware handler for LSI/Engenio/NetApp RDAC class as NetApp SANtricity E/EF +-Series, and OEM arrays from IBM DELL SGI STK and SUN. ++Series, and rebranded arrays. + .TP + .I 1 hp_sw + (Hardware-dependent) diff --git a/0029-multipath-tools-correct-CLARiiON-info-from-multipath.patch b/0029-multipath-tools-correct-CLARiiON-info-from-multipath.patch new file mode 100644 index 0000000..8777ea1 --- /dev/null +++ b/0029-multipath-tools-correct-CLARiiON-info-from-multipath.patch @@ -0,0 +1,47 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Sat, 23 Jul 2022 00:01:13 +0200 +Subject: [PATCH] multipath-tools: correct CLARiiON info from multipath.conf + man page + +Remove "Unity" from emc prio and hardware_handler, because +Unity does not support PNR mode, just ALUA (page 113 and 153): +https://www.delltechnologies.com/asset/en-us/products/storage/technical-support/docu5128.pdf +And add PNR info. + +Cc: Yanfei Chen +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + multipath/multipath.conf.5 | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 +index 8b7dc511..acdd1ae6 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5 +@@ -306,7 +306,7 @@ generate the path priority. This prioritizer accepts the optional prio_arg + .I emc + (Hardware-dependent) + Generate the path priority for DGC class arrays as CLARiiON CX/AX and +-EMC VNX and Unity families. ++EMC VNX families with Failover Mode 1 (Passive Not Ready(PNR)). + .TP + .I alua + (Hardware-dependent) +@@ -1562,8 +1562,8 @@ The following hardware handler are implemented: + .TP 12 + .I 1 emc + (Hardware-dependent) +-Hardware handler for DGC class arrays as CLARiiON CX/AX and EMC VNX and Unity +-families. ++Hardware handler for DGC class arrays as CLARiiON CX/AX and EMC VNX families ++with Failover Mode 1 (Passive Not Ready(PNR)). + .TP + .I 1 rdac + (Hardware-dependent) diff --git a/0030-multipath-tools-add-basic-info-on-how-to-use-multipa.patch b/0030-multipath-tools-add-basic-info-on-how-to-use-multipa.patch new file mode 100644 index 0000000..592be10 --- /dev/null +++ b/0030-multipath-tools-add-basic-info-on-how-to-use-multipa.patch @@ -0,0 +1,41 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Sat, 23 Jul 2022 15:12:04 +0200 +Subject: [PATCH] multipath-tools: add basic info on how to use multipath-tools + with NVMe devices + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + README.md | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/README.md b/README.md +index 2322082c..b05b1332 100644 +--- a/README.md ++++ b/README.md +@@ -174,3 +174,19 @@ To enable ALUA, the following options should be changed: + + - Huawei OceanStor: + "Host Access Mode" should be changed to "Asymmetric". ++ ++ ++NVMe ++==== ++To use Device Mapper/multipath-tools with NVMe devices, ++if the Native NVMe Multipath subsystem is enabled ++( "Y" in `/sys/module/nvme_core/parameters/multipath` ), ++it has to be disabled: ++ ++`echo "options nvme_core multipath=N" > /etc/modprobe.d/01-nvme_core-mp.conf`, ++regenerate the initramfs (`dracut -f` or `update-initramfs`) and reboot. ++ ++Check that it is disabled(N) with: ++`cat /sys/module/nvme_core/parameters/multipath` ++or ++`systool -m nvme_core -A multipath` diff --git a/0031-multipathd-factor-out-the-code-to-flush-a-map-with-n.patch b/0031-multipathd-factor-out-the-code-to-flush-a-map-with-n.patch new file mode 100644 index 0000000..bb8aa05 --- /dev/null +++ b/0031-multipathd-factor-out-the-code-to-flush-a-map-with-n.patch @@ -0,0 +1,90 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 9 Aug 2022 16:46:26 -0500 +Subject: [PATCH] multipathd: factor out the code to flush a map with no paths + +The code to flush a multipath device because all of its paths have +been removed will be used by another caller, so factor it out of +ev_remove_path(). + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + multipathd/main.c | 56 ++++++++++++++++++++++++----------------------- + 1 file changed, 29 insertions(+), 27 deletions(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index defee10a..53cbdb61 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -561,6 +561,30 @@ int update_multipath (struct vectors *vecs, char *mapname, int reset) + return 0; + } + ++static bool ++flush_map_nopaths(struct multipath *mpp, struct vectors *vecs) { ++ char alias[WWID_SIZE]; ++ ++ /* ++ * flush_map will fail if the device is open ++ */ ++ strlcpy(alias, mpp->alias, WWID_SIZE); ++ if (mpp->flush_on_last_del == FLUSH_ENABLED) { ++ condlog(2, "%s Last path deleted, disabling queueing", ++ mpp->alias); ++ mpp->retry_tick = 0; ++ mpp->no_path_retry = NO_PATH_RETRY_FAIL; ++ mpp->disable_queueing = 1; ++ mpp->stat_map_failures++; ++ dm_queue_if_no_path(mpp->alias, 0); ++ } ++ if (!flush_map(mpp, vecs, 1)) { ++ condlog(2, "%s: removed map after removing all paths", alias); ++ return true; ++ } ++ return false; ++} ++ + static int + update_map (struct multipath *mpp, struct vectors *vecs, int new_map) + { +@@ -1363,34 +1387,12 @@ ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map) + vector_del_slot(mpp->paths, i); + + /* +- * remove the map IF removing the last path ++ * remove the map IF removing the last path. If ++ * flush_map_nopaths succeeds, the path has been removed. + */ +- if (VECTOR_SIZE(mpp->paths) == 0) { +- char alias[WWID_SIZE]; +- +- /* +- * flush_map will fail if the device is open +- */ +- strlcpy(alias, mpp->alias, WWID_SIZE); +- if (mpp->flush_on_last_del == FLUSH_ENABLED) { +- condlog(2, "%s Last path deleted, disabling queueing", mpp->alias); +- mpp->retry_tick = 0; +- mpp->no_path_retry = NO_PATH_RETRY_FAIL; +- mpp->disable_queueing = 1; +- mpp->stat_map_failures++; +- dm_queue_if_no_path(mpp->alias, 0); +- } +- if (!flush_map(mpp, vecs, 1)) { +- condlog(2, "%s: removed map after" +- " removing all paths", +- alias); +- /* flush_map() has freed the path */ +- goto out; +- } +- /* +- * Not an error, continue +- */ +- } ++ if (VECTOR_SIZE(mpp->paths) == 0 && ++ flush_map_nopaths(mpp, vecs)) ++ goto out; + + if (setup_map(mpp, ¶ms, vecs)) { + condlog(0, "%s: failed to setup map for" diff --git a/0032-libmultipath-return-success-if-we-raced-to-remove-a-.patch b/0032-libmultipath-return-success-if-we-raced-to-remove-a-.patch new file mode 100644 index 0000000..ab04fd9 --- /dev/null +++ b/0032-libmultipath-return-success-if-we-raced-to-remove-a-.patch @@ -0,0 +1,47 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 9 Aug 2022 16:46:27 -0500 +Subject: [PATCH] libmultipath: return success if we raced to remove a map and + lost + +_dm_flush_map() was returning failure if it failed to remove a map, +even if that was because the map had already been removed. Return +success in this case. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/devmapper.c | 4 ++++ + multipathd/main.c | 4 ---- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index 1748d258..a49db3b0 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -1111,6 +1111,10 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, + } + condlog(4, "multipath map %s removed", mapname); + return 0; ++ } else if (dm_is_mpath(mapname) != 1) { ++ condlog(4, "multipath map %s removed externally", ++ mapname); ++ return 0; /*we raced with someone else removing it */ + } else { + condlog(2, "failed to remove multipath map %s", + mapname); +diff --git a/multipathd/main.c b/multipathd/main.c +index 53cbdb61..3fcd6bdb 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -758,10 +758,6 @@ flush_map(struct multipath * mpp, struct vectors * vecs, int nopaths) + * the spurious uevent we may generate with the dm_flush_map call below + */ + if (r) { +- /* +- * May not really be an error -- if the map was already flushed +- * from the device mapper by dmsetup(8) for instance. +- */ + if (r == 1) + condlog(0, "%s: can't flush", mpp->alias); + else { diff --git a/0033-multipathd-Handle-losing-all-path-in-update_map.patch b/0033-multipathd-Handle-losing-all-path-in-update_map.patch new file mode 100644 index 0000000..43358d3 --- /dev/null +++ b/0033-multipathd-Handle-losing-all-path-in-update_map.patch @@ -0,0 +1,36 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 9 Aug 2022 16:46:28 -0500 +Subject: [PATCH] multipathd: Handle losing all path in update_map + +Its possible that when a multipath device is being updated, it will end +up that all the paths for it are gone. This can happen if paths are +added and then removed again before multipathd processes the uevent for +the newly created multipath device. In this case multipathd wasn't +taking the proper action for the case where all the paths had been +removed. If flush_on_last_del was set, multipathd wasn't disabling +flushing and if deferred_remove was set, it wasn't doing a deferred +remove. Multipathd should call flush_map_nopaths(), just like +ev_remove_path() does when the last path is removed. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + multipathd/main.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 3fcd6bdb..7d127dbe 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -602,6 +602,10 @@ retry: + goto fail; + } + verify_paths(mpp); ++ if (VECTOR_SIZE(mpp->paths) == 0 && ++ flush_map_nopaths(mpp, vecs)) ++ return 1; ++ + mpp->action = ACT_RELOAD; + + if (mpp->prflag) { diff --git a/0034-multipath-fix-systemd-timers-in-the-initramfs.patch b/0034-multipath-fix-systemd-timers-in-the-initramfs.patch new file mode 100644 index 0000000..91178ea --- /dev/null +++ b/0034-multipath-fix-systemd-timers-in-the-initramfs.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Fri, 5 Aug 2022 18:16:03 -0500 +Subject: [PATCH] multipath: fix systemd timers in the initramfs + +The systemd timers created for "find_multipaths smart" conflict with +shutdown.target, but not with initrd-cleanup.service. This can make +these timers trigger after the inirtd has started shutting down, +restarting multipathd (which then stops initrd-cleanup.service, since it +conflicts). To avoid this, make sure the timers and the unit they +trigger conflict with inird-cleanup.service. Also don't make them start +multipathd. "multipath -u" will not return "maybe" if multipathd isn't +running or set to run, and since we no longer wait for udev-settle, +multipathd starts up pretty quickly, so it shouldn't be a problem to +not trigger it here. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + multipath/multipath.rules | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/multipath/multipath.rules b/multipath/multipath.rules +index 9df11a95..f993d996 100644 +--- a/multipath/multipath.rules ++++ b/multipath/multipath.rules +@@ -71,7 +71,7 @@ ENV{.SAVED_FM_WAIT_UNTIL}=="?*", GOTO="pretend_mpath" + # + # We must trigger an "add" event because LVM2 will only act on those. + +-RUN+="/usr/bin/systemd-run --unit=cancel-multipath-wait-$kernel --description 'cancel waiting for multipath siblings of $kernel' --no-block --timer-property DefaultDependencies=no --timer-property Conflicts=shutdown.target --timer-property Before=shutdown.target --timer-property AccuracySec=500ms --property DefaultDependencies=no --property Conflicts=shutdown.target --property Before=shutdown.target --property Wants=multipathd.service --property After=multipathd.service --on-active=$env{FIND_MULTIPATHS_WAIT_UNTIL} /usr/bin/udevadm trigger --action=add $sys$devpath" ++RUN+="/usr/bin/systemd-run --unit=cancel-multipath-wait-$kernel --description 'cancel waiting for multipath siblings of $kernel' --no-block --timer-property DefaultDependencies=no --timer-property Conflicts=shutdown.target --timer-property Before=shutdown.target --timer-property Conflicts=initrd-cleanup.service --timer-property Before=initrd-cleanup.service --timer-property AccuracySec=500ms --property DefaultDependencies=no --property Conflicts=shutdown.target --property Before=shutdown.target --property Conflicts=initrd-cleanup.service --property Before=initrd-cleanup.service --on-active=$env{FIND_MULTIPATHS_WAIT_UNTIL} /usr/bin/udevadm trigger --action=add $sys$devpath" + + LABEL="pretend_mpath" + ENV{DM_MULTIPATH_DEVICE_PATH}="1" diff --git a/0035-multipathd-Add-missing-ctype-include.patch b/0035-multipathd-Add-missing-ctype-include.patch new file mode 100644 index 0000000..29ea453 --- /dev/null +++ b/0035-multipathd-Add-missing-ctype-include.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Bastian Germann +Date: Thu, 14 Oct 2021 00:34:33 +0200 +Subject: [PATCH] multipathd: Add missing ctype include + +In uxclnt.c, there are isspace calls. Add an explicit include. + +Signed-off-by: Bastian Germann +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + multipathd/uxclnt.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/multipathd/uxclnt.c b/multipathd/uxclnt.c +index b1b058bd..bdcc7c3f 100644 +--- a/multipathd/uxclnt.c ++++ b/multipathd/uxclnt.c +@@ -8,6 +8,7 @@ + #include + #include + #include ++#include + #include + #include + #include diff --git a/0036-multipathd-replace-libreadline-with-libedit.patch b/0036-multipathd-replace-libreadline-with-libedit.patch new file mode 100644 index 0000000..f376ee7 --- /dev/null +++ b/0036-multipathd-replace-libreadline-with-libedit.patch @@ -0,0 +1,102 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 12 Aug 2022 18:58:15 +0200 +Subject: [PATCH] multipathd: replace libreadline with libedit + +Linking multipathd with libreadline may cause a license conflict, +because libreadline is licensed under GPL-3.0-or-later, and +libmultipath contains several files under GPL-2.0. + +See: + https://github.com/opensvc/multipath-tools/issues/36 + https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=979095 + https://www.gnu.org/licenses/gpl-faq.html#AllCompatibility + +Replace the readline functionality with libedit, which comes under +a BSD license. The readline library can still be enabled (e.g. for +binaries not intended to be distributed) by running +"make READLINE=libreadline". + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 5 +++++ + multipathd/Makefile | 11 ++++++++++- + multipathd/cli.c | 5 +++++ + multipathd/uxclnt.c | 6 ++++++ + 4 files changed, 26 insertions(+), 1 deletion(-) + +diff --git a/Makefile.inc b/Makefile.inc +index bcd2212a..ad7afd04 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -8,6 +8,11 @@ + # + # Uncomment to disable dmevents polling support + # ENABLE_DMEVENTS_POLL = 0 ++# ++# Readline library to use, libedit or libreadline ++# Caution: Using libreadline may make the multipathd binary undistributable, ++# see https://github.com/opensvc/multipath-tools/issues/36 ++READLINE = libedit + + # List of scsi device handler modules to load on boot, e.g. + # SCSI_DH_MODULES_PRELOAD := scsi_dh_alua scsi_dh_rdac +diff --git a/multipathd/Makefile b/multipathd/Makefile +index c937cd55..95acd887 100644 +--- a/multipathd/Makefile ++++ b/multipathd/Makefile +@@ -22,7 +22,16 @@ CFLAGS += $(BIN_CFLAGS) + LDFLAGS += $(BIN_LDFLAGS) + LIBDEPS += -L$(multipathdir) -lmultipath -L$(mpathpersistdir) -lmpathpersist \ + -L$(mpathcmddir) -lmpathcmd -ludev -ldl -lurcu -lpthread \ +- -ldevmapper -lreadline ++ -ldevmapper ++ ++ifeq ($(READLINE),libedit) ++CPPFLAGS += -DUSE_LIBEDIT ++LIBDEPS += -ledit ++endif ++ifeq ($(READLINE),libreadline) ++CPPFLAGS += -DUSE_LIBREADLINE ++LIBDEPS += -lreadline ++endif + + ifdef SYSTEMD + CPPFLAGS += -DUSE_SYSTEMD=$(SYSTEMD) +diff --git a/multipathd/cli.c b/multipathd/cli.c +index b2ee9a99..fa482a67 100644 +--- a/multipathd/cli.c ++++ b/multipathd/cli.c +@@ -11,7 +11,12 @@ + #include "parser.h" + #include "util.h" + #include "version.h" ++#ifdef USE_LIBEDIT ++#include ++#endif ++#ifdef USE_LIBREADLINE + #include ++#endif + + #include "mpath_cmd.h" + #include "cli.h" +diff --git a/multipathd/uxclnt.c b/multipathd/uxclnt.c +index bdcc7c3f..251e7d75 100644 +--- a/multipathd/uxclnt.c ++++ b/multipathd/uxclnt.c +@@ -16,8 +16,14 @@ + #include + #include + #include ++ ++#ifdef USE_LIBEDIT ++#include ++#endif ++#ifdef USE_LIBREADLINE + #include + #include ++#endif + + #include "mpath_cmd.h" + #include "uxsock.h" diff --git a/0037-libmultipath-convert-license-of-strbuf-code-to-GPL-2.patch b/0037-libmultipath-convert-license-of-strbuf-code-to-GPL-2.patch new file mode 100644 index 0000000..f8085e8 --- /dev/null +++ b/0037-libmultipath-convert-license-of-strbuf-code-to-GPL-2.patch @@ -0,0 +1,42 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 12 Aug 2022 21:25:37 +0200 +Subject: [PATCH] libmultipath: convert license of strbuf code to GPL-2.0+ + +This (partly) fixes the license incompatibility reported in +https://github.com/opensvc/multipath-tools/issues/36 + +As I'm the only author (except for a trivial spelling fix), +I see no issue with changing the license. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/strbuf.c | 2 +- + libmultipath/strbuf.h | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/strbuf.c b/libmultipath/strbuf.c +index f654594d..e23b65e8 100644 +--- a/libmultipath/strbuf.c ++++ b/libmultipath/strbuf.c +@@ -1,6 +1,6 @@ + /* + * Copyright (c) 2021 SUSE LLC +- * SPDX-License-Identifier: GPL-2.0-only ++ * SPDX-License-Identifier: GPL-2.0-or-later + */ + #include + #include +diff --git a/libmultipath/strbuf.h b/libmultipath/strbuf.h +index 31ab519a..ae863417 100644 +--- a/libmultipath/strbuf.h ++++ b/libmultipath/strbuf.h +@@ -1,6 +1,6 @@ + /* + * Copyright (c) 2021 SUSE LLC +- * SPDX-License-Identifier: GPL-2.0-only ++ * SPDX-License-Identifier: GPL-2.0-or-later + */ + #ifndef _STRBUF_H + #define _STRBUF_H diff --git a/0038-github-workflows-build-and-unittest.yaml-add-libedit.patch b/0038-github-workflows-build-and-unittest.yaml-add-libedit.patch new file mode 100644 index 0000000..375940f --- /dev/null +++ b/0038-github-workflows-build-and-unittest.yaml-add-libedit.patch @@ -0,0 +1,44 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 16 Aug 2022 14:10:39 +0200 +Subject: [PATCH] github workflows: build-and-unittest.yaml: add libedit-dev + +This is is required after switching from libreadline to libedit. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/build-and-unittest.yaml | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/.github/workflows/build-and-unittest.yaml b/.github/workflows/build-and-unittest.yaml +index 7ff45842..1ab0d36c 100644 +--- a/.github/workflows/build-and-unittest.yaml ++++ b/.github/workflows/build-and-unittest.yaml +@@ -27,7 +27,7 @@ jobs: + sudo apt-get install --yes gcc + make perl-base pkg-config valgrind + libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev +- libudev-dev libjson-c-dev liburcu-dev libcmocka-dev ++ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev + - name: build + run: make -O -j$(grep -c ^processor /proc/cpuinfo) + - name: test +@@ -55,7 +55,7 @@ jobs: + sudo apt-get install --yes gcc-10 + make perl-base pkg-config valgrind + libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev +- libudev-dev libjson-c-dev liburcu-dev libcmocka-dev ++ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev + - name: set CC + run: echo CC=gcc-10 >> $GITHUB_ENV + - name: build +@@ -85,7 +85,7 @@ jobs: + sudo apt-get install --yes clang + make perl-base pkg-config valgrind + libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev +- libudev-dev libjson-c-dev liburcu-dev libcmocka-dev ++ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev + - name: set CC + run: echo CC=clang >> $GITHUB_ENV + - name: build diff --git a/0039-github-workflows-coverity.yaml-add-libedit-dev.patch b/0039-github-workflows-coverity.yaml-add-libedit-dev.patch new file mode 100644 index 0000000..63ef9dc --- /dev/null +++ b/0039-github-workflows-coverity.yaml-add-libedit-dev.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 16 Aug 2022 14:10:39 +0200 +Subject: [PATCH] github workflows: coverity.yaml: add libedit-dev + +This is is required after switching from libreadline to libedit. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/coverity.yaml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/.github/workflows/coverity.yaml b/.github/workflows/coverity.yaml +index a8b56d43..3c6b3824 100644 +--- a/.github/workflows/coverity.yaml ++++ b/.github/workflows/coverity.yaml +@@ -15,7 +15,7 @@ jobs: + sudo apt-get install --yes + gcc make pkg-config + libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev +- libudev-dev libjson-c-dev liburcu-dev libcmocka-dev ++ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev + - name: download coverity + run: > + curl -o cov-analysis-linux64.tar.gz diff --git a/0040-github-workflows-abi.yaml-add-libedit-dev.patch b/0040-github-workflows-abi.yaml-add-libedit-dev.patch new file mode 100644 index 0000000..93e2331 --- /dev/null +++ b/0040-github-workflows-abi.yaml-add-libedit-dev.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 16 Aug 2022 14:10:39 +0200 +Subject: [PATCH] github workflows: abi.yaml: add libedit-dev + +This is is required after switching from libreadline to libedit. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/abi.yaml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/.github/workflows/abi.yaml b/.github/workflows/abi.yaml +index 0a40104a..89b971cd 100644 +--- a/.github/workflows/abi.yaml ++++ b/.github/workflows/abi.yaml +@@ -30,7 +30,7 @@ jobs: + sudo apt-get install --yes gcc + gcc make pkg-config abigail-tools + libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev +- libudev-dev libjson-c-dev liburcu-dev libcmocka-dev ++ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev + - name: create ABI + run: make -O -j$(grep -c ^processor /proc/cpuinfo) abi.tar.gz + - name: save ABI diff --git a/0041-GitHub-workflows-native.yaml-add-libedit-dev-except-.patch b/0041-GitHub-workflows-native.yaml-add-libedit-dev-except-.patch new file mode 100644 index 0000000..7fc05a6 --- /dev/null +++ b/0041-GitHub-workflows-native.yaml-add-libedit-dev-except-.patch @@ -0,0 +1,71 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 16 Aug 2022 16:52:07 +0200 +Subject: [PATCH] GitHub workflows: native.yaml: add libedit-dev, except for + jessie + +This is is required after switching from libreadline to libedit. + +On jessie, we can use libreadline5 (libreadline-gpl2-dev) without +license issues. Trying to compile against libedit results in an +"incompatible pointer type" error on jessie, because libedit +uses a different prototype for rl_completion_entry_function. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/native.yaml | 15 ++++++++++++++- + 1 file changed, 14 insertions(+), 1 deletion(-) + +diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml +index ddfd4a09..8b599209 100644 +--- a/.github/workflows/native.yaml ++++ b/.github/workflows/native.yaml +@@ -22,13 +22,24 @@ jobs: + - name: checkout + uses: actions/checkout@v1 + - name: build and test ++ if: ${{ matrix.os != 'jessie' }} + run: make test ++ - name: build and test (jessie) ++ # On jessie, we use libreadline 5 (no licensing issue) ++ if: ${{ matrix.os == 'jessie' }} ++ run: make READLINE=libreadline test + - name: clean + run: make clean + - name: clang ++ if: ${{ matrix.os != 'jessie' }} + env: + CC: clang + run: make test ++ - name: clang (jessie) ++ if: ${{ matrix.os == 'jessie' }} ++ env: ++ CC: clang ++ run: make READLINE=libreadline test + + rolling: + runs-on: ubuntu-20.04 +@@ -56,12 +67,13 @@ jobs: + libjson-c-dev + liburcu-dev + libcmocka-dev ++ libedit-dev + - name: dependencies-alpine + if: ${{ matrix.os == 'alpine' }} + run: > + apk add make gcc clang cmocka + musl-dev lvm2-dev libaio-dev readline-dev ncurses-dev eudev-dev +- userspace-rcu-dev json-c-dev cmocka-dev ++ userspace-rcu-dev json-c-dev cmocka-dev libedit-dev + - name: dependencies-fedora + if: ${{ matrix.os == 'fedora:rawhide' }} + run: > +@@ -76,6 +88,7 @@ jobs: + userspace-rcu-devel + json-c-devel + libcmocka-devel ++ libedit-devel + - name: checkout + uses: actions/checkout@v1 + - name: build and test diff --git a/0042-GitHub-workflows-foreign.yaml-switch-to-Debian-11-bu.patch b/0042-GitHub-workflows-foreign.yaml-switch-to-Debian-11-bu.patch new file mode 100644 index 0000000..3af19df --- /dev/null +++ b/0042-GitHub-workflows-foreign.yaml-switch-to-Debian-11-bu.patch @@ -0,0 +1,40 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 16 Aug 2022 23:38:18 +0200 +Subject: [PATCH] GitHub workflows: foreign.yaml: switch to Debian 11 + (bullseye) + +Building the containers in the build-multipath project recently +started failing for buster/s390x and buster/ppc64el. That failure +had nothing to do with the switch to libedit. + +It's about time to switch to bullseye anyway. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/foreign.yaml | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/.github/workflows/foreign.yaml b/.github/workflows/foreign.yaml +index 32915186..f6e69709 100644 +--- a/.github/workflows/foreign.yaml ++++ b/.github/workflows/foreign.yaml +@@ -13,7 +13,7 @@ jobs: + runs-on: ubuntu-20.04 + strategy: + matrix: +- os: [buster] ++ os: [bullseye] + arch: ['ppc64le', 'aarch64', 's390x'] + container: mwilck/multipath-build-${{ matrix.os }}-${{ matrix.arch }} + steps: +@@ -44,7 +44,7 @@ jobs: + needs: build + strategy: + matrix: +- os: [buster] ++ os: [bullseye] + arch: ['ppc64le', 'aarch64', 's390x'] + steps: + - name: get binaries diff --git a/0007-RH-fixup-udev-rules-for-redhat.patch b/0043-RH-fixup-udev-rules-for-redhat.patch similarity index 97% rename from 0007-RH-fixup-udev-rules-for-redhat.patch rename to 0043-RH-fixup-udev-rules-for-redhat.patch index f24e8db..47a1ab2 100644 --- a/0007-RH-fixup-udev-rules-for-redhat.patch +++ b/0043-RH-fixup-udev-rules-for-redhat.patch @@ -15,10 +15,10 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index bcd2212a..40cfbd0c 100644 +index ad7afd04..03450610 100644 --- a/Makefile.inc +++ b/Makefile.inc -@@ -76,7 +76,7 @@ endif +@@ -81,7 +81,7 @@ endif prefix = exec_prefix = $(prefix) usr_prefix = $(prefix) diff --git a/0008-RH-Remove-the-property-blacklist-exception-builtin.patch b/0044-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 99% rename from 0008-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0044-RH-Remove-the-property-blacklist-exception-builtin.patch index 3bf0684..ded9aab 100644 --- a/0008-RH-Remove-the-property-blacklist-exception-builtin.patch +++ b/0044-RH-Remove-the-property-blacklist-exception-builtin.patch @@ -43,7 +43,7 @@ index 8d15d2ea..eff690fd 100644 udev_device_get_properties_list_entry(udev)) { diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index c2d34f18..18a55b70 100644 +index acdd1ae6..5ab770ba 100644 --- a/multipath/multipath.conf.5 +++ b/multipath/multipath.conf.5 @@ -1348,9 +1348,14 @@ keywords. Both are regular expressions. For a full description of these keywords diff --git a/0009-RH-don-t-start-without-a-config-file.patch b/0045-RH-don-t-start-without-a-config-file.patch similarity index 98% rename from 0009-RH-don-t-start-without-a-config-file.patch rename to 0045-RH-don-t-start-without-a-config-file.patch index 77f2958..dda921b 100644 --- a/0009-RH-don-t-start-without-a-config-file.patch +++ b/0045-RH-don-t-start-without-a-config-file.patch @@ -45,7 +45,7 @@ index ab8b26e7..f06fcbf9 100644 conf->processed_main_config = 1; diff --git a/libmultipath/config.h b/libmultipath/config.h -index 36d40157..115b463b 100644 +index fdcdff0a..affba937 100644 --- a/libmultipath/config.h +++ b/libmultipath/config.h @@ -9,6 +9,7 @@ @@ -57,7 +57,7 @@ index 36d40157..115b463b 100644 enum devtypes { DEV_NONE, diff --git a/multipath/multipath.rules b/multipath/multipath.rules -index 9df11a95..0486bf70 100644 +index f993d996..68c30644 100644 --- a/multipath/multipath.rules +++ b/multipath/multipath.rules @@ -9,6 +9,7 @@ IMPORT{cmdline}="nompath" diff --git a/0010-RH-Fix-nvme-function-missing-argument.patch b/0046-RH-Fix-nvme-function-missing-argument.patch similarity index 100% rename from 0010-RH-Fix-nvme-function-missing-argument.patch rename to 0046-RH-Fix-nvme-function-missing-argument.patch diff --git a/0011-RH-use-rpm-optflags-if-present.patch b/0047-RH-use-rpm-optflags-if-present.patch similarity index 96% rename from 0011-RH-use-rpm-optflags-if-present.patch rename to 0047-RH-use-rpm-optflags-if-present.patch index 5b0ed18..bd3b6e1 100644 --- a/0011-RH-use-rpm-optflags-if-present.patch +++ b/0047-RH-use-rpm-optflags-if-present.patch @@ -13,10 +13,10 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 40cfbd0c..307b6b4d 100644 +index 03450610..2cf6e85f 100644 --- a/Makefile.inc +++ b/Makefile.inc -@@ -136,18 +136,30 @@ ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers +@@ -141,18 +141,30 @@ ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered -Wno-error=clobbered,) WFORMATOVERFLOW := $(call TEST_CC_OPTION,-Wformat-overflow=2,) diff --git a/0012-RH-add-mpathconf.patch b/0048-RH-add-mpathconf.patch similarity index 100% rename from 0012-RH-add-mpathconf.patch rename to 0048-RH-add-mpathconf.patch diff --git a/0013-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0049-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 100% rename from 0013-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0049-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch diff --git a/0014-RH-reset-default-find_mutipaths-value-to-off.patch b/0050-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 100% rename from 0014-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0050-RH-reset-default-find_mutipaths-value-to-off.patch diff --git a/0015-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0051-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 100% rename from 0015-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0051-RH-attempt-to-get-ANA-info-via-sysfs-first.patch diff --git a/0016-RH-make-parse_vpd_pg83-match-scsi_id-output.patch b/0052-RH-make-parse_vpd_pg83-match-scsi_id-output.patch similarity index 94% rename from 0016-RH-make-parse_vpd_pg83-match-scsi_id-output.patch rename to 0052-RH-make-parse_vpd_pg83-match-scsi_id-output.patch index 619ce7d..604ff75 100644 --- a/0016-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +++ b/0052-RH-make-parse_vpd_pg83-match-scsi_id-output.patch @@ -14,10 +14,10 @@ Signed-off-by: Benjamin Marzinski 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 0d8a558c..0c73b754 100644 +index 15560f8c..2339c9a9 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c -@@ -1177,13 +1177,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, +@@ -1175,13 +1175,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, good_len = 8; break; case 2: @@ -33,7 +33,7 @@ index 0d8a558c..0c73b754 100644 good_len = 8; break; default: -@@ -1201,10 +1197,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, +@@ -1199,10 +1195,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, break; case 0x8: /* SCSI Name: Prio 3 */ diff --git a/0017-RH-add-scsi-device-handlers-to-modules-load.d.patch b/0053-RH-add-scsi-device-handlers-to-modules-load.d.patch similarity index 92% rename from 0017-RH-add-scsi-device-handlers-to-modules-load.d.patch rename to 0053-RH-add-scsi-device-handlers-to-modules-load.d.patch index d86e03b..423f107 100644 --- a/0017-RH-add-scsi-device-handlers-to-modules-load.d.patch +++ b/0053-RH-add-scsi-device-handlers-to-modules-load.d.patch @@ -11,10 +11,10 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc -index 307b6b4d..8f64c700 100644 +index 2cf6e85f..7277cf5f 100644 --- a/Makefile.inc +++ b/Makefile.inc -@@ -11,7 +11,7 @@ +@@ -16,7 +16,7 @@ READLINE = libedit # List of scsi device handler modules to load on boot, e.g. # SCSI_DH_MODULES_PRELOAD := scsi_dh_alua scsi_dh_rdac diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 84d0472..f140e00 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.9.0 -Release: 2%{?dist} +Release: 3%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -14,25 +14,62 @@ Patch0001: 0001-github-workflows-switch-to-fedora-36.patch Patch0002: 0002-multipath-tools-fix-multipath-ll-bug-for-Native-NVME.patch Patch0003: 0003-multipath-tools-update-Huawei-OceanStor-NVMe-vendor-.patch Patch0004: 0004-multipath-tools-update-Generic-NVMe-vendor-regex-in-.patch -Patch0005: 0005-libmultipath-unset-detect_checker-for-clariion-Unity.patch -Patch0006: 0006-libmultipath-fix-find_multipaths_timeout-for-unknown.patch -Patch0007: 0007-RH-fixup-udev-rules-for-redhat.patch -Patch0008: 0008-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0009: 0009-RH-don-t-start-without-a-config-file.patch -Patch0010: 0010-RH-Fix-nvme-function-missing-argument.patch -Patch0011: 0011-RH-use-rpm-optflags-if-present.patch -Patch0012: 0012-RH-add-mpathconf.patch -Patch0013: 0013-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0014: 0014-RH-reset-default-find_mutipaths-value-to-off.patch -Patch0015: 0015-RH-attempt-to-get-ANA-info-via-sysfs-first.patch -Patch0016: 0016-RH-make-parse_vpd_pg83-match-scsi_id-output.patch -Patch0017: 0017-RH-add-scsi-device-handlers-to-modules-load.d.patch +Patch0005: 0005-libmultipath-fix-find_multipaths_timeout-for-unknown.patch +Patch0006: 0006-multipath-tools-update-devel-repo-info-in-README.md.patch +Patch0007: 0007-multipath-tools-delete-README.alua.patch +Patch0008: 0008-multipath-tools-add-ALUA-info-to-README.md.patch +Patch0009: 0009-libmultipath-alua-remove-get_sysfs_pg83.patch +Patch0010: 0010-libmultipath-remove-sysfs_get_binary.patch +Patch0011: 0011-libmultipath-sysfs_bin_attr_get_value-no-error-if-bu.patch +Patch0012: 0012-libmultipath-common-code-path-for-sysfs_attr_get_val.patch +Patch0013: 0013-libmultipath-sanitize-error-checking-in-sysfs-access.patch +Patch0014: 0014-libmultipath-get-rid-of-PATH_SIZE.patch +Patch0015: 0015-libmultipath-sysfs_attr_get_value-don-t-return-0-if-.patch +Patch0016: 0016-libmultipath-sysfs_attr_set_value-don-t-return-0-on-.patch +Patch0017: 0017-libmultipath-sysfs-cleanup-file-descriptors-on-pthre.patch +Patch0018: 0018-libmultipath-multipathd-log-failure-setting-sysfs-at.patch +Patch0019: 0019-multipath-tests-expect_condlog-skip-depending-on-ver.patch +Patch0020: 0020-multipath-tests-__wrap_dlog-print-log-message.patch +Patch0021: 0021-multipath-tests-add-sysfs-test.patch +Patch0022: 0022-libmultipath.version-bump-version-for-sysfs-accessor.patch +Patch0023: 0023-libmultipath-unset-detect_checker-for-clariion-Unity.patch +Patch0024: 0024-libmultipath-spelling-cplusplus.patch +Patch0025: 0025-libmultipath-spelling-ascii.patch +Patch0026: 0026-libmultipath-spelling-progress.patch +Patch0027: 0027-multipath-tools-spelling-fixes.patch +Patch0028: 0028-multipath-tools-remove-list-of-rebranded-arrays-vend.patch +Patch0029: 0029-multipath-tools-correct-CLARiiON-info-from-multipath.patch +Patch0030: 0030-multipath-tools-add-basic-info-on-how-to-use-multipa.patch +Patch0031: 0031-multipathd-factor-out-the-code-to-flush-a-map-with-n.patch +Patch0032: 0032-libmultipath-return-success-if-we-raced-to-remove-a-.patch +Patch0033: 0033-multipathd-Handle-losing-all-path-in-update_map.patch +Patch0034: 0034-multipath-fix-systemd-timers-in-the-initramfs.patch +Patch0035: 0035-multipathd-Add-missing-ctype-include.patch +Patch0036: 0036-multipathd-replace-libreadline-with-libedit.patch +Patch0037: 0037-libmultipath-convert-license-of-strbuf-code-to-GPL-2.patch +Patch0038: 0038-github-workflows-build-and-unittest.yaml-add-libedit.patch +Patch0039: 0039-github-workflows-coverity.yaml-add-libedit-dev.patch +Patch0040: 0040-github-workflows-abi.yaml-add-libedit-dev.patch +Patch0041: 0041-GitHub-workflows-native.yaml-add-libedit-dev-except-.patch +Patch0042: 0042-GitHub-workflows-foreign.yaml-switch-to-Debian-11-bu.patch +Patch0043: 0043-RH-fixup-udev-rules-for-redhat.patch +Patch0044: 0044-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0045: 0045-RH-don-t-start-without-a-config-file.patch +Patch0046: 0046-RH-Fix-nvme-function-missing-argument.patch +Patch0047: 0047-RH-use-rpm-optflags-if-present.patch +Patch0048: 0048-RH-add-mpathconf.patch +Patch0049: 0049-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0050: 0050-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0051: 0051-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0052: 0052-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +Patch0053: 0053-RH-add-scsi-device-handlers-to-modules-load.d.patch # runtime Requires: %{name}-libs = %{version}-%{release} Requires: kpartx = %{version}-%{release} Requires: device-mapper >= 1.02.96 Requires: userspace-rcu +Requires: libedit Requires(post): systemd-units Requires(preun): systemd-units Requires(postun): systemd-units @@ -50,7 +87,7 @@ Conflicts: udisks2 < 2.8.0-2 # build/setup BuildRequires: libaio-devel, device-mapper-devel >= 1.02.89 BuildRequires: libselinux-devel, libsepol-devel -BuildRequires: readline-devel, ncurses-devel +BuildRequires: libedit-devel, ncurses-devel BuildRequires: systemd-units, systemd-devel BuildRequires: json-c-devel, perl-interpreter, pkgconfig, gcc BuildRequires: userspace-rcu-devel @@ -172,7 +209,6 @@ fi /usr/lib/modules-load.d/multipath.conf /usr/lib/modules-load.d/scsi_dh.conf %doc README.md -%doc README.alua %doc multipath.conf %dir /etc/multipath @@ -227,6 +263,18 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Fri Aug 19 2022 Benjamin Marzinski - 0.9.0-3 +- Update to the head of the upstream staging branch + * Patches 0005-0042 are from the upstream staging branch + * Previous patches 0005 & 0006 are now patches 0023 & 0005 +- Rename redhat patches + * Previous patches 0007-0017 are now patches 0043-0053 +- Change from using readline to libedit + * readline is licensed GPL v3, and multipathd includes code + licensed gpl v2. +- Remove README.alua + * information moved to README.md + * Thu Jul 21 2022 Fedora Release Engineering - 0.9.0-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild From c5432960d94c62defc79cbd94a361c469bfb75a1 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Wed, 16 Nov 2022 14:11:59 -0600 Subject: [PATCH 35/67] device-mapper-multipath-0.9.3-1 Update to the head of the upstream staging branch * Previous patches 0001-0042 are included in the source tarball * Patches 0001-0032 are from the upstream staging branch Rename redhat patches * Previous patches 0043-0053 are now patches 0033-0043 Change back to using readline instead of libedit * The code the uses readline has been isolated from the code that is licensed gpl v2 only. Add libmpathutil libraries to spec file Add multipathc program to spec file Add multipath.conf systemd tempfile configuration to spec file Misc spec file cleanups --- .gitignore | 1 + ...github-workflows-switch-to-fedora-36.patch | 29 - ...tipath-fix-show-paths-format-failure.patch | 35 + ...kefile.inc-fix-man-and-include-paths.patch | 41 + ...fix-multipath-ll-bug-for-Native-NVME.patch | 103 -- ...s-Makefile.inc-Fix-paths-for-systemd.patch | 65 ++ ...update-Huawei-OceanStor-NVMe-vendor-.patch | 40 - ...Makefile.inc-don-t-take-values-from-.patch | 113 +++ ...update-Generic-NVMe-vendor-regex-in-.patch | 33 - ...-find_multipaths_timeout-for-unknown.patch | 29 - ...th-tools-Makefile.inc-get-rid-of-RUN.patch | 63 ++ ...Makefile.inc-more-compact-code-for-L.patch | 38 + ...-update-devel-repo-info-in-README.md.patch | 52 -- ...Makefiles-simplify-code-for-include-.patch | 139 +++ 0007-multipath-tools-delete-README.alua.patch | 48 - ...multipath-tools-Makefiles-use-mandir.patch | 185 ++++ ...ath-tools-add-ALUA-info-to-README.md.patch | 53 -- ...multipath-alua-remove-get_sysfs_pg83.patch | 95 -- ...Makefile.inc-simplify-expression-for.patch | 36 + ...libmultipath-remove-sysfs_get_binary.patch | 77 -- ...Makefile.inc-untangle-paths-and-sour.patch | 68 ++ ...fs_bin_attr_get_value-no-error-if-bu.patch | 65 -- ...Makefiles-replace-libdir-by-plugindi.patch | 110 +++ ...mon-code-path-for-sysfs_attr_get_val.patch | 115 --- ...Makefile.inc-use-simple-make-variabl.patch | 112 +++ ...itize-error-checking-in-sysfs-access.patch | 165 ---- ...tools-Makefile.inc-fix-a-log-message.patch | 24 + 0014-libmultipath-get-rid-of-PATH_SIZE.patch | 115 --- ...Makefile.inc-set-systemd-specific-fl.patch | 129 +++ ...fs_attr_get_value-don-t-return-0-if-.patch | 172 ---- ...ile-fix-compilation-flags-for-libedi.patch | 54 ++ ...fs_attr_set_value-don-t-return-0-on-.patch | 251 ----- ...Makefiles-clean-up-executable-Makefi.patch | 136 +++ ...fs-cleanup-file-descriptors-on-pthre.patch | 71 -- ...Makefiles-use-common-code-for-librar.patch | 261 ++++++ ...tipathd-log-failure-setting-sysfs-at.patch | 168 ---- ...Makefiles-move-common-code-to-rules..patch | 172 ++++ ...expect_condlog-skip-depending-on-ver.patch | 37 - ...ath-tools-Makefiles-create-config.mk.patch | 603 ++++++++++++ ...-tests-__wrap_dlog-print-log-message.patch | 27 - ...h-tools-Makefiles-enable-quiet-build.patch | 879 ++++++++++++++++++ 0021-multipath-tests-add-sysfs-test.patch | 538 ----------- ...quiet-build-support-for-top-level-Ma.patch | 183 ++++ ...itHub-workflows-use-make-j8-Orecurse.patch | 132 +++ ...sion-bump-version-for-sysfs-accessor.patch | 43 - ...ection-about-libedit-and-libreadline.patch | 48 + ...et-detect_checker-for-clariion-Unity.patch | 31 - ...dentation-in-paragraph-about-device-.patch | 34 + 0024-libmultipath-spelling-cplusplus.patch | 26 - ...nt-options-for-paths-and-optimizatio.patch | 47 + 0025-libmultipath-spelling-ascii.patch | 25 - ...E.md-document-how-to-customize-build.patch | 37 + 0026-libmultipath-spelling-progress.patch | 25 - ...id-Warray-bounds-error-with-gcc-12-a.patch | 63 ++ 0027-multipath-tools-spelling-fixes.patch | 599 ------------ ...d-NULL-string-in-released_to_systemd.patch | 26 + ...remove-list-of-rebranded-arrays-vend.patch | 57 -- ...h-avoid-NULL-string-in-is_udev_ready.patch | 26 + ...correct-CLARiiON-info-from-multipath.patch | 47 - ...th-impove-add_feature-variable-names.patch | 115 +++ ...add-basic-info-on-how-to-use-multipa.patch | 41 - ...-initialize-the-field-width-in-show_.patch | 31 + ...r-out-the-code-to-flush-a-map-with-n.patch | 90 -- ...mprove-remove_feature-variable-names.patch | 144 +++ ...urn-success-if-we-raced-to-remove-a-.patch | 47 - 0033-RH-fixup-udev-rules-for-redhat.patch | 66 ++ ...Handle-losing-all-path-in-update_map.patch | 36 - ...property-blacklist-exception-builtin.patch | 6 +- ...-fix-systemd-timers-in-the-initramfs.patch | 35 - ...RH-don-t-start-without-a-config-file.patch | 28 +- ...multipathd-Add-missing-ctype-include.patch | 26 - ...H-Fix-nvme-function-missing-argument.patch | 0 ...thd-replace-libreadline-with-libedit.patch | 102 -- ... 0037-RH-use-rpm-optflags-if-present.patch | 29 +- ...vert-license-of-strbuf-code-to-GPL-2.patch | 42 - ...hconf.patch => 0038-RH-add-mpathconf.patch | 55 +- ...-build-and-unittest.yaml-add-libedit.patch | 44 - ...om-kernel-cmdline-mpath.wwids-with-A.patch | 10 +- ...kflows-coverity.yaml-add-libedit-dev.patch | 26 - ...-default-find_mutipaths-value-to-off.patch | 2 +- ...b-workflows-abi.yaml-add-libedit-dev.patch | 26 - ...-native.yaml-add-libedit-dev-except-.patch | 71 -- ...empt-to-get-ANA-info-via-sysfs-first.patch | 0 ...-foreign.yaml-switch-to-Debian-11-bu.patch | 40 - ...-parse_vpd_pg83-match-scsi_id-output.patch | 6 +- ...si-device-handlers-to-modules-load.d.patch | 4 +- 0043-RH-fixup-udev-rules-for-redhat.patch | 63 -- ...-RH-compile-with-libreadline-support.patch | 26 + device-mapper-multipath.spec | 159 ++-- sources | 2 +- 90 files changed, 4400 insertions(+), 3968 deletions(-) delete mode 100644 0001-github-workflows-switch-to-fedora-36.patch create mode 100644 0001-libmultipath-fix-show-paths-format-failure.patch create mode 100644 0002-fixup-Makefile.inc-fix-man-and-include-paths.patch delete mode 100644 0002-multipath-tools-fix-multipath-ll-bug-for-Native-NVME.patch create mode 100644 0003-multipath-tools-Makefile.inc-Fix-paths-for-systemd.patch delete mode 100644 0003-multipath-tools-update-Huawei-OceanStor-NVMe-vendor-.patch create mode 100644 0004-multipath-tools-Makefile.inc-don-t-take-values-from-.patch delete mode 100644 0004-multipath-tools-update-Generic-NVMe-vendor-regex-in-.patch delete mode 100644 0005-libmultipath-fix-find_multipaths_timeout-for-unknown.patch create mode 100644 0005-multipath-tools-Makefile.inc-get-rid-of-RUN.patch create mode 100644 0006-multipath-tools-Makefile.inc-more-compact-code-for-L.patch delete mode 100644 0006-multipath-tools-update-devel-repo-info-in-README.md.patch create mode 100644 0007-multipath-tools-Makefiles-simplify-code-for-include-.patch delete mode 100644 0007-multipath-tools-delete-README.alua.patch create mode 100644 0008-multipath-tools-Makefiles-use-mandir.patch delete mode 100644 0008-multipath-tools-add-ALUA-info-to-README.md.patch delete mode 100644 0009-libmultipath-alua-remove-get_sysfs_pg83.patch create mode 100644 0009-multipath-tools-Makefile.inc-simplify-expression-for.patch delete mode 100644 0010-libmultipath-remove-sysfs_get_binary.patch create mode 100644 0010-multipath-tools-Makefile.inc-untangle-paths-and-sour.patch delete mode 100644 0011-libmultipath-sysfs_bin_attr_get_value-no-error-if-bu.patch create mode 100644 0011-multipath-tools-Makefiles-replace-libdir-by-plugindi.patch delete mode 100644 0012-libmultipath-common-code-path-for-sysfs_attr_get_val.patch create mode 100644 0012-multipath-tools-Makefile.inc-use-simple-make-variabl.patch delete mode 100644 0013-libmultipath-sanitize-error-checking-in-sysfs-access.patch create mode 100644 0013-multipath-tools-Makefile.inc-fix-a-log-message.patch delete mode 100644 0014-libmultipath-get-rid-of-PATH_SIZE.patch create mode 100644 0014-multipath-tools-Makefile.inc-set-systemd-specific-fl.patch delete mode 100644 0015-libmultipath-sysfs_attr_get_value-don-t-return-0-if-.patch create mode 100644 0015-multipathd-Makefile-fix-compilation-flags-for-libedi.patch delete mode 100644 0016-libmultipath-sysfs_attr_set_value-don-t-return-0-on-.patch create mode 100644 0016-multipath-tools-Makefiles-clean-up-executable-Makefi.patch delete mode 100644 0017-libmultipath-sysfs-cleanup-file-descriptors-on-pthre.patch create mode 100644 0017-multipath-tools-Makefiles-use-common-code-for-librar.patch delete mode 100644 0018-libmultipath-multipathd-log-failure-setting-sysfs-at.patch create mode 100644 0018-multipath-tools-Makefiles-move-common-code-to-rules..patch delete mode 100644 0019-multipath-tests-expect_condlog-skip-depending-on-ver.patch create mode 100644 0019-multipath-tools-Makefiles-create-config.mk.patch delete mode 100644 0020-multipath-tests-__wrap_dlog-print-log-message.patch create mode 100644 0020-multipath-tools-Makefiles-enable-quiet-build.patch delete mode 100644 0021-multipath-tests-add-sysfs-test.patch create mode 100644 0021-multipath-tools-quiet-build-support-for-top-level-Ma.patch create mode 100644 0022-GitHub-workflows-use-make-j8-Orecurse.patch delete mode 100644 0022-libmultipath.version-bump-version-for-sysfs-accessor.patch create mode 100644 0023-README.md-Move-section-about-libedit-and-libreadline.patch delete mode 100644 0023-libmultipath-unset-detect_checker-for-clariion-Unity.patch create mode 100644 0024-README.md-Fix-indentation-in-paragraph-about-device-.patch delete mode 100644 0024-libmultipath-spelling-cplusplus.patch create mode 100644 0025-README.md-document-options-for-paths-and-optimizatio.patch delete mode 100644 0025-libmultipath-spelling-ascii.patch create mode 100644 0026-README.md-document-how-to-customize-build.patch delete mode 100644 0026-libmultipath-spelling-progress.patch create mode 100644 0027-libmultipath-avoid-Warray-bounds-error-with-gcc-12-a.patch delete mode 100644 0027-multipath-tools-spelling-fixes.patch create mode 100644 0028-multipath-avoid-NULL-string-in-released_to_systemd.patch delete mode 100644 0028-multipath-tools-remove-list-of-rebranded-arrays-vend.patch create mode 100644 0029-libmultipath-avoid-NULL-string-in-is_udev_ready.patch delete mode 100644 0029-multipath-tools-correct-CLARiiON-info-from-multipath.patch create mode 100644 0030-libmultipath-impove-add_feature-variable-names.patch delete mode 100644 0030-multipath-tools-add-basic-info-on-how-to-use-multipa.patch create mode 100644 0031-multipathd-don-t-initialize-the-field-width-in-show_.patch delete mode 100644 0031-multipathd-factor-out-the-code-to-flush-a-map-with-n.patch create mode 100644 0032-libmultipath-improve-remove_feature-variable-names.patch delete mode 100644 0032-libmultipath-return-success-if-we-raced-to-remove-a-.patch create mode 100644 0033-RH-fixup-udev-rules-for-redhat.patch delete mode 100644 0033-multipathd-Handle-losing-all-path-in-update_map.patch rename 0044-RH-Remove-the-property-blacklist-exception-builtin.patch => 0034-RH-Remove-the-property-blacklist-exception-builtin.patch (96%) delete mode 100644 0034-multipath-fix-systemd-timers-in-the-initramfs.patch rename 0045-RH-don-t-start-without-a-config-file.patch => 0035-RH-don-t-start-without-a-config-file.patch (83%) delete mode 100644 0035-multipathd-Add-missing-ctype-include.patch rename 0046-RH-Fix-nvme-function-missing-argument.patch => 0036-RH-Fix-nvme-function-missing-argument.patch (100%) delete mode 100644 0036-multipathd-replace-libreadline-with-libedit.patch rename 0047-RH-use-rpm-optflags-if-present.patch => 0037-RH-use-rpm-optflags-if-present.patch (71%) delete mode 100644 0037-libmultipath-convert-license-of-strbuf-code-to-GPL-2.patch rename 0048-RH-add-mpathconf.patch => 0038-RH-add-mpathconf.patch (94%) delete mode 100644 0038-github-workflows-build-and-unittest.yaml-add-libedit.patch rename 0049-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch => 0039-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch (95%) delete mode 100644 0039-github-workflows-coverity.yaml-add-libedit-dev.patch rename 0050-RH-reset-default-find_mutipaths-value-to-off.patch => 0040-RH-reset-default-find_mutipaths-value-to-off.patch (96%) delete mode 100644 0040-github-workflows-abi.yaml-add-libedit-dev.patch delete mode 100644 0041-GitHub-workflows-native.yaml-add-libedit-dev-except-.patch rename 0051-RH-attempt-to-get-ANA-info-via-sysfs-first.patch => 0041-RH-attempt-to-get-ANA-info-via-sysfs-first.patch (100%) delete mode 100644 0042-GitHub-workflows-foreign.yaml-switch-to-Debian-11-bu.patch rename 0052-RH-make-parse_vpd_pg83-match-scsi_id-output.patch => 0042-RH-make-parse_vpd_pg83-match-scsi_id-output.patch (94%) rename 0053-RH-add-scsi-device-handlers-to-modules-load.d.patch => 0043-RH-add-scsi-device-handlers-to-modules-load.d.patch (92%) delete mode 100644 0043-RH-fixup-udev-rules-for-redhat.patch create mode 100644 0044-RH-compile-with-libreadline-support.patch diff --git a/.gitignore b/.gitignore index 7a13460..c9e44d7 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,4 @@ multipath-tools-091027.tar.gz /multipath-tools-0.8.7.tgz /multipath-tools-0.8.9.tgz /multipath-tools-0.9.0.tgz +/multipath-tools-0.9.3.tgz diff --git a/0001-github-workflows-switch-to-fedora-36.patch b/0001-github-workflows-switch-to-fedora-36.patch deleted file mode 100644 index 1583fd8..0000000 --- a/0001-github-workflows-switch-to-fedora-36.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 10 Jun 2022 22:44:11 +0200 -Subject: [PATCH] github workflows: switch to fedora 36 - -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/native.yaml | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - -diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml -index 19c9e297..ddfd4a09 100644 ---- a/.github/workflows/native.yaml -+++ b/.github/workflows/native.yaml -@@ -12,12 +12,10 @@ jobs: - runs-on: ubuntu-20.04 - strategy: - matrix: -- os: [buster, jessie, bullseye, fedora-35] -+ os: [buster, jessie, bullseye, fedora-36] - arch: ['', '-i386'] - exclude: -- - os: fedora-34 -- arch: '-i386' -- - os: fedora-35 -+ - os: fedora-36 - arch: '-i386' - container: mwilck/multipath-build-${{ matrix.os }}${{ matrix.arch }} - steps: diff --git a/0001-libmultipath-fix-show-paths-format-failure.patch b/0001-libmultipath-fix-show-paths-format-failure.patch new file mode 100644 index 0000000..4f56830 --- /dev/null +++ b/0001-libmultipath-fix-show-paths-format-failure.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Paul Koetsier +Date: Thu, 27 Oct 2022 19:29:28 +0200 +Subject: [PATCH] libmultipath: fix 'show paths format' failure + +Prevent 'multipathd show paths format "%c"' from failing on orphan paths. +For orphan paths the checker class isn't set, which caused +snprint_path_checker() to fail which in turn caused 'show paths format' to fail +when the format string contained "%c". + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/print.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/print.c b/libmultipath/print.c +index d7d522c8..3193dbe0 100644 +--- a/libmultipath/print.c ++++ b/libmultipath/print.c +@@ -734,8 +734,12 @@ snprint_host_adapter (struct strbuf *buff, const struct path * pp) + static int + snprint_path_checker (struct strbuf *buff, const struct path * pp) + { +- const struct checker * c = &pp->checker; +- return snprint_str(buff, checker_name(c)); ++ const char * n = checker_name(&pp->checker); ++ ++ if (n) ++ return snprint_str(buff, n); ++ else ++ return snprint_str(buff, "(null)"); + } + + static int diff --git a/0002-fixup-Makefile.inc-fix-man-and-include-paths.patch b/0002-fixup-Makefile.inc-fix-man-and-include-paths.patch new file mode 100644 index 0000000..4afae52 --- /dev/null +++ b/0002-fixup-Makefile.inc-fix-man-and-include-paths.patch @@ -0,0 +1,41 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 28 Oct 2022 18:22:59 +0200 +Subject: [PATCH] fixup! Makefile.inc: fix man and include paths + +Paths would now be wrong with the default (empty) prefix. +Fix it. + +Fixes: 2b2885c ("Makefile.inc: fix man and include paths") +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 4d843ce5..32001434 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -89,9 +89,9 @@ modulesloaddir = $(prefix)/$(SYSTEMDPATH)/modules-load.d + multipathdir = $(TOPDIR)/libmultipath + daemondir = $(TOPDIR)/multipathd + mpathutildir = $(TOPDIR)/libmpathutil +-man8dir = $(prefix)/share/man/man8 +-man5dir = $(prefix)/share/man/man5 +-man3dir = $(prefix)/share/man/man3 ++man8dir = $(usr_prefix)/share/man/man8 ++man5dir = $(usr_prefix)/share/man/man5 ++man3dir = $(usr_prefix)/share/man/man3 + syslibdir = $(prefix)/$(LIB) + usrlibdir = $(usr_prefix)/$(LIB) + libdir = $(prefix)/$(LIB)/multipath +@@ -102,7 +102,7 @@ mpathvaliddir = $(TOPDIR)/libmpathvalid + thirdpartydir = $(TOPDIR)/third-party + libdmmpdir = $(TOPDIR)/libdmmp + nvmedir = $(TOPDIR)/libmultipath/nvme +-includedir = $(prefix)/include ++includedir = $(usr_prefix)/include + pkgconfdir = $(usrlibdir)/pkgconfig + plugindir := $(prefix)/$(LIB)/multipath + configdir := $(prefix)/etc/multipath/conf.d diff --git a/0002-multipath-tools-fix-multipath-ll-bug-for-Native-NVME.patch b/0002-multipath-tools-fix-multipath-ll-bug-for-Native-NVME.patch deleted file mode 100644 index c54b4cd..0000000 --- a/0002-multipath-tools-fix-multipath-ll-bug-for-Native-NVME.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: chengjike -Date: Fri, 8 Oct 2021 20:24:49 +0800 -Subject: [PATCH] multipath-tools: fix "multipath -ll" bug for Native NVME - Multipath devices - -After "Native NVME Multipath" is configured, -the content displayed is incorrect when you run "multipath -ll" command. -Each NVME devices have the same path name. For example: - -[root@localhost home]# multipath -ll -eui.710032e8fb22a86c24a52c1000000db8 [nvme]:nvme1n1 NVMe,Huawei-XSG1,1000001 -size=10485760 features='n/a' hwhandler='ANA' wp=rw -|-+- policy='n/a' prio=50 status=optimized -| `- 1:4:1 nvme1c4n1 0:0 n/a optimized live -`-+- policy='n/a' prio=50 status=optimized - `- 1:9:1 nvme1c9n1 0:0 n/a optimized live -eui.710032e8fb22a86b24a52c7c00000db7 [nvme]:nvme1n2 NVMe,Huawei-XSG1,1000001 -size=10485760 features='n/a' hwhandler='ANA' wp=rw -|-+- policy='n/a' prio=50 status=optimized -| `- 1:4:1 nvme1c4n1 0:0 n/a optimized live -`-+- policy='n/a' prio=50 status=optimized - `- 1:9:1 nvme1c9n1 0:0 n/a optimized live -[root@localhost home]# - -The logical paths of "nvme1n1" and "nvme1n2" are both "nvme1c4n1" and "nvme1c9n1". -So when multipath-tools aggregates disks, use "nvme_ns_head->instance" for matching. -such as ,Use "b" in "nvmeanb" string to match "z" in "nvmexcynz"(a,b,x,y,z can be any number), -and if "b" and "z" are the same, they are related. - -Signed-off-by: chengjike -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/foreign/nvme.c | 26 ++++++++++++++++++++------ - 1 file changed, 20 insertions(+), 6 deletions(-) - -diff --git a/libmultipath/foreign/nvme.c b/libmultipath/foreign/nvme.c -index 52ca56d8..9a05b333 100644 ---- a/libmultipath/foreign/nvme.c -+++ b/libmultipath/foreign/nvme.c -@@ -531,14 +531,18 @@ static int _dirent_controller(const struct dirent *di) - - /* Find the block device for a given nvme controller */ - struct udev_device *get_ctrl_blkdev(const struct context *ctx, -- struct udev_device *ctrl) -+ struct udev_device *ctrl, const char *ctrl_name) - { -+ int ctrl_num, ns_num; - struct udev_list_entry *item; - struct udev_device *blkdev = NULL; - struct udev_enumerate *enm = udev_enumerate_new(ctx->udev); - const char *devtype; - -- if (enm == NULL) -+ if (enm == NULL || ctrl_name == NULL) -+ return NULL; -+ -+ if (sscanf(ctrl_name, "nvme%dn%d", &ctrl_num, &ns_num) != 2) - return NULL; - - pthread_cleanup_push(_udev_enumerate_unref, enm); -@@ -556,6 +560,8 @@ struct udev_device *get_ctrl_blkdev(const struct context *ctx, - item != NULL; - item = udev_list_entry_get_next(item)) { - struct udev_device *tmp; -+ const char *name = NULL ; -+ int m, n, l; - - tmp = udev_device_new_from_syspath(ctx->udev, - udev_list_entry_get_name(item)); -@@ -563,11 +569,19 @@ struct udev_device *get_ctrl_blkdev(const struct context *ctx, - continue; - - devtype = udev_device_get_devtype(tmp); -- if (devtype && !strcmp(devtype, "disk")) { -+ if (devtype == NULL || strcmp(devtype, "disk")) { -+ udev_device_unref(tmp); -+ continue; -+ } -+ -+ name = udev_device_get_sysname(tmp); -+ if (name != NULL && -+ sscanf(name, "nvme%dc%dn%d", &m, &n, &l) == 3 && -+ l == ns_num) { - blkdev = tmp; - break; -- } else -- udev_device_unref(tmp); -+ } -+ udev_device_unref(tmp); - } - - if (blkdev == NULL) -@@ -680,7 +694,7 @@ static void _find_controllers(struct context *ctx, struct nvme_map *map) - } - - pthread_cleanup_push(_udev_device_unref, ctrl); -- udev = get_ctrl_blkdev(ctx, ctrl); -+ udev = get_ctrl_blkdev(ctx, ctrl, udev_device_get_sysname(map->udev)); - /* - * We give up the reference to the nvme device here and get - * it back from the child below. diff --git a/0003-multipath-tools-Makefile.inc-Fix-paths-for-systemd.patch b/0003-multipath-tools-Makefile.inc-Fix-paths-for-systemd.patch new file mode 100644 index 0000000..8a25fe0 --- /dev/null +++ b/0003-multipath-tools-Makefile.inc-Fix-paths-for-systemd.patch @@ -0,0 +1,65 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 27 Oct 2022 17:09:52 +0200 +Subject: [PATCH] multipath-tools: Makefile.inc: Fix paths for systemd + +With prefix=/usr, systemd files were installed under /usr/usr/lib, +which is bogus. Clean this up, and document how to handle systemd's +"rootprefix" options. Remove the previous SYSTEMDPATH option. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 21 ++++++++++++--------- + 1 file changed, 12 insertions(+), 9 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 32001434..351358a9 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -53,10 +53,6 @@ ifndef SYSTEMD + endif + endif + +-ifndef SYSTEMDPATH +- SYSTEMDPATH=usr/lib +-endif +- + ifndef DEVMAPPER_INCDIR + ifeq ($(shell $(PKGCONFIG) --modversion devmapper >/dev/null 2>&1 && echo 1), 1) + DEVMAPPER_INCDIR = $(shell $(PKGCONFIG) --variable=includedir devmapper) +@@ -78,14 +74,22 @@ ifndef LINUX_HEADERS_INCDIR + LINUX_HEADERS_INCDIR = /usr/include + endif + ++# Paths. All these can be overridden on the "make" command line. + prefix = ++# Prefix for binaries + exec_prefix = $(prefix) ++# Prefix for non-essential libraries (libdmmp) + usr_prefix = $(prefix) ++# Where to install systemd-related files. systemd is usually installed under /usr ++# Note: some systemd installations use separate "prefix" and "rootprefix". ++# In this case, override only unitdir to use systemd's "rootprefix" instead of $(systemd_prefix) ++systemd_prefix := /usr ++unitdir := $(systemd_prefix)/lib/systemd/system ++tmpfilesdir := $(systemd_prefix)/lib/tmpfiles.d ++modulesloaddir := $(systemd_prefix)/lib/modules-load.d ++libudevdir := $(systemd_prefix)/lib/udev ++udevrulesdir := $(libudevdir)/rules.d + bindir = $(exec_prefix)/sbin +-libudevdir = $(prefix)/$(SYSTEMDPATH)/udev +-tmpfilesdir = $(prefix)/$(SYSTEMDPATH)/tmpfiles.d +-udevrulesdir = $(libudevdir)/rules.d +-modulesloaddir = $(prefix)/$(SYSTEMDPATH)/modules-load.d + multipathdir = $(TOPDIR)/libmultipath + daemondir = $(TOPDIR)/multipathd + mpathutildir = $(TOPDIR)/libmpathutil +@@ -95,7 +99,6 @@ man3dir = $(usr_prefix)/share/man/man3 + syslibdir = $(prefix)/$(LIB) + usrlibdir = $(usr_prefix)/$(LIB) + libdir = $(prefix)/$(LIB)/multipath +-unitdir = $(prefix)/$(SYSTEMDPATH)/systemd/system + mpathpersistdir = $(TOPDIR)/libmpathpersist + mpathcmddir = $(TOPDIR)/libmpathcmd + mpathvaliddir = $(TOPDIR)/libmpathvalid diff --git a/0003-multipath-tools-update-Huawei-OceanStor-NVMe-vendor-.patch b/0003-multipath-tools-update-Huawei-OceanStor-NVMe-vendor-.patch deleted file mode 100644 index 9643721..0000000 --- a/0003-multipath-tools-update-Huawei-OceanStor-NVMe-vendor-.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Sun, 10 Jul 2022 01:07:08 +0200 -Subject: [PATCH] multipath-tools: update Huawei OceanStor NVMe vendor id - -"NVME" in the doc, but "NVMe" is the real output: -(page 61-62): https://drive.google.com/file/d/1c5RK4GXX7ofZBFxTtZ_IN1qHyIjw5eR1 -https://marc.info/?l=dm-devel&m=163393151312418 -Use both, just in case. - -Cc: -Cc: -Cc: -Cc: Zhouweigang (Jack) -Cc: Zou Ming -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez -Reviewed-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/hwtable.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index 513fa679..fc0252ba 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -1116,7 +1116,7 @@ static struct hwentry default_hw[] = { - }, - { - /* OceanStor NVMe */ -- .vendor = "NVME", -+ .vendor = "NVM[eE]", - .product = "Huawei-XSG1", - .checker_name = DIRECTIO, - .no_path_retry = 12, diff --git a/0004-multipath-tools-Makefile.inc-don-t-take-values-from-.patch b/0004-multipath-tools-Makefile.inc-don-t-take-values-from-.patch new file mode 100644 index 0000000..5c1b7b3 --- /dev/null +++ b/0004-multipath-tools-Makefile.inc-don-t-take-values-from-.patch @@ -0,0 +1,113 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 27 Oct 2022 13:24:34 +0200 +Subject: [PATCH] multipath-tools: Makefile.inc: don't take values from + environment + +Don't use environment variables to initialize LIB, RUN, SYSTEMD, SYSTEMDPATH, +DEVMAPPER_INCDIR, LIBUDEV_INCDIR, and LINUX_HEADERS_INCDIR. Taking +such variables from the environment is generally discouraged +(see https://www.gnu.org/software/make/manual/html_node/Environment.html). + +Overriding variables from the commandline is still possible +(https://www.gnu.org/software/make/manual/html_node/Overriding.html). +So now, when building multipath-tools, rather then running +"RUN=/somedir make", users need to run "make RUN=/somedir". + +This simplifies the Makefile without losing important functionality. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 60 ++++++++++++++++++++++------------------------------ + 1 file changed, 25 insertions(+), 35 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 351358a9..d897ac7a 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -20,59 +20,49 @@ SCSI_DH_MODULES_PRELOAD := + + EXTRAVERSION := $(shell rev=$$(git rev-parse --short=7 HEAD 2>/dev/null); echo $${rev:+-g$$rev}) + ++# PKGCONFIG must be read from the environment to enable compilation ++# in Debian multiarch setups + PKGCONFIG ?= pkg-config + + ifeq ($(TOPDIR),) + TOPDIR = .. + endif + +-ifndef LIB +- ifeq ($(shell test -d /lib64 && echo 1),1) +- LIB=lib64 +- else +- LIB=lib +- endif ++ifeq ($(shell test -d /lib64 && echo 1),1) ++ LIB=lib64 ++else ++ LIB=lib + endif + +-ifndef RUN +- ifeq ($(shell test -L /var/run -o ! -d /var/run && echo 1),1) +- RUN=run +- else +- RUN=var/run +- endif ++ifeq ($(shell test -L /var/run -o ! -d /var/run && echo 1),1) ++ RUN=run ++else ++ RUN=var/run + endif + +-ifndef SYSTEMD +- ifeq ($(shell $(PKGCONFIG) --modversion libsystemd >/dev/null 2>&1 && echo 1), 1) +- SYSTEMD = $(shell $(PKGCONFIG) --modversion libsystemd | awk '{print $$1}') +- else +- ifeq ($(shell systemctl --version >/dev/null 2>&1 && echo 1), 1) +- SYSTEMD = $(shell systemctl --version 2> /dev/null | \ +- sed -n 's/systemd \([0-9]*\).*/\1/p') +- endif ++ifeq ($(shell $(PKGCONFIG) --modversion libsystemd >/dev/null 2>&1 && echo 1), 1) ++ SYSTEMD = $(shell $(PKGCONFIG) --modversion libsystemd | awk '{print $$1}') ++else ++ ifeq ($(shell systemctl --version >/dev/null 2>&1 && echo 1), 1) ++ SYSTEMD = $(shell systemctl --version 2> /dev/null | \ ++ sed -n 's/systemd \([0-9]*\).*/\1/p') + endif + endif + +-ifndef DEVMAPPER_INCDIR +- ifeq ($(shell $(PKGCONFIG) --modversion devmapper >/dev/null 2>&1 && echo 1), 1) +- DEVMAPPER_INCDIR = $(shell $(PKGCONFIG) --variable=includedir devmapper) +- else +- DEVMAPPER_INCDIR = /usr/include +- endif ++ifeq ($(shell $(PKGCONFIG) --modversion devmapper >/dev/null 2>&1 && echo 1), 1) ++ DEVMAPPER_INCDIR = $(shell $(PKGCONFIG) --variable=includedir devmapper) ++else ++ DEVMAPPER_INCDIR = /usr/include + endif + +-ifndef LIBUDEV_INCDIR +- ifeq ($(shell $(PKGCONFIG) --modversion libudev >/dev/null 2>&1 && echo 1), 1) +- LIBUDEV_INCDIR = $(shell $(PKGCONFIG) --variable=includedir libudev) +- else +- LIBUDEV_INCDIR = /usr/include +- endif ++ifeq ($(shell $(PKGCONFIG) --modversion libudev >/dev/null 2>&1 && echo 1), 1) ++ LIBUDEV_INCDIR = $(shell $(PKGCONFIG) --variable=includedir libudev) ++else ++ LIBUDEV_INCDIR = /usr/include + endif + + # Allow user to override default location. +-ifndef LINUX_HEADERS_INCDIR +- LINUX_HEADERS_INCDIR = /usr/include +-endif ++LINUX_HEADERS_INCDIR = /usr/include + + # Paths. All these can be overridden on the "make" command line. + prefix = diff --git a/0004-multipath-tools-update-Generic-NVMe-vendor-regex-in-.patch b/0004-multipath-tools-update-Generic-NVMe-vendor-regex-in-.patch deleted file mode 100644 index 4ef193d..0000000 --- a/0004-multipath-tools-update-Generic-NVMe-vendor-regex-in-.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Sun, 10 Jul 2022 01:07:09 +0200 -Subject: [PATCH] multipath-tools: update "Generic NVMe" vendor regex in - hwtable - -to accept NVME and NVMe - -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez -Reviewed-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/hwtable.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index fc0252ba..c88fa09a 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -86,7 +86,7 @@ static struct hwentry default_hw[] = { - */ - { - /* Generic NVMe */ -- .vendor = "NVME", -+ .vendor = "NVM[eE]", - .product = ".*", - .uid_attribute = DEFAULT_NVME_UID_ATTRIBUTE, - .checker_name = NONE, diff --git a/0005-libmultipath-fix-find_multipaths_timeout-for-unknown.patch b/0005-libmultipath-fix-find_multipaths_timeout-for-unknown.patch deleted file mode 100644 index c2abfaa..0000000 --- a/0005-libmultipath-fix-find_multipaths_timeout-for-unknown.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 12 Jul 2022 17:02:51 -0500 -Subject: [PATCH] libmultipath: fix find_multipaths_timeout for unknown - hardware - -pp->hwe is now a vector that will always be allocated for all path -devices. Instead of checking if it is NULL, check if it is empty. - -Fixes: f0462f0 ("libmultipath: use vector for for pp->hwe and mp->hwe") -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/propsel.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c -index 50d0b5c8..f782f251 100644 ---- a/libmultipath/propsel.c -+++ b/libmultipath/propsel.c -@@ -1293,7 +1293,7 @@ out: - */ - if (pp->find_multipaths_timeout < 0) { - pp->find_multipaths_timeout = -pp->find_multipaths_timeout; -- if (!pp->hwe) { -+ if (VECTOR_SIZE(pp->hwe) == 0) { - pp->find_multipaths_timeout = - DEFAULT_UNKNOWN_FIND_MULTIPATHS_TIMEOUT; - origin = "(default for unknown hardware)"; diff --git a/0005-multipath-tools-Makefile.inc-get-rid-of-RUN.patch b/0005-multipath-tools-Makefile.inc-get-rid-of-RUN.patch new file mode 100644 index 0000000..c0543f5 --- /dev/null +++ b/0005-multipath-tools-Makefile.inc-get-rid-of-RUN.patch @@ -0,0 +1,63 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 27 Oct 2022 15:25:31 +0200 +Subject: [PATCH] multipath-tools: Makefile.inc: get rid of RUN + +Just use $(runtimedir). Also, make the code more compact by using +the "if" function instead of a conditional. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 10 ++-------- + libmultipath/defaults.h | 2 +- + 2 files changed, 3 insertions(+), 9 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index d897ac7a..b4ec647c 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -34,12 +34,6 @@ else + LIB=lib + endif + +-ifeq ($(shell test -L /var/run -o ! -d /var/run && echo 1),1) +- RUN=run +-else +- RUN=var/run +-endif +- + ifeq ($(shell $(PKGCONFIG) --modversion libsystemd >/dev/null 2>&1 && echo 1), 1) + SYSTEMD = $(shell $(PKGCONFIG) --modversion libsystemd | awk '{print $$1}') + else +@@ -99,7 +93,7 @@ includedir = $(usr_prefix)/include + pkgconfdir = $(usrlibdir)/pkgconfig + plugindir := $(prefix)/$(LIB)/multipath + configdir := $(prefix)/etc/multipath/conf.d +-runtimedir := /$(RUN) ++runtimedir := $(if $(shell test -L /var/run -o ! -d /var/run && echo 1),/run,/var/run) + + GZIP_PROG = gzip -9 -c + RM = rm -f +@@ -143,7 +137,7 @@ WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implici + -Werror=implicit-function-declaration -Werror=format-security \ + $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) + CPPFLAGS := $(FORTIFY_OPT) \ +- -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" -DRUN_DIR=\"${RUN}\" \ ++ -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \ + -DRUNTIME_DIR=\"$(runtimedir)\" \ + -DCONFIG_DIR=\"$(configdir)\" -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP + CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe +diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h +index 3d552b33..a5e9ea0c 100644 +--- a/libmultipath/defaults.h ++++ b/libmultipath/defaults.h +@@ -62,7 +62,7 @@ + + #define DEV_LOSS_TMO_UNSET 0U + #define MAX_DEV_LOSS_TMO UINT_MAX +-#define DEFAULT_PIDFILE "/" RUN_DIR "/multipathd.pid" ++#define DEFAULT_PIDFILE RUNTIME_DIR "/multipathd.pid" + #define DEFAULT_SOCKET "/org/kernel/linux/storage/multipathd" + #define DEFAULT_CONFIGFILE "/etc/multipath.conf" + #define DEFAULT_BINDINGS_FILE "/etc/multipath/bindings" diff --git a/0006-multipath-tools-Makefile.inc-more-compact-code-for-L.patch b/0006-multipath-tools-Makefile.inc-more-compact-code-for-L.patch new file mode 100644 index 0000000..2a0eda4 --- /dev/null +++ b/0006-multipath-tools-Makefile.inc-more-compact-code-for-L.patch @@ -0,0 +1,38 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 27 Oct 2022 16:14:22 +0200 +Subject: [PATCH] multipath-tools: Makefile.inc: more compact code for LIB + +Use make's "if" function instead of a conditional. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index b4ec647c..c39cec9b 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -28,12 +28,6 @@ ifeq ($(TOPDIR),) + TOPDIR = .. + endif + +-ifeq ($(shell test -d /lib64 && echo 1),1) +- LIB=lib64 +-else +- LIB=lib +-endif +- + ifeq ($(shell $(PKGCONFIG) --modversion libsystemd >/dev/null 2>&1 && echo 1), 1) + SYSTEMD = $(shell $(PKGCONFIG) --modversion libsystemd | awk '{print $$1}') + else +@@ -80,6 +74,7 @@ mpathutildir = $(TOPDIR)/libmpathutil + man8dir = $(usr_prefix)/share/man/man8 + man5dir = $(usr_prefix)/share/man/man5 + man3dir = $(usr_prefix)/share/man/man3 ++LIB := $(if $(shell test -d /lib64 && echo 1),lib64,lib) + syslibdir = $(prefix)/$(LIB) + usrlibdir = $(usr_prefix)/$(LIB) + libdir = $(prefix)/$(LIB)/multipath diff --git a/0006-multipath-tools-update-devel-repo-info-in-README.md.patch b/0006-multipath-tools-update-devel-repo-info-in-README.md.patch deleted file mode 100644 index 3eaf2c0..0000000 --- a/0006-multipath-tools-update-devel-repo-info-in-README.md.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Thu, 14 Jul 2022 21:05:39 +0200 -Subject: [PATCH] multipath-tools: update devel repo info in README.md - -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - README.md | 10 +++------- - 1 file changed, 3 insertions(+), 7 deletions(-) - -diff --git a/README.md b/README.md -index f06f8cea..dcf51f20 100644 ---- a/README.md -+++ b/README.md -@@ -3,7 +3,6 @@ - multipath-tools for Linux - ========================= - -- - https://github.com/opensvc/multipath-tools - - This package provides the following binaries to drive the Device Mapper multipathing driver: -@@ -42,14 +41,12 @@ Go to: https://github.com/opensvc/multipath-tools/tags - Select a release-tag and then click on "zip" or "tar.gz". - - --Source code --=========== -+Devel code -+========== - - To get latest devel code: - -- git clone https://github.com/opensvc/multipath-tools.git -- --Github page: https://github.com/opensvc/multipath-tools -+ git clone -b queue https://github.com/openSUSE/multipath-tools - - - Building multipath-tools -@@ -149,4 +146,3 @@ The multipath-tools source code is covered by several different licences. - Refer to the individual source files for details. - Source files which do not specify a licence are shipped under LGPL-2.0 - (see `LICENSES/LGPL-2.0`). -- diff --git a/0007-multipath-tools-Makefiles-simplify-code-for-include-.patch b/0007-multipath-tools-Makefiles-simplify-code-for-include-.patch new file mode 100644 index 0000000..c6be343 --- /dev/null +++ b/0007-multipath-tools-Makefiles-simplify-code-for-include-.patch @@ -0,0 +1,139 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 27 Oct 2022 16:17:40 +0200 +Subject: [PATCH] multipath-tools: Makefiles: simplify code for include dirs + +Use make's if function, and use lower-case latters for make variable +names that represent directories, such as elsewhere. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 16 +++------------- + kpartx/Makefile | 2 +- + libmultipath/Makefile | 14 +++++++------- + libmultipath/prioritizers/Makefile | 2 +- + multipathd/Makefile | 4 ++-- + 5 files changed, 14 insertions(+), 24 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index c39cec9b..38bd1d80 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -37,20 +37,7 @@ else + endif + endif + +-ifeq ($(shell $(PKGCONFIG) --modversion devmapper >/dev/null 2>&1 && echo 1), 1) +- DEVMAPPER_INCDIR = $(shell $(PKGCONFIG) --variable=includedir devmapper) +-else +- DEVMAPPER_INCDIR = /usr/include +-endif +- +-ifeq ($(shell $(PKGCONFIG) --modversion libudev >/dev/null 2>&1 && echo 1), 1) +- LIBUDEV_INCDIR = $(shell $(PKGCONFIG) --variable=includedir libudev) +-else +- LIBUDEV_INCDIR = /usr/include +-endif +- + # Allow user to override default location. +-LINUX_HEADERS_INCDIR = /usr/include + + # Paths. All these can be overridden on the "make" command line. + prefix = +@@ -89,6 +76,9 @@ pkgconfdir = $(usrlibdir)/pkgconfig + plugindir := $(prefix)/$(LIB)/multipath + configdir := $(prefix)/etc/multipath/conf.d + runtimedir := $(if $(shell test -L /var/run -o ! -d /var/run && echo 1),/run,/var/run) ++devmapper_incdir := $(or $(shell $(PKGCONFIG) --variable=includedir devmapper),/usr/include) ++libudev_incdir := $(or $(shell $(PKGCONFIG) --variable=includedir libudev),/usr/include) ++kernel_incdir := /usr/include + + GZIP_PROG = gzip -9 -c + RM = rm -f +diff --git a/kpartx/Makefile b/kpartx/Makefile +index 742d3bcd..bdf2d035 100644 +--- a/kpartx/Makefile ++++ b/kpartx/Makefile +@@ -9,7 +9,7 @@ LDFLAGS += $(BIN_LDFLAGS) + + LIBDEPS += -ldevmapper + +-ifneq ($(call check_func,dm_task_set_cookie,$(DEVMAPPER_INCDIR)/libdevmapper.h),0) ++ifneq ($(call check_func,dm_task_set_cookie,$(devmapper_incdir)/libdevmapper.h),0) + CPPFLAGS += -DLIBDM_API_COOKIE + endif + +diff --git a/libmultipath/Makefile b/libmultipath/Makefile +index 3b60a525..f0df27c0 100644 +--- a/libmultipath/Makefile ++++ b/libmultipath/Makefile +@@ -22,31 +22,31 @@ ifdef SYSTEMD + endif + endif + +-ifneq ($(call check_func,dm_task_no_flush,$(DEVMAPPER_INCDIR)/libdevmapper.h),0) ++ifneq ($(call check_func,dm_task_no_flush,$(devmapper_incdir)/libdevmapper.h),0) + CPPFLAGS += -DLIBDM_API_FLUSH + endif + +-ifneq ($(call check_func,dm_task_get_errno,$(DEVMAPPER_INCDIR)/libdevmapper.h),0) ++ifneq ($(call check_func,dm_task_get_errno,$(devmapper_incdir)/libdevmapper.h),0) + CPPFLAGS += -DLIBDM_API_GET_ERRNO + endif + +-ifneq ($(call check_func,dm_task_set_cookie,$(DEVMAPPER_INCDIR)/libdevmapper.h),0) ++ifneq ($(call check_func,dm_task_set_cookie,$(devmapper_incdir)/libdevmapper.h),0) + CPPFLAGS += -DLIBDM_API_COOKIE + endif + +-ifneq ($(call check_func,udev_monitor_set_receive_buffer_size,$(LIBUDEV_INCDIR)/libudev.h),0) ++ifneq ($(call check_func,udev_monitor_set_receive_buffer_size,$(libudev_incdir)/libudev.h),0) + CPPFLAGS += -DLIBUDEV_API_RECVBUF + endif + +-ifneq ($(call check_func,dm_task_deferred_remove,$(DEVMAPPER_INCDIR)/libdevmapper.h),0) ++ifneq ($(call check_func,dm_task_deferred_remove,$(devmapper_incdir)/libdevmapper.h),0) + CPPFLAGS += -DLIBDM_API_DEFERRED + endif + +-ifneq ($(call check_func,dm_hold_control_dev,$(DEVMAPPER_INCDIR)/libdevmapper.h),0) ++ifneq ($(call check_func,dm_hold_control_dev,$(devmapper_incdir)/libdevmapper.h),0) + CPPFLAGS += -DLIBDM_API_HOLD_CONTROL + endif + +-ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(LINUX_HEADERS_INCDIR)/scsi/fc/fc_els.h),0) ++ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(kernel_incdir)/scsi/fc/fc_els.h),0) + CPPFLAGS += -DFPIN_EVENT_HANDLER + endif + +diff --git a/libmultipath/prioritizers/Makefile b/libmultipath/prioritizers/Makefile +index 400f7735..97155f51 100644 +--- a/libmultipath/prioritizers/Makefile ++++ b/libmultipath/prioritizers/Makefile +@@ -26,7 +26,7 @@ LIBS = \ + libpriopath_latency.so \ + libpriosysfs.so + +-ifneq ($(call check_file,$(LINUX_HEADERS_INCDIR)/linux/nvme_ioctl.h),0) ++ifneq ($(call check_file,$(kernel_incdir)/linux/nvme_ioctl.h),0) + LIBS += libprioana.so + CPPFLAGS += -I../nvme + endif +diff --git a/multipathd/Makefile b/multipathd/Makefile +index 3ce9465e..c462d7b1 100644 +--- a/multipathd/Makefile ++++ b/multipathd/Makefile +@@ -1,10 +1,10 @@ + include ../Makefile.inc + +-ifneq ($(call check_func,dm_task_get_errno,$(DEVMAPPER_INCDIR)/libdevmapper.h),0) ++ifneq ($(call check_func,dm_task_get_errno,$(devmapper_incdir)/libdevmapper.h),0) + CPPFLAGS += -DLIBDM_API_GET_ERRNO + endif + +-ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(LINUX_HEADERS_INCDIR)/scsi/fc/fc_els.h),0) ++ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(kernel_incdir)/scsi/fc/fc_els.h),0) + CPPFLAGS += -DFPIN_EVENT_HANDLER + FPIN_SUPPORT = 1 + endif diff --git a/0007-multipath-tools-delete-README.alua.patch b/0007-multipath-tools-delete-README.alua.patch deleted file mode 100644 index 8682745..0000000 --- a/0007-multipath-tools-delete-README.alua.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Thu, 14 Jul 2022 21:05:40 +0200 -Subject: [PATCH] multipath-tools: delete README.alua - -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - README.alua | 24 ------------------------ - 1 file changed, 24 deletions(-) - delete mode 100644 README.alua - -diff --git a/README.alua b/README.alua -deleted file mode 100644 -index 5d2b1c64..00000000 ---- a/README.alua -+++ /dev/null -@@ -1,24 +0,0 @@ --This is a rough guide, consult your storage device manufacturer documentation. -- --ALUA is supported in some devices, but usually it's disabled by default. --To enable ALUA, the following options should be changed: -- --- EMC CLARiiON/VNX: -- "Failover Mode" should be changed to "4" or "Active-Active mode(ALUA)-failover mode 4" -- --- HPE 3PAR, Primera, and Alletra 9000: -- "Host:" should be changed to "Generic-ALUA Persona 2 (UARepLun, SESLun, ALUA)". -- --- Promise VTrak/Vess: -- "LUN Affinity" and "ALUA" should be changed to "Enable", "Redundancy Type" -- must be "Active-Active". -- --- LSI/Engenio/NetApp RDAC class, as NetApp SANtricity E/EF Series and OEM arrays: -- "Select operating system:" should be changed to "Linux DM-MP (Kernel 3.10 or later)". -- --- NetApp ONTAP: -- To check ALUA state: "igroup show -v ", and to enable ALUA: -- "igroup set alua yes". -- --- Huawei OceanStor: -- "Host Access Mode" should be changed to "Asymmetric". diff --git a/0008-multipath-tools-Makefiles-use-mandir.patch b/0008-multipath-tools-Makefiles-use-mandir.patch new file mode 100644 index 0000000..10e1ca8 --- /dev/null +++ b/0008-multipath-tools-Makefiles-use-mandir.patch @@ -0,0 +1,185 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 27 Oct 2022 16:25:04 +0200 +Subject: [PATCH] multipath-tools: Makefiles: use $(mandir) + +Simply use $(mandir) rather than 3 different variables. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 4 +--- + kpartx/Makefile | 6 +++--- + libdmmp/Makefile | 8 ++++---- + libmpathpersist/Makefile | 10 +++++----- + mpathpersist/Makefile | 6 +++--- + multipath/Makefile | 12 ++++++------ + multipathd/Makefile | 10 +++++----- + 7 files changed, 27 insertions(+), 29 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 38bd1d80..f3c84771 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -58,9 +58,7 @@ bindir = $(exec_prefix)/sbin + multipathdir = $(TOPDIR)/libmultipath + daemondir = $(TOPDIR)/multipathd + mpathutildir = $(TOPDIR)/libmpathutil +-man8dir = $(usr_prefix)/share/man/man8 +-man5dir = $(usr_prefix)/share/man/man5 +-man3dir = $(usr_prefix)/share/man/man3 ++mandir := $(usr_prefix)/share/man + LIB := $(if $(shell test -d /lib64 && echo 1),lib64,lib) + syslibdir = $(prefix)/$(LIB) + usrlibdir = $(usr_prefix)/$(LIB) +diff --git a/kpartx/Makefile b/kpartx/Makefile +index bdf2d035..464925ad 100644 +--- a/kpartx/Makefile ++++ b/kpartx/Makefile +@@ -32,12 +32,12 @@ install: $(EXEC) $(EXEC).8 + $(INSTALL_PROGRAM) -m 644 dm-parts.rules $(DESTDIR)$(libudevdir)/rules.d/11-dm-parts.rules + $(INSTALL_PROGRAM) -m 644 kpartx.rules $(DESTDIR)$(libudevdir)/rules.d/66-kpartx.rules + $(INSTALL_PROGRAM) -m 644 del-part-nodes.rules $(DESTDIR)$(libudevdir)/rules.d/68-del-part-nodes.rules +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(man8dir) +- $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(man8dir) ++ $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 ++ $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 + + uninstall: + $(RM) $(DESTDIR)$(bindir)/$(EXEC) +- $(RM) $(DESTDIR)$(man8dir)/$(EXEC).8 ++ $(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 + $(RM) $(DESTDIR)$(libudevdir)/kpartx_id + $(RM) $(DESTDIR)$(libudevdir)/rules.d/11-dm-parts.rules + $(RM) $(DESTDIR)$(libudevdir)/rules.d/66-kpartx.rules +diff --git a/libdmmp/Makefile b/libdmmp/Makefile +index e4589250..985b694b 100644 +--- a/libdmmp/Makefile ++++ b/libdmmp/Makefile +@@ -45,17 +45,17 @@ install: + $(DESTDIR)$(pkgconfdir)/$(PKGFILE) + perl -i -pe 's|__INCLUDEDIR__|$(includedir)|g' \ + $(DESTDIR)$(pkgconfdir)/$(PKGFILE) +- $(INSTALL_PROGRAM) -d 755 $(DESTDIR)$(man3dir) +- $(INSTALL_PROGRAM) -m 644 -t $(DESTDIR)$(man3dir) docs/man/*.3 ++ $(INSTALL_PROGRAM) -d 755 $(DESTDIR)$(mandir)/man3 ++ $(INSTALL_PROGRAM) -m 644 -t $(DESTDIR)$(mandir)/man3 docs/man/*.3 + + uninstall: + $(RM) $(DESTDIR)$(usrlibdir)/$(LIBS) + $(RM) $(DESTDIR)$(includedir)/$(HEADERS) + $(RM) $(DESTDIR)$(usrlibdir)/$(DEVLIB) +- @for file in $(DESTDIR)$(man3dir)/dmmp_*; do \ ++ @for file in $(DESTDIR)$(mandir)/man3/dmmp_*; do \ + $(RM) $$file; \ + done +- $(RM) $(DESTDIR)$(man3dir)/libdmmp.h* ++ $(RM) $(DESTDIR)$(mandir)/man3/libdmmp.h* + $(RM) $(DESTDIR)$(pkgconfdir)/$(PKGFILE) + + clean: dep_clean +diff --git a/libmpathpersist/Makefile b/libmpathpersist/Makefile +index 4e1717ef..479524d4 100644 +--- a/libmpathpersist/Makefile ++++ b/libmpathpersist/Makefile +@@ -36,17 +36,17 @@ install: all + $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) + $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) + $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(syslibdir) +- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(man3dir) ++ $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(mandir)/man3 + $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(includedir) + $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) +- $(INSTALL_PROGRAM) -m 644 mpath_persistent_reserve_in.3 $(DESTDIR)$(man3dir) +- $(INSTALL_PROGRAM) -m 644 mpath_persistent_reserve_out.3 $(DESTDIR)$(man3dir) ++ $(INSTALL_PROGRAM) -m 644 mpath_persistent_reserve_in.3 $(DESTDIR)$(mandir)/man3 ++ $(INSTALL_PROGRAM) -m 644 mpath_persistent_reserve_out.3 $(DESTDIR)$(mandir)/man3 + $(INSTALL_PROGRAM) -m 644 mpath_persist.h $(DESTDIR)$(includedir) + + uninstall: + $(RM) $(DESTDIR)$(syslibdir)/$(LIBS) +- $(RM) $(DESTDIR)$(man3dir)/mpath_persistent_reserve_in.3 +- $(RM) $(DESTDIR)$(man3dir)/mpath_persistent_reserve_out.3 ++ $(RM) $(DESTDIR)$(mandir)/man3/mpath_persistent_reserve_in.3 ++ $(RM) $(DESTDIR)$(mandir)/man3/mpath_persistent_reserve_out.3 + $(RM) $(DESTDIR)$(includedir)/mpath_persist.h + $(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) + +diff --git a/mpathpersist/Makefile b/mpathpersist/Makefile +index 2219c86a..d62537b5 100644 +--- a/mpathpersist/Makefile ++++ b/mpathpersist/Makefile +@@ -19,8 +19,8 @@ $(EXEC): $(OBJS) + install: + $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) + $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(man8dir) +- $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(man8dir) ++ $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 ++ $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 + + clean: dep_clean + $(RM) core *.o $(EXEC) +@@ -29,7 +29,7 @@ include $(wildcard $(OBJS:.o=.d)) + + uninstall: + $(RM) $(DESTDIR)$(bindir)/$(EXEC) +- $(RM) $(DESTDIR)$(man8dir)/$(EXEC).8 ++ $(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 + + dep_clean: + $(RM) $(OBJS:.o=.d) +diff --git a/multipath/Makefile b/multipath/Makefile +index 116348e2..1c4e7a52 100644 +--- a/multipath/Makefile ++++ b/multipath/Makefile +@@ -28,10 +28,10 @@ install: + $(INSTALL_PROGRAM) -m 644 modules-load.conf $(DESTDIR)$(modulesloaddir)/multipath.conf + $(INSTALL_PROGRAM) -d $(DESTDIR)$(tmpfilesdir) + $(INSTALL_PROGRAM) -m 644 tmpfiles.conf $(DESTDIR)$(tmpfilesdir)/multipath.conf +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(man8dir) +- $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(man8dir) +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(man5dir) +- $(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5 $(DESTDIR)$(man5dir) ++ $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 ++ $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 ++ $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man5 ++ $(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5 $(DESTDIR)$(mandir)/man5 + ifneq ($(SCSI_DH_MODULES_PRELOAD),) + $(INSTALL_PROGRAM) -m 644 scsi_dh.conf $(DESTDIR)$(modulesloaddir)/scsi_dh.conf + for _x in $(SCSI_DH_MODULES_PRELOAD); do echo "$$_x"; done \ +@@ -44,8 +44,8 @@ uninstall: + $(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf + $(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf + $(RM) $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules +- $(RM) $(DESTDIR)$(man8dir)/$(EXEC).8 +- $(RM) $(DESTDIR)$(man5dir)/$(EXEC).conf.5 ++ $(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 ++ $(RM) $(DESTDIR)$(mandir)/man5/$(EXEC).conf.5 + + clean: dep_clean + $(RM) core *.o $(EXEC) multipath.rules tmpfiles.conf +diff --git a/multipathd/Makefile b/multipathd/Makefile +index c462d7b1..78aefee0 100644 +--- a/multipathd/Makefile ++++ b/multipathd/Makefile +@@ -89,14 +89,14 @@ ifdef SYSTEMD + $(INSTALL_PROGRAM) -m 644 $(EXEC).service $(DESTDIR)$(unitdir) + $(INSTALL_PROGRAM) -m 644 $(EXEC).socket $(DESTDIR)$(unitdir) + endif +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(man8dir) +- $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(man8dir) +- $(INSTALL_PROGRAM) -m 644 $(CLI).8 $(DESTDIR)$(man8dir) ++ $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 ++ $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 ++ $(INSTALL_PROGRAM) -m 644 $(CLI).8 $(DESTDIR)$(mandir)/man8 + + uninstall: + $(RM) $(DESTDIR)$(bindir)/$(EXEC) $(DESTDIR)$(bindir)/$(CLI) +- $(RM) $(DESTDIR)$(man8dir)/$(EXEC).8 +- $(RM) $(DESTDIR)$(man8dir)/$(CLI).8 ++ $(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 ++ $(RM) $(DESTDIR)$(mandir)/man8/$(CLI).8 + $(RM) $(DESTDIR)$(unitdir)/$(EXEC).service + $(RM) $(DESTDIR)$(unitdir)/$(EXEC).socket + diff --git a/0008-multipath-tools-add-ALUA-info-to-README.md.patch b/0008-multipath-tools-add-ALUA-info-to-README.md.patch deleted file mode 100644 index 2a11fce..0000000 --- a/0008-multipath-tools-add-ALUA-info-to-README.md.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Thu, 14 Jul 2022 23:14:31 +0200 -Subject: [PATCH] multipath-tools: add ALUA info to README.md - -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - README.md | 28 ++++++++++++++++++++++++++++ - 1 file changed, 28 insertions(+) - -diff --git a/README.md b/README.md -index dcf51f20..2322082c 100644 ---- a/README.md -+++ b/README.md -@@ -146,3 +146,31 @@ The multipath-tools source code is covered by several different licences. - Refer to the individual source files for details. - Source files which do not specify a licence are shipped under LGPL-2.0 - (see `LICENSES/LGPL-2.0`). -+ -+ -+ALUA -+==== -+This is a rough guide, consult your storage device manufacturer documentation. -+ -+ALUA is supported in some devices, but usually it's disabled by default. -+To enable ALUA, the following options should be changed: -+ -+- EMC CLARiiON/VNX: -+ "Failover Mode" should be changed to "4" or "Active-Active mode(ALUA)-failover mode 4" -+ -+- HPE 3PAR, Primera, and Alletra 9000: -+ "Host:" should be changed to "Generic-ALUA Persona 2 (UARepLun, SESLun, ALUA)". -+ -+- Promise VTrak/Vess: -+ "LUN Affinity" and "ALUA" should be changed to "Enable", "Redundancy Type" -+ must be "Active-Active". -+ -+- LSI/Engenio/NetApp RDAC class, as NetApp SANtricity E/EF Series and OEM arrays: -+ "Select operating system:" should be changed to "Linux DM-MP (Kernel 3.10 or later)". -+ -+- NetApp ONTAP: -+ To check ALUA state: "igroup show -v ", and to enable ALUA: -+ "igroup set alua yes". -+ -+- Huawei OceanStor: -+ "Host Access Mode" should be changed to "Asymmetric". diff --git a/0009-libmultipath-alua-remove-get_sysfs_pg83.patch b/0009-libmultipath-alua-remove-get_sysfs_pg83.patch deleted file mode 100644 index 4aa92fc..0000000 --- a/0009-libmultipath-alua-remove-get_sysfs_pg83.patch +++ /dev/null @@ -1,95 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 6 Jul 2022 15:57:21 +0200 -Subject: [PATCH] libmultipath: alua: remove get_sysfs_pg83() - -Since b72e753 ("libmultipath: alua: try to retrieve inquiry data from sysfs"), -we fetch inquiry and VPD data from sysfs anyway. No need to do this twice. - -Signed-off-by: Martin Wilck - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/prioritizers/alua_rtpg.c | 57 ++++++++------------------- - 1 file changed, 16 insertions(+), 41 deletions(-) - -diff --git a/libmultipath/prioritizers/alua_rtpg.c b/libmultipath/prioritizers/alua_rtpg.c -index 3f9c0e73..4db13c20 100644 ---- a/libmultipath/prioritizers/alua_rtpg.c -+++ b/libmultipath/prioritizers/alua_rtpg.c -@@ -228,25 +228,6 @@ get_target_port_group_support(const struct path *pp, unsigned int timeout) - return rc; - } - --static int --get_sysfs_pg83(const struct path *pp, unsigned char *buff, int buflen) --{ -- struct udev_device *parent = pp->udev; -- -- while (parent) { -- const char *subsys = udev_device_get_subsystem(parent); -- if (subsys && !strncmp(subsys, "scsi", 4)) -- break; -- parent = udev_device_get_parent(parent); -- } -- -- if (!parent || sysfs_get_vpd(parent, 0x83, buff, buflen) <= 0) { -- PRINT_DEBUG("failed to read sysfs vpd pg83"); -- return -1; -- } -- return 0; --} -- - int - get_target_port_group(const struct path * pp, unsigned int timeout) - { -@@ -265,32 +246,26 @@ get_target_port_group(const struct path * pp, unsigned int timeout) - } - - memset(buf, 0, buflen); -+ rc = do_inquiry(pp, 1, 0x83, buf, buflen, timeout); -+ if (rc < 0) -+ goto out; - -- rc = get_sysfs_pg83(pp, buf, buflen); -- -- if (rc < 0) { -+ scsi_buflen = get_unaligned_be16(&buf[2]) + 4; -+ if (scsi_buflen >= USHRT_MAX) -+ scsi_buflen = USHRT_MAX; -+ if (buflen < scsi_buflen) { -+ free(buf); -+ buf = (unsigned char *)malloc(scsi_buflen); -+ if (!buf) { -+ PRINT_DEBUG("malloc failed: could not allocate" -+ "%u bytes", scsi_buflen); -+ return -RTPG_RTPG_FAILED; -+ } -+ buflen = scsi_buflen; -+ memset(buf, 0, buflen); - rc = do_inquiry(pp, 1, 0x83, buf, buflen, timeout); - if (rc < 0) - goto out; -- -- scsi_buflen = get_unaligned_be16(&buf[2]) + 4; -- /* Paranoia */ -- if (scsi_buflen >= USHRT_MAX) -- scsi_buflen = USHRT_MAX; -- if (buflen < scsi_buflen) { -- free(buf); -- buf = (unsigned char *)malloc(scsi_buflen); -- if (!buf) { -- PRINT_DEBUG("malloc failed: could not allocate" -- "%u bytes", scsi_buflen); -- return -RTPG_RTPG_FAILED; -- } -- buflen = scsi_buflen; -- memset(buf, 0, buflen); -- rc = do_inquiry(pp, 1, 0x83, buf, buflen, timeout); -- if (rc < 0) -- goto out; -- } - } - - vpd83 = (struct vpd83_data *) buf; diff --git a/0009-multipath-tools-Makefile.inc-simplify-expression-for.patch b/0009-multipath-tools-Makefile.inc-simplify-expression-for.patch new file mode 100644 index 0000000..9b0dbc5 --- /dev/null +++ b/0009-multipath-tools-Makefile.inc-simplify-expression-for.patch @@ -0,0 +1,36 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 27 Oct 2022 16:34:34 +0200 +Subject: [PATCH] multipath-tools: Makefile.inc: simplify expression for + SYSTEMD + +Use a shell "or" function here. Note the use of "strip" to remove +the whitespace that are caused by the line break. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 10 ++-------- + 1 file changed, 2 insertions(+), 8 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index f3c84771..1a08b8fa 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -28,14 +28,8 @@ ifeq ($(TOPDIR),) + TOPDIR = .. + endif + +-ifeq ($(shell $(PKGCONFIG) --modversion libsystemd >/dev/null 2>&1 && echo 1), 1) +- SYSTEMD = $(shell $(PKGCONFIG) --modversion libsystemd | awk '{print $$1}') +-else +- ifeq ($(shell systemctl --version >/dev/null 2>&1 && echo 1), 1) +- SYSTEMD = $(shell systemctl --version 2> /dev/null | \ +- sed -n 's/systemd \([0-9]*\).*/\1/p') +- endif +-endif ++SYSTEMD := $(strip $(or $(shell $(PKGCONFIG) --modversion libsystemd 2>/dev/null | awk '{print $$1}'), \ ++ $(shell systemctl --version 2>/dev/null | sed -n 's/systemd \([0-9]*\).*/\1/p'))) + + # Allow user to override default location. + diff --git a/0010-libmultipath-remove-sysfs_get_binary.patch b/0010-libmultipath-remove-sysfs_get_binary.patch deleted file mode 100644 index c2661ed..0000000 --- a/0010-libmultipath-remove-sysfs_get_binary.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 5 Jul 2022 10:54:02 +0200 -Subject: [PATCH] libmultipath: remove sysfs_get_binary() - -This function adds no value on top of sysfs_bin_attr_get_value(). -Remove it. - -Signed-off-by: Martin Wilck - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/discovery.c | 26 ++------------------------ - tests/test-lib.c | 1 - - 2 files changed, 2 insertions(+), 25 deletions(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 0d8a558c..7e09e4e2 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -263,41 +263,19 @@ declare_sysfs_get_str(vendor); - declare_sysfs_get_str(model); - declare_sysfs_get_str(rev); - --static ssize_t --sysfs_get_binary (struct udev_device * udev, const char *attrname, -- unsigned char *buff, size_t len) --{ -- ssize_t attr_len; -- const char * devname; -- -- if (!udev) { -- condlog(3, "No udev device given\n"); -- return -ENOSYS; -- } -- -- devname = udev_device_get_sysname(udev); -- attr_len = sysfs_bin_attr_get_value(udev, attrname, buff, len); -- if (attr_len < 0) { -- condlog(3, "%s: attribute %s not found in sysfs", -- devname, attrname); -- return attr_len; -- } -- return attr_len; --} -- - ssize_t sysfs_get_vpd(struct udev_device * udev, unsigned char pg, - unsigned char *buff, size_t len) - { - char attrname[9]; - - snprintf(attrname, sizeof(attrname), "vpd_pg%02x", pg); -- return sysfs_get_binary(udev, attrname, buff, len); -+ return sysfs_bin_attr_get_value(udev, attrname, buff, len); - } - - ssize_t sysfs_get_inquiry(struct udev_device * udev, - unsigned char *buff, size_t len) - { -- return sysfs_get_binary(udev, "inquiry", buff, len); -+ return sysfs_bin_attr_get_value(udev, "inquiry", buff, len); - } - - int -diff --git a/tests/test-lib.c b/tests/test-lib.c -index 6dd3ee88..0bc49d53 100644 ---- a/tests/test-lib.c -+++ b/tests/test-lib.c -@@ -334,7 +334,6 @@ void mock_pathinfo(int mask, const struct mocked_path *mp) - if (mask & DI_SERIAL) { - will_return(__wrap_udev_device_get_subsystem, "scsi"); - will_return(__wrap_udev_device_get_sysname, hbtl); -- will_return(__wrap_udev_device_get_sysname, hbtl); - } - - if (mask & DI_WWID) { diff --git a/0010-multipath-tools-Makefile.inc-untangle-paths-and-sour.patch b/0010-multipath-tools-Makefile.inc-untangle-paths-and-sour.patch new file mode 100644 index 0000000..8591ac4 --- /dev/null +++ b/0010-multipath-tools-Makefile.inc-untangle-paths-and-sour.patch @@ -0,0 +1,68 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 27 Oct 2022 16:53:04 +0200 +Subject: [PATCH] multipath-tools: Makefile.inc: untangle paths and source + directories + +Only the installation paths can be customized. Move the definitions +of $(multipathdir) etc. further down. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 23 ++++++++++++----------- + 1 file changed, 12 insertions(+), 11 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 1a08b8fa..6ec8201b 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -31,8 +31,6 @@ endif + SYSTEMD := $(strip $(or $(shell $(PKGCONFIG) --modversion libsystemd 2>/dev/null | awk '{print $$1}'), \ + $(shell systemctl --version 2>/dev/null | sed -n 's/systemd \([0-9]*\).*/\1/p'))) + +-# Allow user to override default location. +- + # Paths. All these can be overridden on the "make" command line. + prefix = + # Prefix for binaries +@@ -49,20 +47,11 @@ modulesloaddir := $(systemd_prefix)/lib/modules-load.d + libudevdir := $(systemd_prefix)/lib/udev + udevrulesdir := $(libudevdir)/rules.d + bindir = $(exec_prefix)/sbin +-multipathdir = $(TOPDIR)/libmultipath +-daemondir = $(TOPDIR)/multipathd +-mpathutildir = $(TOPDIR)/libmpathutil + mandir := $(usr_prefix)/share/man + LIB := $(if $(shell test -d /lib64 && echo 1),lib64,lib) + syslibdir = $(prefix)/$(LIB) + usrlibdir = $(usr_prefix)/$(LIB) + libdir = $(prefix)/$(LIB)/multipath +-mpathpersistdir = $(TOPDIR)/libmpathpersist +-mpathcmddir = $(TOPDIR)/libmpathcmd +-mpathvaliddir = $(TOPDIR)/libmpathvalid +-thirdpartydir = $(TOPDIR)/third-party +-libdmmpdir = $(TOPDIR)/libdmmp +-nvmedir = $(TOPDIR)/libmultipath/nvme + includedir = $(usr_prefix)/include + pkgconfdir = $(usrlibdir)/pkgconfig + plugindir := $(prefix)/$(LIB)/multipath +@@ -124,6 +113,18 @@ SHARED_FLAGS = -shared + LDFLAGS := $(LDFLAGS) -Wl,-z,relro -Wl,-z,now -Wl,-z,defs + BIN_LDFLAGS = -pie + ++# Source code directories. Don't modify. ++ ++multipathdir = $(TOPDIR)/libmultipath ++daemondir = $(TOPDIR)/multipathd ++mpathutildir = $(TOPDIR)/libmpathutil ++mpathpersistdir = $(TOPDIR)/libmpathpersist ++mpathcmddir = $(TOPDIR)/libmpathcmd ++mpathvaliddir = $(TOPDIR)/libmpathvalid ++thirdpartydir = $(TOPDIR)/third-party ++libdmmpdir = $(TOPDIR)/libdmmp ++nvmedir = $(TOPDIR)/libmultipath/nvme ++ + # Check whether a function with name $1 has been declared in header file $2. + check_func = $(shell \ + if grep -Eq "^[^[:blank:]]+[[:blank:]]+$1[[:blank:]]*(.*)*" "$2"; then \ diff --git a/0011-libmultipath-sysfs_bin_attr_get_value-no-error-if-bu.patch b/0011-libmultipath-sysfs_bin_attr_get_value-no-error-if-bu.patch deleted file mode 100644 index 787d230..0000000 --- a/0011-libmultipath-sysfs_bin_attr_get_value-no-error-if-bu.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 5 Jul 2022 10:47:51 +0200 -Subject: [PATCH] libmultipath: sysfs_bin_attr_get_value(): no error if buffer - is filled - -sysfs_bin_attr_get_value() sets the length of bytes read to 0 -when the provided buffer was too small, truncating potentially -useful data. This is harmful e.g. in do_inquiry(), if the "inquiry" -sysfs attribute contains more than 96 bytes (which is possible). - -Actually, binary attributes don't need to be 0-terminated. Thus, -unlike for string attributes, it's not an error if the requested number of -bytes is exactly equal to the number of bytes read. We expect that -the caller knows how many bytes it needs to read. - -Signed-off-by: Martin Wilck - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/discovery.c | 10 ++++++---- - libmultipath/sysfs.c | 5 +---- - 2 files changed, 7 insertions(+), 8 deletions(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 7e09e4e2..f5b8401c 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -1341,13 +1341,15 @@ static int - get_vpd_sysfs (struct udev_device *parent, int pg, char * str, int maxlen) - { - int len; -- size_t buff_len; -+ ssize_t buff_len; - unsigned char buff[VPD_BUFLEN]; - - memset(buff, 0x0, VPD_BUFLEN); -- if (!parent || sysfs_get_vpd(parent, pg, buff, VPD_BUFLEN) <= 0) { -- condlog(3, "failed to read sysfs vpd pg%02x", pg); -- return -EINVAL; -+ buff_len = sysfs_get_vpd(parent, pg, buff, VPD_BUFLEN); -+ if (buff_len < 0) { -+ condlog(3, "failed to read sysfs vpd pg%02x: %s", -+ pg, strerror(-buff_len)); -+ return buff_len; - } - - if (buff[1] != pg) { -diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c -index f45dbee1..3ec92512 100644 ---- a/libmultipath/sysfs.c -+++ b/libmultipath/sysfs.c -@@ -146,10 +146,7 @@ ssize_t sysfs_bin_attr_get_value(struct udev_device *dev, const char *attr_name, - if (size < 0) { - condlog(4, "read from %s failed: %s", devpath, strerror(errno)); - size = -errno; -- } else if (size == (ssize_t)value_len) { -- condlog(4, "overflow while reading from %s", devpath); -- size = 0; -- } -+ }; - - close(fd); - return size; diff --git a/0011-multipath-tools-Makefiles-replace-libdir-by-plugindi.patch b/0011-multipath-tools-Makefiles-replace-libdir-by-plugindi.patch new file mode 100644 index 0000000..82c63d1 --- /dev/null +++ b/0011-multipath-tools-Makefiles-replace-libdir-by-plugindi.patch @@ -0,0 +1,110 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 27 Oct 2022 17:17:00 +0200 +Subject: [PATCH] multipath-tools: Makefiles: replace $(libdir) by $(plugindir) + +The make variables $(libdir) and $(plugindir) are redundant. +I overlooked that in af15832 ("multipath-tools: make multipath_dir a +compiled-in option"). While libdir has existed longer, I think +plugindir describes better what this path is used for, so replace +libdir by plugindir. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 1 - + libmpathutil/Makefile | 1 - + libmultipath/Makefile | 2 +- + libmultipath/checkers/Makefile | 4 ++-- + libmultipath/foreign/Makefile | 4 ++-- + libmultipath/prioritizers/Makefile | 4 ++-- + 6 files changed, 7 insertions(+), 9 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 6ec8201b..17707a3e 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -51,7 +51,6 @@ mandir := $(usr_prefix)/share/man + LIB := $(if $(shell test -d /lib64 && echo 1),lib64,lib) + syslibdir = $(prefix)/$(LIB) + usrlibdir = $(usr_prefix)/$(LIB) +-libdir = $(prefix)/$(LIB)/multipath + includedir = $(usr_prefix)/include + pkgconfdir = $(usrlibdir)/pkgconfig + plugindir := $(prefix)/$(LIB)/multipath +diff --git a/libmpathutil/Makefile b/libmpathutil/Makefile +index 68b1c7d6..c913c761 100644 +--- a/libmpathutil/Makefile ++++ b/libmpathutil/Makefile +@@ -54,7 +54,6 @@ abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) + install: all + $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) + $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) +- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(libdir) + $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) + + uninstall: +diff --git a/libmultipath/Makefile b/libmultipath/Makefile +index f0df27c0..c7d4fc99 100644 +--- a/libmultipath/Makefile ++++ b/libmultipath/Makefile +@@ -119,7 +119,7 @@ test-lib: ../tests/$(LIBS) + install: all + $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) + $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) +- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(libdir) ++ $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(plugindir) + $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) + + uninstall: +diff --git a/libmultipath/checkers/Makefile b/libmultipath/checkers/Makefile +index c9a2c4ca..39ad76e0 100644 +--- a/libmultipath/checkers/Makefile ++++ b/libmultipath/checkers/Makefile +@@ -25,10 +25,10 @@ libcheck%.so: %.o + $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) + + install: +- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(libdir) ++ $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(plugindir) + + uninstall: +- for file in $(LIBS); do $(RM) $(DESTDIR)$(libdir)/$$file; done ++ for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done + + clean: dep_clean + $(RM) core *.a *.o *.gz *.so +diff --git a/libmultipath/foreign/Makefile b/libmultipath/foreign/Makefile +index d0232f20..8bf9047b 100644 +--- a/libmultipath/foreign/Makefile ++++ b/libmultipath/foreign/Makefile +@@ -17,10 +17,10 @@ libforeign-%.so: %.o + $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) + + install: +- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(libdir) ++ $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(plugindir) + + uninstall: +- for file in $(LIBS); do $(RM) $(DESTDIR)$(libdir)/$$file; done ++ for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done + + clean: dep_clean + $(RM) core *.a *.o *.gz *.so +diff --git a/libmultipath/prioritizers/Makefile b/libmultipath/prioritizers/Makefile +index 97155f51..72eefe49 100644 +--- a/libmultipath/prioritizers/Makefile ++++ b/libmultipath/prioritizers/Makefile +@@ -37,10 +37,10 @@ libprio%.so: %.o + $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) + + install: $(LIBS) +- $(INSTALL_PROGRAM) -m 755 libprio*.so $(DESTDIR)$(libdir) ++ $(INSTALL_PROGRAM) -m 755 libprio*.so $(DESTDIR)$(plugindir) + + uninstall: +- for file in $(LIBS); do $(RM) $(DESTDIR)$(libdir)/$$file; done ++ for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done + + clean: dep_clean + $(RM) core *.a *.o *.gz *.so diff --git a/0012-libmultipath-common-code-path-for-sysfs_attr_get_val.patch b/0012-libmultipath-common-code-path-for-sysfs_attr_get_val.patch deleted file mode 100644 index d09cd8a..0000000 --- a/0012-libmultipath-common-code-path-for-sysfs_attr_get_val.patch +++ /dev/null @@ -1,115 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 5 Jul 2022 11:14:30 +0200 -Subject: [PATCH] libmultipath: common code path for sysfs_attr_get_value() - -The code for sysfs_attr_get_value and sysfs_bin_attr_get_value() was -almost identical. Use a common code path. - -Signed-off-by: Martin Wilck - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/sysfs.c | 70 +++++++++++--------------------------------- - 1 file changed, 17 insertions(+), 53 deletions(-) - -diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c -index 3ec92512..4db911cc 100644 ---- a/libmultipath/sysfs.c -+++ b/libmultipath/sysfs.c -@@ -44,8 +44,8 @@ - * as libudev lacks the capability to update an attribute value. - * So for modified attributes we need to implement our own function. - */ --ssize_t sysfs_attr_get_value(struct udev_device *dev, const char *attr_name, -- char * value, size_t value_len) -+static ssize_t __sysfs_attr_get_value(struct udev_device *dev, const char *attr_name, -+ char *value, size_t value_len, bool binary) - { - char devpath[PATH_SIZE]; - struct stat statbuf; -@@ -87,12 +87,14 @@ ssize_t sysfs_attr_get_value(struct udev_device *dev, const char *attr_name, - if (size < 0) { - condlog(4, "read from %s failed: %s", devpath, strerror(errno)); - size = -errno; -- value[0] = '\0'; -- } else if (size == (ssize_t)value_len) { -+ if (!binary) -+ value[0] = '\0'; -+ } else if (!binary && size == (ssize_t)value_len) { -+ condlog(3, "%s: overflow reading from %s (required len: %zu)", -+ __func__, devpath, size); - value[size - 1] = '\0'; -- condlog(4, "overflow while reading from %s", devpath); - size = 0; -- } else { -+ } else if (!binary) { - value[size] = '\0'; - size = strchop(value); - } -@@ -101,55 +103,17 @@ ssize_t sysfs_attr_get_value(struct udev_device *dev, const char *attr_name, - return size; - } - --ssize_t sysfs_bin_attr_get_value(struct udev_device *dev, const char *attr_name, -- unsigned char * value, size_t value_len) -+ssize_t sysfs_attr_get_value(struct udev_device *dev, const char *attr_name, -+ char *value, size_t value_len) - { -- char devpath[PATH_SIZE]; -- struct stat statbuf; -- int fd; -- ssize_t size = -1; -- -- if (!dev || !attr_name || !value) -- return 0; -- -- snprintf(devpath, PATH_SIZE, "%s/%s", udev_device_get_syspath(dev), -- attr_name); -- condlog(4, "open '%s'", devpath); -- /* read attribute value */ -- fd = open(devpath, O_RDONLY); -- if (fd < 0) { -- condlog(4, "attribute '%s' can not be opened: %s", -- devpath, strerror(errno)); -- return -errno; -- } -- if (fstat(fd, &statbuf) != 0) { -- condlog(4, "stat '%s' failed: %s", devpath, strerror(errno)); -- close(fd); -- return -ENXIO; -- } -- -- /* skip directories */ -- if (S_ISDIR(statbuf.st_mode)) { -- condlog(4, "%s is a directory", devpath); -- close(fd); -- return -EISDIR; -- } -- -- /* skip non-writeable files */ -- if ((statbuf.st_mode & S_IRUSR) == 0) { -- condlog(4, "%s is not readable", devpath); -- close(fd); -- return -EPERM; -- } -- -- size = read(fd, value, value_len); -- if (size < 0) { -- condlog(4, "read from %s failed: %s", devpath, strerror(errno)); -- size = -errno; -- }; -+ return __sysfs_attr_get_value(dev, attr_name, value, value_len, false); -+} - -- close(fd); -- return size; -+ssize_t sysfs_bin_attr_get_value(struct udev_device *dev, const char *attr_name, -+ unsigned char *value, size_t value_len) -+{ -+ return __sysfs_attr_get_value(dev, attr_name, (char *)value, -+ value_len, true); - } - - ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, diff --git a/0012-multipath-tools-Makefile.inc-use-simple-make-variabl.patch b/0012-multipath-tools-Makefile.inc-use-simple-make-variabl.patch new file mode 100644 index 0000000..16cca1e --- /dev/null +++ b/0012-multipath-tools-Makefile.inc-use-simple-make-variabl.patch @@ -0,0 +1,112 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 27 Oct 2022 17:35:48 +0200 +Subject: [PATCH] multipath-tools: Makefile.inc: use simple make variables + consistently + +"Simply expanded" make variables are generally preferred over "recursively +expanded" make variables, unless they reference other variables that are +defined over overwritten further down in the Makefile (see +https://www.gnu.org/software/make/manual/html_node/Flavors.html). +Using them makes the code easier to read and even somewhat faster. + +We've been adding simply expanded variables over time, but most older +code still uses recursively expanded ones. Try to be consistent, at least +in Makefile.inc. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 50 +++++++++++++++++++++++++------------------------- + 1 file changed, 25 insertions(+), 25 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 17707a3e..86602e2a 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -32,11 +32,11 @@ SYSTEMD := $(strip $(or $(shell $(PKGCONFIG) --modversion libsystemd 2>/dev/null + $(shell systemctl --version 2>/dev/null | sed -n 's/systemd \([0-9]*\).*/\1/p'))) + + # Paths. All these can be overridden on the "make" command line. +-prefix = ++prefix := + # Prefix for binaries +-exec_prefix = $(prefix) ++exec_prefix := $(prefix) + # Prefix for non-essential libraries (libdmmp) +-usr_prefix = $(prefix) ++usr_prefix := $(prefix) + # Where to install systemd-related files. systemd is usually installed under /usr + # Note: some systemd installations use separate "prefix" and "rootprefix". + # In this case, override only unitdir to use systemd's "rootprefix" instead of $(systemd_prefix) +@@ -46,13 +46,13 @@ tmpfilesdir := $(systemd_prefix)/lib/tmpfiles.d + modulesloaddir := $(systemd_prefix)/lib/modules-load.d + libudevdir := $(systemd_prefix)/lib/udev + udevrulesdir := $(libudevdir)/rules.d +-bindir = $(exec_prefix)/sbin ++bindir := $(exec_prefix)/sbin + mandir := $(usr_prefix)/share/man + LIB := $(if $(shell test -d /lib64 && echo 1),lib64,lib) +-syslibdir = $(prefix)/$(LIB) +-usrlibdir = $(usr_prefix)/$(LIB) +-includedir = $(usr_prefix)/include +-pkgconfdir = $(usrlibdir)/pkgconfig ++syslibdir := $(prefix)/$(LIB) ++usrlibdir := $(usr_prefix)/$(LIB) ++includedir := $(usr_prefix)/include ++pkgconfdir := $(usrlibdir)/pkgconfig + plugindir := $(prefix)/$(LIB)/multipath + configdir := $(prefix)/etc/multipath/conf.d + runtimedir := $(if $(shell test -L /var/run -o ! -d /var/run && echo 1),/run,/var/run) +@@ -60,10 +60,10 @@ devmapper_incdir := $(or $(shell $(PKGCONFIG) --variable=includedir devmapper),/ + libudev_incdir := $(or $(shell $(PKGCONFIG) --variable=includedir libudev),/usr/include) + kernel_incdir := /usr/include + +-GZIP_PROG = gzip -9 -c +-RM = rm -f +-LN = ln -sf +-INSTALL_PROGRAM = install ++GZIP_PROG := gzip -9 -c ++RM := rm -f ++LN := ln -sf ++INSTALL_PROGRAM := install + NV_VERSION_SCRIPT = $(VERSION_SCRIPT:%.version=%-nv.version) + + # $(call TEST_CC_OPTION,option,fallback) +@@ -106,23 +106,23 @@ CPPFLAGS := $(FORTIFY_OPT) \ + -DRUNTIME_DIR=\"$(runtimedir)\" \ + -DCONFIG_DIR=\"$(configdir)\" -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP + CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe +-BIN_CFLAGS = -fPIE -DPIE +-LIB_CFLAGS = -fPIC +-SHARED_FLAGS = -shared ++BIN_CFLAGS := -fPIE -DPIE ++LIB_CFLAGS := -fPIC ++SHARED_FLAGS := -shared + LDFLAGS := $(LDFLAGS) -Wl,-z,relro -Wl,-z,now -Wl,-z,defs +-BIN_LDFLAGS = -pie ++BIN_LDFLAGS := -pie + + # Source code directories. Don't modify. + +-multipathdir = $(TOPDIR)/libmultipath +-daemondir = $(TOPDIR)/multipathd +-mpathutildir = $(TOPDIR)/libmpathutil +-mpathpersistdir = $(TOPDIR)/libmpathpersist +-mpathcmddir = $(TOPDIR)/libmpathcmd +-mpathvaliddir = $(TOPDIR)/libmpathvalid +-thirdpartydir = $(TOPDIR)/third-party +-libdmmpdir = $(TOPDIR)/libdmmp +-nvmedir = $(TOPDIR)/libmultipath/nvme ++multipathdir := $(TOPDIR)/libmultipath ++daemondir := $(TOPDIR)/multipathd ++mpathutildir := $(TOPDIR)/libmpathutil ++mpathpersistdir := $(TOPDIR)/libmpathpersist ++mpathcmddir := $(TOPDIR)/libmpathcmd ++mpathvaliddir := $(TOPDIR)/libmpathvalid ++thirdpartydir := $(TOPDIR)/third-party ++libdmmpdir := $(TOPDIR)/libdmmp ++nvmedir := $(TOPDIR)/libmultipath/nvme + + # Check whether a function with name $1 has been declared in header file $2. + check_func = $(shell \ diff --git a/0013-libmultipath-sanitize-error-checking-in-sysfs-access.patch b/0013-libmultipath-sanitize-error-checking-in-sysfs-access.patch deleted file mode 100644 index 9dc3dc5..0000000 --- a/0013-libmultipath-sanitize-error-checking-in-sysfs-access.patch +++ /dev/null @@ -1,165 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 5 Jul 2022 11:41:40 +0200 -Subject: [PATCH] libmultipath: sanitize error checking in sysfs accessors - -udev_device_get_syspath() may return NULL; check for it, and check -for pathname overflow. Disallow a zero buffer length. The fstat() -calls were superfluous, as a read() or write() on the fd would -return the respective error codes depending on file type or permissions, -the extra system call and code complexity adds no value. - -Log levels should be moderate in sysfs.c, because it depends -on the caller whether errors getting/setting certain attributes are -fatal. - -Signed-off-by: Martin Wilck - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/sysfs.c | 94 ++++++++++++++++++-------------------------- - 1 file changed, 39 insertions(+), 55 deletions(-) - -diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c -index 4db911cc..1f0f2074 100644 ---- a/libmultipath/sysfs.c -+++ b/libmultipath/sysfs.c -@@ -47,46 +47,38 @@ - static ssize_t __sysfs_attr_get_value(struct udev_device *dev, const char *attr_name, - char *value, size_t value_len, bool binary) - { -+ const char *syspath; - char devpath[PATH_SIZE]; -- struct stat statbuf; - int fd; - ssize_t size = -1; - -- if (!dev || !attr_name || !value) -- return 0; -+ if (!dev || !attr_name || !value || !value_len) { -+ condlog(1, "%s: invalid parameters", __func__); -+ return -EINVAL; -+ } - -- snprintf(devpath, PATH_SIZE, "%s/%s", udev_device_get_syspath(dev), -- attr_name); -+ syspath = udev_device_get_syspath(dev); -+ if (!syspath) { -+ condlog(3, "%s: invalid udevice", __func__); -+ return -EINVAL; -+ } -+ if (safe_sprintf(devpath, "%s/%s", syspath, attr_name)) { -+ condlog(3, "%s: devpath overflow", __func__); -+ return -EOVERFLOW; -+ } - condlog(4, "open '%s'", devpath); - /* read attribute value */ - fd = open(devpath, O_RDONLY); - if (fd < 0) { -- condlog(4, "attribute '%s' can not be opened: %s", -- devpath, strerror(errno)); -+ condlog(3, "%s: attribute '%s' can not be opened: %s", -+ __func__, devpath, strerror(errno)); - return -errno; - } -- if (fstat(fd, &statbuf) < 0) { -- condlog(4, "stat '%s' failed: %s", devpath, strerror(errno)); -- close(fd); -- return -ENXIO; -- } -- /* skip directories */ -- if (S_ISDIR(statbuf.st_mode)) { -- condlog(4, "%s is a directory", devpath); -- close(fd); -- return -EISDIR; -- } -- /* skip non-writeable files */ -- if ((statbuf.st_mode & S_IRUSR) == 0) { -- condlog(4, "%s is not readable", devpath); -- close(fd); -- return -EPERM; -- } -- - size = read(fd, value, value_len); - if (size < 0) { -- condlog(4, "read from %s failed: %s", devpath, strerror(errno)); - size = -errno; -+ condlog(3, "%s: read from %s failed: %s", __func__, devpath, -+ strerror(errno)); - if (!binary) - value[0] = '\0'; - } else if (!binary && size == (ssize_t)value_len) { -@@ -119,51 +111,43 @@ ssize_t sysfs_bin_attr_get_value(struct udev_device *dev, const char *attr_name, - ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, - const char * value, size_t value_len) - { -+ const char *syspath; - char devpath[PATH_SIZE]; -- struct stat statbuf; - int fd; - ssize_t size = -1; - -- if (!dev || !attr_name || !value || !value_len) -- return 0; -+ if (!dev || !attr_name || !value || !value_len) { -+ condlog(1, "%s: invalid parameters", __func__); -+ return -EINVAL; -+ } -+ -+ syspath = udev_device_get_syspath(dev); -+ if (!syspath) { -+ condlog(3, "%s: invalid udevice", __func__); -+ return -EINVAL; -+ } -+ if (safe_sprintf(devpath, "%s/%s", syspath, attr_name)) { -+ condlog(3, "%s: devpath overflow", __func__); -+ return -EOVERFLOW; -+ } - -- snprintf(devpath, PATH_SIZE, "%s/%s", udev_device_get_syspath(dev), -- attr_name); - condlog(4, "open '%s'", devpath); - /* write attribute value */ - fd = open(devpath, O_WRONLY); - if (fd < 0) { -- condlog(4, "attribute '%s' can not be opened: %s", -- devpath, strerror(errno)); -- return -errno; -- } -- if (fstat(fd, &statbuf) != 0) { -- condlog(4, "stat '%s' failed: %s", devpath, strerror(errno)); -- close(fd); -+ condlog(2, "%s: attribute '%s' can not be opened: %s", -+ __func__, devpath, strerror(errno)); - return -errno; - } - -- /* skip directories */ -- if (S_ISDIR(statbuf.st_mode)) { -- condlog(4, "%s is a directory", devpath); -- close(fd); -- return -EISDIR; -- } -- -- /* skip non-writeable files */ -- if ((statbuf.st_mode & S_IWUSR) == 0) { -- condlog(4, "%s is not writeable", devpath); -- close(fd); -- return -EPERM; -- } -- - size = write(fd, value, value_len); - if (size < 0) { -- condlog(4, "write to %s failed: %s", devpath, strerror(errno)); - size = -errno; -+ condlog(3, "%s: write to %s failed: %s", __func__, -+ devpath, strerror(errno)); - } else if (size < (ssize_t)value_len) { -- condlog(4, "tried to write %ld to %s. Wrote %ld", -- (long)value_len, devpath, (long)size); -+ condlog(3, "%s: underflow writing %zu bytes to %s. Wrote %zd bytes", -+ __func__, value_len, devpath, size); - size = 0; - } - diff --git a/0013-multipath-tools-Makefile.inc-fix-a-log-message.patch b/0013-multipath-tools-Makefile.inc-fix-a-log-message.patch new file mode 100644 index 0000000..3e424dc --- /dev/null +++ b/0013-multipath-tools-Makefile.inc-fix-a-log-message.patch @@ -0,0 +1,24 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 27 Oct 2022 17:40:30 +0200 +Subject: [PATCH] multipath-tools: Makefile.inc: fix a log message + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 86602e2a..77790ddf 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -159,7 +159,7 @@ check_var = $(shell \ + found=0; \ + status="no"; \ + fi; \ +- echo 1>&2 "Checking for .. $1 in $2 ... $$status"; \ ++ echo 1>&2 "Checking for $1 in $2 ... $$status"; \ + echo "$$found" \ + ) + diff --git a/0014-libmultipath-get-rid-of-PATH_SIZE.patch b/0014-libmultipath-get-rid-of-PATH_SIZE.patch deleted file mode 100644 index a080792..0000000 --- a/0014-libmultipath-get-rid-of-PATH_SIZE.patch +++ /dev/null @@ -1,115 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 5 Jul 2022 11:52:42 +0200 -Subject: [PATCH] libmultipath: get rid of PATH_SIZE - -replace PATH_SIZE with the system limit PATH_MAX. In some places, -PATH_SIZE was used for file names. Use FILE_NAME_SIZE in these cases. -Also, use a constant for "multipathd.service" in systemd_service_enabled_in(). - -Signed-off-by: Martin Wilck - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/structs.h | 3 --- - libmultipath/sysfs.c | 8 ++++---- - libmultipath/util.c | 8 +++++--- - multipathd/cli_handlers.c | 2 +- - 4 files changed, 10 insertions(+), 11 deletions(-) - -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index a6a09441..dfa12ff9 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -17,7 +17,6 @@ - #define FILE_NAME_SIZE 256 - #define CALLOUT_MAX_SIZE 256 - #define BLK_DEV_SIZE 33 --#define PATH_SIZE 512 - #define NAME_SIZE 512 - #define HOST_NAME_LEN 16 - #define SLOT_NAME_SIZE 40 -@@ -519,6 +518,4 @@ int pathcmp (const struct pathgroup *, const struct pathgroup *); - int add_feature (char **, const char *); - int remove_feature (char **, const char *); - --extern char sysfs_path[PATH_SIZE]; -- - #endif /* _STRUCTS_H */ -diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c -index 1f0f2074..e48b05ec 100644 ---- a/libmultipath/sysfs.c -+++ b/libmultipath/sysfs.c -@@ -48,7 +48,7 @@ static ssize_t __sysfs_attr_get_value(struct udev_device *dev, const char *attr_ - char *value, size_t value_len, bool binary) - { - const char *syspath; -- char devpath[PATH_SIZE]; -+ char devpath[PATH_MAX]; - int fd; - ssize_t size = -1; - -@@ -112,7 +112,7 @@ ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, - const char * value, size_t value_len) - { - const char *syspath; -- char devpath[PATH_SIZE]; -+ char devpath[PATH_MAX]; - int fd; - ssize_t size = -1; - -@@ -184,7 +184,7 @@ sysfs_get_size (struct path *pp, unsigned long long * size) - int sysfs_check_holders(char * check_devt, char * new_devt) - { - unsigned int major, new_minor, table_minor; -- char path[PATH_MAX], check_dev[PATH_SIZE]; -+ char path[PATH_MAX], check_dev[FILE_NAME_SIZE]; - char * table_name; - DIR *dirfd; - struct dirent *holder; -@@ -194,7 +194,7 @@ int sysfs_check_holders(char * check_devt, char * new_devt) - return 0; - } - -- if (devt2devname(check_dev, PATH_SIZE, check_devt)) { -+ if (devt2devname(check_dev, sizeof(check_dev), check_devt)) { - condlog(1, "can't get devname for %s", check_devt); - return 0; - } -diff --git a/libmultipath/util.c b/libmultipath/util.c -index ce5ea73e..e7e7d4c1 100644 ---- a/libmultipath/util.c -+++ b/libmultipath/util.c -@@ -242,13 +242,15 @@ setup_thread_attr(pthread_attr_t *attr, size_t stacksize, int detached) - - int systemd_service_enabled_in(const char *dev, const char *prefix) - { -- char path[PATH_SIZE], file[PATH_MAX], service[PATH_SIZE]; -+ static const char service[] = "multipathd.service"; -+ char path[PATH_MAX], file[PATH_MAX]; - DIR *dirfd; - struct dirent *d; - int found = 0; - -- snprintf(service, PATH_SIZE, "multipathd.service"); -- snprintf(path, PATH_SIZE, "%s/systemd/system", prefix); -+ if (safe_sprintf(path, "%s/systemd/system", prefix)) -+ return 0; -+ - condlog(3, "%s: checking for %s in %s", dev, service, path); - - dirfd = opendir(path); -diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c -index d79cdd7c..db4d4412 100644 ---- a/multipathd/cli_handlers.c -+++ b/multipathd/cli_handlers.c -@@ -688,7 +688,7 @@ cli_add_map (void * v, struct strbuf *reply, void * data) - struct vectors * vecs = (struct vectors *)data; - char * param = get_keyparam(v, MAP); - int major = -1, minor = -1; -- char dev_path[PATH_SIZE]; -+ char dev_path[FILE_NAME_SIZE]; - char *refwwid, *alias = NULL; - int rc, count = 0; - struct config *conf; diff --git a/0014-multipath-tools-Makefile.inc-set-systemd-specific-fl.patch b/0014-multipath-tools-Makefile.inc-set-systemd-specific-fl.patch new file mode 100644 index 0000000..fa37b7c --- /dev/null +++ b/0014-multipath-tools-Makefile.inc-set-systemd-specific-fl.patch @@ -0,0 +1,129 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 27 Oct 2022 16:40:27 +0200 +Subject: [PATCH] multipath-tools: Makefile.inc: set systemd-specific flags + +Define SYSTEMD_CPPFLAGS and SYSTEMD_LIBDEPS, and use them in Makefiles. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 3 +++ + libmpathutil/Makefile | 13 ++----------- + libmultipath/Makefile | 14 +++----------- + multipathd/Makefile | 25 ++++++++----------------- + 4 files changed, 16 insertions(+), 39 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 77790ddf..2cf25745 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -97,6 +97,9 @@ ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers + WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered -Wno-error=clobbered,) + WFORMATOVERFLOW := $(call TEST_CC_OPTION,-Wformat-overflow=2,) + ++SYSTEMD_CPPFLAGS := $(if $(SYSTEMD),-DUSE_SYSTEMD=$(SYSTEMD)) ++SYSTEMD_LIBDEPS := $(if $(SYSTEMD),$(if $(shell test $(SYSTEMD) -gt 209 && echo 1),-lsystemd,-lsystemd-daemon)) ++ + OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 + WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int \ + -Werror=implicit-function-declaration -Werror=format-security \ +diff --git a/libmpathutil/Makefile b/libmpathutil/Makefile +index c913c761..4be75d2d 100644 +--- a/libmpathutil/Makefile ++++ b/libmpathutil/Makefile +@@ -8,19 +8,10 @@ DEVLIB = libmpathutil.so + LIBS = $(DEVLIB).$(SONAME) + VERSION_SCRIPT := libmpathutil.version + +-CPPFLAGS += -I. -I$(multipathdir) -I$(mpathcmddir) ++CPPFLAGS += -I. -I$(multipathdir) -I$(mpathcmddir) $(SYSTEMD_CPPFLAGS) + CFLAGS += $(LIB_CFLAGS) -D_GNU_SOURCE + +-LIBDEPS += -lpthread -ldl -ludev -L$(mpathcmddir) -lmpathcmd +- +-ifdef SYSTEMD +- CPPFLAGS += -DUSE_SYSTEMD=$(SYSTEMD) +- ifeq ($(shell test $(SYSTEMD) -gt 209 && echo 1), 1) +- LIBDEPS += -lsystemd +- else +- LIBDEPS += -lsystemd-daemon +- endif +-endif ++LIBDEPS += -lpthread -ldl -ludev -L$(mpathcmddir) -lmpathcmd $(SYSTEMD_LIBDEPS) + + # object files referencing MULTIPATH_DIR or CONFIG_DIR + # they need to be recompiled for unit tests +diff --git a/libmultipath/Makefile b/libmultipath/Makefile +index c7d4fc99..009f26a3 100644 +--- a/libmultipath/Makefile ++++ b/libmultipath/Makefile +@@ -8,19 +8,11 @@ DEVLIB = libmultipath.so + LIBS = $(DEVLIB).$(SONAME) + VERSION_SCRIPT := libmultipath.version + +-CPPFLAGS += -I$(mpathutildir) -I$(mpathcmddir) -I$(nvmedir) -D_GNU_SOURCE ++CPPFLAGS += -I$(mpathutildir) -I$(mpathcmddir) -I$(nvmedir) -D_GNU_SOURCE $(SYSTEMD_CPPFLAGS) + CFLAGS += $(LIB_CFLAGS) + +-LIBDEPS += -lpthread -ldl -ldevmapper -ludev -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd -lurcu -laio +- +-ifdef SYSTEMD +- CPPFLAGS += -DUSE_SYSTEMD=$(SYSTEMD) +- ifeq ($(shell test $(SYSTEMD) -gt 209 && echo 1), 1) +- LIBDEPS += -lsystemd +- else +- LIBDEPS += -lsystemd-daemon +- endif +-endif ++LIBDEPS += -lpthread -ldl -ldevmapper -ludev -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd \ ++ -lurcu -laio $(SYSTEMD_LIBDEPS) + + ifneq ($(call check_func,dm_task_no_flush,$(devmapper_incdir)/libdevmapper.h),0) + CPPFLAGS += -DLIBDM_API_FLUSH +diff --git a/multipathd/Makefile b/multipathd/Makefile +index 78aefee0..cdda371b 100644 +--- a/multipathd/Makefile ++++ b/multipathd/Makefile +@@ -18,14 +18,17 @@ endif + CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathpersistdir) -I$(mpathcmddir) -I$(thirdpartydir) \ + $(shell $(PKGCONFIG) --modversion liburcu 2>/dev/null | \ + awk -F. '{ printf("-DURCU_VERSION=0x%06x", 256 * ( 256 * $$1 + $$2) + $$3); }') \ +- -DBINDIR='"$(bindir)"' ++ -DBINDIR='"$(bindir)"' $(SYSTEMD_CPPFLAGS) ++ifeq ($(ENABLE_DMEVENTS_POLL),0) ++ CPPFLAGS += -DNO_DMEVENTS_POLL ++endif + CFLAGS += $(BIN_CFLAGS) + LDFLAGS += $(BIN_LDFLAGS) + +-CLI_LIBDEPS := -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd -ludev -ldl -lurcu -lpthread +-LIBDEPS += -L$(multipathdir) -lmultipath -L$(mpathpersistdir) -lmpathpersist \ +- -ldevmapper $(CLI_LIBDEPS) +- ++CLI_LIBDEPS := -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd \ ++ -ludev -ldl -lurcu -lpthread $(SYSTEMD_LIBDEPS) ++LIBDEPS := -L$(multipathdir) -lmultipath -L$(mpathpersistdir) -lmpathpersist \ ++ -ldevmapper $(CLI_LIBDEPS) + + ifeq ($(READLINE),libedit) + RL_CPPFLAGS = -DUSE_LIBEDIT +@@ -40,18 +43,6 @@ RL_CPPFLAGS += -DBROKEN_RL_COMPLETION_FUNC + endif + endif + +-ifdef SYSTEMD +- CPPFLAGS += -DUSE_SYSTEMD=$(SYSTEMD) +- ifeq ($(shell test $(SYSTEMD) -gt 209 && echo 1), 1) +- CLI_LIBDEPS += -lsystemd +- else +- CLI_LIBDEPS += -lsystemd-daemon +- endif +-endif +-ifeq ($(ENABLE_DMEVENTS_POLL),0) +- CPPFLAGS += -DNO_DMEVENTS_POLL +-endif +- + OBJS = main.o pidfile.o uxlsnr.o uxclnt.o cli.o cli_handlers.o waiter.o \ + dmevents.o init_unwinder.o + diff --git a/0015-libmultipath-sysfs_attr_get_value-don-t-return-0-if-.patch b/0015-libmultipath-sysfs_attr_get_value-don-t-return-0-if-.patch deleted file mode 100644 index d58b785..0000000 --- a/0015-libmultipath-sysfs_attr_get_value-don-t-return-0-if-.patch +++ /dev/null @@ -1,172 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 5 Jul 2022 13:33:51 +0200 -Subject: [PATCH] libmultipath: sysfs_attr_get_value(): don't return 0 if - buffer too small - -If the passed read buffer is too small to hold the value read plus -terminating 0 byte, return the given size value rather than 0. - -This way we get similar semantics as for sysfs_bin_attr_get_get_value(), -except that sysfs_attr_get_value() must always 0-terminate the value; -thus a return value equal to the length parameter is an error for -the non-binary case. - -Provide a helper macro to test this "overflow" condition. - -Signed-off-by: Martin Wilck - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 2 +- - libmultipath/discovery.c | 14 +++++++------- - libmultipath/propsel.c | 6 +++++- - libmultipath/sysfs.c | 3 +-- - libmultipath/sysfs.h | 13 +++++++++++++ - multipathd/main.c | 2 +- - 6 files changed, 28 insertions(+), 12 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 09ae708d..467bbaa6 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -589,7 +589,7 @@ sysfs_set_max_sectors_kb(struct multipath *mpp, int is_reload) - ret = sysfs_attr_get_value(udd, "queue/max_sectors_kb", buff, - sizeof(buff)); - udev_device_unref(udd); -- if (ret <= 0) { -+ if (!sysfs_attr_value_ok(ret, sizeof(buff))) { - condlog(1, "failed to get current max_sectors_kb from %s", mpp->alias); - return 1; - } -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index f5b8401c..54b1caf0 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -560,10 +560,10 @@ sysfs_get_asymmetric_access_state(struct path *pp, char *buff, int buflen) - if (!parent) - return -1; - -- if (sysfs_attr_get_value(parent, "access_state", buff, buflen) <= 0) -+ if (!sysfs_attr_get_value_ok(parent, "access_state", buff, buflen)) - return -1; - -- if (sysfs_attr_get_value(parent, "preferred_path", value, 16) <= 0) -+ if (!sysfs_attr_get_value_ok(parent, "preferred_path", value, sizeof(value))) - return 0; - - preferred = strtoul(value, &eptr, 0); -@@ -638,8 +638,8 @@ sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp) - /* - * read the current dev_loss_tmo value from sysfs - */ -- ret = sysfs_attr_get_value(rport_dev, "dev_loss_tmo", value, 16); -- if (ret <= 0) { -+ ret = sysfs_attr_get_value(rport_dev, "dev_loss_tmo", value, sizeof(value)); -+ if (!sysfs_attr_value_ok(ret, sizeof(value))) { - condlog(0, "%s: failed to read dev_loss_tmo value, " - "error %d", rport_id, -ret); - goto out; -@@ -1737,8 +1737,8 @@ path_offline (struct path * pp) - } - - memset(buff, 0x0, SCSI_STATE_SIZE); -- err = sysfs_attr_get_value(parent, "state", buff, SCSI_STATE_SIZE); -- if (err <= 0) { -+ err = sysfs_attr_get_value(parent, "state", buff, sizeof(buff)); -+ if (!sysfs_attr_value_ok(err, sizeof(buff))) { - if (err == -ENXIO) - return PATH_REMOVED; - else -@@ -2142,7 +2142,7 @@ static ssize_t uid_fallback(struct path *pp, int path_state, - return -1; - len = sysfs_attr_get_value(pp->udev, "wwid", value, - sizeof(value)); -- if (len <= 0) -+ if (!sysfs_attr_value_ok(len, sizeof(value))) - return -1; - len = strlcpy(pp->wwid, value, WWID_SIZE); - if (len >= WWID_SIZE) { -diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c -index f782f251..98e3aad1 100644 ---- a/libmultipath/propsel.c -+++ b/libmultipath/propsel.c -@@ -435,6 +435,7 @@ out: - static int get_dh_state(struct path *pp, char *value, size_t value_len) - { - struct udev_device *ud; -+ ssize_t rc; - - if (pp->udev == NULL) - return -1; -@@ -444,7 +445,10 @@ static int get_dh_state(struct path *pp, char *value, size_t value_len) - if (ud == NULL) - return -1; - -- return sysfs_attr_get_value(ud, "dh_state", value, value_len); -+ rc = sysfs_attr_get_value(ud, "dh_state", value, value_len); -+ if (!sysfs_attr_value_ok(rc, value_len)) -+ return -1; -+ return rc; - } - - int select_hwhandler(struct config *conf, struct multipath *mp) -diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c -index e48b05ec..125f1c2b 100644 ---- a/libmultipath/sysfs.c -+++ b/libmultipath/sysfs.c -@@ -85,7 +85,6 @@ static ssize_t __sysfs_attr_get_value(struct udev_device *dev, const char *attr_ - condlog(3, "%s: overflow reading from %s (required len: %zu)", - __func__, devpath, size); - value[size - 1] = '\0'; -- size = 0; - } else if (!binary) { - value[size] = '\0'; - size = strchop(value); -@@ -165,7 +164,7 @@ sysfs_get_size (struct path *pp, unsigned long long * size) - return 1; - - attr[0] = '\0'; -- if (sysfs_attr_get_value(pp->udev, "size", attr, 255) <= 0) { -+ if (!sysfs_attr_get_value_ok(pp->udev, "size", attr, sizeof(attr))) { - condlog(3, "%s: No size attribute in sysfs", pp->dev); - return 1; - } -diff --git a/libmultipath/sysfs.h b/libmultipath/sysfs.h -index 72b39ab2..cdc84e40 100644 ---- a/libmultipath/sysfs.h -+++ b/libmultipath/sysfs.h -@@ -12,6 +12,19 @@ ssize_t sysfs_attr_get_value(struct udev_device *dev, const char *attr_name, - char * value, size_t value_len); - ssize_t sysfs_bin_attr_get_value(struct udev_device *dev, const char *attr_name, - unsigned char * value, size_t value_len); -+#define sysfs_attr_value_ok(rc, value_len) \ -+ ({ \ -+ ssize_t __r = rc; \ -+ __r >= 0 && (size_t)__r < (size_t)value_len; \ -+ }) -+ -+#define sysfs_attr_get_value_ok(dev, attr, val, len) \ -+ ({ \ -+ size_t __l = (len); \ -+ ssize_t __rc = sysfs_attr_get_value(dev, attr, val, __l); \ -+ sysfs_attr_value_ok(__rc, __l); \ -+ }) -+ - int sysfs_get_size (struct path *pp, unsigned long long * size); - int sysfs_check_holders(char * check_devt, char * new_devt); - bool sysfs_is_multipathed(struct path *pp, bool set_wwid); -diff --git a/multipathd/main.c b/multipathd/main.c -index 2f2b9d4c..68eca925 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -1126,7 +1126,7 @@ sysfs_get_ro (struct path *pp) - if (!pp->udev) - return -1; - -- if (sysfs_attr_get_value(pp->udev, "ro", buff, sizeof(buff)) <= 0) { -+ if (!sysfs_attr_get_value_ok(pp->udev, "ro", buff, sizeof(buff))) { - condlog(3, "%s: Cannot read ro attribute in sysfs", pp->dev); - return -1; - } diff --git a/0015-multipathd-Makefile-fix-compilation-flags-for-libedi.patch b/0015-multipathd-Makefile-fix-compilation-flags-for-libedi.patch new file mode 100644 index 0000000..0013036 --- /dev/null +++ b/0015-multipathd-Makefile-fix-compilation-flags-for-libedi.patch @@ -0,0 +1,54 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 27 Oct 2022 18:51:52 +0200 +Subject: [PATCH] multipathd: Makefile: fix compilation flags for libedit + +The workaround for the wrong prototype in older libedit versions +had ended up in the code for libreadline. Fix it, and use simple +make variables. + +Fixes: 2bd80f6 ("multipathd: fix incompatible pointer type error with libedit") +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + multipathd/Makefile | 16 +++++++--------- + 1 file changed, 7 insertions(+), 9 deletions(-) + +diff --git a/multipathd/Makefile b/multipathd/Makefile +index cdda371b..7221b6af 100644 +--- a/multipathd/Makefile ++++ b/multipathd/Makefile +@@ -31,17 +31,17 @@ LIBDEPS := -L$(multipathdir) -lmultipath -L$(mpathpersistdir) -lmpathpersist \ + -ldevmapper $(CLI_LIBDEPS) + + ifeq ($(READLINE),libedit) +-RL_CPPFLAGS = -DUSE_LIBEDIT +-RL_LIBDEPS += -ledit +-endif +-ifeq ($(READLINE),libreadline) +-RL_CPPFLAGS += -DUSE_LIBREADLINE +-RL_LIBDEPS += -lreadline +-# See comment in uxclnt.c ++RL_CPPFLAGS := -DUSE_LIBEDIT ++RL_LIBDEPS := -ledit ++# See comment in multipathc.c + ifeq ($(shell sed -En 's/.*\ -Date: Tue, 5 Jul 2022 17:51:41 +0200 -Subject: [PATCH] libmultipath: sysfs_attr_set_value(): don't return 0 on - partial write - -sysfs_attr_set_value() returned 0 if not all requested bytes were written. -Change this to return the number of bytes written. Error checking is now -somewhat more involved; provide a helper macro for it. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 10 ++++-- - libmultipath/discovery.c | 74 +++++++++++++++++++++++++--------------- - libmultipath/sysfs.c | 6 ++-- - libmultipath/sysfs.h | 10 ++++++ - 4 files changed, 66 insertions(+), 34 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 467bbaa6..0607dbac 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -568,6 +568,7 @@ sysfs_set_max_sectors_kb(struct multipath *mpp, int is_reload) - struct pathgroup * pgp; - struct path *pp; - char buff[11]; -+ ssize_t len; - int i, j, ret, err = 0; - struct udev_device *udd; - int max_sectors_kb; -@@ -600,14 +601,17 @@ sysfs_set_max_sectors_kb(struct multipath *mpp, int is_reload) - } - } - snprintf(buff, 11, "%d", max_sectors_kb); -+ len = strlen(buff); - - vector_foreach_slot (mpp->pg, pgp, i) { - vector_foreach_slot(pgp->paths, pp, j) { - ret = sysfs_attr_set_value(pp->udev, - "queue/max_sectors_kb", -- buff, strlen(buff)); -- if (ret < 0) { -- condlog(1, "failed setting max_sectors_kb on %s : %s", pp->dev, strerror(-ret)); -+ buff, len); -+ if (ret != len) { -+ log_sysfs_attr_set_value(1, ret, -+ "failed setting max_sectors_kb on %s", -+ pp->dev); - err = 1; - } - } -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 54b1caf0..ee290093 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -598,13 +598,15 @@ sysfs_set_eh_deadline(struct path *pp) - len = sprintf(value, "%d", pp->eh_deadline); - - ret = sysfs_attr_set_value(hostdev, "eh_deadline", -- value, len + 1); -+ value, len); - /* - * not all scsi drivers support setting eh_deadline, so failing - * is totally reasonable - */ -- if (ret <= 0) -- condlog(3, "%s: failed to set eh_deadline to %s, error %d", udev_device_get_sysname(hostdev), value, -ret); -+ if (ret != len) -+ log_sysfs_attr_set_value(3, ret, -+ "%s: failed to set eh_deadline to %s", -+ udev_device_get_sysname(hostdev), value); - - udev_device_unref(hostdev); - return (ret <= 0); -@@ -667,19 +669,22 @@ sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp) - pp->fast_io_fail != MP_FAST_IO_FAIL_OFF) { - /* Check if we need to temporarily increase dev_loss_tmo */ - if ((unsigned int)pp->fast_io_fail >= tmo) { -+ ssize_t len; -+ - /* Increase dev_loss_tmo temporarily */ - snprintf(value, sizeof(value), "%u", - (unsigned int)pp->fast_io_fail + 1); -+ len = strlen(value); - ret = sysfs_attr_set_value(rport_dev, "dev_loss_tmo", -- value, strlen(value)); -- if (ret <= 0) { -+ value, len); -+ if (ret != len) { - if (ret == -EBUSY) - condlog(3, "%s: rport blocked", - rport_id); - else -- condlog(0, "%s: failed to set " -- "dev_loss_tmo to %s, error %d", -- rport_id, value, -ret); -+ log_sysfs_attr_set_value(0, ret, -+ "%s: failed to set dev_loss_tmo to %s", -+ rport_id, value); - goto out; - } - } -@@ -691,32 +696,39 @@ sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp) - pp->dev_loss = DEFAULT_DEV_LOSS_TMO; - } - if (pp->fast_io_fail != MP_FAST_IO_FAIL_UNSET) { -+ ssize_t len; -+ - if (pp->fast_io_fail == MP_FAST_IO_FAIL_OFF) - sprintf(value, "off"); - else if (pp->fast_io_fail == MP_FAST_IO_FAIL_ZERO) - sprintf(value, "0"); - else - snprintf(value, 16, "%u", pp->fast_io_fail); -+ len = strlen(value); - ret = sysfs_attr_set_value(rport_dev, "fast_io_fail_tmo", -- value, strlen(value)); -- if (ret <= 0) { -+ value, len); -+ if (ret != len) { - if (ret == -EBUSY) - condlog(3, "%s: rport blocked", rport_id); - else -- condlog(0, "%s: failed to set fast_io_fail_tmo to %s, error %d", -- rport_id, value, -ret); -+ log_sysfs_attr_set_value(0, ret, -+ "%s: failed to set fast_io_fail_tmo to %s", -+ rport_id, value); - } - } - if (pp->dev_loss != DEV_LOSS_TMO_UNSET) { -+ ssize_t len; -+ - snprintf(value, 16, "%u", pp->dev_loss); -- ret = sysfs_attr_set_value(rport_dev, "dev_loss_tmo", -- value, strlen(value)); -- if (ret <= 0) { -+ len = strlen(value); -+ ret = sysfs_attr_set_value(rport_dev, "dev_loss_tmo", value, len); -+ if (ret != len) { - if (ret == -EBUSY) - condlog(3, "%s: rport blocked", rport_id); - else -- condlog(0, "%s: failed to set dev_loss_tmo to %s, error %d", -- rport_id, value, -ret); -+ log_sysfs_attr_set_value(0, ret, -+ "%s: failed to set dev_loss_tmo to %s", -+ rport_id, value); - } - } - out: -@@ -754,12 +766,16 @@ sysfs_set_session_tmo(struct path *pp) - condlog(3, "%s: can't set fast_io_fail_tmo to '0'" - "on iSCSI", pp->dev); - } else { -+ ssize_t len, ret; -+ - snprintf(value, 11, "%u", pp->fast_io_fail); -- if (sysfs_attr_set_value(session_dev, "recovery_tmo", -- value, strlen(value)) <= 0) { -- condlog(3, "%s: Failed to set recovery_tmo, " -- " error %d", pp->dev, errno); -- } -+ len = strlen(value); -+ ret = sysfs_attr_set_value(session_dev, "recovery_tmo", -+ value, len); -+ if (ret != len) -+ log_sysfs_attr_set_value(3, ret, -+ "%s: Failed to set recovery_tmo to %s", -+ pp->dev, value); - } - } - udev_device_unref(session_dev); -@@ -802,12 +818,16 @@ sysfs_set_nexus_loss_tmo(struct path *pp) - pp->sg_id.channel, pp->sg_id.scsi_id, end_dev_id); - - if (pp->dev_loss != DEV_LOSS_TMO_UNSET) { -+ ssize_t len, ret; -+ - snprintf(value, 11, "%u", pp->dev_loss); -- if (sysfs_attr_set_value(sas_dev, "I_T_nexus_loss_timeout", -- value, strlen(value)) <= 0) -- condlog(3, "%s: failed to update " -- "I_T Nexus loss timeout, error %d", -- pp->dev, errno); -+ len = strlen(value); -+ ret = sysfs_attr_set_value(sas_dev, "I_T_nexus_loss_timeout", -+ value, len); -+ if (ret != len) -+ log_sysfs_attr_set_value(3, ret, -+ "%s: failed to update I_T Nexus loss timeout", -+ pp->dev); - } - udev_device_unref(sas_dev); - return; -diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c -index 125f1c2b..9c84af70 100644 ---- a/libmultipath/sysfs.c -+++ b/libmultipath/sysfs.c -@@ -134,7 +134,7 @@ ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, - /* write attribute value */ - fd = open(devpath, O_WRONLY); - if (fd < 0) { -- condlog(2, "%s: attribute '%s' can not be opened: %s", -+ condlog(3, "%s: attribute '%s' can not be opened: %s", - __func__, devpath, strerror(errno)); - return -errno; - } -@@ -144,11 +144,9 @@ ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, - size = -errno; - condlog(3, "%s: write to %s failed: %s", __func__, - devpath, strerror(errno)); -- } else if (size < (ssize_t)value_len) { -+ } else if (size < (ssize_t)value_len) - condlog(3, "%s: underflow writing %zu bytes to %s. Wrote %zd bytes", - __func__, value_len, devpath, size); -- size = 0; -- } - - close(fd); - return size; -diff --git a/libmultipath/sysfs.h b/libmultipath/sysfs.h -index cdc84e40..799f68e9 100644 ---- a/libmultipath/sysfs.h -+++ b/libmultipath/sysfs.h -@@ -5,6 +5,7 @@ - #ifndef _LIBMULTIPATH_SYSFS_H - #define _LIBMULTIPATH_SYSFS_H - #include -+#include "strbuf.h" - - ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, - const char * value, size_t value_len); -@@ -25,6 +26,15 @@ ssize_t sysfs_bin_attr_get_value(struct udev_device *dev, const char *attr_name, - sysfs_attr_value_ok(__rc, __l); \ - }) - -+#define log_sysfs_attr_set_value(prio, rc, fmt, __args...) \ -+do { \ -+ STRBUF_ON_STACK(__buf); \ -+ if (print_strbuf(&__buf, fmt, ##__args) >= 0 && \ -+ print_strbuf(&__buf, ": %s", rc < 0 ? strerror(-rc) : \ -+ "write underflow") >= 0) \ -+ condlog(prio, "%s", get_strbuf_str(&__buf)); \ -+} while(0) -+ - int sysfs_get_size (struct path *pp, unsigned long long * size); - int sysfs_check_holders(char * check_devt, char * new_devt); - bool sysfs_is_multipathed(struct path *pp, bool set_wwid); diff --git a/0016-multipath-tools-Makefiles-clean-up-executable-Makefi.patch b/0016-multipath-tools-Makefiles-clean-up-executable-Makefi.patch new file mode 100644 index 0000000..3dd4a8a --- /dev/null +++ b/0016-multipath-tools-Makefiles-clean-up-executable-Makefi.patch @@ -0,0 +1,136 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 27 Oct 2022 21:59:36 +0200 +Subject: [PATCH] multipath-tools Makefiles: clean up executable Makefiles + +Move the EXEC definition to the top, and use simple make variables +where possible. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + kpartx/Makefile | 15 +++++++-------- + multipath/Makefile | 6 +++--- + multipathd/Makefile | 30 ++++++++++++++---------------- + 3 files changed, 24 insertions(+), 27 deletions(-) + +diff --git a/kpartx/Makefile b/kpartx/Makefile +index 464925ad..7ceae96b 100644 +--- a/kpartx/Makefile ++++ b/kpartx/Makefile +@@ -3,20 +3,19 @@ + # + include ../Makefile.inc + +-CPPFLAGS += -I. -I$(multipathdir) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 +-CFLAGS += $(BIN_CFLAGS) +-LDFLAGS += $(BIN_LDFLAGS) +- +-LIBDEPS += -ldevmapper ++EXEC := kpartx + ++CPPFLAGS += -I. -I$(multipathdir) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 + ifneq ($(call check_func,dm_task_set_cookie,$(devmapper_incdir)/libdevmapper.h),0) + CPPFLAGS += -DLIBDM_API_COOKIE + endif + +-OBJS = bsd.o dos.o kpartx.o solaris.o unixware.o dasd.o sun.o \ +- gpt.o mac.o ps3.o crc32.o lopart.o xstrncpy.o devmapper.o ++CFLAGS += $(BIN_CFLAGS) ++LDFLAGS += $(BIN_LDFLAGS) ++LIBDEPS += -ldevmapper + +-EXEC = kpartx ++OBJS := bsd.o dos.o kpartx.o solaris.o unixware.o dasd.o sun.o \ ++ gpt.o mac.o ps3.o crc32.o lopart.o xstrncpy.o devmapper.o + + all: $(EXEC) + +diff --git a/multipath/Makefile b/multipath/Makefile +index 1c4e7a52..7f7b341d 100644 +--- a/multipath/Makefile ++++ b/multipath/Makefile +@@ -3,15 +3,15 @@ + # + include ../Makefile.inc + ++EXEC := multipath ++ + CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathcmddir) + CFLAGS += $(BIN_CFLAGS) + LDFLAGS += $(BIN_LDFLAGS) + LIBDEPS += -L$(multipathdir) -lmultipath -L$(mpathutildir) -lmpathutil \ + -L$(mpathcmddir) -lmpathcmd -lpthread -ldevmapper -ldl -ludev + +-EXEC = multipath +- +-OBJS = main.o ++OBJS := main.o + + all: $(EXEC) multipath.rules tmpfiles.conf + +diff --git a/multipathd/Makefile b/multipathd/Makefile +index 7221b6af..bb8f7770 100644 +--- a/multipathd/Makefile ++++ b/multipathd/Makefile +@@ -1,27 +1,30 @@ + include ../Makefile.inc + ++EXEC := multipathd ++CLI := multipathc ++ ++CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathpersistdir) -I$(mpathcmddir) -I$(thirdpartydir) \ ++ $(shell $(PKGCONFIG) --modversion liburcu 2>/dev/null | \ ++ awk -F. '{ printf("-DURCU_VERSION=0x%06x", 256 * ( 256 * $$1 + $$2) + $$3); }') \ ++ -DBINDIR='"$(bindir)"' $(SYSTEMD_CPPFLAGS) ++ ++ifeq ($(ENABLE_DMEVENTS_POLL),0) ++ CPPFLAGS += -DNO_DMEVENTS_POLL ++endif + ifneq ($(call check_func,dm_task_get_errno,$(devmapper_incdir)/libdevmapper.h),0) + CPPFLAGS += -DLIBDM_API_GET_ERRNO + endif +- + ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(kernel_incdir)/scsi/fc/fc_els.h),0) + CPPFLAGS += -DFPIN_EVENT_HANDLER + FPIN_SUPPORT = 1 + endif ++ + # + # debugging stuff + # + #CPPFLAGS += -DLCKDBG +-#CPPFLAGS += -D_DEBUG_ + #CPPFLAGS += -DLOGDBG + +-CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathpersistdir) -I$(mpathcmddir) -I$(thirdpartydir) \ +- $(shell $(PKGCONFIG) --modversion liburcu 2>/dev/null | \ +- awk -F. '{ printf("-DURCU_VERSION=0x%06x", 256 * ( 256 * $$1 + $$2) + $$3); }') \ +- -DBINDIR='"$(bindir)"' $(SYSTEMD_CPPFLAGS) +-ifeq ($(ENABLE_DMEVENTS_POLL),0) +- CPPFLAGS += -DNO_DMEVENTS_POLL +-endif + CFLAGS += $(BIN_CFLAGS) + LDFLAGS += $(BIN_LDFLAGS) + +@@ -43,18 +46,13 @@ RL_CPPFLAGS := -DUSE_LIBREADLINE + RL_LIBDEPS := -lreadline + endif + +-OBJS = main.o pidfile.o uxlsnr.o uxclnt.o cli.o cli_handlers.o waiter.o \ ++CLI_OBJS := multipathc.o cli.o ++OBJS := main.o pidfile.o uxlsnr.o uxclnt.o cli.o cli_handlers.o waiter.o \ + dmevents.o init_unwinder.o +- +-CLI_OBJS = multipathc.o cli.o +- + ifeq ($(FPIN_SUPPORT),1) + OBJS += fpin_handlers.o + endif + +-EXEC = multipathd +-CLI = multipathc +- + all : $(EXEC) $(CLI) + + $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so diff --git a/0017-libmultipath-sysfs-cleanup-file-descriptors-on-pthre.patch b/0017-libmultipath-sysfs-cleanup-file-descriptors-on-pthre.patch deleted file mode 100644 index 90fbfdf..0000000 --- a/0017-libmultipath-sysfs-cleanup-file-descriptors-on-pthre.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 5 Jul 2022 18:07:57 +0200 -Subject: [PATCH] libmultipath: sysfs: cleanup file descriptors on - pthread_cancel() - -Signed-off-by: Martin Wilck - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/sysfs.c | 11 +++++++---- - 1 file changed, 7 insertions(+), 4 deletions(-) - -diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c -index 9c84af70..64946385 100644 ---- a/libmultipath/sysfs.c -+++ b/libmultipath/sysfs.c -@@ -49,7 +49,7 @@ static ssize_t __sysfs_attr_get_value(struct udev_device *dev, const char *attr_ - { - const char *syspath; - char devpath[PATH_MAX]; -- int fd; -+ long fd; - ssize_t size = -1; - - if (!dev || !attr_name || !value || !value_len) { -@@ -74,6 +74,8 @@ static ssize_t __sysfs_attr_get_value(struct udev_device *dev, const char *attr_ - __func__, devpath, strerror(errno)); - return -errno; - } -+ pthread_cleanup_push(close_fd, (void *)fd); -+ - size = read(fd, value, value_len); - if (size < 0) { - size = -errno; -@@ -90,7 +92,7 @@ static ssize_t __sysfs_attr_get_value(struct udev_device *dev, const char *attr_ - size = strchop(value); - } - -- close(fd); -+ pthread_cleanup_pop(1); - return size; - } - -@@ -112,7 +114,7 @@ ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, - { - const char *syspath; - char devpath[PATH_MAX]; -- int fd; -+ long fd; - ssize_t size = -1; - - if (!dev || !attr_name || !value || !value_len) { -@@ -138,6 +140,7 @@ ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, - __func__, devpath, strerror(errno)); - return -errno; - } -+ pthread_cleanup_push(close_fd, (void *)fd); - - size = write(fd, value, value_len); - if (size < 0) { -@@ -148,7 +151,7 @@ ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, - condlog(3, "%s: underflow writing %zu bytes to %s. Wrote %zd bytes", - __func__, value_len, devpath, size); - -- close(fd); -+ pthread_cleanup_pop(1); - return size; - } - diff --git a/0017-multipath-tools-Makefiles-use-common-code-for-librar.patch b/0017-multipath-tools-Makefiles-use-common-code-for-librar.patch new file mode 100644 index 0000000..0b45e62 --- /dev/null +++ b/0017-multipath-tools-Makefiles-use-common-code-for-librar.patch @@ -0,0 +1,261 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 27 Oct 2022 21:52:06 +0200 +Subject: [PATCH] multipath-tools: Makefiles: use common code for libraries + +Move shared code to Makefile.inc as far as possible. Use simple +make variables where possible. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 15 ++++++++++++++- + libdmmp/Makefile | 17 ++++++++--------- + libmpathcmd/Makefile | 14 ++------------ + libmpathpersist/Makefile | 14 ++------------ + libmpathutil/Makefile | 14 +------------- + libmpathvalid/Makefile | 14 ++------------ + libmultipath/Makefile | 12 +----------- + 7 files changed, 30 insertions(+), 70 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 2cf25745..fe6bc088 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -64,7 +64,6 @@ GZIP_PROG := gzip -9 -c + RM := rm -f + LN := ln -sf + INSTALL_PROGRAM := install +-NV_VERSION_SCRIPT = $(VERSION_SCRIPT:%.version=%-nv.version) + + # $(call TEST_CC_OPTION,option,fallback) + # Test if the C compiler supports the option. +@@ -127,6 +126,13 @@ thirdpartydir := $(TOPDIR)/third-party + libdmmpdir := $(TOPDIR)/libdmmp + nvmedir := $(TOPDIR)/libmultipath/nvme + ++# Common code for libraries - library Makefiles just set DEVLIB ++# SONAME defaults to 0 (we use version scripts) ++SONAME := 0 ++LIBS = $(DEVLIB).$(SONAME) ++VERSION_SCRIPT = $(DEVLIB:%.so=%.version) ++NV_VERSION_SCRIPT = $(DEVLIB:%.so=%-nv.version) ++ + # Check whether a function with name $1 has been declared in header file $2. + check_func = $(shell \ + if grep -Eq "^[^[:blank:]]+[[:blank:]]+$1[[:blank:]]*(.*)*" "$2"; then \ +@@ -175,3 +181,10 @@ check_var = $(shell \ + + %.abi: %.so + abidw $< >$@ ++ ++%-nv.version: %.version ++ @echo creating $@ from $< ++ @printf 'NOVERSION {\nglobal:\n' >$@ ++ @grep -P '^[ \t]+[a-zA-Z_][a-zA-Z0-9_]*;' $< >>$@ ++ @printf 'local:\n\t*;\n};\n' >>$@ ++ +diff --git a/libdmmp/Makefile b/libdmmp/Makefile +index 985b694b..67b6f86f 100644 +--- a/libdmmp/Makefile ++++ b/libdmmp/Makefile +@@ -5,15 +5,14 @@ + # + include ../Makefile.inc + +-LIBDMMP_VERSION=0.2.0 +-SONAME=$(LIBDMMP_VERSION) +-DEVLIB = libdmmp.so +-LIBS = $(DEVLIB).$(SONAME) +-PKGFILE = libdmmp.pc +-EXTRA_MAN_FILES = libdmmp.h.3 +-HEADERS = libdmmp/libdmmp.h +- +-OBJS = libdmmp.o libdmmp_mp.o libdmmp_pg.o libdmmp_path.o libdmmp_misc.o ++LIBDMMP_VERSION := 0.2.0 ++SONAME := $(LIBDMMP_VERSION) ++DEVLIB := libdmmp.so ++PKGFILE := libdmmp.pc ++EXTRA_MAN_FILES := libdmmp.h.3 ++HEADERS := libdmmp/libdmmp.h ++ ++OBJS := libdmmp.o libdmmp_mp.o libdmmp_pg.o libdmmp_path.o libdmmp_misc.o + + CPPFLAGS += -I$(libdmmpdir) -I$(mpathcmddir) $(shell $(PKGCONFIG) --cflags json-c) + CFLAGS += $(LIB_CFLAGS) -fvisibility=hidden +diff --git a/libmpathcmd/Makefile b/libmpathcmd/Makefile +index 0f83fe7b..f705c7f0 100644 +--- a/libmpathcmd/Makefile ++++ b/libmpathcmd/Makefile +@@ -1,13 +1,8 @@ + include ../Makefile.inc + +-SONAME = 0 +-DEVLIB = libmpathcmd.so +-LIBS = $(DEVLIB).$(SONAME) +-VERSION_SCRIPT := libmpathcmd.version +- ++DEVLIB := libmpathcmd.so + CFLAGS += $(LIB_CFLAGS) +- +-OBJS = mpath_cmd.o ++OBJS := mpath_cmd.o + + all: $(DEVLIB) + +@@ -15,11 +10,6 @@ $(LIBS): $(OBJS) $(VERSION_SCRIPT) + $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ + -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) + +-$(NV_VERSION_SCRIPT): $(VERSION_SCRIPT) +- @printf 'NOVERSION {\nglobal:\n' >$@ +- @grep -P '^[ \t]+[a-zA-Z_][a-zA-Z0-9_]*;' $< >>$@ +- @printf 'local:\n\t*;\n};\n' >>$@ +- + $(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) + $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ + -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) +diff --git a/libmpathpersist/Makefile b/libmpathpersist/Makefile +index 479524d4..6f69168f 100644 +--- a/libmpathpersist/Makefile ++++ b/libmpathpersist/Makefile +@@ -1,16 +1,11 @@ + include ../Makefile.inc + +-SONAME = 0 +-DEVLIB = libmpathpersist.so +-LIBS = $(DEVLIB).$(SONAME) +-VERSION_SCRIPT:= libmpathpersist.version +- ++DEVLIB := libmpathpersist.so + CFLAGS += $(LIB_CFLAGS) -I$(multipathdir) -I$(mpathutildir) -I$(mpathpersistdir) -I$(mpathcmddir) + LDFLAGS += -L$(multipathdir) -L$(mpathutildir) -L$(mpathcmddir) +- + LIBDEPS += -lmultipath -lmpathutil -lmpathcmd -ldevmapper -lpthread -ldl + +-OBJS = mpath_persist.o mpath_updatepr.o mpath_pr_ioctl.o mpath_persist_int.o ++OBJS := mpath_persist.o mpath_updatepr.o mpath_pr_ioctl.o mpath_persist_int.o + + all: $(DEVLIB) + +@@ -18,11 +13,6 @@ $(LIBS): $(OBJS) $(VERSION_SCRIPT) + $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ + -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) + +-$(NV_VERSION_SCRIPT): $(VERSION_SCRIPT) +- @printf 'NOVERSION {\nglobal:\n' >$@ +- @grep -P '^[ \t]+[a-zA-Z_][a-zA-Z0-9_]*;' $< >>$@ +- @printf 'local:\n\t*;\n};\n' >>$@ +- + $(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) + $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ + -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) +diff --git a/libmpathutil/Makefile b/libmpathutil/Makefile +index 4be75d2d..5665af28 100644 +--- a/libmpathutil/Makefile ++++ b/libmpathutil/Makefile +@@ -3,14 +3,9 @@ + # + include ../Makefile.inc + +-SONAME = 0 +-DEVLIB = libmpathutil.so +-LIBS = $(DEVLIB).$(SONAME) +-VERSION_SCRIPT := libmpathutil.version +- ++DEVLIB := libmpathutil.so + CPPFLAGS += -I. -I$(multipathdir) -I$(mpathcmddir) $(SYSTEMD_CPPFLAGS) + CFLAGS += $(LIB_CFLAGS) -D_GNU_SOURCE +- + LIBDEPS += -lpthread -ldl -ludev -L$(mpathcmddir) -lmpathcmd $(SYSTEMD_LIBDEPS) + + # object files referencing MULTIPATH_DIR or CONFIG_DIR +@@ -22,8 +17,6 @@ OBJS := parser.o vector.o util.o debug.o time-util.o \ + + all: $(DEVLIB) + +-make_static = $(shell sed '/^static/!s/^\([a-z]\{1,\} \)/static \1/' <$1 >$2) +- + $(LIBS): $(OBJS) $(VERSION_SCRIPT) + $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ + -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) +@@ -31,11 +24,6 @@ $(LIBS): $(OBJS) $(VERSION_SCRIPT) + $(DEVLIB): $(LIBS) + $(LN) $(LIBS) $@ + +-$(NV_VERSION_SCRIPT): $(VERSION_SCRIPT) +- @printf 'NOVERSION {\nglobal:\n' >$@ +- @grep -P '^[ \t]+[a-zA-Z_][a-zA-Z0-9_]*;' $< >>$@ +- @printf 'local:\n\t*;\n};\n' >>$@ +- + $(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) + $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ + -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) +diff --git a/libmpathvalid/Makefile b/libmpathvalid/Makefile +index 5dbfb923..bd4ccc0d 100644 +--- a/libmpathvalid/Makefile ++++ b/libmpathvalid/Makefile +@@ -1,17 +1,12 @@ + include ../Makefile.inc + +-SONAME = 0 +-DEVLIB = libmpathvalid.so +-LIBS = $(DEVLIB).$(SONAME) +-VERSION_SCRIPT := libmpathvalid.version +- ++DEVLIB := libmpathvalid.so + CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathcmddir) + CFLAGS += $(LIB_CFLAGS) +- + LIBDEPS += -lpthread -ldevmapper -ldl -L$(multipathdir) -lmultipath \ + -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd -ludev + +-OBJS = mpath_valid.o ++OBJS := mpath_valid.o + + all: $(LIBS) + +@@ -20,11 +15,6 @@ $(LIBS): $(OBJS) $(VERSION_SCRIPT) + -Wl,--version-script=$(VERSION_SCRIPT) + $(LN) $(LIBS) $(DEVLIB) + +-$(NV_VERSION_SCRIPT): $(VERSION_SCRIPT) +- @printf 'NOVERSION {\nglobal:\n' >$@ +- @grep -P '^[ \t]+[a-zA-Z_][a-zA-Z0-9_]*;' $< >>$@ +- @printf 'local:\n\t*;\n};\n' >>$@ +- + $(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) + $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ + -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) +diff --git a/libmultipath/Makefile b/libmultipath/Makefile +index 009f26a3..9dc229ae 100644 +--- a/libmultipath/Makefile ++++ b/libmultipath/Makefile +@@ -3,14 +3,9 @@ + # + include ../Makefile.inc + +-SONAME = 0 +-DEVLIB = libmultipath.so +-LIBS = $(DEVLIB).$(SONAME) +-VERSION_SCRIPT := libmultipath.version +- ++DEVLIB := libmultipath.so + CPPFLAGS += -I$(mpathutildir) -I$(mpathcmddir) -I$(nvmedir) -D_GNU_SOURCE $(SYSTEMD_CPPFLAGS) + CFLAGS += $(LIB_CFLAGS) +- + LIBDEPS += -lpthread -ldl -ldevmapper -ludev -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd \ + -lurcu -laio $(SYSTEMD_LIBDEPS) + +@@ -85,11 +80,6 @@ $(LIBS): $(OBJS) $(VERSION_SCRIPT) + $(DEVLIB): $(LIBS) + $(LN) $(LIBS) $@ + +-$(NV_VERSION_SCRIPT): $(VERSION_SCRIPT) +- @printf 'NOVERSION {\nglobal:\n' >$@ +- @grep -P '^[ \t]+[a-zA-Z_][a-zA-Z0-9_]*;' $< >>$@ +- @printf 'local:\n\t*;\n};\n' >>$@ +- + $(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) + $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ + -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) diff --git a/0018-libmultipath-multipathd-log-failure-setting-sysfs-at.patch b/0018-libmultipath-multipathd-log-failure-setting-sysfs-at.patch deleted file mode 100644 index 710f633..0000000 --- a/0018-libmultipath-multipathd-log-failure-setting-sysfs-at.patch +++ /dev/null @@ -1,168 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 5 Jul 2022 18:45:11 +0200 -Subject: [PATCH] libmultipath, multipathd: log failure setting sysfs - attributes - -Failure to set a sysfs attribute is worth noting, normally. - -Signed-off-by: Martin Wilck - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 18 ++++++++++++++--- - multipathd/fpin_handlers.c | 11 +++++++++-- - multipathd/main.c | 40 ++++++++++++++++++++++++++++++-------- - 3 files changed, 56 insertions(+), 13 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 0607dbac..4427f910 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -489,9 +489,15 @@ void trigger_partitions_udev_change(struct udev_device *dev, - - devtype = udev_device_get_devtype(part); - if (devtype && !strcmp("partition", devtype)) { -+ ssize_t ret; -+ - condlog(4, "%s: triggering %s event for %s", __func__, - action, syspath); -- sysfs_attr_set_value(part, "uevent", action, len); -+ ret = sysfs_attr_set_value(part, "uevent", action, len); -+ if (ret != len) -+ log_sysfs_attr_set_value(2, ret, -+ "%s: failed to trigger %s uevent", -+ syspath, action); - } - udev_device_unref(part); - } -@@ -510,6 +516,7 @@ trigger_path_udev_change(struct path *pp, bool is_mpath) - */ - const char *action = is_mpath ? "change" : "add"; - const char *env; -+ ssize_t len, ret; - - if (!pp->udev) - return; -@@ -536,8 +543,13 @@ trigger_path_udev_change(struct path *pp, bool is_mpath) - - condlog(3, "triggering %s uevent for %s (is %smultipath member)", - action, pp->dev, is_mpath ? "" : "no "); -- sysfs_attr_set_value(pp->udev, "uevent", -- action, strlen(action)); -+ -+ len = strlen(action); -+ ret = sysfs_attr_set_value(pp->udev, "uevent", action, len); -+ if (ret != len) -+ log_sysfs_attr_set_value(2, ret, -+ "%s: failed to trigger %s uevent", -+ pp->dev, action); - trigger_partitions_udev_change(pp->udev, action, - strlen(action)); - } -diff --git a/multipathd/fpin_handlers.c b/multipathd/fpin_handlers.c -index 384ae318..00195721 100644 ---- a/multipathd/fpin_handlers.c -+++ b/multipathd/fpin_handlers.c -@@ -172,8 +172,15 @@ fpin_els_add_li_frame(struct fc_nl_event *fc_event) - /*Sets the rport port_state to marginal*/ - static void fpin_set_rport_marginal(struct udev_device *rport_dev) - { -- sysfs_attr_set_value(rport_dev, "port_state", -- "Marginal", strlen("Marginal")); -+ static const char marginal[] = "Marginal"; -+ ssize_t ret; -+ -+ ret = sysfs_attr_set_value(rport_dev, "port_state", -+ marginal, sizeof(marginal) - 1); -+ if (ret != sizeof(marginal) - 1) -+ log_sysfs_attr_set_value(2, ret, -+ "%s: failed to set port_state to marginal", -+ udev_device_get_syspath(rport_dev)); - } - - /*Add the marginal devices info into the list*/ -diff --git a/multipathd/main.c b/multipathd/main.c -index 68eca925..a160c824 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -911,14 +911,22 @@ rescan_path(struct udev_device *ud) - { - ud = udev_device_get_parent_with_subsystem_devtype(ud, "scsi", - "scsi_device"); -- if (ud) -- sysfs_attr_set_value(ud, "rescan", "1", strlen("1")); -+ if (ud) { -+ ssize_t ret = -+ sysfs_attr_set_value(ud, "rescan", "1", strlen("1")); -+ if (ret != strlen("1")) -+ log_sysfs_attr_set_value(1, ret, -+ "%s: failed to trigger rescan", -+ udev_device_get_syspath(ud)); -+ } - } - - void - handle_path_wwid_change(struct path *pp, struct vectors *vecs) - { - struct udev_device *udd; -+ static const char add[] = "add"; -+ ssize_t ret; - - if (!pp || !pp->udev) - return; -@@ -929,8 +937,12 @@ handle_path_wwid_change(struct path *pp, struct vectors *vecs) - dm_fail_path(pp->mpp->alias, pp->dev_t); - } - rescan_path(udd); -- sysfs_attr_set_value(udd, "uevent", "add", strlen("add")); -+ ret = sysfs_attr_set_value(udd, "uevent", add, sizeof(add) - 1); - udev_device_unref(udd); -+ if (ret != sizeof(add) - 1) -+ log_sysfs_attr_set_value(1, ret, -+ "%s: failed to trigger add event", -+ pp->dev); - } - - bool -@@ -2003,9 +2015,14 @@ partial_retrigger_tick(vector pathvec) - --pp->partial_retrigger_delay == 0) { - const char *msg = udev_device_get_is_initialized(pp->udev) ? - "change" : "add"; -- -- sysfs_attr_set_value(pp->udev, "uevent", msg, -- strlen(msg)); -+ ssize_t len = strlen(msg); -+ ssize_t ret = sysfs_attr_set_value(pp->udev, "uevent", msg, -+ len); -+ -+ if (len != ret) -+ log_sysfs_attr_set_value(2, ret, -+ "%s: failed to trigger %s event", -+ pp->dev, msg); - } - } - } -@@ -2245,12 +2262,19 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) - - if (!pp->mpp && pp->initialized == INIT_MISSING_UDEV) { - if (pp->retriggers < retrigger_tries) { -+ static const char change[] = "change"; -+ ssize_t ret; -+ - condlog(2, "%s: triggering change event to reinitialize", - pp->dev); - pp->initialized = INIT_REQUESTED_UDEV; - pp->retriggers++; -- sysfs_attr_set_value(pp->udev, "uevent", "change", -- strlen("change")); -+ ret = sysfs_attr_set_value(pp->udev, "uevent", change, -+ sizeof(change) - 1); -+ if (ret != sizeof(change) - 1) -+ log_sysfs_attr_set_value(1, ret, -+ "%s: failed to trigger change event", -+ pp->dev); - return 0; - } else { - condlog(1, "%s: not initialized after %d udev retriggers", diff --git a/0018-multipath-tools-Makefiles-move-common-code-to-rules..patch b/0018-multipath-tools-Makefiles-move-common-code-to-rules..patch new file mode 100644 index 0000000..1a2069f --- /dev/null +++ b/0018-multipath-tools-Makefiles-move-common-code-to-rules..patch @@ -0,0 +1,172 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 27 Oct 2022 22:18:22 +0200 +Subject: [PATCH] multipath-tools: Makefiles: move common code to rules.mk + +The library Makefiles contain a lot of similar rules. Just +maintain them in a single file. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmpathcmd/Makefile | 13 +------------ + libmpathpersist/Makefile | 13 +------------ + libmpathutil/Makefile | 13 +------------ + libmpathvalid/Makefile | 13 ++----------- + libmultipath/Makefile | 16 ++-------------- + rules.mk | 15 +++++++++++++++ + 6 files changed, 22 insertions(+), 61 deletions(-) + create mode 100644 rules.mk + +diff --git a/libmpathcmd/Makefile b/libmpathcmd/Makefile +index f705c7f0..cfb202b8 100644 +--- a/libmpathcmd/Makefile ++++ b/libmpathcmd/Makefile +@@ -6,18 +6,7 @@ OBJS := mpath_cmd.o + + all: $(DEVLIB) + +-$(LIBS): $(OBJS) $(VERSION_SCRIPT) +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ +- -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) +- +-$(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ +- -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) +- +-abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) +- +-$(DEVLIB): $(LIBS) +- $(LN) $(LIBS) $@ ++include $(TOPDIR)/rules.mk + + install: all + $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) +diff --git a/libmpathpersist/Makefile b/libmpathpersist/Makefile +index 6f69168f..94672556 100644 +--- a/libmpathpersist/Makefile ++++ b/libmpathpersist/Makefile +@@ -9,18 +9,7 @@ OBJS := mpath_persist.o mpath_updatepr.o mpath_pr_ioctl.o mpath_persist_int.o + + all: $(DEVLIB) + +-$(LIBS): $(OBJS) $(VERSION_SCRIPT) +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ +- -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) +- +-$(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ +- -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) +- +-abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) +- +-$(DEVLIB): $(LIBS) +- $(LN) $(LIBS) $@ ++include $(TOPDIR)/rules.mk + + install: all + $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) +diff --git a/libmpathutil/Makefile b/libmpathutil/Makefile +index 5665af28..5ab33c09 100644 +--- a/libmpathutil/Makefile ++++ b/libmpathutil/Makefile +@@ -17,18 +17,7 @@ OBJS := parser.o vector.o util.o debug.o time-util.o \ + + all: $(DEVLIB) + +-$(LIBS): $(OBJS) $(VERSION_SCRIPT) +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ +- -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) +- +-$(DEVLIB): $(LIBS) +- $(LN) $(LIBS) $@ +- +-$(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ +- -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) +- +-abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) ++include $(TOPDIR)/rules.mk + + install: all + $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) +diff --git a/libmpathvalid/Makefile b/libmpathvalid/Makefile +index bd4ccc0d..88034df3 100644 +--- a/libmpathvalid/Makefile ++++ b/libmpathvalid/Makefile +@@ -8,18 +8,9 @@ LIBDEPS += -lpthread -ldevmapper -ldl -L$(multipathdir) -lmultipath \ + + OBJS := mpath_valid.o + +-all: $(LIBS) ++all: $(DEVLIB) + +-$(LIBS): $(OBJS) $(VERSION_SCRIPT) +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ -o $@ $(OBJS) $(LIBDEPS) \ +- -Wl,--version-script=$(VERSION_SCRIPT) +- $(LN) $(LIBS) $(DEVLIB) +- +-$(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ +- -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) +- +-abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) ++include $(TOPDIR)/rules.mk + + install: $(LIBS) + $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(syslibdir) +diff --git a/libmultipath/Makefile b/libmultipath/Makefile +index 9dc229ae..e24eab8a 100644 +--- a/libmultipath/Makefile ++++ b/libmultipath/Makefile +@@ -56,6 +56,8 @@ OBJS := $(OBJS-O) $(OBJS-U) + + all: $(DEVLIB) + ++include $(TOPDIR)/rules.mk ++ + nvme-lib.o: nvme-lib.c nvme-ioctl.c nvme-ioctl.h + $(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-function -c -o $@ $< + +@@ -72,20 +74,6 @@ nvme-ioctl.c: nvme/nvme-ioctl.c + nvme-ioctl.h: nvme/nvme-ioctl.h + $(call make_static,$<,$@) + +- +-$(LIBS): $(OBJS) $(VERSION_SCRIPT) +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ +- -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) +- +-$(DEVLIB): $(LIBS) +- $(LN) $(LIBS) $@ +- +-$(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ +- -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) +- +-abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) +- + ../tests/$(LIBS): $(OBJS-O) $(OBJS-T) $(VERSION_SCRIPT) + $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=`basename $@` \ + -o $@ $(OBJS-O) $(OBJS-T) $(LIBDEPS) +diff --git a/rules.mk b/rules.mk +new file mode 100644 +index 00000000..c1d80820 +--- /dev/null ++++ b/rules.mk +@@ -0,0 +1,15 @@ ++# Copyright (c) SUSE LLC ++# SPDX-License-Identifier: GPL-2.0-or-later ++ ++$(DEVLIB): $(LIBS) ++ $(LN) $(LIBS) $@ ++ ++$(LIBS): $(OBJS) $(VERSION_SCRIPT) ++ $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ ++ -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) ++ ++$(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) ++ $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ ++ -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) ++ ++abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) diff --git a/0019-multipath-tests-expect_condlog-skip-depending-on-ver.patch b/0019-multipath-tests-expect_condlog-skip-depending-on-ver.patch deleted file mode 100644 index 6b7c06b..0000000 --- a/0019-multipath-tests-expect_condlog-skip-depending-on-ver.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 5 Jul 2022 23:18:07 +0200 -Subject: [PATCH] multipath tests: expect_condlog: skip depending on verbosity - -otherwise we'll get failures if verbosity level is low. - -Signed-off-by: Martin Wilck - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - tests/test-log.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/tests/test-log.c b/tests/test-log.c -index 14f25b9b..0c17cd96 100644 ---- a/tests/test-log.c -+++ b/tests/test-log.c -@@ -6,6 +6,8 @@ - #include - #include "log.h" - #include "test-log.h" -+#include "debug.h" -+ - - __attribute__((format(printf, 2, 0))) - void __wrap_dlog (int prio, const char * fmt, ...) -@@ -24,6 +26,8 @@ void __wrap_dlog (int prio, const char * fmt, ...) - - void expect_condlog(int prio, char *string) - { -+ if (prio > MAX_VERBOSITY || prio > libmp_verbosity) -+ return; - expect_value(__wrap_dlog, prio, prio); - will_return(__wrap_dlog, string); - } diff --git a/0019-multipath-tools-Makefiles-create-config.mk.patch b/0019-multipath-tools-Makefiles-create-config.mk.patch new file mode 100644 index 0000000..4d403d0 --- /dev/null +++ b/0019-multipath-tools-Makefiles-create-config.mk.patch @@ -0,0 +1,603 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 28 Oct 2022 00:01:46 +0200 +Subject: [PATCH] multipath-tools Makefiles: create config.mk + +Rather than running the test scripts for certain system features +every time "make" is called, save the configuration in "config.mk" +and "libmultipath/autoconfig.h", and reuse it later. This reduces +build time, especially in subsequent builds, and the build output is +less garbled by compiler options. + +It works by invoking the separate make file "create-config.mk" at +the beginning of the build process. Most of the complex makefile +functions are moved to "create-config.mk". + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/foreign.yaml | 2 +- + .gitignore | 2 + + Makefile | 19 +++- + Makefile.inc | 76 +-------------- + create-config.mk | 144 +++++++++++++++++++++++++++++ + kpartx/Makefile | 4 - + kpartx/devmapper.c | 1 + + kpartx/kpartx.c | 1 + + libdmmp/test/Makefile | 1 + + libmultipath/Makefile | 30 +----- + libmultipath/devmapper.h | 2 +- + libmultipath/dict.c | 1 + + libmultipath/prioritizers/Makefile | 2 +- + libmultipath/propsel.c | 1 + + libmultipath/uevent.c | 1 + + multipathd/Makefile | 11 --- + multipathd/fpin.h | 1 + + multipathd/main.c | 1 + + rules.mk | 3 + + tests/Makefile | 8 -- + 20 files changed, 179 insertions(+), 132 deletions(-) + create mode 100644 create-config.mk + +diff --git a/.github/workflows/foreign.yaml b/.github/workflows/foreign.yaml +index bd4e9c12..5a19913a 100644 +--- a/.github/workflows/foreign.yaml ++++ b/.github/workflows/foreign.yaml +@@ -30,7 +30,7 @@ jobs: + if: ${{ matrix.arch != '' && matrix.arch != '-i386' }} + run: > + tar cfv binaries.tar +- Makefile* ++ Makefile* config.mk + libmpathcmd/*.so* libmultipath/*.so* libmpathutil/*.so* + libmultipath/checkers/*.so libmultipath/prioritizers/*.so + libmultipath/foreign/*.so +diff --git a/.gitignore b/.gitignore +index 83f8a552..535353e5 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -8,6 +8,7 @@ + *.gz + *.d + \#* ++config.mk + cscope.files + cscope.out + kpartx/kpartx +@@ -35,5 +36,6 @@ tests/*.out + tests/*.vgr + libmultipath/nvme-ioctl.c + libmultipath/nvme-ioctl.h ++libmultipath/autoconfig.h + */*-nv.version + reference-abi +diff --git a/Makefile b/Makefile +index 27b4641f..1b28db62 100644 +--- a/Makefile ++++ b/Makefile +@@ -30,7 +30,14 @@ BUILDDIRS.clean := $(BUILDDIRS:=.clean) tests.clean + + all: $(BUILDDIRS) + +-$(BUILDDIRS): ++config.mk libmultipath/autoconfig.h: ++ @$(MAKE) -f create-config.mk ++ @echo ==== config.mk ==== ++ @cat config.mk ++ @echo ==== autoconfig.h ==== ++ @cat libmultipath/autoconfig.h ++ ++$(BUILDDIRS): config.mk + $(MAKE) -C $@ + + $(LIB_BUILDDIRS:=.abi): $(LIB_BUILDDIRS) +@@ -83,7 +90,7 @@ libmultipath/checkers.install \ + libmultipath/prioritizers.install \ + libmultipath/foreign.install: libmultipath.install + +-$(BUILDDIRS.clean): ++%.clean: + $(MAKE) -C ${@:.clean=} clean + + %.install: % +@@ -92,8 +99,12 @@ $(BUILDDIRS.clean): + $(BUILDDIRS:=.uninstall): + $(MAKE) -C ${@:.uninstall=} uninstall + +-clean: $(BUILDDIRS.clean) +- rm -rf abi abi.tar.gz abi-test compile_commands.json ++# If config.mk is missing, "make clean" in subdir either fails, or tries to ++# build it. Both is undesirable. Avoid it by creating config.mk temporarily. ++clean: ++ @touch config.mk ++ $(MAKE) $(BUILDDIRS:=.clean) tests.clean || true ++ rm -rf abi abi.tar.gz abi-test compile_commands.json config.mk + + install: $(BUILDDIRS:=.install) + uninstall: $(BUILDDIRS:=.uninstall) +diff --git a/Makefile.inc b/Makefile.inc +index fe6bc088..415634f5 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -27,9 +27,9 @@ PKGCONFIG ?= pkg-config + ifeq ($(TOPDIR),) + TOPDIR = .. + endif +- +-SYSTEMD := $(strip $(or $(shell $(PKGCONFIG) --modversion libsystemd 2>/dev/null | awk '{print $$1}'), \ +- $(shell systemctl --version 2>/dev/null | sed -n 's/systemd \([0-9]*\).*/\1/p'))) ++ifneq ($(CREATE_CONFIG),1) ++include $(TOPDIR)/config.mk ++endif + + # Paths. All these can be overridden on the "make" command line. + prefix := +@@ -65,37 +65,6 @@ RM := rm -f + LN := ln -sf + INSTALL_PROGRAM := install + +-# $(call TEST_CC_OPTION,option,fallback) +-# Test if the C compiler supports the option. +-# Evaluates to "option" if yes, and "fallback" otherwise. +-TEST_CC_OPTION = $(shell \ +- if echo 'int main(void){return 0;}' | \ +- $(CC) -o /dev/null -c -Werror "$(1)" -xc - >/dev/null 2>&1; \ +- then \ +- echo "$(1)"; \ +- else \ +- echo "$(2)"; \ +- fi) +- +-# "make" on some distros will fail on explicit '#' or '\#' in the program text below +-__HASH__ := \# +-# Check if _DFORTIFY_SOURCE=3 is supported. +-# On some distros (e.g. Debian Buster) it will be falsely reported as supported +-# but it doesn't seem to make a difference wrt the compilation result. +-FORTIFY_OPT := $(shell \ +- if /bin/echo -e '$(__HASH__)include \nint main(void) { return 0; }' | \ +- $(CC) -o /dev/null -c -O2 -Werror -D_FORTIFY_SOURCE=3 -xc - 2>/dev/null; \ +- then \ +- echo "-D_FORTIFY_SOURCE=3"; \ +- else \ +- echo "-D_FORTIFY_SOURCE=2"; \ +- fi) +- +-STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector) +-ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers,) +-WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered -Wno-error=clobbered,) +-WFORMATOVERFLOW := $(call TEST_CC_OPTION,-Wformat-overflow=2,) +- + SYSTEMD_CPPFLAGS := $(if $(SYSTEMD),-DUSE_SYSTEMD=$(SYSTEMD)) + SYSTEMD_LIBDEPS := $(if $(SYSTEMD),$(if $(shell test $(SYSTEMD) -gt 209 && echo 1),-lsystemd,-lsystemd-daemon)) + +@@ -133,45 +102,6 @@ LIBS = $(DEVLIB).$(SONAME) + VERSION_SCRIPT = $(DEVLIB:%.so=%.version) + NV_VERSION_SCRIPT = $(DEVLIB:%.so=%-nv.version) + +-# Check whether a function with name $1 has been declared in header file $2. +-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" \ +- ) +- +-# Checker whether a file with name $1 exists +-check_file = $(shell \ +- if [ -f "$1" ]; then \ +- found=1; \ +- status="yes"; \ +- else \ +- found=0; \ +- status="no"; \ +- fi; \ +- echo 1>&2 "Checking if $1 exists ... $$status"; \ +- echo "$$found" \ +- ) +- +-# Check whether a file contains a variable with name $1 in header file $2 +-check_var = $(shell \ +- if grep -Eq "(^|[[: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" \ +- ) +- + %.o: %.c + @echo building $@ because of $? + $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< +diff --git a/create-config.mk b/create-config.mk +new file mode 100644 +index 00000000..2cc5284f +--- /dev/null ++++ b/create-config.mk +@@ -0,0 +1,144 @@ ++# Copyright (c) SUSE LLC ++# SPDX-License-Identifier: GPL-2.0-or-later ++ ++TOPDIR := . ++CREATE_CONFIG := 1 ++include $(TOPDIR)/Makefile.inc ++ ++# Check whether a function with name $1 has been declared in header file $2. ++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" \ ++ ) ++ ++# Checker whether a file with name $1 exists ++check_file = $(shell \ ++ if [ -f "$1" ]; then \ ++ found=1; \ ++ status="yes"; \ ++ else \ ++ found=0; \ ++ status="no"; \ ++ fi; \ ++ echo 1>&2 "Checking if $1 exists ... $$status"; \ ++ echo "$$found" \ ++ ) ++ ++# Check whether a file contains a variable with name $1 in header file $2 ++check_var = $(shell \ ++ if grep -Eq "(^|[[: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" \ ++ ) ++ ++# Test special behavior of gcc 4.8 with nested initializers ++# gcc 4.8 compiles blacklist.c only with -Wno-missing-field-initializers ++TEST_MISSING_INITIALIZERS = $(shell \ ++ echo 'struct A {int a, b;}; struct B {struct A a; int b;} b = {.a.a=1};' | \ ++ $(CC) -c -Werror -Wmissing-field-initializers -o /dev/null -xc - >/dev/null 2>&1 \ ++ || echo -Wno-missing-field-initializers) ++ ++DEFINES := ++ ++ifneq ($(call check_func,dm_task_no_flush,$(devmapper_incdir)/libdevmapper.h),0) ++ DEFINES += LIBDM_API_FLUSH ++endif ++ ++ifneq ($(call check_func,dm_task_get_errno,$(devmapper_incdir)/libdevmapper.h),0) ++ DEFINES += LIBDM_API_GET_ERRNO ++endif ++ ++ifneq ($(call check_func,dm_task_set_cookie,$(devmapper_incdir)/libdevmapper.h),0) ++ DEFINES += LIBDM_API_COOKIE ++endif ++ ++ifneq ($(call check_func,udev_monitor_set_receive_buffer_size,$(libudev_incdir)/libudev.h),0) ++ DEFINES += LIBUDEV_API_RECVBUF ++endif ++ ++ifneq ($(call check_func,dm_task_deferred_remove,$(devmapper_incdir)/libdevmapper.h),0) ++ DEFINES += LIBDM_API_DEFERRED ++endif ++ ++ifneq ($(call check_func,dm_hold_control_dev,$(devmapper_incdir)/libdevmapper.h),0) ++ DEFINES += LIBDM_API_HOLD_CONTROL ++endif ++ ++ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(kernel_incdir)/scsi/fc/fc_els.h),0) ++ DEFINES += FPIN_EVENT_HANDLER ++ FPIN_SUPPORT = 1 ++endif ++ ++ifneq ($(call check_file,$(kernel_incdir)/linux/nvme_ioctl.h),0) ++ ANA_SUPPORT := 1 ++endif ++ ++ifeq ($(ENABLE_DMEVENTS_POLL),0) ++ DEFINES += -DNO_DMEVENTS_POLL ++endif ++ ++SYSTEMD := $(strip $(or $(shell $(PKGCONFIG) --modversion libsystemd 2>/dev/null | awk '{print $$1}'), \ ++ $(shell systemctl --version 2>/dev/null | sed -n 's/systemd \([0-9]*\).*/\1/p'))) ++ ++ ++# $(call TEST_CC_OPTION,option,fallback) ++# Test if the C compiler supports the option. ++# Evaluates to "option" if yes, and "fallback" otherwise. ++TEST_CC_OPTION = $(shell \ ++ if echo 'int main(void){return 0;}' | \ ++ $(CC) -o /dev/null -c -Werror "$(1)" -xc - >/dev/null 2>&1; \ ++ then \ ++ echo "$(1)"; \ ++ else \ ++ echo "$(2)"; \ ++ fi) ++ ++# "make" on some distros will fail on explicit '#' or '\#' in the program text below ++__HASH__ := \# ++# Check if _DFORTIFY_SOURCE=3 is supported. ++# On some distros (e.g. Debian Buster) it will be falsely reported as supported ++# but it doesn't seem to make a difference wrt the compilation result. ++FORTIFY_OPT := $(shell \ ++ if /bin/echo -e '$(__HASH__)include \nint main(void) { return 0; }' | \ ++ $(CC) -o /dev/null -c -O2 -Werror -D_FORTIFY_SOURCE=3 -xc - 2>/dev/null; \ ++ then \ ++ echo "-D_FORTIFY_SOURCE=3"; \ ++ else \ ++ echo "-D_FORTIFY_SOURCE=2"; \ ++ fi) ++ ++STACKPROT := ++ ++all: $(multipathdir)/autoconfig.h $(TOPDIR)/config.mk ++ ++$(multipathdir)/autoconfig.h: ++ @echo creating $@ ++ @echo '#ifndef _AUTOCONFIG_H' >$@ ++ @echo '#define _AUTOCONFIG_H' >>$@ ++ @for x in $(DEFINES); do echo "#define $$x" >>$@; done ++ @echo '#endif' >>$@ ++ ++$(TOPDIR)/config.mk: ++ @echo creating $@ ++ @echo "FPIN_SUPPORT := $(FPIN_SUPPORT)" >$@ ++ @echo "FORTIFY_OPT := $(FORTIFY_OPT)" >>$@ ++ @echo "SYSTEMD := $(SYSTEMD)" >>$@ ++ @echo "ANA_SUPPORT := $(ANA_SUPPORT)" >>$@ ++ @echo "STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector)" >>$@ ++ @echo "ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers,)" >>$@ ++ @echo "WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered -Wno-error=clobbered,)" >>$@ ++ @echo "WFORMATOVERFLOW := $(call TEST_CC_OPTION,-Wformat-overflow=2,)" >>$@ ++ @echo "W_MISSING_INITIALIZERS := $(call TEST_MISSING_INITIALIZERS)" >>$@ +diff --git a/kpartx/Makefile b/kpartx/Makefile +index 7ceae96b..31b1138a 100644 +--- a/kpartx/Makefile ++++ b/kpartx/Makefile +@@ -6,10 +6,6 @@ include ../Makefile.inc + EXEC := kpartx + + CPPFLAGS += -I. -I$(multipathdir) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 +-ifneq ($(call check_func,dm_task_set_cookie,$(devmapper_incdir)/libdevmapper.h),0) +- CPPFLAGS += -DLIBDM_API_COOKIE +-endif +- + CFLAGS += $(BIN_CFLAGS) + LDFLAGS += $(BIN_LDFLAGS) + LIBDEPS += -ldevmapper +diff --git a/kpartx/devmapper.c b/kpartx/devmapper.c +index bf14c784..f12762c5 100644 +--- a/kpartx/devmapper.c ++++ b/kpartx/devmapper.c +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include "autoconfig.h" + #include "devmapper.h" + #include "kpartx.h" + +diff --git a/kpartx/kpartx.c b/kpartx/kpartx.c +index 1d568c9e..46cb76ba 100644 +--- a/kpartx/kpartx.c ++++ b/kpartx/kpartx.c +@@ -34,6 +34,7 @@ + #include + #include + ++#include "autoconfig.h" + #include "devmapper.h" + #include "crc32.h" + #include "lopart.h" +diff --git a/libdmmp/test/Makefile b/libdmmp/test/Makefile +index 76b24d61..93de64a0 100644 +--- a/libdmmp/test/Makefile ++++ b/libdmmp/test/Makefile +@@ -2,6 +2,7 @@ + # + # Copyright (C) 2015-2016 Gris Ge + # ++TOPDIR := ../.. + include ../../Makefile.inc + + _libdmmpdir=../$(libdmmpdir) +diff --git a/libmultipath/Makefile b/libmultipath/Makefile +index e24eab8a..1cc13577 100644 +--- a/libmultipath/Makefile ++++ b/libmultipath/Makefile +@@ -9,34 +9,6 @@ CFLAGS += $(LIB_CFLAGS) + LIBDEPS += -lpthread -ldl -ldevmapper -ludev -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd \ + -lurcu -laio $(SYSTEMD_LIBDEPS) + +-ifneq ($(call check_func,dm_task_no_flush,$(devmapper_incdir)/libdevmapper.h),0) +- CPPFLAGS += -DLIBDM_API_FLUSH +-endif +- +-ifneq ($(call check_func,dm_task_get_errno,$(devmapper_incdir)/libdevmapper.h),0) +- CPPFLAGS += -DLIBDM_API_GET_ERRNO +-endif +- +-ifneq ($(call check_func,dm_task_set_cookie,$(devmapper_incdir)/libdevmapper.h),0) +- CPPFLAGS += -DLIBDM_API_COOKIE +-endif +- +-ifneq ($(call check_func,udev_monitor_set_receive_buffer_size,$(libudev_incdir)/libudev.h),0) +- CPPFLAGS += -DLIBUDEV_API_RECVBUF +-endif +- +-ifneq ($(call check_func,dm_task_deferred_remove,$(devmapper_incdir)/libdevmapper.h),0) +- CPPFLAGS += -DLIBDM_API_DEFERRED +-endif +- +-ifneq ($(call check_func,dm_hold_control_dev,$(devmapper_incdir)/libdevmapper.h),0) +- CPPFLAGS += -DLIBDM_API_HOLD_CONTROL +-endif +- +-ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(kernel_incdir)/scsi/fc/fc_els.h),0) +- CPPFLAGS += -DFPIN_EVENT_HANDLER +-endif +- + # object files referencing MULTIPATH_DIR or CONFIG_DIR + # they need to be recompiled for unit tests + OBJS-U := prio.o checkers.o foreign.o config.o +@@ -97,7 +69,7 @@ uninstall: + $(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) + + clean: dep_clean +- $(RM) core *.a *.o *.so *.so.* *.abi nvme-ioctl.c nvme-ioctl.h $(NV_VERSION_SCRIPT) ++ $(RM) core *.a *.o *.so *.so.* *.abi nvme-ioctl.c nvme-ioctl.h autoconfig.h $(NV_VERSION_SCRIPT) + + include $(wildcard $(OBJS:.o=.d)) + +diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h +index 703f3bf8..42f8eccd 100644 +--- a/libmultipath/devmapper.h ++++ b/libmultipath/devmapper.h +@@ -1,6 +1,6 @@ + #ifndef _DEVMAPPER_H + #define _DEVMAPPER_H +- ++#include "autoconfig.h" + #include "structs.h" + + #define TGT_MPATH "multipath" +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index aa93fe43..6fc77315 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include "autoconfig.h" + #include "mpath_cmd.h" + #include "dict.h" + #include "strbuf.h" +diff --git a/libmultipath/prioritizers/Makefile b/libmultipath/prioritizers/Makefile +index 72eefe49..a699e8a6 100644 +--- a/libmultipath/prioritizers/Makefile ++++ b/libmultipath/prioritizers/Makefile +@@ -26,7 +26,7 @@ LIBS = \ + libpriopath_latency.so \ + libpriosysfs.so + +-ifneq ($(call check_file,$(kernel_incdir)/linux/nvme_ioctl.h),0) ++ifneq ($(ANA_SUPPORT),1) + LIBS += libprioana.so + CPPFLAGS += -I../nvme + endif +diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c +index d4f19897..d1d5cc25 100644 +--- a/libmultipath/propsel.c ++++ b/libmultipath/propsel.c +@@ -5,6 +5,7 @@ + */ + #include + ++#include "autoconfig.h" + #include "nvme-lib.h" + #include "checkers.h" + #include "vector.h" +diff --git a/libmultipath/uevent.c b/libmultipath/uevent.c +index 57447ca0..bbc8e9e5 100644 +--- a/libmultipath/uevent.c ++++ b/libmultipath/uevent.c +@@ -42,6 +42,7 @@ + #include + #include + ++#include "autoconfig.h" + #include "debug.h" + #include "list.h" + #include "uevent.h" +diff --git a/multipathd/Makefile b/multipathd/Makefile +index bb8f7770..587bb916 100644 +--- a/multipathd/Makefile ++++ b/multipathd/Makefile +@@ -8,17 +8,6 @@ CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathpersistdir) -I$(mpathcm + awk -F. '{ printf("-DURCU_VERSION=0x%06x", 256 * ( 256 * $$1 + $$2) + $$3); }') \ + -DBINDIR='"$(bindir)"' $(SYSTEMD_CPPFLAGS) + +-ifeq ($(ENABLE_DMEVENTS_POLL),0) +- CPPFLAGS += -DNO_DMEVENTS_POLL +-endif +-ifneq ($(call check_func,dm_task_get_errno,$(devmapper_incdir)/libdevmapper.h),0) +- CPPFLAGS += -DLIBDM_API_GET_ERRNO +-endif +-ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(kernel_incdir)/scsi/fc/fc_els.h),0) +- CPPFLAGS += -DFPIN_EVENT_HANDLER +- FPIN_SUPPORT = 1 +-endif +- + # + # debugging stuff + # +diff --git a/multipathd/fpin.h b/multipathd/fpin.h +index bfcc1ce2..3c374441 100644 +--- a/multipathd/fpin.h ++++ b/multipathd/fpin.h +@@ -1,5 +1,6 @@ + #ifndef __FPIN_H__ + #define __FPIN_H__ ++#include "autoconfig.h" + + #ifdef FPIN_EVENT_HANDLER + void *fpin_fabric_notification_receiver(void *unused); +diff --git a/multipathd/main.c b/multipathd/main.c +index ba52d393..1e1b254f 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -4,6 +4,7 @@ + * Copyright (c) 2005 Benjamin Marzinski, Redhat + * Copyright (c) 2005 Edward Goggin, EMC + */ ++#include "autoconfig.h" + #include + #include + #include +diff --git a/rules.mk b/rules.mk +index c1d80820..d8612527 100644 +--- a/rules.mk ++++ b/rules.mk +@@ -13,3 +13,6 @@ $(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) + -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) + + abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) ++ ++$(TOPDIR)/config.mk $(multipathdir)/autoconfig.h: ++ $(MAKE) -C $(TOPDIR) -f create-config.mk +diff --git a/tests/Makefile b/tests/Makefile +index 3a5b161c..d9856d17 100644 +--- a/tests/Makefile ++++ b/tests/Makefile +@@ -3,14 +3,6 @@ include ../Makefile.inc + # directory where to run the tests + TESTDIR := $(CURDIR) + +-# Test special behavior of gcc 4.8 with nested initializers +-# gcc 4.8 compiles blacklist.c only with -Wno-missing-field-initializers +-TEST_MISSING_INITIALIZERS = $(shell \ +- echo 'struct A {int a, b;}; struct B {struct A a; int b;} b = {.a.a=1};' | \ +- $(CC) -c -Werror -Wmissing-field-initializers -o /dev/null -xc - >/dev/null 2>&1 \ +- || echo -Wno-missing-field-initializers) +-W_MISSING_INITIALIZERS := $(call TEST_MISSING_INITIALIZERS) +- + CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathcmddir) -I$(daemondir) \ + -DTESTCONFDIR=\"$(TESTDIR)/conf.d\" + CFLAGS += $(BIN_CFLAGS) -Wno-unused-parameter $(W_MISSING_INITIALIZERS) diff --git a/0020-multipath-tests-__wrap_dlog-print-log-message.patch b/0020-multipath-tests-__wrap_dlog-print-log-message.patch deleted file mode 100644 index 216e5a2..0000000 --- a/0020-multipath-tests-__wrap_dlog-print-log-message.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 6 Jul 2022 11:15:27 +0200 -Subject: [PATCH] multipath tests: __wrap_dlog: print log message - -This makes it easier to analyze errors from __wrap_dlog(). - -Signed-off-by: Martin Wilck - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - tests/test-log.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/tests/test-log.c b/tests/test-log.c -index 0c17cd96..c1745872 100644 ---- a/tests/test-log.c -+++ b/tests/test-log.c -@@ -20,6 +20,7 @@ void __wrap_dlog (int prio, const char * fmt, ...) - va_start(ap, fmt); - vsnprintf(buff, MAX_MSG_SIZE, fmt, ap); - va_end(ap); -+ fprintf(stderr, "%s(%d): %s", __func__, prio, buff); - expected = mock_ptr_type(char *); - assert_memory_equal(buff, expected, strlen(expected)); - } diff --git a/0020-multipath-tools-Makefiles-enable-quiet-build.patch b/0020-multipath-tools-Makefiles-enable-quiet-build.patch new file mode 100644 index 0000000..dbe1129 --- /dev/null +++ b/0020-multipath-tools-Makefiles-enable-quiet-build.patch @@ -0,0 +1,879 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 28 Oct 2022 12:39:06 +0200 +Subject: [PATCH] multipath-tools Makefiles: enable quiet build + +Like many other projects, make it possible to print much less +output during build. Verbose output is enabled with "make V=1", as +usual. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + Makefile | 12 +++---- + Makefile.inc | 10 +++--- + kpartx/Makefile | 41 ++++++++++++----------- + libdmmp/Makefile | 48 +++++++++++++------------- + libdmmp/test/Makefile | 8 ++--- + libmpathcmd/Makefile | 20 +++++------ + libmpathpersist/Makefile | 32 +++++++++--------- + libmpathutil/Makefile | 14 ++++---- + libmpathvalid/Makefile | 20 +++++------ + libmultipath/Makefile | 30 ++++++++--------- + libmultipath/checkers/Makefile | 8 ++--- + libmultipath/foreign/Makefile | 8 ++--- + libmultipath/prioritizers/Makefile | 8 ++--- + mpathpersist/Makefile | 18 +++++----- + multipath/Makefile | 54 ++++++++++++++++-------------- + multipathd/Makefile | 42 ++++++++++++----------- + rules.mk | 8 ++--- + tests/Makefile | 23 +++++++------ + 18 files changed, 206 insertions(+), 198 deletions(-) + +diff --git a/Makefile b/Makefile +index 1b28db62..e3ce1a8d 100644 +--- a/Makefile ++++ b/Makefile +@@ -38,17 +38,17 @@ config.mk libmultipath/autoconfig.h: + @cat libmultipath/autoconfig.h + + $(BUILDDIRS): config.mk +- $(MAKE) -C $@ ++ @$(MAKE) -C $@ + + $(LIB_BUILDDIRS:=.abi): $(LIB_BUILDDIRS) +- $(MAKE) -C ${@:.abi=} abi ++ @$(MAKE) -C ${@:.abi=} abi + + # Create formal representation of the ABI + # Useful for verifying ABI compatibility + # Requires abidw from the abigail suite (https://sourceware.org/libabigail/) + .PHONY: abi + abi: $(LIB_BUILDDIRS:=.abi) +- mkdir -p $@ ++ @mkdir -p $@ + ln -ft $@ $(LIB_BUILDDIRS:=/*.abi) + + abi.tar.gz: abi +@@ -91,13 +91,13 @@ libmultipath/checkers.install \ + libmultipath/foreign.install: libmultipath.install + + %.clean: +- $(MAKE) -C ${@:.clean=} clean ++ @$(MAKE) -C ${@:.clean=} clean + + %.install: % +- $(MAKE) -C ${@:.install=} install ++ @$(MAKE) -C ${@:.install=} install + + $(BUILDDIRS:=.uninstall): +- $(MAKE) -C ${@:.uninstall=} uninstall ++ @$(MAKE) -C ${@:.uninstall=} uninstall + + # If config.mk is missing, "make clean" in subdir either fails, or tries to + # build it. Both is undesirable. Avoid it by creating config.mk temporarily. +diff --git a/Makefile.inc b/Makefile.inc +index 415634f5..3e14cb8c 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -1,4 +1,4 @@ +-# ++# -*- Makefile -*- + # Copyright (C) 2004 Christophe Varoqui, + # + +@@ -60,6 +60,8 @@ devmapper_incdir := $(or $(shell $(PKGCONFIG) --variable=includedir devmapper),/ + libudev_incdir := $(or $(shell $(PKGCONFIG) --variable=includedir libudev),/usr/include) + kernel_incdir := /usr/include + ++Q := $(if $(V),,@) ++ + GZIP_PROG := gzip -9 -c + RM := rm -f + LN := ln -sf +@@ -104,13 +106,13 @@ NV_VERSION_SCRIPT = $(DEVLIB:%.so=%-nv.version) + + %.o: %.c + @echo building $@ because of $? +- $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< ++ $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< + + %.abi: %.so.0 +- abidw $< >$@ ++ $(Q)abidw $< >$@ + + %.abi: %.so +- abidw $< >$@ ++ $(Q)abidw $< >$@ + + %-nv.version: %.version + @echo creating $@ from $< +diff --git a/kpartx/Makefile b/kpartx/Makefile +index 31b1138a..7720a740 100644 +--- a/kpartx/Makefile ++++ b/kpartx/Makefile +@@ -16,33 +16,34 @@ OBJS := bsd.o dos.o kpartx.o solaris.o unixware.o dasd.o sun.o \ + all: $(EXEC) + + $(EXEC): $(OBJS) +- $(CC) $(CFLAGS) $(OBJS) -o $(EXEC) $(LDFLAGS) $(LIBDEPS) ++ @echo building $@ because of $? ++ $(Q)$(CC) $(CFLAGS) $(OBJS) -o $(EXEC) $(LDFLAGS) $(LIBDEPS) + + install: $(EXEC) $(EXEC).8 +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) +- $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir) +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(libudevdir) +- $(INSTALL_PROGRAM) -m 755 kpartx_id $(DESTDIR)$(libudevdir) +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(libudevdir)/rules.d +- $(INSTALL_PROGRAM) -m 644 dm-parts.rules $(DESTDIR)$(libudevdir)/rules.d/11-dm-parts.rules +- $(INSTALL_PROGRAM) -m 644 kpartx.rules $(DESTDIR)$(libudevdir)/rules.d/66-kpartx.rules +- $(INSTALL_PROGRAM) -m 644 del-part-nodes.rules $(DESTDIR)$(libudevdir)/rules.d/68-del-part-nodes.rules +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 +- $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 ++ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) ++ $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir) ++ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(libudevdir) ++ $(Q)$(INSTALL_PROGRAM) -m 755 kpartx_id $(DESTDIR)$(libudevdir) ++ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(libudevdir)/rules.d ++ $(Q)$(INSTALL_PROGRAM) -m 644 dm-parts.rules $(DESTDIR)$(libudevdir)/rules.d/11-dm-parts.rules ++ $(Q)$(INSTALL_PROGRAM) -m 644 kpartx.rules $(DESTDIR)$(libudevdir)/rules.d/66-kpartx.rules ++ $(Q)$(INSTALL_PROGRAM) -m 644 del-part-nodes.rules $(DESTDIR)$(libudevdir)/rules.d/68-del-part-nodes.rules ++ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 ++ $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 + + uninstall: +- $(RM) $(DESTDIR)$(bindir)/$(EXEC) +- $(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 +- $(RM) $(DESTDIR)$(libudevdir)/kpartx_id +- $(RM) $(DESTDIR)$(libudevdir)/rules.d/11-dm-parts.rules +- $(RM) $(DESTDIR)$(libudevdir)/rules.d/66-kpartx.rules +- $(RM) $(DESTDIR)$(libudevdir)/rules.d/67-kpartx-compat.rules +- $(RM) $(DESTDIR)$(libudevdir)/rules.d/68-del-part-nodes.rules ++ $(Q)$(RM) $(DESTDIR)$(bindir)/$(EXEC) ++ $(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 ++ $(Q)$(RM) $(DESTDIR)$(libudevdir)/kpartx_id ++ $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/11-dm-parts.rules ++ $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/66-kpartx.rules ++ $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/67-kpartx-compat.rules ++ $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/68-del-part-nodes.rules + + clean: dep_clean +- $(RM) core *.o $(EXEC) ++ $(Q)$(RM) core *.o $(EXEC) + + include $(wildcard $(OBJS:.o=.d)) + + dep_clean: +- $(RM) $(OBJS:.o=.d) ++ $(Q)$(RM) $(OBJS:.o=.d) +diff --git a/libdmmp/Makefile b/libdmmp/Makefile +index 67b6f86f..7693facb 100644 +--- a/libdmmp/Makefile ++++ b/libdmmp/Makefile +@@ -23,62 +23,62 @@ all: $(LIBS) doc + .PHONY: doc clean install uninstall check speed_test dep_clean + + $(LIBS): $(OBJS) +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ -o $@ $(OBJS) $(LIBDEPS) ++ $(Q)$(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ -o $@ $(OBJS) $(LIBDEPS) + + $(DEVLIB): $(LIBS) +- $(LN) $(LIBS) $@ ++ $(Q)$(LN) $(LIBS) $@ + + abi: $(DEVLIB:%.so=%.abi) + + install: +- mkdir -p $(DESTDIR)$(usrlibdir) +- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(usrlibdir)/$(LIBS) +- $(INSTALL_PROGRAM) -m 644 -D \ ++ @mkdir -p $(DESTDIR)$(usrlibdir) ++ $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(usrlibdir)/$(LIBS) ++ $(Q)$(INSTALL_PROGRAM) -m 644 -D \ + $(HEADERS) $(DESTDIR)$(includedir)/$(HEADERS) +- $(LN) $(LIBS) $(DESTDIR)$(usrlibdir)/$(DEVLIB) +- $(INSTALL_PROGRAM) -m 644 -D \ ++ $(Q)$(LN) $(LIBS) $(DESTDIR)$(usrlibdir)/$(DEVLIB) ++ $(Q)$(INSTALL_PROGRAM) -m 644 -D \ + $(PKGFILE).in $(DESTDIR)$(pkgconfdir)/$(PKGFILE) +- perl -i -pe 's|__VERSION__|$(LIBDMMP_VERSION)|g' \ ++ $(Q)perl -i -pe 's|__VERSION__|$(LIBDMMP_VERSION)|g' \ + $(DESTDIR)$(pkgconfdir)/$(PKGFILE) +- perl -i -pe 's|__LIBDIR__|$(usrlibdir)|g' \ ++ $(Q)perl -i -pe 's|__LIBDIR__|$(usrlibdir)|g' \ + $(DESTDIR)$(pkgconfdir)/$(PKGFILE) +- perl -i -pe 's|__INCLUDEDIR__|$(includedir)|g' \ ++ $(Q)perl -i -pe 's|__INCLUDEDIR__|$(includedir)|g' \ + $(DESTDIR)$(pkgconfdir)/$(PKGFILE) +- $(INSTALL_PROGRAM) -d 755 $(DESTDIR)$(mandir)/man3 +- $(INSTALL_PROGRAM) -m 644 -t $(DESTDIR)$(mandir)/man3 docs/man/*.3 ++ $(Q)$(INSTALL_PROGRAM) -d 755 $(DESTDIR)$(mandir)/man3 ++ $(Q)$(INSTALL_PROGRAM) -m 644 -t $(DESTDIR)$(mandir)/man3 docs/man/*.3 + + uninstall: +- $(RM) $(DESTDIR)$(usrlibdir)/$(LIBS) +- $(RM) $(DESTDIR)$(includedir)/$(HEADERS) +- $(RM) $(DESTDIR)$(usrlibdir)/$(DEVLIB) ++ $(Q)$(RM) $(DESTDIR)$(usrlibdir)/$(LIBS) ++ $(Q)$(RM) $(DESTDIR)$(includedir)/$(HEADERS) ++ $(Q)$(RM) $(DESTDIR)$(usrlibdir)/$(DEVLIB) + @for file in $(DESTDIR)$(mandir)/man3/dmmp_*; do \ + $(RM) $$file; \ + done +- $(RM) $(DESTDIR)$(mandir)/man3/libdmmp.h* +- $(RM) $(DESTDIR)$(pkgconfdir)/$(PKGFILE) ++ $(Q)$(RM) $(DESTDIR)$(mandir)/man3/libdmmp.h* ++ $(Q)$(RM) $(DESTDIR)$(pkgconfdir)/$(PKGFILE) + + clean: dep_clean +- $(RM) core *.a *.o *.so *.so.* *.abi $(NV_VERSION_SCRIPT) +- $(MAKE) -C test clean ++ $(Q)$(RM) core *.a *.o *.so *.so.* *.abi $(NV_VERSION_SCRIPT) ++ @$(MAKE) -C test clean + + include $(wildcard $(OBJS:.o=.d)) + + check: all +- $(MAKE) -C test check ++ @$(MAKE) -C test check + + speed_test: all +- $(MAKE) -C test speed_test ++ @$(MAKE) -C test speed_test + + doc: docs/man/dmmp_strerror.3 + + docs/man/dmmp_strerror.3: $(HEADERS) +- TEMPFILE=$(shell mktemp); \ ++ $(Q)TEMPFILE=$(shell mktemp); \ + cat $^ | perl docs/doc-preclean.pl >$$TEMPFILE; \ + LC_ALL=C \ + KBUILD_BUILD_TIMESTAMP=`git log -n1 --pretty=%cd --date=iso -- $^` \ + perl docs/kernel-doc -man $$TEMPFILE | \ + perl docs/split-man.pl docs/man; \ +- rm -f $$TEMPFILE ++ $(RM) -f $$TEMPFILE + + dep_clean: +- $(RM) $(OBJS:.o=.d) ++ $(Q)$(RM) $(OBJS:.o=.d) +diff --git a/libdmmp/test/Makefile b/libdmmp/test/Makefile +index 93de64a0..9d0817c8 100644 +--- a/libdmmp/test/Makefile ++++ b/libdmmp/test/Makefile +@@ -16,7 +16,7 @@ LDFLAGS += -L$(_libdmmpdir) -ldmmp + all: $(TEST_EXEC) $(SPD_TEST_EXEC) + + check: $(TEST_EXEC) $(SPD_TEST_EXEC) +- sudo env LD_LIBRARY_PATH=$(_libdmmpdir):$(_mpathcmddir) \ ++ $(Q)sudo env LD_LIBRARY_PATH=$(_libdmmpdir):$(_mpathcmddir) \ + valgrind --quiet --leak-check=full \ + --show-reachable=no --show-possibly-lost=no \ + --trace-children=yes --error-exitcode=1 \ +@@ -24,15 +24,15 @@ check: $(TEST_EXEC) $(SPD_TEST_EXEC) + $(MAKE) speed_test + + speed_test: $(SPD_TEST_EXEC) +- sudo env LD_LIBRARY_PATH=$(_libdmmpdir):$(_mpathcmddir) \ ++ $(Q)sudo env LD_LIBRARY_PATH=$(_libdmmpdir):$(_mpathcmddir) \ + time -p ./$(SPD_TEST_EXEC) + + clean: dep_clean +- rm -f $(TEST_EXEC) $(SPD_TEST_EXEC) ++ $(Q)$(RM) -f $(TEST_EXEC) $(SPD_TEST_EXEC) + + OBJS = $(TEST_EXEC).o $(SPD_TEST_EXEC).o + include $(wildcard $(OBJS:.o=.d)) + + + dep_clean: +- $(RM) $(OBJS:.o=.d) ++ $(Q)$(RM) $(OBJS:.o=.d) +diff --git a/libmpathcmd/Makefile b/libmpathcmd/Makefile +index cfb202b8..be615c2f 100644 +--- a/libmpathcmd/Makefile ++++ b/libmpathcmd/Makefile +@@ -9,22 +9,22 @@ all: $(DEVLIB) + include $(TOPDIR)/rules.mk + + install: all +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) +- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) +- $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(includedir) +- $(INSTALL_PROGRAM) -m 644 mpath_cmd.h $(DESTDIR)$(includedir) ++ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) ++ $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) ++ $(Q)$(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) ++ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(includedir) ++ $(Q)$(INSTALL_PROGRAM) -m 644 mpath_cmd.h $(DESTDIR)$(includedir) + + uninstall: +- $(RM) $(DESTDIR)$(syslibdir)/$(LIBS) +- $(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) +- $(RM) $(DESTDIR)$(includedir)/mpath_cmd.h ++ $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(LIBS) ++ $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) ++ $(Q)$(RM) $(DESTDIR)$(includedir)/mpath_cmd.h + + clean: dep_clean +- $(RM) core *.a *.o *.so *.so.* *.abi $(NV_VERSION_SCRIPT) ++ $(Q)$(RM) core *.a *.o *.so *.so.* *.abi $(NV_VERSION_SCRIPT) + + include $(wildcard $(OBJS:.o=.d)) + + + dep_clean: +- $(RM) $(OBJS:.o=.d) ++ $(Q)$(RM) $(OBJS:.o=.d) +diff --git a/libmpathpersist/Makefile b/libmpathpersist/Makefile +index 94672556..8f9a43f6 100644 +--- a/libmpathpersist/Makefile ++++ b/libmpathpersist/Makefile +@@ -12,28 +12,28 @@ all: $(DEVLIB) + include $(TOPDIR)/rules.mk + + install: all +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) +- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) +- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(syslibdir) +- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(mandir)/man3 +- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(includedir) +- $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) +- $(INSTALL_PROGRAM) -m 644 mpath_persistent_reserve_in.3 $(DESTDIR)$(mandir)/man3 +- $(INSTALL_PROGRAM) -m 644 mpath_persistent_reserve_out.3 $(DESTDIR)$(mandir)/man3 +- $(INSTALL_PROGRAM) -m 644 mpath_persist.h $(DESTDIR)$(includedir) ++ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) ++ $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) ++ $(Q)$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(syslibdir) ++ $(Q)$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(mandir)/man3 ++ $(Q)$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(includedir) ++ $(Q)$(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) ++ $(Q)$(INSTALL_PROGRAM) -m 644 mpath_persistent_reserve_in.3 $(DESTDIR)$(mandir)/man3 ++ $(Q)$(INSTALL_PROGRAM) -m 644 mpath_persistent_reserve_out.3 $(DESTDIR)$(mandir)/man3 ++ $(Q)$(INSTALL_PROGRAM) -m 644 mpath_persist.h $(DESTDIR)$(includedir) + + uninstall: +- $(RM) $(DESTDIR)$(syslibdir)/$(LIBS) +- $(RM) $(DESTDIR)$(mandir)/man3/mpath_persistent_reserve_in.3 +- $(RM) $(DESTDIR)$(mandir)/man3/mpath_persistent_reserve_out.3 +- $(RM) $(DESTDIR)$(includedir)/mpath_persist.h +- $(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) ++ $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(LIBS) ++ $(Q)$(RM) $(DESTDIR)$(mandir)/man3/mpath_persistent_reserve_in.3 ++ $(Q)$(RM) $(DESTDIR)$(mandir)/man3/mpath_persistent_reserve_out.3 ++ $(Q)$(RM) $(DESTDIR)$(includedir)/mpath_persist.h ++ $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) + + clean: dep_clean +- $(RM) core *.a *.o *.so *.so.* *.abi $(NV_VERSION_SCRIPT) ++ $(Q)$(RM) core *.a *.o *.so *.so.* *.abi $(NV_VERSION_SCRIPT) + + include $(wildcard $(OBJS:.o=.d)) + + + dep_clean: +- $(RM) $(OBJS:.o=.d) ++ $(Q)$(RM) $(OBJS:.o=.d) +diff --git a/libmpathutil/Makefile b/libmpathutil/Makefile +index 5ab33c09..f059de14 100644 +--- a/libmpathutil/Makefile ++++ b/libmpathutil/Makefile +@@ -20,18 +20,18 @@ all: $(DEVLIB) + include $(TOPDIR)/rules.mk + + install: all +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) +- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) +- $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) ++ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) ++ $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) ++ $(Q)$(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) + + uninstall: +- $(RM) $(DESTDIR)$(syslibdir)/$(LIBS) +- $(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) ++ $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(LIBS) ++ $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) + + clean: dep_clean +- $(RM) core *.a *.o *.so *.so.* *.abi nvme-ioctl.c nvme-ioctl.h $(NV_VERSION_SCRIPT) ++ $(Q)$(RM) core *.a *.o *.so *.so.* *.abi nvme-ioctl.c nvme-ioctl.h $(NV_VERSION_SCRIPT) + + include $(wildcard $(OBJS:.o=.d)) + + dep_clean: +- $(RM) $(OBJS:.o=.d) ++ $(Q)$(RM) $(OBJS:.o=.d) +diff --git a/libmpathvalid/Makefile b/libmpathvalid/Makefile +index 88034df3..791a0398 100644 +--- a/libmpathvalid/Makefile ++++ b/libmpathvalid/Makefile +@@ -13,21 +13,21 @@ all: $(DEVLIB) + include $(TOPDIR)/rules.mk + + install: $(LIBS) +- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(syslibdir) +- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) +- $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) +- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(includedir) +- $(INSTALL_PROGRAM) -m 644 mpath_valid.h $(DESTDIR)$(includedir) ++ $(Q)$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(syslibdir) ++ $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) ++ $(Q)$(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) ++ $(Q)$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(includedir) ++ $(Q)$(INSTALL_PROGRAM) -m 644 mpath_valid.h $(DESTDIR)$(includedir) + + uninstall: +- $(RM) $(DESTDIR)$(syslibdir)/$(LIBS) +- $(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) +- $(RM) $(DESTDIR)$(includedir)/mpath_valid.h ++ $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(LIBS) ++ $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) ++ $(Q)$(RM) $(DESTDIR)$(includedir)/mpath_valid.h + + clean: dep_clean +- $(RM) core *.a *.o *.so *.so.* *.abi $(NV_VERSION_SCRIPT) ++ $(Q)$(RM) core *.a *.o *.so *.so.* *.abi $(NV_VERSION_SCRIPT) + + include $(wildcard $(OBJS:.o=.d)) + + dep_clean: +- $(RM) $(OBJS:.o=.d) ++ $(Q)$(RM) $(OBJS:.o=.d) +diff --git a/libmultipath/Makefile b/libmultipath/Makefile +index 1cc13577..3df851e2 100644 +--- a/libmultipath/Makefile ++++ b/libmultipath/Makefile +@@ -31,47 +31,47 @@ all: $(DEVLIB) + include $(TOPDIR)/rules.mk + + nvme-lib.o: nvme-lib.c nvme-ioctl.c nvme-ioctl.h +- $(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-function -c -o $@ $< ++ $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-function -c -o $@ $< + + # there are lots of "unused parameters" in dict.c + # because not all handler / snprint methods need all parameters + dict.o: dict.c +- $(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-parameter -c -o $@ $< ++ $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-parameter -c -o $@ $< + + make_static = $(shell sed '/^static/!s/^\([a-z]\{1,\} \)/static \1/' <$1 >$2) + + nvme-ioctl.c: nvme/nvme-ioctl.c +- $(call make_static,$<,$@) ++ $(Q)$(call make_static,$<,$@) + + nvme-ioctl.h: nvme/nvme-ioctl.h +- $(call make_static,$<,$@) ++ $(Q)$(call make_static,$<,$@) + + ../tests/$(LIBS): $(OBJS-O) $(OBJS-T) $(VERSION_SCRIPT) +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=`basename $@` \ ++ $(Q)$(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=`basename $@` \ + -o $@ $(OBJS-O) $(OBJS-T) $(LIBDEPS) +- $(LN) $@ ${@:.so.0=.so} ++ $(Q)$(LN) $@ ${@:.so.0=.so} + + # This rule is invoked from tests/Makefile, overriding configdir and plugindir + %-test.o: %.c + @echo building $@ because of $? +- $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< ++ $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< + + test-lib: ../tests/$(LIBS) + + install: all +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) +- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) +- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(plugindir) +- $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) ++ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) ++ $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) ++ $(Q)$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(plugindir) ++ $(Q)$(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) + + uninstall: +- $(RM) $(DESTDIR)$(syslibdir)/$(LIBS) +- $(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) ++ $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(LIBS) ++ $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) + + clean: dep_clean +- $(RM) core *.a *.o *.so *.so.* *.abi nvme-ioctl.c nvme-ioctl.h autoconfig.h $(NV_VERSION_SCRIPT) ++ $(Q)$(RM) core *.a *.o *.so *.so.* *.abi nvme-ioctl.c nvme-ioctl.h autoconfig.h $(NV_VERSION_SCRIPT) + + include $(wildcard $(OBJS:.o=.d)) + + dep_clean: +- $(RM) $(OBJS:.o=.d) ++ $(Q)$(RM) $(OBJS:.o=.d) +diff --git a/libmultipath/checkers/Makefile b/libmultipath/checkers/Makefile +index 39ad76e0..b3120611 100644 +--- a/libmultipath/checkers/Makefile ++++ b/libmultipath/checkers/Makefile +@@ -22,16 +22,16 @@ LIBS= \ + all: $(LIBS) + + libcheck%.so: %.o +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) ++ $(Q)$(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) + + install: +- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(plugindir) ++ $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(plugindir) + + uninstall: + for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done + + clean: dep_clean +- $(RM) core *.a *.o *.gz *.so ++ $(Q)$(RM) core *.a *.o *.gz *.so + + OBJS := $(LIBS:libcheck%.so=%.o) + .SECONDARY: $(OBJS) +@@ -39,4 +39,4 @@ OBJS := $(LIBS:libcheck%.so=%.o) + include $(wildcard $(OBJS:.o=.d)) + + dep_clean: +- $(RM) $(OBJS:.o=.d) ++ $(Q)$(RM) $(OBJS:.o=.d) +diff --git a/libmultipath/foreign/Makefile b/libmultipath/foreign/Makefile +index 8bf9047b..0e245d6f 100644 +--- a/libmultipath/foreign/Makefile ++++ b/libmultipath/foreign/Makefile +@@ -14,16 +14,16 @@ LIBS = libforeign-nvme.so + all: $(LIBS) + + libforeign-%.so: %.o +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) ++ $(Q)$(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) + + install: +- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(plugindir) ++ $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(plugindir) + + uninstall: + for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done + + clean: dep_clean +- $(RM) core *.a *.o *.gz *.so ++ $(Q)$(RM) core *.a *.o *.gz *.so + + OBJS := $(LIBS:libforeign-%.so=%.o) + .SECONDARY: $(OBJS) +@@ -31,4 +31,4 @@ OBJS := $(LIBS:libforeign-%.so=%.o) + include $(wildcard $(OBJS:.o=.d)) + + dep_clean: +- $(RM) $(OBJS:.o=.d) ++ $(Q)$(RM) $(OBJS:.o=.d) +diff --git a/libmultipath/prioritizers/Makefile b/libmultipath/prioritizers/Makefile +index a699e8a6..e1688163 100644 +--- a/libmultipath/prioritizers/Makefile ++++ b/libmultipath/prioritizers/Makefile +@@ -34,16 +34,16 @@ endif + all: $(LIBS) + + libprio%.so: %.o +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) ++ $(Q)$(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) + + install: $(LIBS) +- $(INSTALL_PROGRAM) -m 755 libprio*.so $(DESTDIR)$(plugindir) ++ $(Q)$(INSTALL_PROGRAM) -m 755 libprio*.so $(DESTDIR)$(plugindir) + + uninstall: + for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done + + clean: dep_clean +- $(RM) core *.a *.o *.gz *.so ++ $(Q)$(RM) core *.a *.o *.gz *.so + + OBJS = $(LIBS:libprio%.so=%.o) alua_rtpg.o + .SECONDARY: $(OBJS) +@@ -51,4 +51,4 @@ OBJS = $(LIBS:libprio%.so=%.o) alua_rtpg.o + include $(wildcard $(OBJS:.o=.d)) + + dep_clean: +- $(RM) $(OBJS:.o=.d) ++ $(Q)$(RM) $(OBJS:.o=.d) +diff --git a/mpathpersist/Makefile b/mpathpersist/Makefile +index d62537b5..f57c105c 100644 +--- a/mpathpersist/Makefile ++++ b/mpathpersist/Makefile +@@ -14,22 +14,22 @@ OBJS = main.o + all: $(EXEC) + + $(EXEC): $(OBJS) +- $(CC) $(OBJS) -o $(EXEC) $(LDFLAGS) $(CFLAGS) $(LIBDEPS) ++ $(Q)$(CC) $(OBJS) -o $(EXEC) $(LDFLAGS) $(CFLAGS) $(LIBDEPS) + + install: +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) +- $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 +- $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 ++ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) ++ $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ ++ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 ++ $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 + + clean: dep_clean +- $(RM) core *.o $(EXEC) ++ $(Q)$(RM) core *.o $(EXEC) + + include $(wildcard $(OBJS:.o=.d)) + + uninstall: +- $(RM) $(DESTDIR)$(bindir)/$(EXEC) +- $(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 ++ $(Q)$(RM) $(DESTDIR)$(bindir)/$(EXEC) ++ $(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 + + dep_clean: +- $(RM) $(OBJS:.o=.d) ++ $(Q)$(RM) $(OBJS:.o=.d) +diff --git a/multipath/Makefile b/multipath/Makefile +index 7f7b341d..73db991a 100644 +--- a/multipath/Makefile ++++ b/multipath/Makefile +@@ -16,44 +16,46 @@ OBJS := main.o + all: $(EXEC) multipath.rules tmpfiles.conf + + $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so +- $(CC) $(CFLAGS) $(OBJS) -o $(EXEC) $(LDFLAGS) $(LIBDEPS) ++ @echo building $@ because of $? ++ $(Q)$(CC) $(CFLAGS) $(OBJS) -o $(EXEC) $(LDFLAGS) $(LIBDEPS) + + install: +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) +- $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) +- $(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) +- $(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)$(udevrulesdir)/56-multipath.rules +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(modulesloaddir) +- $(INSTALL_PROGRAM) -m 644 modules-load.conf $(DESTDIR)$(modulesloaddir)/multipath.conf +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(tmpfilesdir) +- $(INSTALL_PROGRAM) -m 644 tmpfiles.conf $(DESTDIR)$(tmpfilesdir)/multipath.conf +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 +- $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man5 +- $(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5 $(DESTDIR)$(mandir)/man5 ++ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) ++ $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ ++ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) ++ $(Q)$(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) ++ $(Q)$(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)$(udevrulesdir)/56-multipath.rules ++ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(modulesloaddir) ++ $(Q)$(INSTALL_PROGRAM) -m 644 modules-load.conf $(DESTDIR)$(modulesloaddir)/multipath.conf ++ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(tmpfilesdir) ++ $(Q)$(INSTALL_PROGRAM) -m 644 tmpfiles.conf $(DESTDIR)$(tmpfilesdir)/multipath.conf ++ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 ++ $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 ++ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man5 ++ $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5 $(DESTDIR)$(mandir)/man5 + ifneq ($(SCSI_DH_MODULES_PRELOAD),) +- $(INSTALL_PROGRAM) -m 644 scsi_dh.conf $(DESTDIR)$(modulesloaddir)/scsi_dh.conf +- for _x in $(SCSI_DH_MODULES_PRELOAD); do echo "$$_x"; done \ ++ $(Q)$(INSTALL_PROGRAM) -m 644 scsi_dh.conf $(DESTDIR)$(modulesloaddir)/scsi_dh.conf ++ $(Q)for _x in $(SCSI_DH_MODULES_PRELOAD); do echo "$$_x"; done \ + >>$(DESTDIR)$(modulesloaddir)/scsi_dh.conf + endif + + uninstall: +- $(RM) $(DESTDIR)$(bindir)/$(EXEC) +- $(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules +- $(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf +- $(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf +- $(RM) $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules +- $(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 +- $(RM) $(DESTDIR)$(mandir)/man5/$(EXEC).conf.5 ++ $(Q)$(RM) $(DESTDIR)$(bindir)/$(EXEC) ++ $(Q)$(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules ++ $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf ++ $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf ++ $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules ++ $(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 ++ $(Q)$(RM) $(DESTDIR)$(mandir)/man5/$(EXEC).conf.5 + + clean: dep_clean +- $(RM) core *.o $(EXEC) multipath.rules tmpfiles.conf ++ $(Q)$(RM) core *.o $(EXEC) multipath.rules tmpfiles.conf + + include $(wildcard $(OBJS:.o=.d)) + + dep_clean: +- $(RM) $(OBJS:.o=.d) ++ $(Q)$(RM) $(OBJS:.o=.d) + + %: %.in +- sed 's,@RUNTIME_DIR@,$(runtimedir),' $< >$@ ++ @echo creating $@ ++ $(Q)sed 's,@RUNTIME_DIR@,$(runtimedir),' $< >$@ +diff --git a/multipathd/Makefile b/multipathd/Makefile +index 587bb916..9d531329 100644 +--- a/multipathd/Makefile ++++ b/multipathd/Makefile +@@ -45,41 +45,43 @@ endif + all : $(EXEC) $(CLI) + + $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so +- $(CC) $(CFLAGS) $(OBJS) $(LDFLAGS) -o $(EXEC) $(LIBDEPS) ++ @echo building $@ because of $? ++ $(Q)$(CC) $(CFLAGS) $(OBJS) $(LDFLAGS) -o $(EXEC) $(LIBDEPS) + + multipathc.o: multipathc.c +- $(CC) $(CPPFLAGS) $(RL_CPPFLAGS) $(CFLAGS) -Wno-unused-parameter -c -o $@ $< ++ $(Q)$(CC) $(CPPFLAGS) $(RL_CPPFLAGS) $(CFLAGS) -Wno-unused-parameter -c -o $@ $< + + $(CLI): $(CLI_OBJS) +- $(CC) $(CFLAGS) $(CLI_OBJS) $(LDFLAGS) -o $@ $(CLI_LIBDEPS) $(RL_LIBDEPS) ++ @echo building $@ because of $? ++ $(Q)$(CC) $(CFLAGS) $(CLI_OBJS) $(LDFLAGS) -o $@ $(CLI_LIBDEPS) $(RL_LIBDEPS) + + cli_handlers.o: cli_handlers.c +- $(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-parameter -c -o $@ $< ++ $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-parameter -c -o $@ $< + + install: +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) +- $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir) +- $(INSTALL_PROGRAM) -m 755 $(CLI) $(DESTDIR)$(bindir) ++ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) ++ $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir) ++ $(Q)$(INSTALL_PROGRAM) -m 755 $(CLI) $(DESTDIR)$(bindir) + ifdef SYSTEMD +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(unitdir) +- $(INSTALL_PROGRAM) -m 644 $(EXEC).service $(DESTDIR)$(unitdir) +- $(INSTALL_PROGRAM) -m 644 $(EXEC).socket $(DESTDIR)$(unitdir) ++ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(unitdir) ++ $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).service $(DESTDIR)$(unitdir) ++ $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).socket $(DESTDIR)$(unitdir) + endif +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 +- $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 +- $(INSTALL_PROGRAM) -m 644 $(CLI).8 $(DESTDIR)$(mandir)/man8 ++ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 ++ $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 ++ $(Q)$(INSTALL_PROGRAM) -m 644 $(CLI).8 $(DESTDIR)$(mandir)/man8 + + uninstall: +- $(RM) $(DESTDIR)$(bindir)/$(EXEC) $(DESTDIR)$(bindir)/$(CLI) +- $(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 +- $(RM) $(DESTDIR)$(mandir)/man8/$(CLI).8 +- $(RM) $(DESTDIR)$(unitdir)/$(EXEC).service +- $(RM) $(DESTDIR)$(unitdir)/$(EXEC).socket ++ $(Q)$(RM) $(DESTDIR)$(bindir)/$(EXEC) $(DESTDIR)$(bindir)/$(CLI) ++ $(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 ++ $(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(CLI).8 ++ $(Q)$(RM) $(DESTDIR)$(unitdir)/$(EXEC).service ++ $(Q)$(RM) $(DESTDIR)$(unitdir)/$(EXEC).socket + + clean: dep_clean +- $(RM) core *.o $(EXEC) $(CLI) ++ $(Q)$(RM) core *.o $(EXEC) $(CLI) + + include $(wildcard $(OBJS:.o=.d)) + + dep_clean: +- $(RM) $(OBJS:.o=.d) ++ $(Q)$(RM) $(OBJS:.o=.d) +diff --git a/rules.mk b/rules.mk +index d8612527..c3a8e7ac 100644 +--- a/rules.mk ++++ b/rules.mk +@@ -2,17 +2,17 @@ + # SPDX-License-Identifier: GPL-2.0-or-later + + $(DEVLIB): $(LIBS) +- $(LN) $(LIBS) $@ ++ $(Q)$(LN) $(LIBS) $@ + + $(LIBS): $(OBJS) $(VERSION_SCRIPT) +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ ++ $(Q)$(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ + -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) + + $(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ ++ $(Q)$(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ + -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) + + abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) + + $(TOPDIR)/config.mk $(multipathdir)/autoconfig.h: +- $(MAKE) -C $(TOPDIR) -f create-config.mk ++ $(Q)$(MAKE) -C $(TOPDIR) -f create-config.mk +diff --git a/tests/Makefile b/tests/Makefile +index d9856d17..021da0b0 100644 +--- a/tests/Makefile ++++ b/tests/Makefile +@@ -12,7 +12,6 @@ TESTS := uevent parser util dmevents hwtable blacklist unaligned vpd pgpolicy \ + alias directio valid devt mpathvalid strbuf sysfs features cli + HELPERS := test-lib.o test-log.o + +-.SILENT: $(TESTS:%=%.o) + .PRECIOUS: $(TESTS:%=%-test) + + all: $(TESTS:%=%.out) +@@ -71,11 +70,12 @@ features-test_LIBDEPS := -ludev -lpthread + cli-test_OBJDEPS := $(daemondir)/cli.o + + %.o: %.c +- $(CC) $(CPPFLAGS) $(CFLAGS) $($*-test_FLAGS) -c -o $@ $< ++ @echo building $@ because of $? ++ $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) $($*-test_FLAGS) -c -o $@ $< + + lib/libchecktur.so: +- mkdir -p lib +- cd lib && ln -s ../$(multipathdir)/*/*.so . ++ @mkdir -p lib ++ $(Q)cd lib && ln -s ../$(multipathdir)/*/*.so . + + %.out: %-test lib/libchecktur.so + @echo == running $< == +@@ -89,34 +89,35 @@ lib/libchecktur.so: + OBJS = $(TESTS:%=%.o) $(HELPERS) + + test_clean: +- $(RM) $(TESTS:%=%.out) $(TESTS:%=%.vgr) *.so* ++ $(Q)$(RM) $(TESTS:%=%.out) $(TESTS:%=%.vgr) *.so* + + valgrind_clean: +- $(RM) $(TESTS:%=%.vgr) ++ $(Q)$(RM) $(TESTS:%=%.vgr) + + clean: test_clean valgrind_clean dep_clean +- $(RM) $(TESTS:%=%-test) $(OBJS) *.o.wrap +- $(RM) -rf lib conf.d ++ $(Q)$(RM) $(TESTS:%=%-test) $(OBJS) *.o.wrap ++ $(Q)$(RM) -rf lib conf.d + + .SECONDARY: $(OBJS) + + include $(wildcard $(OBJS:.o=.d)) + + dep_clean: +- $(RM) $(OBJS:.o=.d) ++ $(Q)$(RM) $(OBJS:.o=.d) + + %.o.wrap: %.c + @sed -n 's/^.*__wrap_\([a-zA-Z0-9_]*\).*$$/-Wl,--wrap=\1/p' $< | \ + sort -u | tr '\n' ' ' >$@ + + libmultipath.so.0: $(multipathdir)/libmultipath.so.0 +- make -C $(multipathdir) configdir=$(TESTDIR)/conf.d plugindir=$(TESTDIR)/lib test-lib ++ @make -C $(multipathdir) configdir=$(TESTDIR)/conf.d plugindir=$(TESTDIR)/lib test-lib + + # COLON will get expanded during second expansion below + COLON:=: + .SECONDEXPANSION: + %-test: %.o %.o.wrap $$($$@_OBJDEPS) $$($$@_TESTDEPS) $$($$@_TESTDEPS$$(COLON).o=.o.wrap) \ + libmultipath.so.0 $(mpathutildir)/libmpathutil.so.0 $(mpathcmddir)/libmpathcmd.so.0 Makefile +- $(CC) $(CFLAGS) -o $@ $(LDFLAGS) $< $($@_TESTDEPS) $($@_OBJDEPS) \ ++ @echo building $@ ++ $(Q)$(CC) $(CFLAGS) -o $@ $(LDFLAGS) $< $($@_TESTDEPS) $($@_OBJDEPS) \ + $(LIBDEPS) $($@_LIBDEPS) \ + $(shell cat $<.wrap) $(foreach dep,$($@_TESTDEPS),$(shell cat $(dep).wrap)) diff --git a/0021-multipath-tests-add-sysfs-test.patch b/0021-multipath-tests-add-sysfs-test.patch deleted file mode 100644 index b02a055..0000000 --- a/0021-multipath-tests-add-sysfs-test.patch +++ /dev/null @@ -1,538 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 5 Jul 2022 23:19:30 +0200 -Subject: [PATCH] multipath tests: add sysfs test - -Signed-off-by: Martin Wilck - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - tests/Makefile | 5 +- - tests/sysfs.c | 494 +++++++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 498 insertions(+), 1 deletion(-) - create mode 100644 tests/sysfs.c - -diff --git a/tests/Makefile b/tests/Makefile -index d20ef236..95a99908 100644 ---- a/tests/Makefile -+++ b/tests/Makefile -@@ -16,7 +16,7 @@ CFLAGS += $(BIN_CFLAGS) -Wno-unused-parameter $(W_MISSING_INITIALIZERS) - LIBDEPS += -L. -L$(mpathcmddir) -lmultipath -lmpathcmd -lcmocka - - TESTS := uevent parser util dmevents hwtable blacklist unaligned vpd pgpolicy \ -- alias directio valid devt mpathvalid strbuf -+ alias directio valid devt mpathvalid strbuf sysfs - HELPERS := test-lib.o test-log.o - - .SILENT: $(TESTS:%=%.o) -@@ -70,6 +70,9 @@ ifneq ($(DIO_TEST_DEV),) - directio-test_LIBDEPS := -laio - endif - strbuf-test_OBJDEPS := ../libmultipath/strbuf.o -+sysfs-test_TESTDEPS := test-log.o -+sysfs-test_OBJDEPS := ../libmultipath/sysfs.o ../libmultipath/util.o -+sysfs-test_LIBDEPS := -ludev -lpthread -ldl - - %.o: %.c - $(CC) $(CPPFLAGS) $(CFLAGS) $($*-test_FLAGS) -c -o $@ $< -diff --git a/tests/sysfs.c b/tests/sysfs.c -new file mode 100644 -index 00000000..0ec135bf ---- /dev/null -+++ b/tests/sysfs.c -@@ -0,0 +1,494 @@ -+/* -+ * Copyright (c) 2021 SUSE LLC -+ * SPDX-License-Identifier: GPL-2.0-only -+ */ -+ -+#define _GNU_SOURCE -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "debug.h" -+#include "globals.c" -+#include "test-log.h" -+#include "sysfs.h" -+#include "util.h" -+ -+#define TEST_FD 123 -+ -+char *__wrap_udev_device_get_syspath(struct udev_device *ud) -+{ -+ char *val = mock_ptr_type(char *); -+ -+ return val; -+} -+ -+int __wrap_open(const char *pathname, int flags) -+{ -+ int ret; -+ -+ check_expected(pathname); -+ check_expected(flags); -+ ret = mock_type(int); -+ return ret; -+} -+ -+ssize_t __wrap_read(int fd, void *buf, size_t count) -+{ -+ ssize_t ret; -+ char *val; -+ -+ check_expected(fd); -+ check_expected(count); -+ ret = mock_type(int); -+ val = mock_ptr_type(char *); -+ if (ret >= (ssize_t)count) -+ ret = count; -+ if (ret >= 0 && val) { -+ fprintf(stderr, "%s: '%s' -> %zd\n", __func__, val, ret); -+ memcpy(buf, val, ret); -+ } -+ return ret; -+} -+ -+ssize_t __wrap_write(int fd, void *buf, size_t count) -+{ -+ ssize_t ret; -+ -+ check_expected(fd); -+ check_expected(count); -+ ret = mock_type(int); -+ if (ret >= (ssize_t)count) -+ ret = count; -+ return ret; -+} -+ -+int __real_close(int fd); -+int __wrap_close(int fd) { -+ if (fd != TEST_FD) -+ return __real_close(fd); -+ return mock_type(int); -+} -+ -+static int setup(void **state) -+{ -+ udev = udev_new(); -+ return 0; -+} -+ -+static int teardown(void **state) -+{ -+ udev_unref(udev); -+ return 0; -+} -+ -+static void expect_sagv_invalid(void) -+{ -+ expect_condlog(1, "__sysfs_attr_get_value: invalid parameters"); -+} -+ -+static void test_sagv_invalid(void **state) -+{ -+ expect_sagv_invalid(); -+ assert_int_equal(sysfs_attr_get_value(NULL, NULL, NULL, 0), -EINVAL); -+ expect_sagv_invalid(); -+ assert_int_equal(sysfs_bin_attr_get_value(NULL, NULL, NULL, 0), -EINVAL); -+ -+ expect_sagv_invalid(); -+ assert_int_equal(sysfs_attr_get_value(NULL, (void *)state, (void *)state, 1), -+ -EINVAL); -+ expect_sagv_invalid(); -+ assert_int_equal(sysfs_bin_attr_get_value(NULL, (void *)state, (void *)state, 1), -+ -EINVAL); -+ -+ expect_sagv_invalid(); -+ assert_int_equal(sysfs_attr_get_value((void *)state, NULL, (void *)state, 1), -+ -EINVAL); -+ expect_sagv_invalid(); -+ assert_int_equal(sysfs_bin_attr_get_value((void *)state, NULL, (void *)state, 1), -+ -EINVAL); -+ -+ expect_sagv_invalid(); -+ assert_int_equal(sysfs_attr_get_value((void *)state, (void *)state, NULL, 1), -+ -EINVAL); -+ expect_sagv_invalid(); -+ assert_int_equal(sysfs_bin_attr_get_value((void *)state, (void *)state, NULL, 1), -+ -EINVAL); -+ -+ expect_sagv_invalid(); -+ assert_int_equal(sysfs_attr_get_value((void *)state, (void *)state, -+ (void *)state, 0), -EINVAL); -+ expect_sagv_invalid(); -+ assert_int_equal(sysfs_bin_attr_get_value((void *)state, (void *)state, -+ (void *)state, 0), -EINVAL); -+} -+ -+static void test_sagv_bad_udev(void **state) -+{ -+ will_return(__wrap_udev_device_get_syspath, NULL); -+ expect_condlog(3, "__sysfs_attr_get_value: invalid udevice"); -+ assert_int_equal(sysfs_attr_get_value((void *)state, (void *)state, -+ (void *)state, 1), -EINVAL); -+ -+ will_return(__wrap_udev_device_get_syspath, NULL); -+ expect_condlog(3, "__sysfs_attr_get_value: invalid udevice"); -+ assert_int_equal(sysfs_bin_attr_get_value((void *)state, (void *)state, -+ (void *)state, 1), -EINVAL); -+} -+ -+static void test_sagv_bad_snprintf(void **state) -+{ -+ char longstr[PATH_MAX + 1]; -+ char buf[1]; -+ -+ memset(longstr, 'a', sizeof(longstr) - 1); -+ longstr[sizeof(longstr) - 1] = '\0'; -+ -+ will_return(__wrap_udev_device_get_syspath, "/foo"); -+ expect_condlog(3, "__sysfs_attr_get_value: devpath overflow"); -+ assert_int_equal(sysfs_attr_get_value((void *)state, longstr, -+ buf, sizeof(buf)), -EOVERFLOW); -+ will_return(__wrap_udev_device_get_syspath, "/foo"); -+ expect_condlog(3, "__sysfs_attr_get_value: devpath overflow"); -+ assert_int_equal(sysfs_bin_attr_get_value((void *)state, longstr, -+ (unsigned char *)buf, sizeof(buf)), -+ -EOVERFLOW); -+} -+ -+static void test_sagv_open_fail(void **state) -+{ -+ char buf[1]; -+ -+ will_return(__wrap_udev_device_get_syspath, "/foo"); -+ expect_condlog(4, "open '/foo/bar'"); -+ expect_string(__wrap_open, pathname, "/foo/bar"); -+ expect_value(__wrap_open, flags, O_RDONLY); -+ errno = ENOENT; -+ will_return(__wrap_open, -1); -+ expect_condlog(3, "__sysfs_attr_get_value: attribute '/foo/bar' can not be opened"); -+ assert_int_equal(sysfs_attr_get_value((void *)state, "bar", -+ buf, sizeof(buf)), -ENOENT); -+} -+ -+static void test_sagv_read_fail(void **state) -+{ -+ char buf[1]; -+ -+ will_return(__wrap_udev_device_get_syspath, "/foo"); -+ expect_condlog(4, "open '/foo/bar'"); -+ expect_string(__wrap_open, pathname, "/foo/bar"); -+ expect_value(__wrap_open, flags, O_RDONLY); -+ will_return(__wrap_open, TEST_FD); -+ expect_value(__wrap_read, fd, TEST_FD); -+ expect_value(__wrap_read, count, sizeof(buf)); -+ errno = EISDIR; -+ will_return(__wrap_read, -1); -+ will_return(__wrap_read, NULL); -+ expect_condlog(3, "__sysfs_attr_get_value: read from /foo/bar failed:"); -+ will_return(__wrap_close, 0); -+ assert_int_equal(sysfs_attr_get_value((void *)state, "bar", -+ buf, sizeof(buf)), -EISDIR); -+ -+ will_return(__wrap_udev_device_get_syspath, "/foo"); -+ expect_condlog(4, "open '/foo/baz'"); -+ expect_string(__wrap_open, pathname, "/foo/baz"); -+ expect_value(__wrap_open, flags, O_RDONLY); -+ will_return(__wrap_open, TEST_FD); -+ expect_value(__wrap_read, fd, TEST_FD); -+ expect_value(__wrap_read, count, sizeof(buf)); -+ errno = EPERM; -+ will_return(__wrap_read, -1); -+ will_return(__wrap_read, NULL); -+ expect_condlog(3, "__sysfs_attr_get_value: read from /foo/baz failed:"); -+ will_return(__wrap_close, 0); -+ assert_int_equal(sysfs_bin_attr_get_value((void *)state, "baz", -+ (unsigned char *)buf, sizeof(buf)), -+ -EPERM); -+ -+} -+ -+static void _test_sagv_read(void **state, unsigned int bufsz) -+{ -+ char buf[16]; -+ char input[] = "01234567"; -+ unsigned int n, trunc; -+ -+ assert_in_range(bufsz, 1, sizeof(buf)); -+ memset(buf, '.', sizeof(buf)); -+ will_return(__wrap_udev_device_get_syspath, "/foo"); -+ expect_condlog(4, "open '/foo/bar'"); -+ expect_string(__wrap_open, pathname, "/foo/bar"); -+ expect_value(__wrap_open, flags, O_RDONLY); -+ will_return(__wrap_open, TEST_FD); -+ expect_value(__wrap_read, fd, TEST_FD); -+ expect_value(__wrap_read, count, bufsz); -+ will_return(__wrap_read, sizeof(input) - 1); -+ will_return(__wrap_read, input); -+ -+ /* If the buffer is too small, input will be truncated by a 0 byte */ -+ if (bufsz <= sizeof(input) - 1) { -+ n = bufsz; -+ trunc = 1; -+ expect_condlog(3, "__sysfs_attr_get_value: overflow reading from /foo/bar"); -+ } else { -+ n = sizeof(input) - 1; -+ trunc = 0; -+ } -+ will_return(__wrap_close, 0); -+ assert_int_equal(sysfs_attr_get_value((void *)state, "bar", -+ buf, bufsz), n); -+ assert_memory_equal(buf, input, n - trunc); -+ assert_int_equal(buf[n - trunc], '\0'); -+ -+ /* Binary input is not truncated */ -+ memset(buf, '.', sizeof(buf)); -+ will_return(__wrap_udev_device_get_syspath, "/foo"); -+ expect_condlog(4, "open '/foo/baz'"); -+ expect_string(__wrap_open, pathname, "/foo/baz"); -+ expect_value(__wrap_open, flags, O_RDONLY); -+ will_return(__wrap_open, TEST_FD); -+ expect_value(__wrap_read, fd, TEST_FD); -+ expect_value(__wrap_read, count, bufsz); -+ will_return(__wrap_read, sizeof(input) - 1); -+ will_return(__wrap_read, input); -+ will_return(__wrap_close, 0); -+ n = bufsz < sizeof(input) - 1 ? bufsz : sizeof(input) - 1; -+ assert_int_equal(sysfs_bin_attr_get_value((void *)state, "baz", -+ (unsigned char *)buf, -+ bufsz), -+ n); -+ assert_memory_equal(buf, input, n); -+} -+ -+static void test_sagv_read_overflow_8(void **state) -+{ -+ _test_sagv_read(state, 8); -+} -+ -+static void test_sagv_read_overflow_4(void **state) -+{ -+ _test_sagv_read(state, 4); -+} -+ -+static void test_sagv_read_overflow_1(void **state) -+{ -+ _test_sagv_read(state, 1); -+} -+ -+static void test_sagv_read_good_9(void **state) -+{ -+ _test_sagv_read(state, 9); -+} -+ -+static void test_sagv_read_good_15(void **state) -+{ -+ _test_sagv_read(state, 15); -+} -+ -+static void _test_sagv_read_zeroes(void **state, unsigned int bufsz) -+{ -+ char buf[16]; -+ char input[] = { '\0','\0','\0','\0','\0','\0','\0','\0' }; -+ unsigned int n; -+ -+ assert_in_range(bufsz, 1, sizeof(buf)); -+ memset(buf, '.', sizeof(buf)); -+ will_return(__wrap_udev_device_get_syspath, "/foo"); -+ expect_condlog(4, "open '/foo/bar'"); -+ expect_string(__wrap_open, pathname, "/foo/bar"); -+ expect_value(__wrap_open, flags, O_RDONLY); -+ will_return(__wrap_open, TEST_FD); -+ expect_value(__wrap_read, fd, TEST_FD); -+ expect_value(__wrap_read, count, bufsz); -+ will_return(__wrap_read, sizeof(input) - 1); -+ will_return(__wrap_read, input); -+ -+ if (bufsz <= sizeof(input) - 1) { -+ n = bufsz; -+ expect_condlog(3, "__sysfs_attr_get_value: overflow reading from /foo/bar"); -+ } else -+ n = 0; -+ -+ will_return(__wrap_close, 0); -+ assert_int_equal(sysfs_attr_get_value((void *)state, "bar", -+ buf, bufsz), n); -+ -+ /* -+ * The return value of sysfs_attr_get_value ignores zero bytes, -+ * but the read data should have been copied to the buffer -+ */ -+ assert_memory_equal(buf, input, n == 0 ? bufsz : n); -+} -+ -+static void test_sagv_read_zeroes_4(void **state) -+{ -+ _test_sagv_read_zeroes(state, 4); -+} -+ -+static void expect_sasv_invalid(void) -+{ -+ expect_condlog(1, "sysfs_attr_set_value: invalid parameters"); -+} -+ -+static void test_sasv_invalid(void **state) -+{ -+ expect_sasv_invalid(); -+ assert_int_equal(sysfs_attr_set_value(NULL, NULL, NULL, 0), -EINVAL); -+ -+ expect_sasv_invalid(); -+ assert_int_equal(sysfs_attr_set_value(NULL, (void *)state, (void *)state, 1), -+ -EINVAL); -+ -+ expect_sasv_invalid(); -+ assert_int_equal(sysfs_attr_set_value((void *)state, NULL, (void *)state, 1), -+ -EINVAL); -+ -+ expect_sasv_invalid(); -+ assert_int_equal(sysfs_attr_set_value((void *)state, (void *)state, NULL, 1), -+ -EINVAL); -+ -+ expect_sasv_invalid(); -+ assert_int_equal(sysfs_attr_set_value((void *)state, (void *)state, -+ (void *)state, 0), -EINVAL); -+} -+ -+static void test_sasv_bad_udev(void **state) -+{ -+ will_return(__wrap_udev_device_get_syspath, NULL); -+ expect_condlog(3, "sysfs_attr_set_value: invalid udevice"); -+ assert_int_equal(sysfs_attr_set_value((void *)state, (void *)state, -+ (void *)state, 1), -EINVAL); -+} -+ -+static void test_sasv_bad_snprintf(void **state) -+{ -+ char longstr[PATH_MAX + 1]; -+ char buf[1]; -+ -+ memset(longstr, 'a', sizeof(longstr) - 1); -+ longstr[sizeof(longstr) - 1] = '\0'; -+ -+ will_return(__wrap_udev_device_get_syspath, "/foo"); -+ expect_condlog(3, "sysfs_attr_set_value: devpath overflow"); -+ assert_int_equal(sysfs_attr_set_value((void *)state, longstr, -+ buf, sizeof(buf)), -EOVERFLOW); -+} -+ -+static void test_sasv_open_fail(void **state) -+{ -+ char buf[1]; -+ -+ will_return(__wrap_udev_device_get_syspath, "/foo"); -+ expect_condlog(4, "open '/foo/bar'"); -+ expect_string(__wrap_open, pathname, "/foo/bar"); -+ expect_value(__wrap_open, flags, O_WRONLY); -+ errno = EPERM; -+ will_return(__wrap_open, -1); -+ expect_condlog(3, "sysfs_attr_set_value: attribute '/foo/bar' can not be opened"); -+ assert_int_equal(sysfs_attr_set_value((void *)state, "bar", -+ buf, sizeof(buf)), -EPERM); -+} -+ -+static void test_sasv_write_fail(void **state) -+{ -+ char buf[1]; -+ -+ will_return(__wrap_udev_device_get_syspath, "/foo"); -+ expect_condlog(4, "open '/foo/bar'"); -+ expect_string(__wrap_open, pathname, "/foo/bar"); -+ expect_value(__wrap_open, flags, O_WRONLY); -+ will_return(__wrap_open, TEST_FD); -+ expect_value(__wrap_write, fd, TEST_FD); -+ expect_value(__wrap_write, count, sizeof(buf)); -+ errno = EISDIR; -+ will_return(__wrap_write, -1); -+ expect_condlog(3, "sysfs_attr_set_value: write to /foo/bar failed:"); -+ will_return(__wrap_close, 0); -+ assert_int_equal(sysfs_attr_set_value((void *)state, "bar", -+ buf, sizeof(buf)), -EISDIR); -+ -+} -+ -+static void _test_sasv_write(void **state, unsigned int n_written) -+{ -+ char buf[8]; -+ -+ assert_in_range(n_written, 0, sizeof(buf)); -+ will_return(__wrap_udev_device_get_syspath, "/foo"); -+ expect_condlog(4, "open '/foo/bar'"); -+ expect_string(__wrap_open, pathname, "/foo/bar"); -+ expect_value(__wrap_open, flags, O_WRONLY); -+ will_return(__wrap_open, TEST_FD); -+ expect_value(__wrap_write, fd, TEST_FD); -+ expect_value(__wrap_write, count, sizeof(buf)); -+ will_return(__wrap_write, n_written); -+ -+ if (n_written < sizeof(buf)) -+ expect_condlog(3, "sysfs_attr_set_value: underflow writing"); -+ will_return(__wrap_close, 0); -+ assert_int_equal(sysfs_attr_set_value((void *)state, "bar", -+ buf, sizeof(buf)), -+ n_written); -+} -+ -+static void test_sasv_write_0(void **state) -+{ -+ _test_sasv_write(state, 0); -+} -+ -+static void test_sasv_write_4(void **state) -+{ -+ _test_sasv_write(state, 4); -+} -+ -+static void test_sasv_write_7(void **state) -+{ -+ _test_sasv_write(state, 7); -+} -+ -+static void test_sasv_write_8(void **state) -+{ -+ _test_sasv_write(state, 8); -+} -+ -+static int test_sysfs(void) -+{ -+ const struct CMUnitTest tests[] = { -+ cmocka_unit_test(test_sagv_invalid), -+ cmocka_unit_test(test_sagv_bad_udev), -+ cmocka_unit_test(test_sagv_bad_snprintf), -+ cmocka_unit_test(test_sagv_open_fail), -+ cmocka_unit_test(test_sagv_read_fail), -+ cmocka_unit_test(test_sagv_read_overflow_1), -+ cmocka_unit_test(test_sagv_read_overflow_4), -+ cmocka_unit_test(test_sagv_read_overflow_8), -+ cmocka_unit_test(test_sagv_read_good_9), -+ cmocka_unit_test(test_sagv_read_good_15), -+ cmocka_unit_test(test_sagv_read_zeroes_4), -+ cmocka_unit_test(test_sasv_invalid), -+ cmocka_unit_test(test_sasv_bad_udev), -+ cmocka_unit_test(test_sasv_bad_snprintf), -+ cmocka_unit_test(test_sasv_open_fail), -+ cmocka_unit_test(test_sasv_write_fail), -+ cmocka_unit_test(test_sasv_write_0), -+ cmocka_unit_test(test_sasv_write_4), -+ cmocka_unit_test(test_sasv_write_7), -+ cmocka_unit_test(test_sasv_write_8), -+ }; -+ -+ return cmocka_run_group_tests(tests, setup, teardown); -+} -+ -+int main(void) -+{ -+ int ret = 0; -+ -+ init_test_verbosity(4); -+ ret += test_sysfs(); -+ return ret; -+} diff --git a/0021-multipath-tools-quiet-build-support-for-top-level-Ma.patch b/0021-multipath-tools-quiet-build-support-for-top-level-Ma.patch new file mode 100644 index 0000000..d45f99f --- /dev/null +++ b/0021-multipath-tools-quiet-build-support-for-top-level-Ma.patch @@ -0,0 +1,183 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 28 Oct 2022 14:39:22 +0200 +Subject: [PATCH] multipath-tools: quiet build support for top-level Makefile + +This requires including "Makefile.inc" in the top-level Makefile, +too. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + Makefile | 32 ++++++++++++++++++------------ + Makefile.inc | 8 ++++++-- + create-config.mk | 1 - + libmultipath/checkers/Makefile | 2 +- + libmultipath/foreign/Makefile | 2 +- + libmultipath/prioritizers/Makefile | 2 +- + 6 files changed, 28 insertions(+), 19 deletions(-) + +diff --git a/Makefile b/Makefile +index e3ce1a8d..b9e30234 100644 +--- a/Makefile ++++ b/Makefile +@@ -2,6 +2,9 @@ + # Copyright (C) 2003 Christophe Varoqui, + # + ++TOPDIR := . ++include Makefile.inc ++ + LIB_BUILDDIRS := \ + libmpathcmd \ + libmpathutil \ +@@ -32,10 +35,12 @@ all: $(BUILDDIRS) + + config.mk libmultipath/autoconfig.h: + @$(MAKE) -f create-config.mk ++ifeq ($(V),1) + @echo ==== config.mk ==== + @cat config.mk + @echo ==== autoconfig.h ==== + @cat libmultipath/autoconfig.h ++endif + + $(BUILDDIRS): config.mk + @$(MAKE) -C $@ +@@ -48,11 +53,12 @@ $(LIB_BUILDDIRS:=.abi): $(LIB_BUILDDIRS) + # Requires abidw from the abigail suite (https://sourceware.org/libabigail/) + .PHONY: abi + abi: $(LIB_BUILDDIRS:=.abi) ++ @echo creating abi + @mkdir -p $@ +- ln -ft $@ $(LIB_BUILDDIRS:=/*.abi) ++ $(Q)ln -ft $@ $(LIB_BUILDDIRS:=/*.abi) + + abi.tar.gz: abi +- tar cfz $@ abi ++ $(Q)tar cfz $@ abi + + # Check the ABI against a reference. + # This requires the ABI from a previous run to be present +@@ -77,8 +83,8 @@ abi-test: abi reference-abi $(wildcard abi/*.abi) + # Create compile_commands.json, useful for using clangd with an IDE + # Requires bear (https://github.com/rizsotto/Bear) + compile_commands.json: Makefile Makefile.inc $(BUILDDIRS:=/Makefile) +- $(MAKE) clean +- bear -- $(MAKE) ++ $(Q)$(MAKE) clean ++ $(Q)bear -- $(MAKE) + + libmpathutil libdmmp: libmpathcmd + libmultipath: libmpathutil +@@ -103,24 +109,24 @@ $(BUILDDIRS:=.uninstall): + # build it. Both is undesirable. Avoid it by creating config.mk temporarily. + clean: + @touch config.mk +- $(MAKE) $(BUILDDIRS:=.clean) tests.clean || true +- rm -rf abi abi.tar.gz abi-test compile_commands.json config.mk ++ $(Q)$(MAKE) $(BUILDDIRS:=.clean) tests.clean || true ++ $(Q)$(RM) -r abi abi.tar.gz abi-test compile_commands.json config.mk + + install: $(BUILDDIRS:=.install) + uninstall: $(BUILDDIRS:=.uninstall) + + test-progs: all +- $(MAKE) -C tests progs ++ @$(MAKE) -C tests progs + + test: all +- $(MAKE) -C tests all ++ @$(MAKE) -C tests all + + valgrind-test: all +- $(MAKE) -C tests valgrind ++ @$(MAKE) -C tests valgrind + + .PHONY: TAGS + TAGS: +- etags -a libmultipath/*.c +- etags -a libmultipath/*.h +- etags -a multipathd/*.c +- etags -a multipathd/*.h ++ @etags -a libmultipath/*.c ++ @etags -a libmultipath/*.h ++ @etags -a multipathd/*.c ++ @etags -a multipathd/*.h +diff --git a/Makefile.inc b/Makefile.inc +index 3e14cb8c..866ab274 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -27,7 +27,7 @@ PKGCONFIG ?= pkg-config + ifeq ($(TOPDIR),) + TOPDIR = .. + endif +-ifneq ($(CREATE_CONFIG),1) ++ifneq ($(TOPDIR),.) + include $(TOPDIR)/config.mk + endif + +@@ -60,7 +60,11 @@ devmapper_incdir := $(or $(shell $(PKGCONFIG) --variable=includedir devmapper),/ + libudev_incdir := $(or $(shell $(PKGCONFIG) --variable=includedir libudev),/usr/include) + kernel_incdir := /usr/include + +-Q := $(if $(V),,@) ++ifeq ($(V),) ++Q := @ ++# make's "Entering directory" messages are confusing in parallel mode ++#MAKEFLAGS = --no-print-directory ++endif + + GZIP_PROG := gzip -9 -c + RM := rm -f +diff --git a/create-config.mk b/create-config.mk +index 2cc5284f..434dee06 100644 +--- a/create-config.mk ++++ b/create-config.mk +@@ -2,7 +2,6 @@ + # SPDX-License-Identifier: GPL-2.0-or-later + + TOPDIR := . +-CREATE_CONFIG := 1 + include $(TOPDIR)/Makefile.inc + + # Check whether a function with name $1 has been declared in header file $2. +diff --git a/libmultipath/checkers/Makefile b/libmultipath/checkers/Makefile +index b3120611..6f7cfb95 100644 +--- a/libmultipath/checkers/Makefile ++++ b/libmultipath/checkers/Makefile +@@ -28,7 +28,7 @@ install: + $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(plugindir) + + uninstall: +- for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done ++ $(Q)for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done + + clean: dep_clean + $(Q)$(RM) core *.a *.o *.gz *.so +diff --git a/libmultipath/foreign/Makefile b/libmultipath/foreign/Makefile +index 0e245d6f..b83213d6 100644 +--- a/libmultipath/foreign/Makefile ++++ b/libmultipath/foreign/Makefile +@@ -20,7 +20,7 @@ install: + $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(plugindir) + + uninstall: +- for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done ++ $(Q)for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done + + clean: dep_clean + $(Q)$(RM) core *.a *.o *.gz *.so +diff --git a/libmultipath/prioritizers/Makefile b/libmultipath/prioritizers/Makefile +index e1688163..fdec36e7 100644 +--- a/libmultipath/prioritizers/Makefile ++++ b/libmultipath/prioritizers/Makefile +@@ -40,7 +40,7 @@ install: $(LIBS) + $(Q)$(INSTALL_PROGRAM) -m 755 libprio*.so $(DESTDIR)$(plugindir) + + uninstall: +- for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done ++ $(Q)for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done + + clean: dep_clean + $(Q)$(RM) core *.a *.o *.gz *.so diff --git a/0022-GitHub-workflows-use-make-j8-Orecurse.patch b/0022-GitHub-workflows-use-make-j8-Orecurse.patch new file mode 100644 index 0000000..33b7dcd --- /dev/null +++ b/0022-GitHub-workflows-use-make-j8-Orecurse.patch @@ -0,0 +1,132 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 28 Oct 2022 15:29:51 +0200 +Subject: [PATCH] GitHub workflows: use make -j8 -Orecurse + +Without -Orecurse, quiet make output is confusing in parallel mode +because make prints "Entering directory" and "Leaving directory" +messages before and after every target. + +Use parallel compilation also in native.yaml and foreign.yaml. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/abi.yaml | 2 +- + .github/workflows/build-and-unittest.yaml | 18 +++++++++--------- + .github/workflows/coverity.yaml | 2 +- + .github/workflows/foreign.yaml | 4 ++-- + .github/workflows/native.yaml | 6 +++--- + 5 files changed, 16 insertions(+), 16 deletions(-) + +diff --git a/.github/workflows/abi.yaml b/.github/workflows/abi.yaml +index 89b971cd..644fcb62 100644 +--- a/.github/workflows/abi.yaml ++++ b/.github/workflows/abi.yaml +@@ -32,7 +32,7 @@ jobs: + libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev + libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev + - name: create ABI +- run: make -O -j$(grep -c ^processor /proc/cpuinfo) abi.tar.gz ++ run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) abi.tar.gz + - name: save ABI + uses: actions/upload-artifact@v1 + with: +diff --git a/.github/workflows/build-and-unittest.yaml b/.github/workflows/build-and-unittest.yaml +index a5a0717d..8b6bb776 100644 +--- a/.github/workflows/build-and-unittest.yaml ++++ b/.github/workflows/build-and-unittest.yaml +@@ -32,11 +32,11 @@ jobs: + libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev + libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev + - name: build +- run: make -O -j$(grep -c ^processor /proc/cpuinfo) READLINE=${{ matrix.rl }} ++ run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) READLINE=${{ matrix.rl }} + - name: test +- run: make -O -j$(grep -c ^processor /proc/cpuinfo) test ++ run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) test + - name: valgrind-test +- run: make -O -j$(grep -c ^processor /proc/cpuinfo) valgrind-test ++ run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) valgrind-test + - name: valgrind-results + run: cat tests/*.vgr + - name: clean-nonroot-artifacts +@@ -65,11 +65,11 @@ jobs: + - name: set CC + run: echo CC=gcc-10 >> $GITHUB_ENV + - name: build +- run: make -O -j$(grep -c ^processor /proc/cpuinfo) READLINE=${{ matrix.rl }} ++ run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) READLINE=${{ matrix.rl }} + - name: test +- run: make -O -j$(grep -c ^processor /proc/cpuinfo) test ++ run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) test + - name: valgrind-test +- run: make -O -j$(grep -c ^processor /proc/cpuinfo) valgrind-test ++ run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) valgrind-test + - name: valgrind-results + run: cat tests/*.vgr + - name: clean-nonroot-artifacts +@@ -98,11 +98,11 @@ jobs: + - name: set CC + run: echo CC=clang >> $GITHUB_ENV + - name: build +- run: make -O -j$(grep -c ^processor /proc/cpuinfo) READLINE=${{ matrix.rl }} ++ run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) READLINE=${{ matrix.rl }} + - name: test +- run: make -O -j$(grep -c ^processor /proc/cpuinfo) test ++ run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) test + - name: valgrind-test +- run: make -O -j$(grep -c ^processor /proc/cpuinfo) valgrind-test ++ run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) valgrind-test + - name: valgrind-results + run: cat tests/*.vgr + - name: clean-nonroot-artifacts +diff --git a/.github/workflows/coverity.yaml b/.github/workflows/coverity.yaml +index 3c6b3824..321b94e0 100644 +--- a/.github/workflows/coverity.yaml ++++ b/.github/workflows/coverity.yaml +@@ -32,7 +32,7 @@ jobs: + - name: build with cov-build + run: > + PATH="$PWD/coverity/bin:$PATH" +- cov-build --dir cov-int make -O -j"$(grep -c ^processor /proc/cpuinfo)" ++ cov-build --dir cov-int make -Orecurse -j"$(grep -c ^processor /proc/cpuinfo)" + - name: pack results + run: tar cfz multipath-tools.tgz cov-int + - name: submit results +diff --git a/.github/workflows/foreign.yaml b/.github/workflows/foreign.yaml +index 5a19913a..72ac24fb 100644 +--- a/.github/workflows/foreign.yaml ++++ b/.github/workflows/foreign.yaml +@@ -21,11 +21,11 @@ jobs: + uses: actions/checkout@v1 + - name: build and test + if: ${{ matrix.arch == '' || matrix.arch == '-i386' }} +- run: make test ++ run: make -j8 -Orecurse test + - name: build + if: ${{ matrix.arch != '' && matrix.arch != '-i386' }} + # The build path is different between builder and runner +- run: make TESTDIR=${{ github.workspace }}/tests test-progs ++ run: make -j8 -Orecurse TESTDIR=${{ github.workspace }}/tests test-progs + - name: archive + if: ${{ matrix.arch != '' && matrix.arch != '-i386' }} + run: > +diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml +index 8b599209..68bf0984 100644 +--- a/.github/workflows/native.yaml ++++ b/.github/workflows/native.yaml +@@ -92,10 +92,10 @@ jobs: + - name: checkout + uses: actions/checkout@v1 + - name: build and test +- run: make test ++ run: make -j8 -Orecurse test + - name: clean +- run: make clean ++ run: make -j8 -Orecurse clean + - name: clang + env: + CC: clang +- run: make test ++ run: make -j8 -Orecurse test diff --git a/0022-libmultipath.version-bump-version-for-sysfs-accessor.patch b/0022-libmultipath.version-bump-version-for-sysfs-accessor.patch deleted file mode 100644 index fdbb113..0000000 --- a/0022-libmultipath.version-bump-version-for-sysfs-accessor.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 6 Jul 2022 12:45:33 +0200 -Subject: [PATCH] libmultipath.version: bump version for sysfs accessors - -Formally, the ABI is still the same, but the semantics of the -return value have changed. - -Signed-off-by: Martin Wilck - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/libmultipath.version | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version -index b3690ac0..c1d9b156 100644 ---- a/libmultipath/libmultipath.version -+++ b/libmultipath/libmultipath.version -@@ -207,7 +207,6 @@ global: - strchop; - strlcpy; - sync_map_state; -- sysfs_attr_set_value; - sysfs_get_size; - sysfs_is_multipathed; - timespeccmp; -@@ -264,8 +263,13 @@ global: - - /* foreign */ - free_scandir_result; -- sysfs_attr_get_value; - - local: - *; - }; -+ -+LIBMULTIPATH_16.0.0 { -+global: -+ sysfs_attr_set_value; -+ sysfs_attr_get_value; -+}; diff --git a/0023-README.md-Move-section-about-libedit-and-libreadline.patch b/0023-README.md-Move-section-about-libedit-and-libreadline.patch new file mode 100644 index 0000000..b860971 --- /dev/null +++ b/0023-README.md-Move-section-about-libedit-and-libreadline.patch @@ -0,0 +1,48 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 28 Oct 2022 15:40:16 +0200 +Subject: [PATCH] README.md: Move section about libedit and libreadline + +This paragraph belongs in the "Customiting build" section. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + README.md | 17 +++++++++-------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +diff --git a/README.md b/README.md +index d003e1db..52ab776b 100644 +--- a/README.md ++++ b/README.md +@@ -53,14 +53,9 @@ Building multipath-tools + ======================== + + Prerequisites: development packages of for `libdevmapper`, `libaio`, `libudev`, +-`libjson-c`, `liburcu`, and `libsystemd`. +- +-To enable commandline history and TAB completion in the interactive mode *(which +-is entered with `multipathd -k` or `multipathc`)* you might also set `READLINE` +-make variable to `libedit` or `libreadline`, like `make READLINE=libreadline`. +-That requires a development package for the library you chose. Note that using +-libreadline may [make binary indistributable due to license +-incompatibility](https://github.com/opensvc/multipath-tools/issues/36). ++`libjson-c`, `liburcu`, and `libsystemd`. If commandline editing is enabled ++(see below), the development package for either `libedit` or `libreadline` is ++required as well. + + Then, build and install multipath-tools with: + +@@ -82,6 +77,12 @@ The following variables can be passed to the `make` command line: + * `configdir="/some/path"` : directory to search for configuration files. + This used to be the run-time option `config_dir` in earlier versions. + The default is `/etc/multipath/conf.d`. ++ * `READLINE=libedit` or `READLINE=libreadline`: enable command line history ++ and TAB completion in the interactive mode *(which is entered with `multipathd -k` or `multipathc`)*. ++ The respective development package will be required for building. ++ By default, command line editing is disabled. ++ Note that using libreadline may ++ [make binary indistributable due to license incompatibility](https://github.com/opensvc/multipath-tools/issues/36). + * `ENABLE_LIBDMMP=0`: disable building libdmmp + * `ENABLE_DMEVENTS_POLL=0`: disable support for the device-mapper event + polling API. For use with pre-5.0 kernels that don't support dmevent polling diff --git a/0023-libmultipath-unset-detect_checker-for-clariion-Unity.patch b/0023-libmultipath-unset-detect_checker-for-clariion-Unity.patch deleted file mode 100644 index b69f395..0000000 --- a/0023-libmultipath-unset-detect_checker-for-clariion-Unity.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 7 Jun 2022 17:45:01 -0500 -Subject: [PATCH] libmultipath: unset detect_checker for clariion / Unity - arrays - -Dell EMC would like to always use the emc_clariion checker. Currently -detect_checker will switch the checker to TUR for Unity arrays. -This can cause problems on some setups with replicated Unity LUNs, -which are handled correctly the the emc_checker, but not the TUR -checker. - -Cc: vincent.chen1@dell.com -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/hwtable.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index c88fa09a..2085aba5 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -350,6 +350,7 @@ static struct hwentry default_hw[] = { - .no_path_retry = (300 / DEFAULT_CHECKINT), - .checker_name = EMC_CLARIION, - .prio_name = PRIO_EMC, -+ .detect_checker = DETECT_CHECKER_OFF, - }, - { - /* Invista / VPLEX */ diff --git a/0024-README.md-Fix-indentation-in-paragraph-about-device-.patch b/0024-README.md-Fix-indentation-in-paragraph-about-device-.patch new file mode 100644 index 0000000..63b6c2f --- /dev/null +++ b/0024-README.md-Fix-indentation-in-paragraph-about-device-.patch @@ -0,0 +1,34 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 28 Oct 2022 15:42:15 +0200 +Subject: [PATCH] README.md: Fix indentation in paragraph about device handlers + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + README.md | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/README.md b/README.md +index 52ab776b..b1b78fbb 100644 +--- a/README.md ++++ b/README.md +@@ -94,12 +94,12 @@ The following variables can be passed to the `make` command line: + early. This option causes a *modules-load.d(5)* configuration file to be + created, thus it depends on functionality provided by *systemd*. + This variable only matters for `make install`. +- +-Note: The usefulness of the preload list depends on the kernel configuration. +-It's especially useful if `scsi_mod` is builtin but `scsi_dh_alua` and +-other device handler modules are built as modules. If `scsi_mod` itself is compiled +-as a module, it might make more sense to use a module softdep for the same +-purpose. ++ ++ **Note**: The usefulness of the preload list depends on the kernel configuration. ++ It's especially useful if `scsi_mod` is builtin but `scsi_dh_alua` and ++ other device handler modules are built as modules. If `scsi_mod` itself is compiled ++ as a module, it might make more sense to use a module softdep for the same ++ purpose. + + See `Makefile.inc` for additional variables to customize paths and compiler + flags. diff --git a/0024-libmultipath-spelling-cplusplus.patch b/0024-libmultipath-spelling-cplusplus.patch deleted file mode 100644 index bf21a11..0000000 --- a/0024-libmultipath-spelling-cplusplus.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Josh Soref <2119212+jsoref@users.noreply.github.com> -Date: Sun, 31 Jul 2022 13:11:15 -0400 -Subject: [PATCH] libmultipath: spelling: cplusplus - -Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> -Reviewed-by: Xose Vazquez Perez -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmpathvalid/mpath_valid.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmpathvalid/mpath_valid.h b/libmpathvalid/mpath_valid.h -index ed06196e..ec2f9392 100644 ---- a/libmpathvalid/mpath_valid.h -+++ b/libmpathvalid/mpath_valid.h -@@ -20,7 +20,7 @@ - #ifndef LIB_MPATH_VALID_H - #define LIB_MPATH_VALID_H - --#ifdef __cpluscplus -+#ifdef __cplusplus - extern "C" { - #endif - diff --git a/0025-README.md-document-options-for-paths-and-optimizatio.patch b/0025-README.md-document-options-for-paths-and-optimizatio.patch new file mode 100644 index 0000000..ca00d85 --- /dev/null +++ b/0025-README.md-document-options-for-paths-and-optimizatio.patch @@ -0,0 +1,47 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 28 Oct 2022 16:01:17 +0200 +Subject: [PATCH] README.md: document options for paths and optimization + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + README.md | 25 +++++++++++++++++++++++-- + 1 file changed, 23 insertions(+), 2 deletions(-) + +diff --git a/README.md b/README.md +index b1b78fbb..ab7dc3c9 100644 +--- a/README.md ++++ b/README.md +@@ -101,8 +101,29 @@ The following variables can be passed to the `make` command line: + as a module, it might make more sense to use a module softdep for the same + purpose. + +-See `Makefile.inc` for additional variables to customize paths and compiler +-flags. ++### Installation Paths ++ ++ * `prefix`: The directory prefix for (almost) all files to be installed. ++ Distributions may want to set this to `/usr`. ++ **Note**: for multipath-tools, unlike many other packages, `prefix` ++ defaults to the empty string, which resolves to the root directory (`/`). ++ * `usr_prefix`: where to install those parts of the code that aren't necessary ++ for booting. You may want to set this to `/usr` if `prefix` is empty. ++ * `systemd_prefix`: Prefix for systemd-related files. It defaults to `/usr`. ++ Some systemd installations use separate `prefix` and `rootprefix`. On such ++ a distribution, set `prefix`, and override `unitdir` to use systemd's ++ `rootprefix`. ++ * `LIB`: the subdirectory under `prefix` where shared libraries will be ++ installed. By default, the makefile uses `/lib64` if this directory is ++ found on the build system, and `/lib` otherwise. ++ ++See also `configdir` and `plugindir` above. See `Makefile.inc` for more ++fine-grained control. ++ ++### Compiler Options ++ ++Use `OPTFLAGS` to change optimization-related compiler options; ++e.g. `OPTFLAGS="-g -O0"` to disable all optimizations. + + Special Makefile targets + ------------------------ diff --git a/0025-libmultipath-spelling-ascii.patch b/0025-libmultipath-spelling-ascii.patch deleted file mode 100644 index 01e22e4..0000000 --- a/0025-libmultipath-spelling-ascii.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Josh Soref <2119212+jsoref@users.noreply.github.com> -Date: Sun, 31 Jul 2022 13:11:12 -0400 -Subject: [PATCH] libmultipath: spelling: ascii - -Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/prioritizers/alua_spc3.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/prioritizers/alua_spc3.h b/libmultipath/prioritizers/alua_spc3.h -index 08e992bd..e1a6c071 100644 ---- a/libmultipath/prioritizers/alua_spc3.h -+++ b/libmultipath/prioritizers/alua_spc3.h -@@ -143,7 +143,7 @@ inquiry_data_get_tpgs(struct inquiry_data *id) - *----------------------------------------------------------------------------- - */ - #define CODESET_BINARY 0x1 --#define CODESET_ACSII 0x2 -+#define CODESET_ASCII 0x2 - #define CODESET_UTF8 0x3 - - #define ASSOCIATION_UNIT 0x0 diff --git a/0026-README.md-document-how-to-customize-build.patch b/0026-README.md-document-how-to-customize-build.patch new file mode 100644 index 0000000..c3dfedb --- /dev/null +++ b/0026-README.md-document-how-to-customize-build.patch @@ -0,0 +1,37 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 28 Oct 2022 16:01:41 +0200 +Subject: [PATCH] README.md: document how to customize build + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + README.md | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/README.md b/README.md +index ab7dc3c9..bbeb44fe 100644 +--- a/README.md ++++ b/README.md +@@ -66,9 +66,21 @@ To uninstall, type: + + make uninstall + ++By default, the build will run quietly, just printing one-line messages ++about the files being built. To enable more verbose output, run `make V=1`. ++ + Customizing the build + --------------------- + ++**Note**: With very few exceptions, the build process does not read ++configuration from the environment. So using syntax like ++ ++ SOME_VAR=some_value make ++ ++will **not** have the intended effect. Use the following instead: ++ ++ make SOME_VAR=some_value ++ + The following variables can be passed to the `make` command line: + + * `plugindir="/some/path"`: directory where libmultipath plugins (path diff --git a/0026-libmultipath-spelling-progress.patch b/0026-libmultipath-spelling-progress.patch deleted file mode 100644 index 2984f31..0000000 --- a/0026-libmultipath-spelling-progress.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Josh Soref <2119212+jsoref@users.noreply.github.com> -Date: Sun, 31 Jul 2022 13:11:22 -0400 -Subject: [PATCH] libmultipath: spelling: progress - -Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/nvme/linux/nvme.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/nvme/linux/nvme.h b/libmultipath/nvme/linux/nvme.h -index a6975549..9fc2ae7f 100644 ---- a/libmultipath/nvme/linux/nvme.h -+++ b/libmultipath/nvme/linux/nvme.h -@@ -1035,7 +1035,7 @@ enum { - NVME_SANITIZE_LOG_STATUS_MASK = 0x0007, - NVME_SANITIZE_LOG_NEVER_SANITIZED = 0x0000, - NVME_SANITIZE_LOG_COMPLETED_SUCCESS = 0x0001, -- NVME_SANITIZE_LOG_IN_PROGESS = 0x0002, -+ NVME_SANITIZE_LOG_IN_PROGRESS = 0x0002, - NVME_SANITIZE_LOG_COMPLETED_FAILED = 0x0003, - NVME_SANITIZE_LOG_ND_COMPLETED_SUCCESS = 0x0004, - }; diff --git a/0027-libmultipath-avoid-Warray-bounds-error-with-gcc-12-a.patch b/0027-libmultipath-avoid-Warray-bounds-error-with-gcc-12-a.patch new file mode 100644 index 0000000..1ae51d8 --- /dev/null +++ b/0027-libmultipath-avoid-Warray-bounds-error-with-gcc-12-a.patch @@ -0,0 +1,63 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 28 Oct 2022 21:10:41 +0200 +Subject: [PATCH] libmultipath: avoid -Warray-bounds error with gcc 12 and musl + libc +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The following error is observed with gcc 12, strangely only with +MUSL libc: + +In function ‘__uatomic_inc’, + inlined from ‘lock’ at ../libmultipath/lock.h:24:2, + inlined from ‘child’ at main.c:3523:3, + inlined from ‘main’ at main.c:3755:11: +/usr/include/urcu/uatomic/x86.h:439:17: error: array subscript ‘struct __uatomic_dummy[0]’ is partly outside array bounds of ‘unsigned char[72]’ [-Werror=array-bounds] + +The problem is that &(vecs->lock.waiters) is casted to a pointer to +struct { long[10]; } which goes beyond the "struct vectors". +We don't read or write from/to that memory, but the compiler complains either +way. + +latest liburcu has a patch for it: + +http://git.liburcu.org/?p=userspace-rcu.git;a=commitdiff;h=835b9ab3ca3777fe42e37e92096226ebd19ca75b + +For now, just disable the warning in lock.h, using a pragma. + +Signed-off-by: Martin Wilck +Reported-by: Xose Vasquez Perez +Signed-off-by: Benjamin Marzinski +--- + libmultipath/lock.h | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/libmultipath/lock.h b/libmultipath/lock.h +index 20ca77e6..9814be76 100644 +--- a/libmultipath/lock.h ++++ b/libmultipath/lock.h +@@ -13,6 +13,11 @@ struct mutex_lock { + int waiters; /* uatomic access only */ + }; + ++#if !defined(__GLIBC__) && defined(__GNUC__) && __GNUC__ == 12 ++#pragma GCC diagnostic push ++#pragma GCC diagnostic ignored "-Warray-bounds" ++#endif ++ + static inline void init_lock(struct mutex_lock *a) + { + pthread_mutex_init(&a->mutex, NULL); +@@ -46,6 +51,10 @@ static inline bool lock_has_waiters(struct mutex_lock *a) + return (uatomic_read(&a->waiters) > 0); + } + ++#if !defined(__GLIBC__) && defined(__GNUC__) && __GNUC__ == 12 ++#pragma GCC diagnostic pop ++#endif ++ + #define lock_cleanup_pop(a) pthread_cleanup_pop(1) + + void cleanup_lock (void * data); diff --git a/0027-multipath-tools-spelling-fixes.patch b/0027-multipath-tools-spelling-fixes.patch deleted file mode 100644 index c1e9468..0000000 --- a/0027-multipath-tools-spelling-fixes.patch +++ /dev/null @@ -1,599 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Josh Soref <2119212+jsoref@users.noreply.github.com> -Date: Sun, 31 Jul 2022 13:17:53 -0400 -Subject: [PATCH] multipath-tools: spelling fixes - -Spelling errors detected by the GitHub check-spelling action: -https://github.com/marketplace/actions/check-spelling - -Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/foreign.yaml | 2 +- - kpartx/crc32.c | 2 +- - kpartx/gpt.c | 2 +- - libdmmp/libdmmp_path.c | 2 +- - libmpathcmd/mpath_cmd.h | 2 +- - libmpathpersist/mpath_persist_int.c | 2 +- - libmpathvalid/mpath_valid.h | 4 ++-- - libmultipath/checkers/directio.c | 2 +- - libmultipath/config.h | 2 +- - libmultipath/configure.c | 2 +- - libmultipath/discovery.c | 2 +- - libmultipath/nvme/nvme.h | 2 +- - libmultipath/prioritizers/datacore.c | 4 ++-- - libmultipath/prioritizers/hds.c | 2 +- - libmultipath/prioritizers/path_latency.c | 4 ++-- - libmultipath/strbuf.h | 4 ++-- - libmultipath/structs_vec.c | 2 +- - libmultipath/uevent.c | 2 +- - libmultipath/valid.h | 2 +- - mpathpersist/main.c | 2 +- - multipath/multipath.conf.5 | 14 +++++++------- - multipathd/main.c | 10 +++++----- - tests/directio.c | 2 +- - tests/hwtable.c | 10 +++++----- - tests/mpathvalid.c | 2 +- - tests/pgpolicy.c | 2 +- - tests/valid.c | 4 ++-- - third-party/valgrind/valgrind.h | 8 ++++---- - 28 files changed, 50 insertions(+), 50 deletions(-) - -diff --git a/.github/workflows/foreign.yaml b/.github/workflows/foreign.yaml -index e9ffd3d8..32915186 100644 ---- a/.github/workflows/foreign.yaml -+++ b/.github/workflows/foreign.yaml -@@ -56,7 +56,7 @@ jobs: - - name: enable foreign arch - run: sudo docker run --rm --privileged multiarch/qemu-user-static:register --reset - - name: run tests -- # Github actions doesn't support referencing docker images with -+ # GitHub actions doesn't support referencing docker images with - # context variables. Workaround: use mosteo-actions/docker-run action - # See https://github.community/t/expressions-in-docker-uri/16271 - uses: mosteo-actions/docker-run@v1 -diff --git a/kpartx/crc32.c b/kpartx/crc32.c -index e688f8e9..df6c6878 100644 ---- a/kpartx/crc32.c -+++ b/kpartx/crc32.c -@@ -290,7 +290,7 @@ uint32_t attribute((pure)) crc32_be(uint32_t crc, unsigned char const *p, size_t - * the end, so we have to add 32 extra cycles shifting in zeros at the - * end of every message, - * -- * So the standard trick is to rearrage merging in the next_input_bit() -+ * So the standard trick is to rearrange merging in the next_input_bit() - * until the moment it's needed. Then the first 32 cycles can be precomputed, - * and merging in the final 32 zero bits to make room for the CRC can be - * skipped entirely. -diff --git a/kpartx/gpt.c b/kpartx/gpt.c -index 34a910cf..47d8743e 100644 ---- a/kpartx/gpt.c -+++ b/kpartx/gpt.c -@@ -357,7 +357,7 @@ is_gpt_valid(int fd, uint64_t lba, - __le32_to_cpu((*gpt)->num_partition_entries) * - __le32_to_cpu((*gpt)->sizeof_partition_entry)); - if (crc != __le32_to_cpu((*gpt)->partition_entry_array_crc32)) { -- // printf("GUID Partitition Entry Array CRC check failed.\n"); -+ // printf("GUID Partition Entry Array CRC check failed.\n"); - free(*gpt); - *gpt = NULL; - free(*ptes); -diff --git a/libdmmp/libdmmp_path.c b/libdmmp/libdmmp_path.c -index 47a2162c..21714b15 100644 ---- a/libdmmp/libdmmp_path.c -+++ b/libdmmp/libdmmp_path.c -@@ -28,7 +28,7 @@ - #include "libdmmp_private.h" - - #define _DMMP_SHOW_PS_INDEX_BLK_NAME 0 --#define _DMMP_SHOW_PS_INDEX_SATAUS 1 -+#define _DMMP_SHOW_PS_INDEX_STATUS 1 - #define _DMMP_SHOW_PS_INDEX_WWID 2 - #define _DMMP_SHOW_PS_INDEX_PGID 3 - -diff --git a/libmpathcmd/mpath_cmd.h b/libmpathcmd/mpath_cmd.h -index 30838b02..0c293c71 100644 ---- a/libmpathcmd/mpath_cmd.h -+++ b/libmpathcmd/mpath_cmd.h -@@ -65,7 +65,7 @@ int mpath_connect(void); - /* - * DESCRIPTION: - * Disconnect from the multipathd daemon. This function must be -- * run after after processing all the multipath commands. -+ * run after processing all the multipath commands. - * - * RETURNS: - * 0 on success. -1 on failure (with errno set). -diff --git a/libmpathpersist/mpath_persist_int.c b/libmpathpersist/mpath_persist_int.c -index e34fc32d..6924b379 100644 ---- a/libmpathpersist/mpath_persist_int.c -+++ b/libmpathpersist/mpath_persist_int.c -@@ -601,7 +601,7 @@ static int mpath_prout_rel(struct multipath *mpp,int rq_servact, int rq_scope, - if (get_be64(mpp->reservation_key) && - memcmp(pr_buff->prin_descriptor.prin_readfd.descriptors[i]->key, - &mpp->reservation_key, 8)){ -- /*register with tarnsport id*/ -+ /*register with transport id*/ - memset(pamp, 0, length); - pamp->trnptid_list[0] = pptr; - memset (pamp->trnptid_list[0], 0, sizeof (struct transportid)); -diff --git a/libmpathvalid/mpath_valid.h b/libmpathvalid/mpath_valid.h -index ec2f9392..3e34b1fd 100644 ---- a/libmpathvalid/mpath_valid.h -+++ b/libmpathvalid/mpath_valid.h -@@ -112,7 +112,7 @@ int mpathvalid_exit(void); - * RETURNS: - * MPATH_STRICT, MPATH_SMART, MPATH_GREEDY, or MPATH_MODE_ERROR - * -- * MPATH_STRICT = find_multiapths (yes|on|no|off) -+ * MPATH_STRICT = find_multipaths (yes|on|no|off) - * MPATH_SMART = find_multipaths smart - * MPATH_GREEDY = find_multipaths greedy - * MPATH_MODE_ERROR = multipath configuration not initialized -@@ -126,7 +126,7 @@ unsigned int mpathvalid_get_mode(void); - * potentially claimed (MPATH_IS_VALID, MPATH_IS_VALID_NO_CHECK, - * or MPATH_IS_MAYBE_VALID) and wwid is not NULL, then *wiid will - * be set to point to the wwid of device. If set, *wwid must be -- * freed by the caller. path_wwids is an obptional parameter that -+ * freed by the caller. path_wwids is an optional parameter that - * points to an array of wwids, that were returned from previous - * calls to mpathvalid_is_path(). These are wwids of existing - * devices that are or potentially are claimed by device-mapper -diff --git a/libmultipath/checkers/directio.c b/libmultipath/checkers/directio.c -index bc7b7be5..a326e37b 100644 ---- a/libmultipath/checkers/directio.c -+++ b/libmultipath/checkers/directio.c -@@ -124,7 +124,7 @@ remove_aio_group(struct aio_group *aio_grp) - - /* If an aio_group is completely full of orphans, then no checkers can - * use it, which means that no checkers can clear out the orphans. To -- * avoid keeping the useless group around, simply remove remove the -+ * avoid keeping the useless group around, simply remove the - * group */ - static void - check_orphaned_group(struct aio_group *aio_grp) -diff --git a/libmultipath/config.h b/libmultipath/config.h -index 36d40157..fdcdff0a 100644 ---- a/libmultipath/config.h -+++ b/libmultipath/config.h -@@ -248,7 +248,7 @@ struct config { - * libmultipath calls. If an application wants to keep using the - * udev variable after calling libmultipath_exit(), it should have taken - * an additional reference on it beforehand. This is the case e.g. -- * after initiazing udev with udev_new(). -+ * after initializing udev with udev_new(). - */ - extern struct udev *udev; - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 4427f910..8af7cd79 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -397,7 +397,7 @@ int setup_map(struct multipath *mpp, char **params, struct vectors *vecs) - * into a mp->params strings to feed the device-mapper - */ - if (assemble_map(mpp, params)) { -- condlog(0, "%s: problem assembing map", mpp->alias); -+ condlog(0, "%s: problem assembling map", mpp->alias); - return 1; - } - return 0; -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index ee290093..15560f8c 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -1344,7 +1344,7 @@ parse_vpd_c0_hp3par(const unsigned char *in, size_t in_len, - condlog(3, "HP/3PAR vendor specific VPD page length too short: %zu", in_len); - return -EINVAL; - } -- if (in[4] <= 3) /* revision must be > 3 to have Vomlume Name */ -+ if (in[4] <= 3) /* revision must be > 3 to have Volume Name */ - return -ENODATA; - len = get_unaligned_be32(&in[40]); - if (len > out_len || len + 44 > in_len) { -diff --git a/libmultipath/nvme/nvme.h b/libmultipath/nvme/nvme.h -index 7e0278b5..57f82a31 100644 ---- a/libmultipath/nvme/nvme.h -+++ b/libmultipath/nvme/nvme.h -@@ -224,7 +224,7 @@ char *nvme_char_from_block(char *block); - * Notes: This function does not care about transport so that the offset is - * not going to be checked inside of this function for the unsupported fields - * in a specific transport. For example, BPMBL(Boot Partition Memory Buffer -- * Location) register is not supported by fabrics, but it can be chcked here. -+ * Location) register is not supported by fabrics, but it can be checked here. - */ - static inline bool is_64bit_reg(__u32 offset) - { -diff --git a/libmultipath/prioritizers/datacore.c b/libmultipath/prioritizers/datacore.c -index 02dc2e27..d1d473d4 100644 ---- a/libmultipath/prioritizers/datacore.c -+++ b/libmultipath/prioritizers/datacore.c -@@ -1,6 +1,6 @@ - /* - * (C) 2010 Christophe Varoqui -- * (C) 2009 Dembach Goo Infromatik GmbH & Co KG -+ * (C) 2009 Dembach Goo Informatik GmbH & Co KG - * Manon Goo - * - * datacore.c -@@ -10,7 +10,7 @@ - * Matthias Rudolph - * - * This work is made available on the basis of the -- * GPLv2 for detials see . -+ * GPLv2 for details see . - * - * Manon Goo 2009 - * -diff --git a/libmultipath/prioritizers/hds.c b/libmultipath/prioritizers/hds.c -index 88cac5f0..d569f2d7 100644 ---- a/libmultipath/prioritizers/hds.c -+++ b/libmultipath/prioritizers/hds.c -@@ -32,7 +32,7 @@ - * Half of the LUNs are accessed via one HBA/storage controller and the other - * half via the other HBA/storage controller. - * -- * In cluster environmemnts (RAC) it also guarantees that all cluster nodes have -+ * In cluster environments (RAC) it also guarantees that all cluster nodes have - * access to the LDEVs via the same controller. - * - * You can run the prioritizer manually in verbose mode: -diff --git a/libmultipath/prioritizers/path_latency.c b/libmultipath/prioritizers/path_latency.c -index e155f6dc..2f5be9b9 100644 ---- a/libmultipath/prioritizers/path_latency.c -+++ b/libmultipath/prioritizers/path_latency.c -@@ -64,7 +64,7 @@ static int prepare_directio_read(int fd, int *blksz, char **pbuf, - long flags; - - if (ioctl(fd, BLKBSZGET, blksz) < 0) { -- pp_pl_log(3,"catnnot get blocksize, set default"); -+ pp_pl_log(3,"cannot get blocksize, set default"); - *blksz = DEF_BLK_SIZE; - } - if (posix_memalign((void **)pbuf, pgsize, *blksz)) -@@ -193,7 +193,7 @@ out: - } - - /* -- * Do not scale the prioriy in a certain range such as [0, 1024] -+ * Do not scale the priority in a certain range such as [0, 1024] - * because scaling will eliminate the effect of base_num. - */ - int calcPrio(double lg_avglatency, double lg_maxavglatency, -diff --git a/libmultipath/strbuf.h b/libmultipath/strbuf.h -index 41d7d54f..31ab519a 100644 ---- a/libmultipath/strbuf.h -+++ b/libmultipath/strbuf.h -@@ -159,7 +159,7 @@ int fill_strbuf(struct strbuf *buf, char c, int slen); - * - * Appends the given string to @strbuf, with leading and trailing double - * quotes (") added, expanding @strbuf's size as necessary. Any double quote -- * characters (") in the string are transformed to double double quotes (""). -+ * characters (") in the string are transformed to a pair of double quotes (""). - * If the function returns an error, @strbuf is unchanged. - */ - int append_strbuf_quoted(struct strbuf *buf, const char *str); -@@ -171,7 +171,7 @@ int append_strbuf_quoted(struct strbuf *buf, const char *str); - * @returns: number of appended characters if successful, (excluding - * terminating '\0'); negative error code otherwise - * -- * Appends the the arguments following @fmt, formatted as in printf(), to -+ * Appends the arguments following @fmt, formatted as in printf(), to - * @strbuf, expanding @strbuf's size as necessary. The function makes sure that - * the output @strbuf is always 0-terminated. - * If the function returns an error, @strbuf is unchanged. -diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c -index a69f0643..645896c6 100644 ---- a/libmultipath/structs_vec.c -+++ b/libmultipath/structs_vec.c -@@ -205,7 +205,7 @@ static bool update_pathvec_from_dm(vector pathvec, struct multipath *mpp, - continue; - - /* -- * At this point, pp->udev is valid and and pp->wwid -+ * At this point, pp->udev is valid and pp->wwid - * is the best we could get - */ - if (*pp->wwid && strcmp(mpp->wwid, pp->wwid)) { -diff --git a/libmultipath/uevent.c b/libmultipath/uevent.c -index 5793af94..57447ca0 100644 ---- a/libmultipath/uevent.c -+++ b/libmultipath/uevent.c -@@ -373,7 +373,7 @@ uevent_filter(struct uevent *later, struct uevent_filter_state *st) - - list_for_some_entry_reverse_safe(earlier, tmp, &later->node, &st->uevq, node) { - /* -- * filter unnessary earlier uevents -+ * filter unnecessary earlier uevents - * by the later uevent - */ - if (!list_empty(&earlier->merge_node)) { -diff --git a/libmultipath/valid.h b/libmultipath/valid.h -index ce1c7cbf..731e6eff 100644 ---- a/libmultipath/valid.h -+++ b/libmultipath/valid.h -@@ -23,7 +23,7 @@ - * already. - * PATH_IS_VALID is returned by is_path_valid, when the path is - * valid only if it hasn't been released to systemd already. -- * PATH_IS_MAYBE_VALID is returned when the the path would be valid -+ * PATH_IS_MAYBE_VALID is returned when the path would be valid - * if other paths with the same wwid existed. It is up to the caller - * to check for these other paths. - */ -diff --git a/mpathpersist/main.c b/mpathpersist/main.c -index 4bdd55c2..894e8c94 100644 ---- a/mpathpersist/main.c -+++ b/mpathpersist/main.c -@@ -480,7 +480,7 @@ static int handle_args(int argc, char * argv[], int nline) - } - if ((verbose > 2) && num_transportids) - { -- fprintf (stderr, "number of tranport-ids decoded from " -+ fprintf (stderr, "number of transport-ids decoded from " - "command line : %d\n", num_transportids); - } - -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index c2d34f18..853e0feb 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -455,7 +455,7 @@ precedence. See KNOWN ISSUES. - (Since kernel 2.6.38) Number of msecs before pg_init retry, it must be between 0 and 60000. - .TP - .I queue_mode --(Since kernel 4.8) Select the the queueing mode per multipath device. -+(Since kernel 4.8) Select the queueing mode per multipath device. - can be \fIbio\fR, \fIrq\fR or \fImq\fR, which corresponds to - bio-based, request-based, and block-multiqueue (blk-mq) request-based, - respectively. -@@ -935,7 +935,7 @@ This option is not supported any more. The value is ignored. - .B san_path_err_threshold - If set to a value greater than 0, multipathd will watch paths and check how many - times a path has been failed due to errors.If the number of failures on a particular --path is greater then the san_path_err_threshold, then the path will not reinstate -+path is greater than the san_path_err_threshold, then the path will not reinstate - till san_path_err_recovery_time. These path failures should occur within a - san_path_err_forget_rate checks, if not we will consider the path is good enough - to reinstantate. See "Shaky paths detection" below. -@@ -949,7 +949,7 @@ The default is: \fBno\fR - .B san_path_err_forget_rate - If set to a value greater than 0, multipathd will check whether the path failures - has exceeded the san_path_err_threshold within this many checks i.e --san_path_err_forget_rate . If so we will not reinstante the path till -+san_path_err_forget_rate . If so we will not reinstate the path till - san_path_err_recovery_time. See "Shaky paths detection" below. - .RS - .TP -@@ -962,7 +962,7 @@ The default is: \fBno\fR - If set to a value greater than 0, multipathd will make sure that when path failures - has exceeded the san_path_err_threshold within san_path_err_forget_rate then the path - will be placed in failed state for san_path_err_recovery_time duration.Once san_path_err_recovery_time --has timeout we will reinstante the failed path . -+has timeout we will reinstate the failed path . - san_path_err_recovery_time value should be in secs. - See "Shaky paths detection" below. - .RS -@@ -1000,7 +1000,7 @@ If the rate of IO error on a particular path is greater than the - \fImarginal_path_err_rate_threshold\fR, then the path will not reinstate for - \fImarginal_path_err_recheck_gap_time\fR seconds unless there is only one - active path. After \fImarginal_path_err_recheck_gap_time\fR expires, the path --will be requeueed for rechecking. If checking result is good enough, the -+will be requeued for rechecking. If checking result is good enough, the - path will be reinstated. See "Shaky paths detection" below. - .RS - .TP -@@ -1031,7 +1031,7 @@ value, the failed path of which the IO error rate is larger than - \fImarginal_path_err_rate_threshold\fR will be kept in failed state for - \fImarginal_path_err_recheck_gap_time\fR seconds. When - \fImarginal_path_err_recheck_gap_time\fR seconds expires, the path will be --requeueed for checking. If checking result is good enough, the path will be -+requeued for checking. If checking result is good enough, the path will be - reinstated, or else it will keep failed. See "Shaky paths detection" below. - .RS - .TP -@@ -1379,7 +1379,7 @@ 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 5 blacklist criteria are evaluated in the the order -+For every device, these 5 blacklist criteria are evaluated in 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 -diff --git a/multipathd/main.c b/multipathd/main.c -index a160c824..defee10a 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -583,7 +583,7 @@ retry: - if (mpp->prflag) { - vector_foreach_slot(mpp->paths, pp, i) { - if ((pp->state == PATH_UP) || (pp->state == PATH_GHOST)) { -- /* persistent reseravtion check*/ -+ /* persistent reservation check*/ - mpath_pr_event_handle(pp); - } - } -@@ -1515,7 +1515,7 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) - condlog(3, "%s: error in change_foreign", __func__); - break; - default: -- condlog(1, "%s: return code %d of change_forein is unsupported", -+ condlog(1, "%s: return code %d of change_foreign is unsupported", - __func__, rc); - break; - } -@@ -1966,7 +1966,7 @@ ghost_delay_tick(struct vectors *vecs) - } - - static void --defered_failback_tick (vector mpvec) -+deferred_failback_tick (vector mpvec) - { - struct multipath * mpp; - unsigned int i; -@@ -2186,7 +2186,7 @@ static int check_path_reinstate_state(struct path * pp) { - get_monotonic_time(&curr_time); - /* when path failures has exceeded the san_path_err_threshold - * place the path in delayed state till san_path_err_recovery_time -- * so that the cutomer can rectify the issue within this time. After -+ * so that the customer can rectify the issue within this time. After - * the completion of san_path_err_recovery_time it should - * automatically reinstate the path - * (note: we know that san_path_err_threshold > 0 here). -@@ -2647,7 +2647,7 @@ checkerloop (void *ap) - pthread_cleanup_push(cleanup_lock, &vecs->lock); - lock(&vecs->lock); - pthread_testcancel(); -- defered_failback_tick(vecs->mpvec); -+ deferred_failback_tick(vecs->mpvec); - retry_count_tick(vecs->mpvec); - missing_uev_wait_tick(vecs); - ghost_delay_tick(vecs); -diff --git a/tests/directio.c b/tests/directio.c -index 20ccc47a..01fdef28 100644 ---- a/tests/directio.c -+++ b/tests/directio.c -@@ -497,7 +497,7 @@ static void test_free_with_pending(void **state) - do_libcheck_reset(1); - } - --/* test removing orpahed aio_group on free */ -+/* test removing orphaned aio_group on free */ - static void test_orphaned_aio_group(void **state) - { - struct checker c[AIO_GROUP_SIZE] = {{.cls = NULL}}; -diff --git a/tests/hwtable.c b/tests/hwtable.c -index bfaf613f..334b75e8 100644 ---- a/tests/hwtable.c -+++ b/tests/hwtable.c -@@ -29,7 +29,7 @@ - - #define N_CONF_FILES 2 - --static const char tmplate[] = "/tmp/hwtable-XXXXXX"; -+static const char template[] = "/tmp/hwtable-XXXXXX"; - - struct key_value { - const char *key; -@@ -136,7 +136,7 @@ static int setup(void **state) - if (hwt == NULL) - return -1; - -- snprintf(buf, sizeof(buf), "%s", tmplate); -+ snprintf(buf, sizeof(buf), "%s", template); - if (mkdtemp(buf) == NULL) { - condlog(0, "mkdtemp: %s", strerror(errno)); - goto err; -@@ -255,7 +255,7 @@ static void write_defaults(const struct hwt_state *hwt) - { "detect_prio", "no" }, - { "detect_checker", "no" }, - }; -- char buf[sizeof(tmplate) + sizeof(bindings_name)]; -+ char buf[sizeof(template) + sizeof(bindings_name)]; - char dirbuf[PATH_MAX]; - - snprintf(buf, sizeof(buf), "%s/%s", hwt->tmpname, bindings_name); -@@ -308,7 +308,7 @@ static void write_device(FILE *ff, int nkv, const struct key_value *kv) - } - - /* -- * Some macros to avoid boilerplace code -+ * Some macros to avoid boilerplate code - */ - - #define CHECK_STATE(state) ({ \ -@@ -448,7 +448,7 @@ static const struct key_value npr_queue = { _no_path_retry, "queue" }; - /***** BEGIN TESTS SECTION *****/ - - /* -- * Dump the configuration, subistitute the dumped configuration -+ * Dump the configuration, substitute the dumped configuration - * for the current one, and verify that the result is identical. - */ - static void replicate_config(const struct hwt_state *hwt, bool local) -diff --git a/tests/mpathvalid.c b/tests/mpathvalid.c -index 0230a88f..df66ed6a 100644 ---- a/tests/mpathvalid.c -+++ b/tests/mpathvalid.c -@@ -399,7 +399,7 @@ static void test_mpathvalid_is_path_good3(void **state) - free(wwid); - } - --/* mabybe valid with no matching paths */ -+/* maybe valid with no matching paths */ - static void test_mpathvalid_is_path_good4(void **state) - { - const char *wwids[] = { "WWID_A", "WWID_B", "WWID_C", "WWID_D" }; -diff --git a/tests/pgpolicy.c b/tests/pgpolicy.c -index f116d12c..43be831f 100644 ---- a/tests/pgpolicy.c -+++ b/tests/pgpolicy.c -@@ -191,7 +191,7 @@ verify_pathgroups(struct multipath *mp, struct path *pp, int **groups, - /* Test names instead of pointers to get a more - * useful error message */ - assert_string_equal(pgp_path->dev, pp_path->dev); -- /* This test is just a backkup in case the -+ /* This test is just a backup in case the - * something wenth wrong naming the paths */ - assert_ptr_equal(pgp_path, pp_path); - } -diff --git a/tests/valid.c b/tests/valid.c -index e7393a1c..398b771e 100644 ---- a/tests/valid.c -+++ b/tests/valid.c -@@ -293,7 +293,7 @@ static void test_sysfs_is_multipathed(void **state) - - memset(&pp, 0, sizeof(pp)); - conf.find_multipaths = FIND_MULTIPATHS_STRICT; -- /* test for already existing multiapthed device */ -+ /* test for already existing multipathed device */ - will_return(__wrap_sysfs_is_multipathed, true); - will_return(__wrap_sysfs_is_multipathed, wwid); - assert_int_equal(is_path_valid(name, &conf, &pp, true), -@@ -452,7 +452,7 @@ static void test_greedy(void **state) - assert_string_equal(pp.dev, name); - assert_ptr_equal(pp.udev, &test_udev); - assert_string_equal(pp.wwid, wwid); -- /* test greedy success without checking multiapthd */ -+ /* test greedy success without checking multipathd */ - memset(&pp, 0, sizeof(pp)); - setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_IS_FAILED); - assert_int_equal(is_path_valid(name, &conf, &pp, false), -diff --git a/third-party/valgrind/valgrind.h b/third-party/valgrind/valgrind.h -index 577c8f05..1633b318 100644 ---- a/third-party/valgrind/valgrind.h -+++ b/third-party/valgrind/valgrind.h -@@ -1075,7 +1075,7 @@ typedef - - /* Use these to write the name of your wrapper. NOTE: duplicates - VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h. NOTE also: inserts -- the default behaviour equivalance class tag "0000" into the name. -+ the default behaviour equivalence class tag "0000" into the name. - See pub_tool_redir.h for details -- normally you don't need to - think about this, though. */ - -@@ -1620,11 +1620,11 @@ typedef - and say that %r15 is trashed instead. gcc seems happy to go with - that. - -- Oh .. and this all needs to be conditionalised so that it is -+ Oh .. and this all needs to be conditionalized so that it is - unchanged from before this commit, when compiled with older gccs - that don't support __builtin_dwarf_cfa. Furthermore, since - this header file is freestanding, it has to be independent of -- config.h, and so the following conditionalisation cannot depend on -+ config.h, and so the following conditionalization cannot depend on - configure time checks. - - Although it's not clear from -@@ -1673,7 +1673,7 @@ typedef - /* NB 9 Sept 07. There is a nasty kludge here in all these CALL_FN_ - macros. In order not to trash the stack redzone, we need to drop - %rsp by 128 before the hidden call, and restore afterwards. The -- nastyness is that it is only by luck that the stack still appears -+ nastiness is that it is only by luck that the stack still appears - to be unwindable during the hidden call - since then the behaviour - of any routine using this macro does not match what the CFI data - says. Sigh. diff --git a/0028-multipath-avoid-NULL-string-in-released_to_systemd.patch b/0028-multipath-avoid-NULL-string-in-released_to_systemd.patch new file mode 100644 index 0000000..2be93fc --- /dev/null +++ b/0028-multipath-avoid-NULL-string-in-released_to_systemd.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 27 Sep 2022 12:14:09 +0200 +Subject: [PATCH] multipath: avoid NULL string in released_to_systemd() + +Fixes: b28c406 ("multipath -u: don't grab devices already passed to system") +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + multipath/main.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/multipath/main.c b/multipath/main.c +index 7b69a3ce..b9f360b4 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -435,7 +435,8 @@ static bool released_to_systemd(void) + bool ret; + + ret = dm_mp_dev_path != NULL && !strcmp(dm_mp_dev_path, "0"); +- condlog(4, "%s: %s=%s -> %d", __func__, dmdp, dm_mp_dev_path, ret); ++ condlog(4, "%s: %s=%s -> %d", __func__, dmdp, ++ dm_mp_dev_path ? dm_mp_dev_path : "", ret); + return ret; + } + diff --git a/0028-multipath-tools-remove-list-of-rebranded-arrays-vend.patch b/0028-multipath-tools-remove-list-of-rebranded-arrays-vend.patch deleted file mode 100644 index f2dbfce..0000000 --- a/0028-multipath-tools-remove-list-of-rebranded-arrays-vend.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Thu, 21 Jul 2022 19:22:04 +0200 -Subject: [PATCH] multipath-tools: remove list of rebranded arrays vendors from - man page - -It does not provide useful info, and it is incomplete. - -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez -Reviewed-by: Benjamin Marzinski -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - multipath/multipath.conf.5 | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 853e0feb..8b7dc511 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -315,12 +315,12 @@ accepts the optional prio_arg \fIexclusive_pref_bit\fR. - .TP - .I ontap - (Hardware-dependent) --Generate the path priority for NetApp ONTAP class and OEM arrays as IBM NSeries. -+Generate the path priority for NetApp ONTAP class, and rebranded arrays. - .TP - .I rdac - (Hardware-dependent) - Generate the path priority for LSI/Engenio/NetApp RDAC class as NetApp SANtricity --E/EF Series, and OEM arrays from IBM DELL SGI STK and SUN. -+E/EF Series, and rebranded arrays. - .TP - .I hp_sw - (Hardware-dependent) -@@ -496,7 +496,7 @@ Active/Standby mode exclusively. - .I rdac - (Hardware-dependent) - Check the path state for LSI/Engenio/NetApp RDAC class as NetApp SANtricity E/EF --Series, and OEM arrays from IBM DELL SGI STK and SUN. -+Series, and rebranded arrays. - .TP - .I directio - Read the first sector with direct I/O. This checker could cause spurious path -@@ -1568,7 +1568,7 @@ families. - .I 1 rdac - (Hardware-dependent) - Hardware handler for LSI/Engenio/NetApp RDAC class as NetApp SANtricity E/EF --Series, and OEM arrays from IBM DELL SGI STK and SUN. -+Series, and rebranded arrays. - .TP - .I 1 hp_sw - (Hardware-dependent) diff --git a/0029-libmultipath-avoid-NULL-string-in-is_udev_ready.patch b/0029-libmultipath-avoid-NULL-string-in-is_udev_ready.patch new file mode 100644 index 0000000..e48d44c --- /dev/null +++ b/0029-libmultipath-avoid-NULL-string-in-is_udev_ready.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 27 Sep 2022 12:28:26 +0200 +Subject: [PATCH] libmultipath: avoid NULL string in is_udev_ready() + +Fixes: 2b25a9e ("libmultipath: select_action(): force udev reload for uninitialized maps") +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/configure.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index e5249fc1..e551047a 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -662,7 +662,8 @@ static bool is_udev_ready(struct multipath *cmpp) + env = udev_device_get_property_value(mpp_ud, "MPATH_DEVICE_READY"); + rc = (env != NULL && !strcmp(env, "1")); + udev_device_unref(mpp_ud); +- condlog(4, "%s: %s: \"%s\" -> %d\n", __func__, cmpp->alias, env, rc); ++ condlog(4, "%s: %s: \"%s\" -> %d\n", __func__, cmpp->alias, ++ env ? env : "", rc); + return rc; + } + diff --git a/0029-multipath-tools-correct-CLARiiON-info-from-multipath.patch b/0029-multipath-tools-correct-CLARiiON-info-from-multipath.patch deleted file mode 100644 index 8777ea1..0000000 --- a/0029-multipath-tools-correct-CLARiiON-info-from-multipath.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Sat, 23 Jul 2022 00:01:13 +0200 -Subject: [PATCH] multipath-tools: correct CLARiiON info from multipath.conf - man page - -Remove "Unity" from emc prio and hardware_handler, because -Unity does not support PNR mode, just ALUA (page 113 and 153): -https://www.delltechnologies.com/asset/en-us/products/storage/technical-support/docu5128.pdf -And add PNR info. - -Cc: Yanfei Chen -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - multipath/multipath.conf.5 | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 8b7dc511..acdd1ae6 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -306,7 +306,7 @@ generate the path priority. This prioritizer accepts the optional prio_arg - .I emc - (Hardware-dependent) - Generate the path priority for DGC class arrays as CLARiiON CX/AX and --EMC VNX and Unity families. -+EMC VNX families with Failover Mode 1 (Passive Not Ready(PNR)). - .TP - .I alua - (Hardware-dependent) -@@ -1562,8 +1562,8 @@ The following hardware handler are implemented: - .TP 12 - .I 1 emc - (Hardware-dependent) --Hardware handler for DGC class arrays as CLARiiON CX/AX and EMC VNX and Unity --families. -+Hardware handler for DGC class arrays as CLARiiON CX/AX and EMC VNX families -+with Failover Mode 1 (Passive Not Ready(PNR)). - .TP - .I 1 rdac - (Hardware-dependent) diff --git a/0030-libmultipath-impove-add_feature-variable-names.patch b/0030-libmultipath-impove-add_feature-variable-names.patch new file mode 100644 index 0000000..9cc841d --- /dev/null +++ b/0030-libmultipath-impove-add_feature-variable-names.patch @@ -0,0 +1,115 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 9 Nov 2022 15:49:41 -0600 +Subject: [PATCH] libmultipath: impove add_feature() variable names + +Use descriptive names, instead of single letters. No functional changes. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/structs.c | 63 +++++++++++++++++++++--------------------- + 1 file changed, 32 insertions(+), 31 deletions(-) + +diff --git a/libmultipath/structs.c b/libmultipath/structs.c +index 7a2ff589..f90bd0b6 100644 +--- a/libmultipath/structs.c ++++ b/libmultipath/structs.c +@@ -604,65 +604,66 @@ first_path (const struct multipath * mpp) + return pgp?VECTOR_SLOT(pgp->paths, 0):NULL; + } + +-int add_feature(char **f, const char *n) ++int add_feature(char **features_p, const char *new_feat) + { +- int c = 0, d, l; +- char *e, *t; +- const char *p; ++ int count = 0, new_count, len; ++ char *tmp, *feats; ++ const char *ptr; + +- if (!f) ++ if (!features_p) + return 1; + + /* Nothing to do */ +- if (!n || *n == '\0') ++ if (!new_feat || *new_feat == '\0') + return 0; + +- l = strlen(n); +- if (isspace(*n) || isspace(*(n + l - 1))) { +- condlog(0, "internal error: feature \"%s\" has leading or trailing spaces", n); ++ len = strlen(new_feat); ++ if (isspace(*new_feat) || isspace(*(new_feat + len - 1))) { ++ condlog(0, "internal error: feature \"%s\" has leading or trailing spaces", ++ new_feat); + return 1; + } + +- p = n; +- d = 1; +- while (*p != '\0') { +- if (isspace(*p) && !isspace(*(p + 1)) && *(p + 1) != '\0') +- d++; +- p++; ++ ptr = new_feat; ++ new_count = 1; ++ while (*ptr != '\0') { ++ if (isspace(*ptr) && !isspace(*(ptr + 1)) && *(ptr + 1) != '\0') ++ new_count++; ++ ptr++; + } + + /* default feature is null */ +- if(!*f) ++ if(!*features_p) + { +- l = asprintf(&t, "%0d %s", d, n); +- if(l == -1) ++ len = asprintf(&feats, "%0d %s", new_count, new_feat); ++ if(len == -1) + return 1; + +- *f = t; ++ *features_p = feats; + return 0; + } + + /* Check if feature is already present */ +- e = *f; +- while ((e = strstr(e, n)) != NULL) { +- if (isspace(*(e - 1)) && +- (isspace(*(e + l)) || *(e + l) == '\0')) ++ tmp = *features_p; ++ while ((tmp = strstr(tmp, new_feat)) != NULL) { ++ if (isspace(*(tmp - 1)) && ++ (isspace(*(tmp + len)) || *(tmp + len) == '\0')) + return 0; +- e += l; ++ tmp += len; + } + + /* Get feature count */ +- c = strtoul(*f, &e, 10); +- if (*f == e || (!isspace(*e) && *e != '\0')) { +- condlog(0, "parse error in feature string \"%s\"", *f); ++ count = strtoul(*features_p, &tmp, 10); ++ if (*features_p == tmp || (!isspace(*tmp) && *tmp != '\0')) { ++ condlog(0, "parse error in feature string \"%s\"", *features_p); + return 1; + } +- c += d; +- if (asprintf(&t, "%0d%s %s", c, e, n) < 0) ++ count += new_count; ++ if (asprintf(&feats, "%0d%s %s", count, tmp, new_feat) < 0) + return 1; + +- free(*f); +- *f = t; ++ free(*features_p); ++ *features_p = feats; + + return 0; + } diff --git a/0030-multipath-tools-add-basic-info-on-how-to-use-multipa.patch b/0030-multipath-tools-add-basic-info-on-how-to-use-multipa.patch deleted file mode 100644 index 592be10..0000000 --- a/0030-multipath-tools-add-basic-info-on-how-to-use-multipa.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Sat, 23 Jul 2022 15:12:04 +0200 -Subject: [PATCH] multipath-tools: add basic info on how to use multipath-tools - with NVMe devices - -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - README.md | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - -diff --git a/README.md b/README.md -index 2322082c..b05b1332 100644 ---- a/README.md -+++ b/README.md -@@ -174,3 +174,19 @@ To enable ALUA, the following options should be changed: - - - Huawei OceanStor: - "Host Access Mode" should be changed to "Asymmetric". -+ -+ -+NVMe -+==== -+To use Device Mapper/multipath-tools with NVMe devices, -+if the Native NVMe Multipath subsystem is enabled -+( "Y" in `/sys/module/nvme_core/parameters/multipath` ), -+it has to be disabled: -+ -+`echo "options nvme_core multipath=N" > /etc/modprobe.d/01-nvme_core-mp.conf`, -+regenerate the initramfs (`dracut -f` or `update-initramfs`) and reboot. -+ -+Check that it is disabled(N) with: -+`cat /sys/module/nvme_core/parameters/multipath` -+or -+`systool -m nvme_core -A multipath` diff --git a/0031-multipathd-don-t-initialize-the-field-width-in-show_.patch b/0031-multipathd-don-t-initialize-the-field-width-in-show_.patch new file mode 100644 index 0000000..6dc8a0e --- /dev/null +++ b/0031-multipathd-don-t-initialize-the-field-width-in-show_.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 9 Nov 2022 15:49:42 -0600 +Subject: [PATCH] multipathd: don't initialize the field width in show_path() + +It's not used, so don't set it up. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + multipathd/cli_handlers.c | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c +index 5f0dd04e..e65fb75c 100644 +--- a/multipathd/cli_handlers.c ++++ b/multipathd/cli_handlers.c +@@ -67,12 +67,7 @@ static int + show_path (struct strbuf *reply, struct vectors *vecs, struct path *pp, + char *style) + { +- fieldwidth_t *width __attribute__((cleanup(cleanup_ucharp))) = NULL; +- +- if ((width = alloc_path_layout()) == NULL) +- return 1; +- get_path_layout(vecs->pathvec, 1, width); +- if (snprint_path(reply, style, pp, 0) < 0) ++ if (snprint_path(reply, style, pp, NULL) < 0) + return 1; + return 0; + } diff --git a/0031-multipathd-factor-out-the-code-to-flush-a-map-with-n.patch b/0031-multipathd-factor-out-the-code-to-flush-a-map-with-n.patch deleted file mode 100644 index bb8aa05..0000000 --- a/0031-multipathd-factor-out-the-code-to-flush-a-map-with-n.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 9 Aug 2022 16:46:26 -0500 -Subject: [PATCH] multipathd: factor out the code to flush a map with no paths - -The code to flush a multipath device because all of its paths have -been removed will be used by another caller, so factor it out of -ev_remove_path(). - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - multipathd/main.c | 56 ++++++++++++++++++++++++----------------------- - 1 file changed, 29 insertions(+), 27 deletions(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index defee10a..53cbdb61 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -561,6 +561,30 @@ int update_multipath (struct vectors *vecs, char *mapname, int reset) - return 0; - } - -+static bool -+flush_map_nopaths(struct multipath *mpp, struct vectors *vecs) { -+ char alias[WWID_SIZE]; -+ -+ /* -+ * flush_map will fail if the device is open -+ */ -+ strlcpy(alias, mpp->alias, WWID_SIZE); -+ if (mpp->flush_on_last_del == FLUSH_ENABLED) { -+ condlog(2, "%s Last path deleted, disabling queueing", -+ mpp->alias); -+ mpp->retry_tick = 0; -+ mpp->no_path_retry = NO_PATH_RETRY_FAIL; -+ mpp->disable_queueing = 1; -+ mpp->stat_map_failures++; -+ dm_queue_if_no_path(mpp->alias, 0); -+ } -+ if (!flush_map(mpp, vecs, 1)) { -+ condlog(2, "%s: removed map after removing all paths", alias); -+ return true; -+ } -+ return false; -+} -+ - static int - update_map (struct multipath *mpp, struct vectors *vecs, int new_map) - { -@@ -1363,34 +1387,12 @@ ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map) - vector_del_slot(mpp->paths, i); - - /* -- * remove the map IF removing the last path -+ * remove the map IF removing the last path. If -+ * flush_map_nopaths succeeds, the path has been removed. - */ -- if (VECTOR_SIZE(mpp->paths) == 0) { -- char alias[WWID_SIZE]; -- -- /* -- * flush_map will fail if the device is open -- */ -- strlcpy(alias, mpp->alias, WWID_SIZE); -- if (mpp->flush_on_last_del == FLUSH_ENABLED) { -- condlog(2, "%s Last path deleted, disabling queueing", mpp->alias); -- mpp->retry_tick = 0; -- mpp->no_path_retry = NO_PATH_RETRY_FAIL; -- mpp->disable_queueing = 1; -- mpp->stat_map_failures++; -- dm_queue_if_no_path(mpp->alias, 0); -- } -- if (!flush_map(mpp, vecs, 1)) { -- condlog(2, "%s: removed map after" -- " removing all paths", -- alias); -- /* flush_map() has freed the path */ -- goto out; -- } -- /* -- * Not an error, continue -- */ -- } -+ if (VECTOR_SIZE(mpp->paths) == 0 && -+ flush_map_nopaths(mpp, vecs)) -+ goto out; - - if (setup_map(mpp, ¶ms, vecs)) { - condlog(0, "%s: failed to setup map for" diff --git a/0032-libmultipath-improve-remove_feature-variable-names.patch b/0032-libmultipath-improve-remove_feature-variable-names.patch new file mode 100644 index 0000000..c1642d4 --- /dev/null +++ b/0032-libmultipath-improve-remove_feature-variable-names.patch @@ -0,0 +1,144 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 9 Nov 2022 15:49:43 -0600 +Subject: [PATCH] libmultipath: improve remove_feature() variable names + +Use descriptive names, instead of single letters. No functional changes. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/structs.c | 80 +++++++++++++++++++++--------------------- + 1 file changed, 40 insertions(+), 40 deletions(-) + +diff --git a/libmultipath/structs.c b/libmultipath/structs.c +index f90bd0b6..87e84d5d 100644 +--- a/libmultipath/structs.c ++++ b/libmultipath/structs.c +@@ -668,86 +668,86 @@ int add_feature(char **features_p, const char *new_feat) + return 0; + } + +-int remove_feature(char **f, const char *o) ++int remove_feature(char **features_p, const char *old_feat) + { +- int c = 0, d; +- char *e, *p, *n; +- const char *q; ++ int count = 0, len; ++ char *feats_start, *ptr, *new; + +- if (!f || !*f) ++ if (!features_p || !*features_p) + return 1; + + /* Nothing to do */ +- if (!o || *o == '\0') ++ if (!old_feat || *old_feat == '\0') + return 0; + +- d = strlen(o); +- if (isspace(*o) || isspace(*(o + d - 1))) { +- condlog(0, "internal error: feature \"%s\" has leading or trailing spaces", o); ++ len = strlen(old_feat); ++ if (isspace(*old_feat) || isspace(*(old_feat + len - 1))) { ++ condlog(0, "internal error: feature \"%s\" has leading or trailing spaces", ++ old_feat); + return 1; + } + + /* Check if present and not part of a larger feature token*/ +- p = *f + 1; /* the size must be at the start of the features string */ +- while ((p = strstr(p, o)) != NULL) { +- if (isspace(*(p - 1)) && +- (isspace(*(p + d)) || *(p + d) == '\0')) ++ ptr = *features_p + 1; ++ while ((ptr = strstr(ptr, old_feat)) != NULL) { ++ if (isspace(*(ptr - 1)) && ++ (isspace(*(ptr + len)) || *(ptr + len) == '\0')) + break; +- p += d; ++ ptr += len; + } +- if (!p) ++ if (!ptr) + return 0; + + /* Get feature count */ +- c = strtoul(*f, &e, 10); +- if (*f == e || !isspace(*e)) { +- condlog(0, "parse error in feature string \"%s\"", *f); ++ count = strtoul(*features_p, &feats_start, 10); ++ if (*features_p == feats_start || !isspace(*feats_start)) { ++ condlog(0, "parse error in feature string \"%s\"", *features_p); + return 1; + } + + /* Update feature count */ +- c--; +- q = o; +- while (*q != '\0') { +- if (isspace(*q) && !isspace(*(q + 1)) && *(q + 1) != '\0') +- c--; +- q++; ++ count--; ++ while (*old_feat != '\0') { ++ if (isspace(*old_feat) && !isspace(*(old_feat + 1)) && ++ *(old_feat + 1) != '\0') ++ count--; ++ old_feat++; + } + + /* Quick exit if all features have been removed */ +- if (c == 0) { +- n = malloc(2); +- if (!n) ++ if (count == 0) { ++ new = malloc(2); ++ if (!new) + return 1; +- strcpy(n, "0"); ++ strcpy(new, "0"); + goto out; + } + + /* Update feature count space */ +- n = malloc(strlen(*f) - d + 1); +- if (!n) ++ new = malloc(strlen(*features_p) - len + 1); ++ if (!new) + return 1; + + /* Copy the feature count */ +- sprintf(n, "%0d", c); ++ sprintf(new, "%0d", count); + /* + * Copy existing features up to the feature + * about to be removed + */ +- strncat(n, e, (size_t)(p - e)); ++ strncat(new, feats_start, (size_t)(ptr - feats_start)); + /* Skip feature to be removed */ +- p += d; ++ ptr += len; + /* Copy remaining features */ +- while (isspace(*p)) +- p++; +- if (*p != '\0') +- strcat(n, p); ++ while (isspace(*ptr)) ++ ptr++; ++ if (*ptr != '\0') ++ strcat(new, ptr); + else +- strchop(n); ++ strchop(new); + + out: +- free(*f); +- *f = n; ++ free(*features_p); ++ *features_p = new; + + return 0; + } diff --git a/0032-libmultipath-return-success-if-we-raced-to-remove-a-.patch b/0032-libmultipath-return-success-if-we-raced-to-remove-a-.patch deleted file mode 100644 index ab04fd9..0000000 --- a/0032-libmultipath-return-success-if-we-raced-to-remove-a-.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 9 Aug 2022 16:46:27 -0500 -Subject: [PATCH] libmultipath: return success if we raced to remove a map and - lost - -_dm_flush_map() was returning failure if it failed to remove a map, -even if that was because the map had already been removed. Return -success in this case. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/devmapper.c | 4 ++++ - multipathd/main.c | 4 ---- - 2 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index 1748d258..a49db3b0 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -1111,6 +1111,10 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, - } - condlog(4, "multipath map %s removed", mapname); - return 0; -+ } else if (dm_is_mpath(mapname) != 1) { -+ condlog(4, "multipath map %s removed externally", -+ mapname); -+ return 0; /*we raced with someone else removing it */ - } else { - condlog(2, "failed to remove multipath map %s", - mapname); -diff --git a/multipathd/main.c b/multipathd/main.c -index 53cbdb61..3fcd6bdb 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -758,10 +758,6 @@ flush_map(struct multipath * mpp, struct vectors * vecs, int nopaths) - * the spurious uevent we may generate with the dm_flush_map call below - */ - if (r) { -- /* -- * May not really be an error -- if the map was already flushed -- * from the device mapper by dmsetup(8) for instance. -- */ - if (r == 1) - condlog(0, "%s: can't flush", mpp->alias); - else { diff --git a/0033-RH-fixup-udev-rules-for-redhat.patch b/0033-RH-fixup-udev-rules-for-redhat.patch new file mode 100644 index 0000000..f0fc0d2 --- /dev/null +++ b/0033-RH-fixup-udev-rules-for-redhat.patch @@ -0,0 +1,66 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 13 Apr 2017 07:22:23 -0500 +Subject: [PATCH] RH: fixup udev rules for redhat + +The multipath rules need to run after scsi_id is run. This means moving +them after 60-persistent-storage.rules for redhat. Redhat also uses a +different naming scheme for partitions than SuSE. + +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 4 ++-- + kpartx/kpartx.rules | 2 +- + multipath/Makefile | 4 ++-- + 3 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 866ab274..8c5a08a2 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -34,9 +34,9 @@ endif + # Paths. All these can be overridden on the "make" command line. + prefix := + # Prefix for binaries +-exec_prefix := $(prefix) ++exec_prefix := $(prefix)/usr + # Prefix for non-essential libraries (libdmmp) +-usr_prefix := $(prefix) ++usr_prefix := $(prefix)/usr + # Where to install systemd-related files. systemd is usually installed under /usr + # Note: some systemd installations use separate "prefix" and "rootprefix". + # In this case, override only unitdir to use systemd's "rootprefix" instead of $(systemd_prefix) +diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules +index 1969dee0..d2b28233 100644 +--- a/kpartx/kpartx.rules ++++ b/kpartx/kpartx.rules +@@ -39,6 +39,6 @@ LABEL="mpath_kpartx_end" + GOTO="kpartx_end" + + LABEL="run_kpartx" +-RUN+="/sbin/kpartx -un -p -part /dev/$name" ++RUN+="/sbin/kpartx -un /dev/$name" + + LABEL="kpartx_end" +diff --git a/multipath/Makefile b/multipath/Makefile +index 73db991a..b3c2cc81 100644 +--- a/multipath/Makefile ++++ b/multipath/Makefile +@@ -24,7 +24,7 @@ install: + $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) + $(Q)$(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) +- $(Q)$(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)$(udevrulesdir)/56-multipath.rules ++ $(Q)$(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)$(udevrulesdir)/62-multipath.rules + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(modulesloaddir) + $(Q)$(INSTALL_PROGRAM) -m 644 modules-load.conf $(DESTDIR)$(modulesloaddir)/multipath.conf + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(tmpfilesdir) +@@ -44,7 +44,7 @@ uninstall: + $(Q)$(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules + $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf + $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf +- $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules ++ $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules + $(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 + $(Q)$(RM) $(DESTDIR)$(mandir)/man5/$(EXEC).conf.5 + diff --git a/0033-multipathd-Handle-losing-all-path-in-update_map.patch b/0033-multipathd-Handle-losing-all-path-in-update_map.patch deleted file mode 100644 index 43358d3..0000000 --- a/0033-multipathd-Handle-losing-all-path-in-update_map.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 9 Aug 2022 16:46:28 -0500 -Subject: [PATCH] multipathd: Handle losing all path in update_map - -Its possible that when a multipath device is being updated, it will end -up that all the paths for it are gone. This can happen if paths are -added and then removed again before multipathd processes the uevent for -the newly created multipath device. In this case multipathd wasn't -taking the proper action for the case where all the paths had been -removed. If flush_on_last_del was set, multipathd wasn't disabling -flushing and if deferred_remove was set, it wasn't doing a deferred -remove. Multipathd should call flush_map_nopaths(), just like -ev_remove_path() does when the last path is removed. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - multipathd/main.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 3fcd6bdb..7d127dbe 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -602,6 +602,10 @@ retry: - goto fail; - } - verify_paths(mpp); -+ if (VECTOR_SIZE(mpp->paths) == 0 && -+ flush_map_nopaths(mpp, vecs)) -+ return 1; -+ - mpp->action = ACT_RELOAD; - - if (mpp->prflag) { diff --git a/0044-RH-Remove-the-property-blacklist-exception-builtin.patch b/0034-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 96% rename from 0044-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0034-RH-Remove-the-property-blacklist-exception-builtin.patch index ded9aab..feef3f6 100644 --- a/0044-RH-Remove-the-property-blacklist-exception-builtin.patch +++ b/0034-RH-Remove-the-property-blacklist-exception-builtin.patch @@ -43,10 +43,10 @@ index 8d15d2ea..eff690fd 100644 udev_device_get_properties_list_entry(udev)) { diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index acdd1ae6..5ab770ba 100644 +index 1fea9d5a..eef3c605 100644 --- a/multipath/multipath.conf.5 +++ b/multipath/multipath.conf.5 -@@ -1348,9 +1348,14 @@ keywords. Both are regular expressions. For a full description of these keywords +@@ -1353,9 +1353,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, @@ -62,7 +62,7 @@ index acdd1ae6..5ab770ba 100644 . .RS .PP -@@ -1361,10 +1366,6 @@ Blacklisting by missing properties is only applied to devices which do have the +@@ -1366,10 +1371,6 @@ Blacklisting by missing properties is only applied to devices which do have the property specified by \fIuid_attribute\fR (e.g. \fIID_SERIAL\fR) set. Previously, it was applied to every device, possibly causing devices to be blacklisted because of temporary I/O error conditions. diff --git a/0034-multipath-fix-systemd-timers-in-the-initramfs.patch b/0034-multipath-fix-systemd-timers-in-the-initramfs.patch deleted file mode 100644 index 91178ea..0000000 --- a/0034-multipath-fix-systemd-timers-in-the-initramfs.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 5 Aug 2022 18:16:03 -0500 -Subject: [PATCH] multipath: fix systemd timers in the initramfs - -The systemd timers created for "find_multipaths smart" conflict with -shutdown.target, but not with initrd-cleanup.service. This can make -these timers trigger after the inirtd has started shutting down, -restarting multipathd (which then stops initrd-cleanup.service, since it -conflicts). To avoid this, make sure the timers and the unit they -trigger conflict with inird-cleanup.service. Also don't make them start -multipathd. "multipath -u" will not return "maybe" if multipathd isn't -running or set to run, and since we no longer wait for udev-settle, -multipathd starts up pretty quickly, so it shouldn't be a problem to -not trigger it here. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - multipath/multipath.rules | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/multipath/multipath.rules b/multipath/multipath.rules -index 9df11a95..f993d996 100644 ---- a/multipath/multipath.rules -+++ b/multipath/multipath.rules -@@ -71,7 +71,7 @@ ENV{.SAVED_FM_WAIT_UNTIL}=="?*", GOTO="pretend_mpath" - # - # We must trigger an "add" event because LVM2 will only act on those. - --RUN+="/usr/bin/systemd-run --unit=cancel-multipath-wait-$kernel --description 'cancel waiting for multipath siblings of $kernel' --no-block --timer-property DefaultDependencies=no --timer-property Conflicts=shutdown.target --timer-property Before=shutdown.target --timer-property AccuracySec=500ms --property DefaultDependencies=no --property Conflicts=shutdown.target --property Before=shutdown.target --property Wants=multipathd.service --property After=multipathd.service --on-active=$env{FIND_MULTIPATHS_WAIT_UNTIL} /usr/bin/udevadm trigger --action=add $sys$devpath" -+RUN+="/usr/bin/systemd-run --unit=cancel-multipath-wait-$kernel --description 'cancel waiting for multipath siblings of $kernel' --no-block --timer-property DefaultDependencies=no --timer-property Conflicts=shutdown.target --timer-property Before=shutdown.target --timer-property Conflicts=initrd-cleanup.service --timer-property Before=initrd-cleanup.service --timer-property AccuracySec=500ms --property DefaultDependencies=no --property Conflicts=shutdown.target --property Before=shutdown.target --property Conflicts=initrd-cleanup.service --property Before=initrd-cleanup.service --on-active=$env{FIND_MULTIPATHS_WAIT_UNTIL} /usr/bin/udevadm trigger --action=add $sys$devpath" - - LABEL="pretend_mpath" - ENV{DM_MULTIPATH_DEVICE_PATH}="1" diff --git a/0045-RH-don-t-start-without-a-config-file.patch b/0035-RH-don-t-start-without-a-config-file.patch similarity index 83% rename from 0045-RH-don-t-start-without-a-config-file.patch rename to 0035-RH-don-t-start-without-a-config-file.patch index dda921b..c957e2f 100644 --- a/0045-RH-don-t-start-without-a-config-file.patch +++ b/0035-RH-don-t-start-without-a-config-file.patch @@ -14,17 +14,17 @@ Signed-off-by: Benjamin Marzinski --- libmultipath/config.c | 13 +++++++++++++ libmultipath/config.h | 1 + - multipath/multipath.rules | 1 + + multipath/multipath.rules.in | 1 + multipathd/multipathd.8 | 2 ++ multipathd/multipathd.service | 1 + multipathd/multipathd.socket | 1 + 6 files changed, 19 insertions(+) diff --git a/libmultipath/config.c b/libmultipath/config.c -index ab8b26e7..f06fcbf9 100644 +index 5c5c0726..183b319d 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c -@@ -955,6 +955,19 @@ int _init_config (const char *file, struct config *conf) +@@ -966,6 +966,19 @@ int _init_config (const char *file, struct config *conf) } factorize_hwtable(conf->hwtable, builtin_hwtable_size, file); validate_pctable(conf->overrides, 0, file); @@ -45,10 +45,10 @@ index ab8b26e7..f06fcbf9 100644 conf->processed_main_config = 1; diff --git a/libmultipath/config.h b/libmultipath/config.h -index fdcdff0a..affba937 100644 +index 87947469..0dc89c16 100644 --- a/libmultipath/config.h +++ b/libmultipath/config.h -@@ -9,6 +9,7 @@ +@@ -10,6 +10,7 @@ #define ORIGIN_DEFAULT 0 #define ORIGIN_CONFIG 1 @@ -56,10 +56,10 @@ index fdcdff0a..affba937 100644 enum devtypes { DEV_NONE, -diff --git a/multipath/multipath.rules b/multipath/multipath.rules -index f993d996..68c30644 100644 ---- a/multipath/multipath.rules -+++ b/multipath/multipath.rules +diff --git a/multipath/multipath.rules.in b/multipath/multipath.rules.in +index 8d3cf33a..5c4447a2 100644 +--- a/multipath/multipath.rules.in ++++ b/multipath/multipath.rules.in @@ -9,6 +9,7 @@ IMPORT{cmdline}="nompath" ENV{nompath}=="?*", GOTO="end_mpath" IMPORT{cmdline}="multipath" @@ -69,13 +69,13 @@ index f993d996..68c30644 100644 ENV{DEVTYPE}!="partition", GOTO="test_dev" IMPORT{parent}="DM_MULTIPATH_DEVICE_PATH" diff --git a/multipathd/multipathd.8 b/multipathd/multipathd.8 -index 1e318bdc..6aab9325 100644 +index bdf102eb..a16a0bd5 100644 --- a/multipathd/multipathd.8 +++ b/multipathd/multipathd.8 -@@ -39,6 +39,8 @@ map regains its maximum performance and redundancy. - This daemon executes the external \fBmultipath\fR tool when events occur. - In turn, the multipath tool signals the multipathd daemon when it is done with - devmap reconfiguration, so that it can refresh its failed path list. +@@ -48,6 +48,8 @@ map regains its maximum performance and redundancy. + With the \fB-k\fR option, \fBmultipathd\fR acts as a client utility that + sends commands to a running instance of the multipathd daemon (see + \fBCOMMANDS\fR below). + +In this Linux distribution, multipathd does not run unless a /etc/multipath.conf file exists. . diff --git a/0035-multipathd-Add-missing-ctype-include.patch b/0035-multipathd-Add-missing-ctype-include.patch deleted file mode 100644 index 29ea453..0000000 --- a/0035-multipathd-Add-missing-ctype-include.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Bastian Germann -Date: Thu, 14 Oct 2021 00:34:33 +0200 -Subject: [PATCH] multipathd: Add missing ctype include - -In uxclnt.c, there are isspace calls. Add an explicit include. - -Signed-off-by: Bastian Germann -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - multipathd/uxclnt.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/multipathd/uxclnt.c b/multipathd/uxclnt.c -index b1b058bd..bdcc7c3f 100644 ---- a/multipathd/uxclnt.c -+++ b/multipathd/uxclnt.c -@@ -8,6 +8,7 @@ - #include - #include - #include -+#include - #include - #include - #include diff --git a/0046-RH-Fix-nvme-function-missing-argument.patch b/0036-RH-Fix-nvme-function-missing-argument.patch similarity index 100% rename from 0046-RH-Fix-nvme-function-missing-argument.patch rename to 0036-RH-Fix-nvme-function-missing-argument.patch diff --git a/0036-multipathd-replace-libreadline-with-libedit.patch b/0036-multipathd-replace-libreadline-with-libedit.patch deleted file mode 100644 index f376ee7..0000000 --- a/0036-multipathd-replace-libreadline-with-libedit.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 12 Aug 2022 18:58:15 +0200 -Subject: [PATCH] multipathd: replace libreadline with libedit - -Linking multipathd with libreadline may cause a license conflict, -because libreadline is licensed under GPL-3.0-or-later, and -libmultipath contains several files under GPL-2.0. - -See: - https://github.com/opensvc/multipath-tools/issues/36 - https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=979095 - https://www.gnu.org/licenses/gpl-faq.html#AllCompatibility - -Replace the readline functionality with libedit, which comes under -a BSD license. The readline library can still be enabled (e.g. for -binaries not intended to be distributed) by running -"make READLINE=libreadline". - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 5 +++++ - multipathd/Makefile | 11 ++++++++++- - multipathd/cli.c | 5 +++++ - multipathd/uxclnt.c | 6 ++++++ - 4 files changed, 26 insertions(+), 1 deletion(-) - -diff --git a/Makefile.inc b/Makefile.inc -index bcd2212a..ad7afd04 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -8,6 +8,11 @@ - # - # Uncomment to disable dmevents polling support - # ENABLE_DMEVENTS_POLL = 0 -+# -+# Readline library to use, libedit or libreadline -+# Caution: Using libreadline may make the multipathd binary undistributable, -+# see https://github.com/opensvc/multipath-tools/issues/36 -+READLINE = libedit - - # List of scsi device handler modules to load on boot, e.g. - # SCSI_DH_MODULES_PRELOAD := scsi_dh_alua scsi_dh_rdac -diff --git a/multipathd/Makefile b/multipathd/Makefile -index c937cd55..95acd887 100644 ---- a/multipathd/Makefile -+++ b/multipathd/Makefile -@@ -22,7 +22,16 @@ CFLAGS += $(BIN_CFLAGS) - LDFLAGS += $(BIN_LDFLAGS) - LIBDEPS += -L$(multipathdir) -lmultipath -L$(mpathpersistdir) -lmpathpersist \ - -L$(mpathcmddir) -lmpathcmd -ludev -ldl -lurcu -lpthread \ -- -ldevmapper -lreadline -+ -ldevmapper -+ -+ifeq ($(READLINE),libedit) -+CPPFLAGS += -DUSE_LIBEDIT -+LIBDEPS += -ledit -+endif -+ifeq ($(READLINE),libreadline) -+CPPFLAGS += -DUSE_LIBREADLINE -+LIBDEPS += -lreadline -+endif - - ifdef SYSTEMD - CPPFLAGS += -DUSE_SYSTEMD=$(SYSTEMD) -diff --git a/multipathd/cli.c b/multipathd/cli.c -index b2ee9a99..fa482a67 100644 ---- a/multipathd/cli.c -+++ b/multipathd/cli.c -@@ -11,7 +11,12 @@ - #include "parser.h" - #include "util.h" - #include "version.h" -+#ifdef USE_LIBEDIT -+#include -+#endif -+#ifdef USE_LIBREADLINE - #include -+#endif - - #include "mpath_cmd.h" - #include "cli.h" -diff --git a/multipathd/uxclnt.c b/multipathd/uxclnt.c -index bdcc7c3f..251e7d75 100644 ---- a/multipathd/uxclnt.c -+++ b/multipathd/uxclnt.c -@@ -16,8 +16,14 @@ - #include - #include - #include -+ -+#ifdef USE_LIBEDIT -+#include -+#endif -+#ifdef USE_LIBREADLINE - #include - #include -+#endif - - #include "mpath_cmd.h" - #include "uxsock.h" diff --git a/0047-RH-use-rpm-optflags-if-present.patch b/0037-RH-use-rpm-optflags-if-present.patch similarity index 71% rename from 0047-RH-use-rpm-optflags-if-present.patch rename to 0037-RH-use-rpm-optflags-if-present.patch index bd3b6e1..c844afe 100644 --- a/0047-RH-use-rpm-optflags-if-present.patch +++ b/0037-RH-use-rpm-optflags-if-present.patch @@ -13,19 +13,19 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 03450610..2cf6e85f 100644 +index 8c5a08a2..e6e7f7d7 100644 --- a/Makefile.inc +++ b/Makefile.inc -@@ -141,18 +141,30 @@ ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers - WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered -Wno-error=clobbered,) - WFORMATOVERFLOW := $(call TEST_CC_OPTION,-Wformat-overflow=2,) +@@ -74,19 +74,31 @@ INSTALL_PROGRAM := install + SYSTEMD_CPPFLAGS := $(if $(SYSTEMD),-DUSE_SYSTEMD=$(SYSTEMD)) + SYSTEMD_LIBDEPS := $(if $(SYSTEMD),$(if $(shell test $(SYSTEMD) -gt 209 && echo 1),-lsystemd,-lsystemd-daemon)) -OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 -WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int \ +ifndef RPM_OPT_FLAGS -+ OPTFLAGS := -O2 -g -Wall $(FORTIFY_OPT) -fexceptions \ -+ $(STACKPROT) -grecord-gcc-switches \ -+ -fasynchronous-unwind-tables --param=ssp-buffer-size=4 ++ OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 \ ++ -Wall $(FORTIFY_OPT) -fexceptions -grecord-gcc-switches \ ++ -fasynchronous-unwind-tables + ifeq ($(shell test -f /usr/lib/rpm/redhat/redhat-hardened-cc1 && echo 1),1) + OPTFLAGS += -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 + endif @@ -39,17 +39,18 @@ index 03450610..2cf6e85f 100644 -Werror=implicit-function-declaration -Werror=format-security \ - $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) -CPPFLAGS := $(FORTIFY_OPT) \ -- -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" -DRUN_DIR=\"${RUN}\" \ +- -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \ + $(WNOCLOBBERED) -Werror=cast-qual \ + $(ERROR_DISCARDED_QUALIFIERS) -Wstrict-prototypes -+CPPFLAGS := -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" -DRUN_DIR=\"${RUN}\" \ ++CPPFLAGS := -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \ + -DRUNTIME_DIR=\"$(runtimedir)\" \ -DCONFIG_DIR=\"$(configdir)\" -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe - BIN_CFLAGS = -fPIE -DPIE - LIB_CFLAGS = -fPIC - SHARED_FLAGS = -shared + BIN_CFLAGS := -fPIE -DPIE + LIB_CFLAGS := -fPIC + SHARED_FLAGS := -shared -LDFLAGS := $(LDFLAGS) -Wl,-z,relro -Wl,-z,now -Wl,-z,defs +LDFLAGS := $(LDFLAGS) $(RPM_LD_FLAGS) -Wl,-z,relro -Wl,-z,now -Wl,-z,defs - BIN_LDFLAGS = -pie + BIN_LDFLAGS := -pie - # Check whether a function with name $1 has been declared in header file $2. + # Source code directories. Don't modify. diff --git a/0037-libmultipath-convert-license-of-strbuf-code-to-GPL-2.patch b/0037-libmultipath-convert-license-of-strbuf-code-to-GPL-2.patch deleted file mode 100644 index f8085e8..0000000 --- a/0037-libmultipath-convert-license-of-strbuf-code-to-GPL-2.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 12 Aug 2022 21:25:37 +0200 -Subject: [PATCH] libmultipath: convert license of strbuf code to GPL-2.0+ - -This (partly) fixes the license incompatibility reported in -https://github.com/opensvc/multipath-tools/issues/36 - -As I'm the only author (except for a trivial spelling fix), -I see no issue with changing the license. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/strbuf.c | 2 +- - libmultipath/strbuf.h | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/strbuf.c b/libmultipath/strbuf.c -index f654594d..e23b65e8 100644 ---- a/libmultipath/strbuf.c -+++ b/libmultipath/strbuf.c -@@ -1,6 +1,6 @@ - /* - * Copyright (c) 2021 SUSE LLC -- * SPDX-License-Identifier: GPL-2.0-only -+ * SPDX-License-Identifier: GPL-2.0-or-later - */ - #include - #include -diff --git a/libmultipath/strbuf.h b/libmultipath/strbuf.h -index 31ab519a..ae863417 100644 ---- a/libmultipath/strbuf.h -+++ b/libmultipath/strbuf.h -@@ -1,6 +1,6 @@ - /* - * Copyright (c) 2021 SUSE LLC -- * SPDX-License-Identifier: GPL-2.0-only -+ * SPDX-License-Identifier: GPL-2.0-or-later - */ - #ifndef _STRBUF_H - #define _STRBUF_H diff --git a/0048-RH-add-mpathconf.patch b/0038-RH-add-mpathconf.patch similarity index 94% rename from 0048-RH-add-mpathconf.patch rename to 0038-RH-add-mpathconf.patch index ff2487f..e279822 100644 --- a/0048-RH-add-mpathconf.patch +++ b/0038-RH-add-mpathconf.patch @@ -21,10 +21,10 @@ Signed-off-by: Benjamin Marzinski create mode 100644 multipath/mpathconf.8 diff --git a/libmultipath/config.c b/libmultipath/config.c -index f06fcbf9..e2840839 100644 +index 183b319d..01f36a4f 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c -@@ -957,6 +957,8 @@ int _init_config (const char *file, struct config *conf) +@@ -968,6 +968,8 @@ int _init_config (const char *file, struct config *conf) validate_pctable(conf->overrides, 0, file); } else { condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices."); @@ -34,36 +34,39 @@ index f06fcbf9..e2840839 100644 conf->blist_devnode = vector_alloc(); if (!conf->blist_devnode) { diff --git a/multipath/Makefile b/multipath/Makefile -index d2b3fd82..00e46a0d 100644 +index b3c2cc81..413294ef 100644 --- a/multipath/Makefile +++ b/multipath/Makefile -@@ -21,6 +21,7 @@ $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so +@@ -22,6 +22,7 @@ $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so install: - $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) - $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ -+ $(INSTALL_PROGRAM) -m 755 mpathconf $(DESTDIR)$(bindir)/ - $(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) - $(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) - $(INSTALL_PROGRAM) -m 644 $(EXEC).rules $(DESTDIR)$(udevrulesdir)/62-multipath.rules -@@ -30,6 +31,7 @@ install: - $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(man8dir) - $(INSTALL_PROGRAM) -d $(DESTDIR)$(man5dir) - $(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5 $(DESTDIR)$(man5dir) -+ $(INSTALL_PROGRAM) -m 644 mpathconf.8 $(DESTDIR)$(man8dir) + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) + $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ ++ $(Q)$(INSTALL_PROGRAM) -m 755 mpathconf $(DESTDIR)$(bindir)/ + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) + $(Q)$(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) + $(Q)$(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)$(udevrulesdir)/62-multipath.rules +@@ -31,6 +32,7 @@ install: + $(Q)$(INSTALL_PROGRAM) -m 644 tmpfiles.conf $(DESTDIR)$(tmpfilesdir)/multipath.conf + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 + $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 ++ $(Q)$(INSTALL_PROGRAM) -m 644 mpathconf.8 $(DESTDIR)$(mandir)/man8 + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man5 + $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5 $(DESTDIR)$(mandir)/man5 ifneq ($(SCSI_DH_MODULES_PRELOAD),) - $(INSTALL_PROGRAM) -m 644 scsi_dh.conf $(DESTDIR)$(modulesloaddir)/scsi_dh.conf - for _x in $(SCSI_DH_MODULES_PRELOAD); do echo "$$_x"; done \ -@@ -42,8 +44,10 @@ uninstall: - $(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf - $(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf - $(RM) $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules -+ $(RM) $(DESTDIR)$(bindir)/mpathconf - $(RM) $(DESTDIR)$(man8dir)/$(EXEC).8 - $(RM) $(DESTDIR)$(man5dir)/$(EXEC).conf.5 -+ $(RM) $(DESTDIR)$(man8dir)/mpathconf.8 +@@ -41,11 +43,13 @@ endif + + uninstall: + $(Q)$(RM) $(DESTDIR)$(bindir)/$(EXEC) ++ $(Q)$(RM) $(DESTDIR)$(bindir)/mpathconf + $(Q)$(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules + $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf + $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf + $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules + $(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 ++ $(Q)$(RM) $(DESTDIR)$(mandir)/man8/mpathconf.8 + $(Q)$(RM) $(DESTDIR)$(mandir)/man5/$(EXEC).conf.5 clean: dep_clean - $(RM) core *.o $(EXEC) diff --git a/multipath/mpathconf b/multipath/mpathconf new file mode 100644 index 00000000..319664b1 diff --git a/0038-github-workflows-build-and-unittest.yaml-add-libedit.patch b/0038-github-workflows-build-and-unittest.yaml-add-libedit.patch deleted file mode 100644 index 375940f..0000000 --- a/0038-github-workflows-build-and-unittest.yaml-add-libedit.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 16 Aug 2022 14:10:39 +0200 -Subject: [PATCH] github workflows: build-and-unittest.yaml: add libedit-dev - -This is is required after switching from libreadline to libedit. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/build-and-unittest.yaml | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/.github/workflows/build-and-unittest.yaml b/.github/workflows/build-and-unittest.yaml -index 7ff45842..1ab0d36c 100644 ---- a/.github/workflows/build-and-unittest.yaml -+++ b/.github/workflows/build-and-unittest.yaml -@@ -27,7 +27,7 @@ jobs: - sudo apt-get install --yes gcc - make perl-base pkg-config valgrind - libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev -- libudev-dev libjson-c-dev liburcu-dev libcmocka-dev -+ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev - - name: build - run: make -O -j$(grep -c ^processor /proc/cpuinfo) - - name: test -@@ -55,7 +55,7 @@ jobs: - sudo apt-get install --yes gcc-10 - make perl-base pkg-config valgrind - libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev -- libudev-dev libjson-c-dev liburcu-dev libcmocka-dev -+ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev - - name: set CC - run: echo CC=gcc-10 >> $GITHUB_ENV - - name: build -@@ -85,7 +85,7 @@ jobs: - sudo apt-get install --yes clang - make perl-base pkg-config valgrind - libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev -- libudev-dev libjson-c-dev liburcu-dev libcmocka-dev -+ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev - - name: set CC - run: echo CC=clang >> $GITHUB_ENV - - name: build diff --git a/0049-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0039-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 95% rename from 0049-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0039-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch index fbf22db..c98543b 100644 --- a/0049-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +++ b/0039-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch @@ -20,7 +20,7 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/multipath/main.c b/multipath/main.c -index 034dd2f4..4c31820b 100644 +index b9f360b4..5eb752ee 100644 --- a/multipath/main.c +++ b/multipath/main.c @@ -120,7 +120,7 @@ usage (char * progname) @@ -41,7 +41,7 @@ index 034dd2f4..4c31820b 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" -@@ -448,6 +450,50 @@ static void cleanup_vecs(void) +@@ -447,6 +449,50 @@ static void cleanup_vecs(void) free_pathvec(vecs.pathvec, FREE_PATHS); } @@ -92,7 +92,7 @@ index 034dd2f4..4c31820b 100644 static int configure (struct config *conf, enum mpath_cmds cmd, enum devtypes dev_type, char *devpath) -@@ -841,7 +887,7 @@ main (int argc, char *argv[]) +@@ -840,7 +886,7 @@ main (int argc, char *argv[]) conf->force_sync = 1; if (atexit(cleanup_vecs)) condlog(1, "failed to register cleanup handler for vecs: %m"); @@ -101,7 +101,7 @@ index 034dd2f4..4c31820b 100644 switch(arg) { case 'v': if (!isdigit(optarg[0])) { -@@ -912,6 +958,10 @@ main (int argc, char *argv[]) +@@ -911,6 +957,10 @@ main (int argc, char *argv[]) case 'T': cmd = CMD_DUMP_CONFIG; break; @@ -113,7 +113,7 @@ index 034dd2f4..4c31820b 100644 usage(argv[0]); exit(RTVL_OK); diff --git a/multipath/multipath.8 b/multipath/multipath.8 -index 4c7e9885..1d062664 100644 +index 88149d53..072a03ee 100644 --- a/multipath/multipath.8 +++ b/multipath/multipath.8 @@ -63,7 +63,7 @@ multipath \- Device mapper target autoconfig. diff --git a/0039-github-workflows-coverity.yaml-add-libedit-dev.patch b/0039-github-workflows-coverity.yaml-add-libedit-dev.patch deleted file mode 100644 index 63ef9dc..0000000 --- a/0039-github-workflows-coverity.yaml-add-libedit-dev.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 16 Aug 2022 14:10:39 +0200 -Subject: [PATCH] github workflows: coverity.yaml: add libedit-dev - -This is is required after switching from libreadline to libedit. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/coverity.yaml | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/.github/workflows/coverity.yaml b/.github/workflows/coverity.yaml -index a8b56d43..3c6b3824 100644 ---- a/.github/workflows/coverity.yaml -+++ b/.github/workflows/coverity.yaml -@@ -15,7 +15,7 @@ jobs: - sudo apt-get install --yes - gcc make pkg-config - libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev -- libudev-dev libjson-c-dev liburcu-dev libcmocka-dev -+ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev - - name: download coverity - run: > - curl -o cov-analysis-linux64.tar.gz diff --git a/0050-RH-reset-default-find_mutipaths-value-to-off.patch b/0040-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 96% rename from 0050-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0040-RH-reset-default-find_mutipaths-value-to-off.patch index 9b6b7bb..ea12464 100644 --- a/0050-RH-reset-default-find_mutipaths-value-to-off.patch +++ b/0040-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 7979f208..78b3d938 100644 +index a5e9ea0c..514fd880 100644 --- a/libmultipath/defaults.h +++ b/libmultipath/defaults.h @@ -23,7 +23,7 @@ diff --git a/0040-github-workflows-abi.yaml-add-libedit-dev.patch b/0040-github-workflows-abi.yaml-add-libedit-dev.patch deleted file mode 100644 index 93e2331..0000000 --- a/0040-github-workflows-abi.yaml-add-libedit-dev.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 16 Aug 2022 14:10:39 +0200 -Subject: [PATCH] github workflows: abi.yaml: add libedit-dev - -This is is required after switching from libreadline to libedit. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/abi.yaml | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/.github/workflows/abi.yaml b/.github/workflows/abi.yaml -index 0a40104a..89b971cd 100644 ---- a/.github/workflows/abi.yaml -+++ b/.github/workflows/abi.yaml -@@ -30,7 +30,7 @@ jobs: - sudo apt-get install --yes gcc - gcc make pkg-config abigail-tools - libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev -- libudev-dev libjson-c-dev liburcu-dev libcmocka-dev -+ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev - - name: create ABI - run: make -O -j$(grep -c ^processor /proc/cpuinfo) abi.tar.gz - - name: save ABI diff --git a/0041-GitHub-workflows-native.yaml-add-libedit-dev-except-.patch b/0041-GitHub-workflows-native.yaml-add-libedit-dev-except-.patch deleted file mode 100644 index 7fc05a6..0000000 --- a/0041-GitHub-workflows-native.yaml-add-libedit-dev-except-.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 16 Aug 2022 16:52:07 +0200 -Subject: [PATCH] GitHub workflows: native.yaml: add libedit-dev, except for - jessie - -This is is required after switching from libreadline to libedit. - -On jessie, we can use libreadline5 (libreadline-gpl2-dev) without -license issues. Trying to compile against libedit results in an -"incompatible pointer type" error on jessie, because libedit -uses a different prototype for rl_completion_entry_function. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/native.yaml | 15 ++++++++++++++- - 1 file changed, 14 insertions(+), 1 deletion(-) - -diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml -index ddfd4a09..8b599209 100644 ---- a/.github/workflows/native.yaml -+++ b/.github/workflows/native.yaml -@@ -22,13 +22,24 @@ jobs: - - name: checkout - uses: actions/checkout@v1 - - name: build and test -+ if: ${{ matrix.os != 'jessie' }} - run: make test -+ - name: build and test (jessie) -+ # On jessie, we use libreadline 5 (no licensing issue) -+ if: ${{ matrix.os == 'jessie' }} -+ run: make READLINE=libreadline test - - name: clean - run: make clean - - name: clang -+ if: ${{ matrix.os != 'jessie' }} - env: - CC: clang - run: make test -+ - name: clang (jessie) -+ if: ${{ matrix.os == 'jessie' }} -+ env: -+ CC: clang -+ run: make READLINE=libreadline test - - rolling: - runs-on: ubuntu-20.04 -@@ -56,12 +67,13 @@ jobs: - libjson-c-dev - liburcu-dev - libcmocka-dev -+ libedit-dev - - name: dependencies-alpine - if: ${{ matrix.os == 'alpine' }} - run: > - apk add make gcc clang cmocka - musl-dev lvm2-dev libaio-dev readline-dev ncurses-dev eudev-dev -- userspace-rcu-dev json-c-dev cmocka-dev -+ userspace-rcu-dev json-c-dev cmocka-dev libedit-dev - - name: dependencies-fedora - if: ${{ matrix.os == 'fedora:rawhide' }} - run: > -@@ -76,6 +88,7 @@ jobs: - userspace-rcu-devel - json-c-devel - libcmocka-devel -+ libedit-devel - - name: checkout - uses: actions/checkout@v1 - - name: build and test diff --git a/0051-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0041-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 100% rename from 0051-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0041-RH-attempt-to-get-ANA-info-via-sysfs-first.patch diff --git a/0042-GitHub-workflows-foreign.yaml-switch-to-Debian-11-bu.patch b/0042-GitHub-workflows-foreign.yaml-switch-to-Debian-11-bu.patch deleted file mode 100644 index 3af19df..0000000 --- a/0042-GitHub-workflows-foreign.yaml-switch-to-Debian-11-bu.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 16 Aug 2022 23:38:18 +0200 -Subject: [PATCH] GitHub workflows: foreign.yaml: switch to Debian 11 - (bullseye) - -Building the containers in the build-multipath project recently -started failing for buster/s390x and buster/ppc64el. That failure -had nothing to do with the switch to libedit. - -It's about time to switch to bullseye anyway. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/foreign.yaml | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/.github/workflows/foreign.yaml b/.github/workflows/foreign.yaml -index 32915186..f6e69709 100644 ---- a/.github/workflows/foreign.yaml -+++ b/.github/workflows/foreign.yaml -@@ -13,7 +13,7 @@ jobs: - runs-on: ubuntu-20.04 - strategy: - matrix: -- os: [buster] -+ os: [bullseye] - arch: ['ppc64le', 'aarch64', 's390x'] - container: mwilck/multipath-build-${{ matrix.os }}-${{ matrix.arch }} - steps: -@@ -44,7 +44,7 @@ jobs: - needs: build - strategy: - matrix: -- os: [buster] -+ os: [bullseye] - arch: ['ppc64le', 'aarch64', 's390x'] - steps: - - name: get binaries diff --git a/0052-RH-make-parse_vpd_pg83-match-scsi_id-output.patch b/0042-RH-make-parse_vpd_pg83-match-scsi_id-output.patch similarity index 94% rename from 0052-RH-make-parse_vpd_pg83-match-scsi_id-output.patch rename to 0042-RH-make-parse_vpd_pg83-match-scsi_id-output.patch index 604ff75..5812a54 100644 --- a/0052-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +++ b/0042-RH-make-parse_vpd_pg83-match-scsi_id-output.patch @@ -14,10 +14,10 @@ Signed-off-by: Benjamin Marzinski 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 15560f8c..2339c9a9 100644 +index f3fccedd..c883fd02 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c -@@ -1175,13 +1175,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, +@@ -1176,13 +1176,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, good_len = 8; break; case 2: @@ -33,7 +33,7 @@ index 15560f8c..2339c9a9 100644 good_len = 8; break; default: -@@ -1199,10 +1195,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, +@@ -1200,10 +1196,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, break; case 0x8: /* SCSI Name: Prio 3 */ diff --git a/0053-RH-add-scsi-device-handlers-to-modules-load.d.patch b/0043-RH-add-scsi-device-handlers-to-modules-load.d.patch similarity index 92% rename from 0053-RH-add-scsi-device-handlers-to-modules-load.d.patch rename to 0043-RH-add-scsi-device-handlers-to-modules-load.d.patch index 423f107..72fbfe8 100644 --- a/0053-RH-add-scsi-device-handlers-to-modules-load.d.patch +++ b/0043-RH-add-scsi-device-handlers-to-modules-load.d.patch @@ -11,10 +11,10 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc -index 2cf6e85f..7277cf5f 100644 +index e6e7f7d7..15f0b9f6 100644 --- a/Makefile.inc +++ b/Makefile.inc -@@ -16,7 +16,7 @@ READLINE = libedit +@@ -16,7 +16,7 @@ READLINE := # List of scsi device handler modules to load on boot, e.g. # SCSI_DH_MODULES_PRELOAD := scsi_dh_alua scsi_dh_rdac diff --git a/0043-RH-fixup-udev-rules-for-redhat.patch b/0043-RH-fixup-udev-rules-for-redhat.patch deleted file mode 100644 index 47a1ab2..0000000 --- a/0043-RH-fixup-udev-rules-for-redhat.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 13 Apr 2017 07:22:23 -0500 -Subject: [PATCH] RH: fixup udev rules for redhat - -The multipath rules need to run after scsi_id is run. This means moving -them after 60-persistent-storage.rules for redhat. Redhat also uses a -different naming scheme for partitions than SuSE. - -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 2 +- - kpartx/kpartx.rules | 2 +- - multipath/Makefile | 4 ++-- - 3 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index ad7afd04..03450610 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -81,7 +81,7 @@ endif - prefix = - exec_prefix = $(prefix) - usr_prefix = $(prefix) --bindir = $(exec_prefix)/sbin -+bindir = $(exec_prefix)/usr/sbin - libudevdir = $(prefix)/$(SYSTEMDPATH)/udev - udevrulesdir = $(libudevdir)/rules.d - modulesloaddir = $(prefix)/$(SYSTEMDPATH)/modules-load.d -diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules -index 1969dee0..d2b28233 100644 ---- a/kpartx/kpartx.rules -+++ b/kpartx/kpartx.rules -@@ -39,6 +39,6 @@ LABEL="mpath_kpartx_end" - GOTO="kpartx_end" - - LABEL="run_kpartx" --RUN+="/sbin/kpartx -un -p -part /dev/$name" -+RUN+="/sbin/kpartx -un /dev/$name" - - LABEL="kpartx_end" -diff --git a/multipath/Makefile b/multipath/Makefile -index bcb04533..d2b3fd82 100644 ---- a/multipath/Makefile -+++ b/multipath/Makefile -@@ -23,7 +23,7 @@ install: - $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ - $(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) - $(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) -- $(INSTALL_PROGRAM) -m 644 $(EXEC).rules $(DESTDIR)$(udevrulesdir)/56-multipath.rules -+ $(INSTALL_PROGRAM) -m 644 $(EXEC).rules $(DESTDIR)$(udevrulesdir)/62-multipath.rules - $(INSTALL_PROGRAM) -d $(DESTDIR)$(modulesloaddir) - $(INSTALL_PROGRAM) -m 644 modules-load.conf $(DESTDIR)$(modulesloaddir)/multipath.conf - $(INSTALL_PROGRAM) -d $(DESTDIR)$(man8dir) -@@ -41,7 +41,7 @@ uninstall: - $(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules - $(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf - $(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf -- $(RM) $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules -+ $(RM) $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules - $(RM) $(DESTDIR)$(man8dir)/$(EXEC).8 - $(RM) $(DESTDIR)$(man5dir)/$(EXEC).conf.5 - diff --git a/0044-RH-compile-with-libreadline-support.patch b/0044-RH-compile-with-libreadline-support.patch new file mode 100644 index 0000000..b6d59f5 --- /dev/null +++ b/0044-RH-compile-with-libreadline-support.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 15 Nov 2022 18:03:33 -0600 +Subject: [PATCH] RH: compile with libreadline support + +Since the license issue has been resolved, and there are problems with +the command completion with libedit, use libreadline. + +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 15f0b9f6..881c1d52 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -12,7 +12,7 @@ + # Readline library to use, libedit, libreadline, or empty + # Caution: Using libreadline may make the multipathd binary undistributable, + # see https://github.com/opensvc/multipath-tools/issues/36 +-READLINE := ++READLINE := libreadline + + # List of scsi device handler modules to load on boot, e.g. + # SCSI_DH_MODULES_PRELOAD := scsi_dh_alua scsi_dh_rdac diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index f140e00..8a6b8e5 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,75 +1,66 @@ Name: device-mapper-multipath -Version: 0.9.0 -Release: 3%{?dist} +Version: 0.9.3 +Release: 1%{?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 -L https://github.com/opensvc/multipath-tools/archive/0.9.0.tar.gz -o multipath-tools-0.9.0.tgz -Source0: multipath-tools-0.9.0.tgz +# curl -L https://github.com/opensvc/multipath-tools/archive/0.9.3.tar.gz -o multipath-tools-0.9.3.tgz +Source0: multipath-tools-0.9.3.tgz Source1: multipath.conf -Patch0001: 0001-github-workflows-switch-to-fedora-36.patch -Patch0002: 0002-multipath-tools-fix-multipath-ll-bug-for-Native-NVME.patch -Patch0003: 0003-multipath-tools-update-Huawei-OceanStor-NVMe-vendor-.patch -Patch0004: 0004-multipath-tools-update-Generic-NVMe-vendor-regex-in-.patch -Patch0005: 0005-libmultipath-fix-find_multipaths_timeout-for-unknown.patch -Patch0006: 0006-multipath-tools-update-devel-repo-info-in-README.md.patch -Patch0007: 0007-multipath-tools-delete-README.alua.patch -Patch0008: 0008-multipath-tools-add-ALUA-info-to-README.md.patch -Patch0009: 0009-libmultipath-alua-remove-get_sysfs_pg83.patch -Patch0010: 0010-libmultipath-remove-sysfs_get_binary.patch -Patch0011: 0011-libmultipath-sysfs_bin_attr_get_value-no-error-if-bu.patch -Patch0012: 0012-libmultipath-common-code-path-for-sysfs_attr_get_val.patch -Patch0013: 0013-libmultipath-sanitize-error-checking-in-sysfs-access.patch -Patch0014: 0014-libmultipath-get-rid-of-PATH_SIZE.patch -Patch0015: 0015-libmultipath-sysfs_attr_get_value-don-t-return-0-if-.patch -Patch0016: 0016-libmultipath-sysfs_attr_set_value-don-t-return-0-on-.patch -Patch0017: 0017-libmultipath-sysfs-cleanup-file-descriptors-on-pthre.patch -Patch0018: 0018-libmultipath-multipathd-log-failure-setting-sysfs-at.patch -Patch0019: 0019-multipath-tests-expect_condlog-skip-depending-on-ver.patch -Patch0020: 0020-multipath-tests-__wrap_dlog-print-log-message.patch -Patch0021: 0021-multipath-tests-add-sysfs-test.patch -Patch0022: 0022-libmultipath.version-bump-version-for-sysfs-accessor.patch -Patch0023: 0023-libmultipath-unset-detect_checker-for-clariion-Unity.patch -Patch0024: 0024-libmultipath-spelling-cplusplus.patch -Patch0025: 0025-libmultipath-spelling-ascii.patch -Patch0026: 0026-libmultipath-spelling-progress.patch -Patch0027: 0027-multipath-tools-spelling-fixes.patch -Patch0028: 0028-multipath-tools-remove-list-of-rebranded-arrays-vend.patch -Patch0029: 0029-multipath-tools-correct-CLARiiON-info-from-multipath.patch -Patch0030: 0030-multipath-tools-add-basic-info-on-how-to-use-multipa.patch -Patch0031: 0031-multipathd-factor-out-the-code-to-flush-a-map-with-n.patch -Patch0032: 0032-libmultipath-return-success-if-we-raced-to-remove-a-.patch -Patch0033: 0033-multipathd-Handle-losing-all-path-in-update_map.patch -Patch0034: 0034-multipath-fix-systemd-timers-in-the-initramfs.patch -Patch0035: 0035-multipathd-Add-missing-ctype-include.patch -Patch0036: 0036-multipathd-replace-libreadline-with-libedit.patch -Patch0037: 0037-libmultipath-convert-license-of-strbuf-code-to-GPL-2.patch -Patch0038: 0038-github-workflows-build-and-unittest.yaml-add-libedit.patch -Patch0039: 0039-github-workflows-coverity.yaml-add-libedit-dev.patch -Patch0040: 0040-github-workflows-abi.yaml-add-libedit-dev.patch -Patch0041: 0041-GitHub-workflows-native.yaml-add-libedit-dev-except-.patch -Patch0042: 0042-GitHub-workflows-foreign.yaml-switch-to-Debian-11-bu.patch -Patch0043: 0043-RH-fixup-udev-rules-for-redhat.patch -Patch0044: 0044-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0045: 0045-RH-don-t-start-without-a-config-file.patch -Patch0046: 0046-RH-Fix-nvme-function-missing-argument.patch -Patch0047: 0047-RH-use-rpm-optflags-if-present.patch -Patch0048: 0048-RH-add-mpathconf.patch -Patch0049: 0049-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0050: 0050-RH-reset-default-find_mutipaths-value-to-off.patch -Patch0051: 0051-RH-attempt-to-get-ANA-info-via-sysfs-first.patch -Patch0052: 0052-RH-make-parse_vpd_pg83-match-scsi_id-output.patch -Patch0053: 0053-RH-add-scsi-device-handlers-to-modules-load.d.patch +Patch0001: 0001-libmultipath-fix-show-paths-format-failure.patch +Patch0002: 0002-fixup-Makefile.inc-fix-man-and-include-paths.patch +Patch0003: 0003-multipath-tools-Makefile.inc-Fix-paths-for-systemd.patch +Patch0004: 0004-multipath-tools-Makefile.inc-don-t-take-values-from-.patch +Patch0005: 0005-multipath-tools-Makefile.inc-get-rid-of-RUN.patch +Patch0006: 0006-multipath-tools-Makefile.inc-more-compact-code-for-L.patch +Patch0007: 0007-multipath-tools-Makefiles-simplify-code-for-include-.patch +Patch0008: 0008-multipath-tools-Makefiles-use-mandir.patch +Patch0009: 0009-multipath-tools-Makefile.inc-simplify-expression-for.patch +Patch0010: 0010-multipath-tools-Makefile.inc-untangle-paths-and-sour.patch +Patch0011: 0011-multipath-tools-Makefiles-replace-libdir-by-plugindi.patch +Patch0012: 0012-multipath-tools-Makefile.inc-use-simple-make-variabl.patch +Patch0013: 0013-multipath-tools-Makefile.inc-fix-a-log-message.patch +Patch0014: 0014-multipath-tools-Makefile.inc-set-systemd-specific-fl.patch +Patch0015: 0015-multipathd-Makefile-fix-compilation-flags-for-libedi.patch +Patch0016: 0016-multipath-tools-Makefiles-clean-up-executable-Makefi.patch +Patch0017: 0017-multipath-tools-Makefiles-use-common-code-for-librar.patch +Patch0018: 0018-multipath-tools-Makefiles-move-common-code-to-rules..patch +Patch0019: 0019-multipath-tools-Makefiles-create-config.mk.patch +Patch0020: 0020-multipath-tools-Makefiles-enable-quiet-build.patch +Patch0021: 0021-multipath-tools-quiet-build-support-for-top-level-Ma.patch +Patch0022: 0022-GitHub-workflows-use-make-j8-Orecurse.patch +Patch0023: 0023-README.md-Move-section-about-libedit-and-libreadline.patch +Patch0024: 0024-README.md-Fix-indentation-in-paragraph-about-device-.patch +Patch0025: 0025-README.md-document-options-for-paths-and-optimizatio.patch +Patch0026: 0026-README.md-document-how-to-customize-build.patch +Patch0027: 0027-libmultipath-avoid-Warray-bounds-error-with-gcc-12-a.patch +Patch0028: 0028-multipath-avoid-NULL-string-in-released_to_systemd.patch +Patch0029: 0029-libmultipath-avoid-NULL-string-in-is_udev_ready.patch +Patch0030: 0030-libmultipath-impove-add_feature-variable-names.patch +Patch0031: 0031-multipathd-don-t-initialize-the-field-width-in-show_.patch +Patch0032: 0032-libmultipath-improve-remove_feature-variable-names.patch +Patch0033: 0033-RH-fixup-udev-rules-for-redhat.patch +Patch0034: 0034-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0035: 0035-RH-don-t-start-without-a-config-file.patch +Patch0036: 0036-RH-Fix-nvme-function-missing-argument.patch +Patch0037: 0037-RH-use-rpm-optflags-if-present.patch +Patch0038: 0038-RH-add-mpathconf.patch +Patch0039: 0039-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0040: 0040-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0041: 0041-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0042: 0042-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +Patch0043: 0043-RH-add-scsi-device-handlers-to-modules-load.d.patch +Patch0044: 0044-RH-compile-with-libreadline-support.patch # runtime Requires: %{name}-libs = %{version}-%{release} Requires: kpartx = %{version}-%{release} Requires: device-mapper >= 1.02.96 Requires: userspace-rcu -Requires: libedit +Requires: readline Requires(post): systemd-units Requires(preun): systemd-units Requires(postun): systemd-units @@ -87,7 +78,7 @@ Conflicts: udisks2 < 2.8.0-2 # build/setup BuildRequires: libaio-devel, device-mapper-devel >= 1.02.89 BuildRequires: libselinux-devel, libsepol-devel -BuildRequires: libedit-devel, ncurses-devel +BuildRequires: readline-devel, ncurses-devel BuildRequires: systemd-units, systemd-devel BuildRequires: json-c-devel, perl-interpreter, pkgconfig, gcc BuildRequires: userspace-rcu-devel @@ -147,7 +138,7 @@ This package contains the files needed to develop applications that use device-mapper-multipath's libdmmp C API library %prep -%autosetup -n multipath-tools-0.9.0 -p1 +%autosetup -n multipath-tools-0.9.3 -p1 cp %{SOURCE1} . %build @@ -162,11 +153,12 @@ cp %{SOURCE1} . bindir=%{_sbindir} \ syslibdir=%{_libdir} \ usrlibdir=%{_libdir} \ - libdir=%{_libmpathdir} \ - rcdir=%{_initrddir} \ + plugindir=%{_libmpathdir} \ + mandir=%{_mandir} \ unitdir=%{_unitdir} \ includedir=%{_includedir} \ - pkgconfdir=%{_pkgconfdir} + pkgconfdir=%{_pkgconfdir} \ + tmpfilesdir=%{_tmpfilesdir} # tree fix up install -d %{buildroot}/etc/multipath @@ -191,32 +183,37 @@ fi /bin/systemctl --quiet is-enabled multipathd.service >/dev/null 2>&1 && /bin/systemctl reenable multipathd.service ||: %files -%license LICENSES/GPL-2.0 LICENSES/LGPL-2.0 +%license LICENSES/GPL-2.0 LICENSES/LGPL-2.0 LICENSES/GPL-3.0 %{_sbindir}/multipath %{_sbindir}/multipathd +%{_sbindir}/multipathc %{_sbindir}/mpathconf %{_sbindir}/mpathpersist %{_unitdir}/multipathd.service %{_unitdir}/multipathd.socket -%{_mandir}/man5/multipath.conf.5.gz -%{_mandir}/man8/multipath.8.gz -%{_mandir}/man8/multipathd.8.gz -%{_mandir}/man8/mpathconf.8.gz -%{_mandir}/man8/mpathpersist.8.gz +%{_mandir}/man5/multipath.conf.5* +%{_mandir}/man8/multipath.8* +%{_mandir}/man8/multipathd.8* +%{_mandir}/man8/multipathc.8* +%{_mandir}/man8/mpathconf.8* +%{_mandir}/man8/mpathpersist.8* %config /usr/lib/udev/rules.d/62-multipath.rules %config /usr/lib/udev/rules.d/11-dm-mpath.rules %dir /usr/lib/modules-load.d /usr/lib/modules-load.d/multipath.conf /usr/lib/modules-load.d/scsi_dh.conf +%{_tmpfilesdir}/multipath.conf %doc README.md %doc multipath.conf %dir /etc/multipath %files libs -%license LICENSES/GPL-2.0 LICENSES/LGPL-2.0 +%license LICENSES/GPL-2.0 LICENSES/LGPL-2.0 LICENSES/LGPL-2.1 %doc README.md %{_libdir}/libmultipath.so %{_libdir}/libmultipath.so.* +%{_libdir}/libmpathutil.so +%{_libdir}/libmpathutil.so.* %{_libdir}/libmpathpersist.so.* %{_libdir}/libmpathcmd.so.* %{_libdir}/libmpathvalid.so.* @@ -233,15 +230,15 @@ fi %{_includedir}/mpath_cmd.h %{_includedir}/mpath_persist.h %{_includedir}/mpath_valid.h -%{_mandir}/man3/mpath_persistent_reserve_in.3.gz -%{_mandir}/man3/mpath_persistent_reserve_out.3.gz +%{_mandir}/man3/mpath_persistent_reserve_in.3* +%{_mandir}/man3/mpath_persistent_reserve_out.3* %files -n kpartx %license LICENSES/GPL-2.0 %doc README.md %{_sbindir}/kpartx /usr/lib/udev/kpartx_id -%{_mandir}/man8/kpartx.8.gz +%{_mandir}/man8/kpartx.8* %config /usr/lib/udev/rules.d/11-dm-parts.rules %config /usr/lib/udev/rules.d/66-kpartx.rules %config /usr/lib/udev/rules.d/68-del-part-nodes.rules @@ -259,10 +256,24 @@ fi %dir %{_includedir}/libdmmp %{_includedir}/libdmmp/* %{_mandir}/man3/dmmp_* -%{_mandir}/man3/libdmmp.h.3.gz +%{_mandir}/man3/libdmmp.h.3* %{_pkgconfdir}/libdmmp.pc %changelog +* Tue Nov 15 2022 Benjamin Marzinski - 0.9.3-1 +- Update to the head of the upstream staging branch + * Previous patches 0001-0042 are included in the source tarball + * Patches 0001-0032 are from the upstream staging branch +- Rename redhat patches + * Previous patches 0043-0053 are now patches 0033-0043 +- Change back to using readline instead of libedit + * The code the uses readline has been isolated from the code that + is licensed gpl v2 only. +- Add libmpathutil libraries to spec file +- Add multipathc program to spec file +- Add multipath.conf systemd tempfile configuration to spec file +- Misc spec file cleanups + * Fri Aug 19 2022 Benjamin Marzinski - 0.9.0-3 - Update to the head of the upstream staging branch * Patches 0005-0042 are from the upstream staging branch diff --git a/sources b/sources index 14c7342..0394f4e 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (multipath-tools-0.9.0.tgz) = 6c417f6d1d116fa43bedb9f77769ece9cbb7b35b78a9b3558c41df2360e52a65a07314b12ab7e4a7bbc867b9755250de9db96a2f7eb4a6a37f0b0b3f0bbc840e +SHA512 (multipath-tools-0.9.3.tgz) = 4faa2ee5a96a9d5d752219931ebc885cb70ed6b022d45ede985ad7919c043a3aee166e6f126d32dffd187c5c32d5cbce91747d87d0b55557e2f7f68b279583da SHA512 (multipath.conf) = 71953dce5a68adcf60a942305f5a66023e6f4c4baf53b1bfdb4edf65ed5b8e03db804363c36d1dcfd85591f4766f52b515269904c53b84d7b076da0b80b09942 From bf5e5e489128385b45b09cbf3d342be46bb56db4 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 19 Jan 2023 01:17:17 +0000 Subject: [PATCH 36/67] Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- device-mapper-multipath.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 8a6b8e5..847d6b9 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.9.3 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -260,6 +260,9 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Thu Jan 19 2023 Fedora Release Engineering - 0.9.3-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild + * Tue Nov 15 2022 Benjamin Marzinski - 0.9.3-1 - Update to the head of the upstream staging branch * Previous patches 0001-0042 are included in the source tarball From 8e8d008d17e0648fd701436f2463651e6d11132d Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 26 Jan 2023 19:02:53 -0600 Subject: [PATCH 37/67] device-mapper-multipath-0.9.4-1 Update to the head of the upstream staging branch * Previous patches 0001-0032 are intlcude in the source tarball * Patches 0001-0010 are from the upstream staging branch Rename redhat patches * Previous patches 0033-0044 are not patches 0011-0022 Add dependency on libmount --- .gitignore | 1 + ...tipath-fix-show-paths-format-failure.patch | 35 - ...athd-make-pr-registration-consistent.patch | 159 ++++ ...kefile.inc-fix-man-and-include-paths.patch | 41 - 0002-libmultipath-make-prflag-an-enum.patch | 166 ++++ ...s-Makefile.inc-Fix-paths-for-systemd.patch | 65 -- ...dle-no-active-paths-in-update_map_pr.patch | 152 +++ ...Makefile.inc-don-t-take-values-from-.patch | 113 --- ...missing-newline-to-cli_del_map-reply.patch | 24 + ...kip-extra-vector-work-in-remove_maps.patch | 33 + ...th-tools-Makefile.inc-get-rid-of-RUN.patch | 63 -- ...han-paths-if-coalesce_paths-frees-ne.patch | 41 + ...Makefile.inc-more-compact-code-for-L.patch | 38 - ...path_valid-check-if-device-is-in-use.patch | 609 ++++++++++++ ...Makefiles-simplify-code-for-include-.patch | 139 --- ...use-conf-timeout-for-updating-persis.patch | 55 ++ ...multipath-tools-Makefiles-use-mandir.patch | 185 ---- ...hinfo-don-t-fail-for-devices-lacking.patch | 77 ++ ...Makefile.inc-simplify-expression-for.patch | 36 - ...multipath-bump-ABI-version-to-18.0.0.patch | 26 + ...Makefile.inc-untangle-paths-and-sour.patch | 68 -- ... 0011-RH-fixup-udev-rules-for-redhat.patch | 2 +- ...Makefiles-replace-libdir-by-plugindi.patch | 110 --- ...property-blacklist-exception-builtin.patch | 6 +- ...Makefile.inc-use-simple-make-variabl.patch | 112 --- ...RH-don-t-start-without-a-config-file.patch | 0 ...tools-Makefile.inc-fix-a-log-message.patch | 24 - ...H-Fix-nvme-function-missing-argument.patch | 0 ...Makefile.inc-set-systemd-specific-fl.patch | 129 --- ... 0015-RH-use-rpm-optflags-if-present.patch | 21 +- ...ile-fix-compilation-flags-for-libedi.patch | 54 -- ...hconf.patch => 0016-RH-add-mpathconf.patch | 0 ...Makefiles-clean-up-executable-Makefi.patch | 136 --- ...om-kernel-cmdline-mpath.wwids-with-A.patch | 0 ...Makefiles-use-common-code-for-librar.patch | 261 ------ ...-default-find_mutipaths-value-to-off.patch | 0 ...Makefiles-move-common-code-to-rules..patch | 172 ---- ...empt-to-get-ANA-info-via-sysfs-first.patch | 0 ...ath-tools-Makefiles-create-config.mk.patch | 603 ------------ ...-parse_vpd_pg83-match-scsi_id-output.patch | 6 +- ...h-tools-Makefiles-enable-quiet-build.patch | 879 ------------------ ...si-device-handlers-to-modules-load.d.patch | 2 +- ...quiet-build-support-for-top-level-Ma.patch | 183 ---- ...itHub-workflows-use-make-j8-Orecurse.patch | 132 --- ...-RH-compile-with-libreadline-support.patch | 2 +- ...ection-about-libedit-and-libreadline.patch | 48 - ...dentation-in-paragraph-about-device-.patch | 34 - ...nt-options-for-paths-and-optimizatio.patch | 47 - ...E.md-document-how-to-customize-build.patch | 37 - ...id-Warray-bounds-error-with-gcc-12-a.patch | 63 -- ...d-NULL-string-in-released_to_systemd.patch | 26 - ...h-avoid-NULL-string-in-is_udev_ready.patch | 26 - ...th-impove-add_feature-variable-names.patch | 115 --- ...-initialize-the-field-width-in-show_.patch | 31 - ...mprove-remove_feature-variable-names.patch | 144 --- device-mapper-multipath.spec | 86 +- sources | 2 +- 57 files changed, 1400 insertions(+), 4219 deletions(-) delete mode 100644 0001-libmultipath-fix-show-paths-format-failure.patch create mode 100644 0001-multipathd-make-pr-registration-consistent.patch delete mode 100644 0002-fixup-Makefile.inc-fix-man-and-include-paths.patch create mode 100644 0002-libmultipath-make-prflag-an-enum.patch delete mode 100644 0003-multipath-tools-Makefile.inc-Fix-paths-for-systemd.patch create mode 100644 0003-multipathd-handle-no-active-paths-in-update_map_pr.patch delete mode 100644 0004-multipath-tools-Makefile.inc-don-t-take-values-from-.patch create mode 100644 0004-multipathd-add-missing-newline-to-cli_del_map-reply.patch create mode 100644 0005-libmultipath-skip-extra-vector-work-in-remove_maps.patch delete mode 100644 0005-multipath-tools-Makefile.inc-get-rid-of-RUN.patch create mode 100644 0006-libmultipath-orphan-paths-if-coalesce_paths-frees-ne.patch delete mode 100644 0006-multipath-tools-Makefile.inc-more-compact-code-for-L.patch create mode 100644 0007-libmultipath-is_path_valid-check-if-device-is-in-use.patch delete mode 100644 0007-multipath-tools-Makefiles-simplify-code-for-include-.patch create mode 100644 0008-libmpathpersist-use-conf-timeout-for-updating-persis.patch delete mode 100644 0008-multipath-tools-Makefiles-use-mandir.patch create mode 100644 0009-libmultipath-pathinfo-don-t-fail-for-devices-lacking.patch delete mode 100644 0009-multipath-tools-Makefile.inc-simplify-expression-for.patch create mode 100644 0010-libmultipath-bump-ABI-version-to-18.0.0.patch delete mode 100644 0010-multipath-tools-Makefile.inc-untangle-paths-and-sour.patch rename 0033-RH-fixup-udev-rules-for-redhat.patch => 0011-RH-fixup-udev-rules-for-redhat.patch (98%) delete mode 100644 0011-multipath-tools-Makefiles-replace-libdir-by-plugindi.patch rename 0034-RH-Remove-the-property-blacklist-exception-builtin.patch => 0012-RH-Remove-the-property-blacklist-exception-builtin.patch (96%) delete mode 100644 0012-multipath-tools-Makefile.inc-use-simple-make-variabl.patch rename 0035-RH-don-t-start-without-a-config-file.patch => 0013-RH-don-t-start-without-a-config-file.patch (100%) delete mode 100644 0013-multipath-tools-Makefile.inc-fix-a-log-message.patch rename 0036-RH-Fix-nvme-function-missing-argument.patch => 0014-RH-Fix-nvme-function-missing-argument.patch (100%) delete mode 100644 0014-multipath-tools-Makefile.inc-set-systemd-specific-fl.patch rename 0037-RH-use-rpm-optflags-if-present.patch => 0015-RH-use-rpm-optflags-if-present.patch (78%) delete mode 100644 0015-multipathd-Makefile-fix-compilation-flags-for-libedi.patch rename 0038-RH-add-mpathconf.patch => 0016-RH-add-mpathconf.patch (100%) delete mode 100644 0016-multipath-tools-Makefiles-clean-up-executable-Makefi.patch rename 0039-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch => 0017-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch (100%) delete mode 100644 0017-multipath-tools-Makefiles-use-common-code-for-librar.patch rename 0040-RH-reset-default-find_mutipaths-value-to-off.patch => 0018-RH-reset-default-find_mutipaths-value-to-off.patch (100%) delete mode 100644 0018-multipath-tools-Makefiles-move-common-code-to-rules..patch rename 0041-RH-attempt-to-get-ANA-info-via-sysfs-first.patch => 0019-RH-attempt-to-get-ANA-info-via-sysfs-first.patch (100%) delete mode 100644 0019-multipath-tools-Makefiles-create-config.mk.patch rename 0042-RH-make-parse_vpd_pg83-match-scsi_id-output.patch => 0020-RH-make-parse_vpd_pg83-match-scsi_id-output.patch (94%) delete mode 100644 0020-multipath-tools-Makefiles-enable-quiet-build.patch rename 0043-RH-add-scsi-device-handlers-to-modules-load.d.patch => 0021-RH-add-scsi-device-handlers-to-modules-load.d.patch (96%) delete mode 100644 0021-multipath-tools-quiet-build-support-for-top-level-Ma.patch delete mode 100644 0022-GitHub-workflows-use-make-j8-Orecurse.patch rename 0044-RH-compile-with-libreadline-support.patch => 0022-RH-compile-with-libreadline-support.patch (96%) delete mode 100644 0023-README.md-Move-section-about-libedit-and-libreadline.patch delete mode 100644 0024-README.md-Fix-indentation-in-paragraph-about-device-.patch delete mode 100644 0025-README.md-document-options-for-paths-and-optimizatio.patch delete mode 100644 0026-README.md-document-how-to-customize-build.patch delete mode 100644 0027-libmultipath-avoid-Warray-bounds-error-with-gcc-12-a.patch delete mode 100644 0028-multipath-avoid-NULL-string-in-released_to_systemd.patch delete mode 100644 0029-libmultipath-avoid-NULL-string-in-is_udev_ready.patch delete mode 100644 0030-libmultipath-impove-add_feature-variable-names.patch delete mode 100644 0031-multipathd-don-t-initialize-the-field-width-in-show_.patch delete mode 100644 0032-libmultipath-improve-remove_feature-variable-names.patch diff --git a/.gitignore b/.gitignore index c9e44d7..1ca930c 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,4 @@ multipath-tools-091027.tar.gz /multipath-tools-0.8.9.tgz /multipath-tools-0.9.0.tgz /multipath-tools-0.9.3.tgz +/multipath-tools-0.9.4.tgz diff --git a/0001-libmultipath-fix-show-paths-format-failure.patch b/0001-libmultipath-fix-show-paths-format-failure.patch deleted file mode 100644 index 4f56830..0000000 --- a/0001-libmultipath-fix-show-paths-format-failure.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paul Koetsier -Date: Thu, 27 Oct 2022 19:29:28 +0200 -Subject: [PATCH] libmultipath: fix 'show paths format' failure - -Prevent 'multipathd show paths format "%c"' from failing on orphan paths. -For orphan paths the checker class isn't set, which caused -snprint_path_checker() to fail which in turn caused 'show paths format' to fail -when the format string contained "%c". - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/print.c | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/print.c b/libmultipath/print.c -index d7d522c8..3193dbe0 100644 ---- a/libmultipath/print.c -+++ b/libmultipath/print.c -@@ -734,8 +734,12 @@ snprint_host_adapter (struct strbuf *buff, const struct path * pp) - static int - snprint_path_checker (struct strbuf *buff, const struct path * pp) - { -- const struct checker * c = &pp->checker; -- return snprint_str(buff, checker_name(c)); -+ const char * n = checker_name(&pp->checker); -+ -+ if (n) -+ return snprint_str(buff, n); -+ else -+ return snprint_str(buff, "(null)"); - } - - static int diff --git a/0001-multipathd-make-pr-registration-consistent.patch b/0001-multipathd-make-pr-registration-consistent.patch new file mode 100644 index 0000000..47c380a --- /dev/null +++ b/0001-multipathd-make-pr-registration-consistent.patch @@ -0,0 +1,159 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 20 Dec 2022 17:41:10 -0600 +Subject: [PATCH] multipathd: make pr registration consistent + +multipathd was inconsistent on what it did with persistent reservations +when a multipath device was created. If a multipath device with a +configured reservation key was created during configure(), multipathd +would try to read the registered keys using an active path. If it saw a +matching key, it would set the prflag, but not attempt to register the +key on any of the other paths. This means that if a new path had +appeared while multipathd was not running, it wouldn't register the key +on this path. + +If the multipath device was created during ev_add_path(), multipathd +would used the added path to check if there was a matching key and if +there was, register the key only on the added path and then set the +prflag. This could be problematic if the device was created with +multiple paths, for instance because find_mutipaths was set to "yes" and +a second path just appeared. In this case, if the device happened to be +only registered on the second path, it would not get registered on the +first path. + +If the multipath device was added to multipathd during a call to +ev_add_map(), multipathd wouldn't set the prflag or register the key on +any paths. + +After a device was created with the prflag set, if a new path appeared +before the creation uevent, and multipathd was forced to delay adding +it, when it finally updated the multipath device, the key would be +registered on all paths, fixing any paths missed during creation. +However, if a new path appeared after the creation uevent, the key would +only be registered on that new path. Any paths that were missed on +creation would stay missed. + +persistent key registration needs to be handled consistently. This +patch does so by making sure that however a multipath device is added to +multipathd, it will check to see if the configured key is registered. If +it is, multipathd will set the prflag and register the key on all the +currently active paths. + +When a new path is added, multipathd will use it to check for active +keys, as before. But if it finds a matching key and prflag isn't +currently set, it will register the key on all paths. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + multipathd/main.c | 43 +++++++++++++++++++++++++++++-------------- + 1 file changed, 29 insertions(+), 14 deletions(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 1e1b254f..f7212d7b 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -586,13 +586,26 @@ flush_map_nopaths(struct multipath *mpp, struct vectors *vecs) { + return false; + } + ++static void ++pr_register_active_paths(struct multipath *mpp) ++{ ++ unsigned int i, j; ++ struct path *pp; ++ struct pathgroup *pgp; ++ ++ vector_foreach_slot (mpp->pg, pgp, i) { ++ vector_foreach_slot (pgp->paths, pp, j) { ++ if ((pp->state == PATH_UP) || (pp->state == PATH_GHOST)) ++ mpath_pr_event_handle(pp); ++ } ++ } ++} ++ + static int + update_map (struct multipath *mpp, struct vectors *vecs, int new_map) + { + int retries = 3; + char *params __attribute__((cleanup(cleanup_charp))) = NULL; +- struct path *pp; +- int i; + + retry: + condlog(4, "%s: updating new map", mpp->alias); +@@ -609,15 +622,6 @@ retry: + + mpp->action = ACT_RELOAD; + +- if (mpp->prflag) { +- vector_foreach_slot(mpp->paths, pp, i) { +- if ((pp->state == PATH_UP) || (pp->state == PATH_GHOST)) { +- /* persistent reservation check*/ +- mpath_pr_event_handle(pp); +- } +- } +- } +- + if (setup_map(mpp, ¶ms, vecs)) { + condlog(0, "%s: failed to setup new map in update", mpp->alias); + retries = -1; +@@ -643,6 +647,11 @@ fail: + + sync_map_state(mpp); + ++ if (!mpp->prflag) ++ update_map_pr(mpp); ++ if (mpp->prflag) ++ pr_register_active_paths(mpp); ++ + if (retries < 0) + condlog(0, "%s: failed reload in new map update", mpp->alias); + return 0; +@@ -1191,6 +1200,7 @@ ev_add_path (struct path * pp, struct vectors * vecs, int need_do_map) + int start_waiter = 0; + int ret; + int ro; ++ unsigned char prflag = 0; + + /* + * need path UID to go any further +@@ -1234,6 +1244,8 @@ rescan: + + verify_paths(mpp); + mpp->action = ACT_RELOAD; ++ prflag = mpp->prflag; ++ mpath_pr_event_handle(pp); + } else { + if (!should_multipath(pp, vecs->pathvec, vecs->mpvec)) { + orphan_path(pp, "only one path"); +@@ -1252,9 +1264,6 @@ rescan: + goto fail; /* leave path added to pathvec */ + } + +- /* persistent reservation check*/ +- mpath_pr_event_handle(pp); +- + /* ro check - if new path is ro, force map to be ro as well */ + ro = sysfs_get_ro(pp); + if (ro == 1) +@@ -1319,6 +1328,10 @@ rescan: + sync_map_state(mpp); + + if (retries >= 0) { ++ if (start_waiter) ++ update_map_pr(mpp); ++ if (mpp->prflag && !prflag) ++ pr_register_active_paths(mpp); + condlog(2, "%s [%s]: path added to devmap %s", + pp->dev, pp->dev_t, mpp->alias); + return 0; +@@ -2852,6 +2865,8 @@ configure (struct vectors * vecs, enum force_reload_types reload_type) + if (remember_wwid(mpp->wwid) == 1) + trigger_paths_udev_change(mpp, true); + update_map_pr(mpp); ++ if (mpp->prflag) ++ pr_register_active_paths(mpp); + } + + /* diff --git a/0002-fixup-Makefile.inc-fix-man-and-include-paths.patch b/0002-fixup-Makefile.inc-fix-man-and-include-paths.patch deleted file mode 100644 index 4afae52..0000000 --- a/0002-fixup-Makefile.inc-fix-man-and-include-paths.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 28 Oct 2022 18:22:59 +0200 -Subject: [PATCH] fixup! Makefile.inc: fix man and include paths - -Paths would now be wrong with the default (empty) prefix. -Fix it. - -Fixes: 2b2885c ("Makefile.inc: fix man and include paths") -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 4d843ce5..32001434 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -89,9 +89,9 @@ modulesloaddir = $(prefix)/$(SYSTEMDPATH)/modules-load.d - multipathdir = $(TOPDIR)/libmultipath - daemondir = $(TOPDIR)/multipathd - mpathutildir = $(TOPDIR)/libmpathutil --man8dir = $(prefix)/share/man/man8 --man5dir = $(prefix)/share/man/man5 --man3dir = $(prefix)/share/man/man3 -+man8dir = $(usr_prefix)/share/man/man8 -+man5dir = $(usr_prefix)/share/man/man5 -+man3dir = $(usr_prefix)/share/man/man3 - syslibdir = $(prefix)/$(LIB) - usrlibdir = $(usr_prefix)/$(LIB) - libdir = $(prefix)/$(LIB)/multipath -@@ -102,7 +102,7 @@ mpathvaliddir = $(TOPDIR)/libmpathvalid - thirdpartydir = $(TOPDIR)/third-party - libdmmpdir = $(TOPDIR)/libdmmp - nvmedir = $(TOPDIR)/libmultipath/nvme --includedir = $(prefix)/include -+includedir = $(usr_prefix)/include - pkgconfdir = $(usrlibdir)/pkgconfig - plugindir := $(prefix)/$(LIB)/multipath - configdir := $(prefix)/etc/multipath/conf.d diff --git a/0002-libmultipath-make-prflag-an-enum.patch b/0002-libmultipath-make-prflag-an-enum.patch new file mode 100644 index 0000000..304f731 --- /dev/null +++ b/0002-libmultipath-make-prflag-an-enum.patch @@ -0,0 +1,166 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 20 Dec 2022 17:41:11 -0600 +Subject: [PATCH] libmultipath: make prflag an enum + +In preparation for a future patch, make prflag an enum, and change the +reply of cli_getprstatus() to a string. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmpathpersist/mpath_persist_int.c | 2 +- + libmultipath/structs.h | 8 +++++++- + multipathd/cli_handlers.c | 17 +++++++++-------- + multipathd/main.c | 14 +++++++------- + 4 files changed, 24 insertions(+), 17 deletions(-) + +diff --git a/libmpathpersist/mpath_persist_int.c b/libmpathpersist/mpath_persist_int.c +index 6924b379..a84d9474 100644 +--- a/libmpathpersist/mpath_persist_int.c ++++ b/libmpathpersist/mpath_persist_int.c +@@ -783,7 +783,7 @@ int update_map_pr(struct multipath *mpp) + + if (isFound) + { +- mpp->prflag = 1; ++ mpp->prflag = PRFLAG_SET; + condlog(2, "%s: prflag flag set.", mpp->alias ); + } + +diff --git a/libmultipath/structs.h b/libmultipath/structs.h +index 9e2c1ab0..f2265300 100644 +--- a/libmultipath/structs.h ++++ b/libmultipath/structs.h +@@ -375,6 +375,12 @@ struct path { + + typedef int (pgpolicyfn) (struct multipath *, vector); + ++ ++enum prflag_value { ++ PRFLAG_UNSET, ++ PRFLAG_SET, ++}; ++ + struct multipath { + char wwid[WWID_SIZE]; + char alias_old[WWID_SIZE]; +@@ -449,7 +455,7 @@ struct multipath { + int prkey_source; + struct be64 reservation_key; + uint8_t sa_flags; +- unsigned char prflag; ++ int prflag; + int all_tg_pt; + struct gen_multipath generic_mp; + bool fpin_must_reload; +diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c +index e65fb75c..7ee2729f 100644 +--- a/multipathd/cli_handlers.c ++++ b/multipathd/cli_handlers.c +@@ -1277,6 +1277,10 @@ cli_shutdown (void * v, struct strbuf *reply, void * data) + static int + cli_getprstatus (void * v, struct strbuf *reply, void * data) + { ++ static const char * const prflag_str[] = { ++ [PRFLAG_UNSET] = "unset\n", ++ [PRFLAG_SET] = "set\n", ++ }; + struct multipath * mpp; + struct vectors * vecs = (struct vectors *)data; + char * param = get_keyparam(v, KEY_MAP); +@@ -1287,10 +1291,7 @@ cli_getprstatus (void * v, struct strbuf *reply, void * data) + if (!mpp) + return 1; + +- condlog(3, "%s: prflag = %u", param, (unsigned int)mpp->prflag); +- +- if (print_strbuf(reply, "%d", mpp->prflag) < 0) +- return 1; ++ append_strbuf_str(reply, prflag_str[mpp->prflag]); + + condlog(3, "%s: reply = %s", param, get_strbuf_str(reply)); + +@@ -1310,8 +1311,8 @@ cli_setprstatus(void * v, struct strbuf *reply, void * data) + if (!mpp) + return 1; + +- if (!mpp->prflag) { +- mpp->prflag = 1; ++ if (mpp->prflag != PRFLAG_SET) { ++ mpp->prflag = PRFLAG_SET; + condlog(2, "%s: prflag set", param); + } + +@@ -1332,8 +1333,8 @@ cli_unsetprstatus(void * v, struct strbuf *reply, void * data) + if (!mpp) + return 1; + +- if (mpp->prflag) { +- mpp->prflag = 0; ++ if (mpp->prflag != PRFLAG_UNSET) { ++ mpp->prflag = PRFLAG_UNSET; + condlog(2, "%s: prflag unset", param); + } + +diff --git a/multipathd/main.c b/multipathd/main.c +index f7212d7b..722235c7 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -647,9 +647,9 @@ fail: + + sync_map_state(mpp); + +- if (!mpp->prflag) ++ if (mpp->prflag == PRFLAG_UNSET) + update_map_pr(mpp); +- if (mpp->prflag) ++ if (mpp->prflag == PRFLAG_SET) + pr_register_active_paths(mpp); + + if (retries < 0) +@@ -1200,7 +1200,7 @@ ev_add_path (struct path * pp, struct vectors * vecs, int need_do_map) + int start_waiter = 0; + int ret; + int ro; +- unsigned char prflag = 0; ++ unsigned char prflag = PRFLAG_UNSET; + + /* + * need path UID to go any further +@@ -1330,7 +1330,7 @@ rescan: + if (retries >= 0) { + if (start_waiter) + update_map_pr(mpp); +- if (mpp->prflag && !prflag) ++ if (mpp->prflag == PRFLAG_SET && prflag == PRFLAG_UNSET) + pr_register_active_paths(mpp); + condlog(2, "%s [%s]: path added to devmap %s", + pp->dev, pp->dev_t, mpp->alias); +@@ -2492,7 +2492,7 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) + } + + if (newstate == PATH_UP || newstate == PATH_GHOST) { +- if (pp->mpp->prflag) { ++ if (pp->mpp->prflag == PRFLAG_SET) { + /* + * Check Persistent Reservation. + */ +@@ -2865,7 +2865,7 @@ configure (struct vectors * vecs, enum force_reload_types reload_type) + if (remember_wwid(mpp->wwid) == 1) + trigger_paths_udev_change(mpp, true); + update_map_pr(mpp); +- if (mpp->prflag) ++ if (mpp->prflag == PRFLAG_SET) + pr_register_active_paths(mpp); + } + +@@ -3840,7 +3840,7 @@ void * mpath_pr_event_handler_fn (void * pathp ) + { + condlog(0,"%s: Reservation registration failed. Error: %d", pp->dev, ret); + } +- mpp->prflag = 1; ++ mpp->prflag = PRFLAG_SET; + + free(param); + out: diff --git a/0003-multipath-tools-Makefile.inc-Fix-paths-for-systemd.patch b/0003-multipath-tools-Makefile.inc-Fix-paths-for-systemd.patch deleted file mode 100644 index 8a25fe0..0000000 --- a/0003-multipath-tools-Makefile.inc-Fix-paths-for-systemd.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 27 Oct 2022 17:09:52 +0200 -Subject: [PATCH] multipath-tools: Makefile.inc: Fix paths for systemd - -With prefix=/usr, systemd files were installed under /usr/usr/lib, -which is bogus. Clean this up, and document how to handle systemd's -"rootprefix" options. Remove the previous SYSTEMDPATH option. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 21 ++++++++++++--------- - 1 file changed, 12 insertions(+), 9 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 32001434..351358a9 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -53,10 +53,6 @@ ifndef SYSTEMD - endif - endif - --ifndef SYSTEMDPATH -- SYSTEMDPATH=usr/lib --endif -- - ifndef DEVMAPPER_INCDIR - ifeq ($(shell $(PKGCONFIG) --modversion devmapper >/dev/null 2>&1 && echo 1), 1) - DEVMAPPER_INCDIR = $(shell $(PKGCONFIG) --variable=includedir devmapper) -@@ -78,14 +74,22 @@ ifndef LINUX_HEADERS_INCDIR - LINUX_HEADERS_INCDIR = /usr/include - endif - -+# Paths. All these can be overridden on the "make" command line. - prefix = -+# Prefix for binaries - exec_prefix = $(prefix) -+# Prefix for non-essential libraries (libdmmp) - usr_prefix = $(prefix) -+# Where to install systemd-related files. systemd is usually installed under /usr -+# Note: some systemd installations use separate "prefix" and "rootprefix". -+# In this case, override only unitdir to use systemd's "rootprefix" instead of $(systemd_prefix) -+systemd_prefix := /usr -+unitdir := $(systemd_prefix)/lib/systemd/system -+tmpfilesdir := $(systemd_prefix)/lib/tmpfiles.d -+modulesloaddir := $(systemd_prefix)/lib/modules-load.d -+libudevdir := $(systemd_prefix)/lib/udev -+udevrulesdir := $(libudevdir)/rules.d - bindir = $(exec_prefix)/sbin --libudevdir = $(prefix)/$(SYSTEMDPATH)/udev --tmpfilesdir = $(prefix)/$(SYSTEMDPATH)/tmpfiles.d --udevrulesdir = $(libudevdir)/rules.d --modulesloaddir = $(prefix)/$(SYSTEMDPATH)/modules-load.d - multipathdir = $(TOPDIR)/libmultipath - daemondir = $(TOPDIR)/multipathd - mpathutildir = $(TOPDIR)/libmpathutil -@@ -95,7 +99,6 @@ man3dir = $(usr_prefix)/share/man/man3 - syslibdir = $(prefix)/$(LIB) - usrlibdir = $(usr_prefix)/$(LIB) - libdir = $(prefix)/$(LIB)/multipath --unitdir = $(prefix)/$(SYSTEMDPATH)/systemd/system - mpathpersistdir = $(TOPDIR)/libmpathpersist - mpathcmddir = $(TOPDIR)/libmpathcmd - mpathvaliddir = $(TOPDIR)/libmpathvalid diff --git a/0003-multipathd-handle-no-active-paths-in-update_map_pr.patch b/0003-multipathd-handle-no-active-paths-in-update_map_pr.patch new file mode 100644 index 0000000..59dd10f --- /dev/null +++ b/0003-multipathd-handle-no-active-paths-in-update_map_pr.patch @@ -0,0 +1,152 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 20 Dec 2022 17:41:12 -0600 +Subject: [PATCH] multipathd: handle no active paths in update_map_pr + +When a multipath device is first created, if it has a reservation key +configured, update_map_pr() will check for a matching key on the active +paths. If there were no active paths to check with, multipathd was +leaving mpp->prflag in PRFLAG_UNSET, as if there were no matching keys. +It's possible that when update_map_pr() is called, all the paths will be +in the PATH_PENDING state because the checkers haven't completed yet. In +this case, multipathd was treating the device as having no registered +keys without ever checking. + +To solve this, multipath devices now start with prflag = PRFLAG_UNKNOWN. +It will remain in this state until multipathd actually tries to get the +registered keys down a path. If the map is in this state, it will check +newly active paths, and if it finds a matching key, it will register +the key down all active paths. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmpathpersist/mpath_persist_int.c | 8 ++++++++ + libmultipath/structs.h | 1 + + multipathd/cli_handlers.c | 1 + + multipathd/main.c | 19 ++++++++++++++----- + 4 files changed, 24 insertions(+), 5 deletions(-) + +diff --git a/libmpathpersist/mpath_persist_int.c b/libmpathpersist/mpath_persist_int.c +index a84d9474..8b52b746 100644 +--- a/libmpathpersist/mpath_persist_int.c ++++ b/libmpathpersist/mpath_persist_int.c +@@ -738,6 +738,7 @@ int update_map_pr(struct multipath *mpp) + if (!get_be64(mpp->reservation_key)) + { + /* Nothing to do. Assuming pr mgmt feature is disabled*/ ++ mpp->prflag = PRFLAG_UNSET; + condlog(4, "%s: reservation_key not set in multipath.conf", + mpp->alias); + return MPATH_PR_SUCCESS; +@@ -749,6 +750,13 @@ int update_map_pr(struct multipath *mpp) + condlog(0,"%s : failed to alloc resp in update_map_pr", mpp->alias); + return MPATH_PR_OTHER; + } ++ if (count_active_paths(mpp) == 0) ++ { ++ condlog(0,"%s: No available paths to check pr status", ++ mpp->alias); ++ return MPATH_PR_OTHER; ++ } ++ mpp->prflag = PRFLAG_UNSET; + ret = mpath_prin_activepath(mpp, MPATH_PRIN_RKEY_SA, resp, noisy); + + if (ret != MPATH_PR_SUCCESS ) +diff --git a/libmultipath/structs.h b/libmultipath/structs.h +index f2265300..e2294323 100644 +--- a/libmultipath/structs.h ++++ b/libmultipath/structs.h +@@ -377,6 +377,7 @@ typedef int (pgpolicyfn) (struct multipath *, vector); + + + enum prflag_value { ++ PRFLAG_UNKNOWN, + PRFLAG_UNSET, + PRFLAG_SET, + }; +diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c +index 7ee2729f..ec5db1b8 100644 +--- a/multipathd/cli_handlers.c ++++ b/multipathd/cli_handlers.c +@@ -1278,6 +1278,7 @@ static int + cli_getprstatus (void * v, struct strbuf *reply, void * data) + { + static const char * const prflag_str[] = { ++ [PRFLAG_UNKNOWN] = "unknown\n", + [PRFLAG_UNSET] = "unset\n", + [PRFLAG_SET] = "set\n", + }; +diff --git a/multipathd/main.c b/multipathd/main.c +index 722235c7..bdeffe76 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -647,7 +647,7 @@ fail: + + sync_map_state(mpp); + +- if (mpp->prflag == PRFLAG_UNSET) ++ if (mpp->prflag != PRFLAG_SET) + update_map_pr(mpp); + if (mpp->prflag == PRFLAG_SET) + pr_register_active_paths(mpp); +@@ -1330,7 +1330,7 @@ rescan: + if (retries >= 0) { + if (start_waiter) + update_map_pr(mpp); +- if (mpp->prflag == PRFLAG_SET && prflag == PRFLAG_UNSET) ++ if (mpp->prflag == PRFLAG_SET && prflag != PRFLAG_SET) + pr_register_active_paths(mpp); + condlog(2, "%s [%s]: path added to devmap %s", + pp->dev, pp->dev_t, mpp->alias); +@@ -2492,13 +2492,17 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) + } + + if (newstate == PATH_UP || newstate == PATH_GHOST) { +- if (pp->mpp->prflag == PRFLAG_SET) { ++ if (pp->mpp->prflag != PRFLAG_UNSET) { ++ int prflag = pp->mpp->prflag; + /* + * Check Persistent Reservation. + */ + condlog(2, "%s: checking persistent " + "reservation registration", pp->dev); + mpath_pr_event_handle(pp); ++ if (pp->mpp->prflag == PRFLAG_SET && ++ prflag != PRFLAG_SET) ++ pr_register_active_paths(pp->mpp); + } + } + +@@ -3788,6 +3792,7 @@ void * mpath_pr_event_handler_fn (void * pathp ) + goto out; + } + ++ mpp->prflag = PRFLAG_UNSET; + ret = prin_do_scsi_ioctl(pp->dev, MPATH_PRIN_RKEY_SA, resp, 0); + if (ret != MPATH_PR_SUCCESS ) + { +@@ -3858,12 +3863,12 @@ int mpath_pr_event_handle(struct path *pp) + struct multipath * mpp; + + if (pp->bus != SYSFS_BUS_SCSI) +- return 0; ++ goto no_pr; + + mpp = pp->mpp; + + if (!get_be64(mpp->reservation_key)) +- return -1; ++ goto no_pr; + + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); +@@ -3876,4 +3881,8 @@ int mpath_pr_event_handle(struct path *pp) + pthread_attr_destroy(&attr); + rc = pthread_join(thread, NULL); + return 0; ++ ++no_pr: ++ pp->mpp->prflag = PRFLAG_UNSET; ++ return 0; + } diff --git a/0004-multipath-tools-Makefile.inc-don-t-take-values-from-.patch b/0004-multipath-tools-Makefile.inc-don-t-take-values-from-.patch deleted file mode 100644 index 5c1b7b3..0000000 --- a/0004-multipath-tools-Makefile.inc-don-t-take-values-from-.patch +++ /dev/null @@ -1,113 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 27 Oct 2022 13:24:34 +0200 -Subject: [PATCH] multipath-tools: Makefile.inc: don't take values from - environment - -Don't use environment variables to initialize LIB, RUN, SYSTEMD, SYSTEMDPATH, -DEVMAPPER_INCDIR, LIBUDEV_INCDIR, and LINUX_HEADERS_INCDIR. Taking -such variables from the environment is generally discouraged -(see https://www.gnu.org/software/make/manual/html_node/Environment.html). - -Overriding variables from the commandline is still possible -(https://www.gnu.org/software/make/manual/html_node/Overriding.html). -So now, when building multipath-tools, rather then running -"RUN=/somedir make", users need to run "make RUN=/somedir". - -This simplifies the Makefile without losing important functionality. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 60 ++++++++++++++++++++++------------------------------ - 1 file changed, 25 insertions(+), 35 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 351358a9..d897ac7a 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -20,59 +20,49 @@ SCSI_DH_MODULES_PRELOAD := - - EXTRAVERSION := $(shell rev=$$(git rev-parse --short=7 HEAD 2>/dev/null); echo $${rev:+-g$$rev}) - -+# PKGCONFIG must be read from the environment to enable compilation -+# in Debian multiarch setups - PKGCONFIG ?= pkg-config - - ifeq ($(TOPDIR),) - TOPDIR = .. - endif - --ifndef LIB -- ifeq ($(shell test -d /lib64 && echo 1),1) -- LIB=lib64 -- else -- LIB=lib -- endif -+ifeq ($(shell test -d /lib64 && echo 1),1) -+ LIB=lib64 -+else -+ LIB=lib - endif - --ifndef RUN -- ifeq ($(shell test -L /var/run -o ! -d /var/run && echo 1),1) -- RUN=run -- else -- RUN=var/run -- endif -+ifeq ($(shell test -L /var/run -o ! -d /var/run && echo 1),1) -+ RUN=run -+else -+ RUN=var/run - endif - --ifndef SYSTEMD -- ifeq ($(shell $(PKGCONFIG) --modversion libsystemd >/dev/null 2>&1 && echo 1), 1) -- SYSTEMD = $(shell $(PKGCONFIG) --modversion libsystemd | awk '{print $$1}') -- else -- ifeq ($(shell systemctl --version >/dev/null 2>&1 && echo 1), 1) -- SYSTEMD = $(shell systemctl --version 2> /dev/null | \ -- sed -n 's/systemd \([0-9]*\).*/\1/p') -- endif -+ifeq ($(shell $(PKGCONFIG) --modversion libsystemd >/dev/null 2>&1 && echo 1), 1) -+ SYSTEMD = $(shell $(PKGCONFIG) --modversion libsystemd | awk '{print $$1}') -+else -+ ifeq ($(shell systemctl --version >/dev/null 2>&1 && echo 1), 1) -+ SYSTEMD = $(shell systemctl --version 2> /dev/null | \ -+ sed -n 's/systemd \([0-9]*\).*/\1/p') - endif - endif - --ifndef DEVMAPPER_INCDIR -- ifeq ($(shell $(PKGCONFIG) --modversion devmapper >/dev/null 2>&1 && echo 1), 1) -- DEVMAPPER_INCDIR = $(shell $(PKGCONFIG) --variable=includedir devmapper) -- else -- DEVMAPPER_INCDIR = /usr/include -- endif -+ifeq ($(shell $(PKGCONFIG) --modversion devmapper >/dev/null 2>&1 && echo 1), 1) -+ DEVMAPPER_INCDIR = $(shell $(PKGCONFIG) --variable=includedir devmapper) -+else -+ DEVMAPPER_INCDIR = /usr/include - endif - --ifndef LIBUDEV_INCDIR -- ifeq ($(shell $(PKGCONFIG) --modversion libudev >/dev/null 2>&1 && echo 1), 1) -- LIBUDEV_INCDIR = $(shell $(PKGCONFIG) --variable=includedir libudev) -- else -- LIBUDEV_INCDIR = /usr/include -- endif -+ifeq ($(shell $(PKGCONFIG) --modversion libudev >/dev/null 2>&1 && echo 1), 1) -+ LIBUDEV_INCDIR = $(shell $(PKGCONFIG) --variable=includedir libudev) -+else -+ LIBUDEV_INCDIR = /usr/include - endif - - # Allow user to override default location. --ifndef LINUX_HEADERS_INCDIR -- LINUX_HEADERS_INCDIR = /usr/include --endif -+LINUX_HEADERS_INCDIR = /usr/include - - # Paths. All these can be overridden on the "make" command line. - prefix = diff --git a/0004-multipathd-add-missing-newline-to-cli_del_map-reply.patch b/0004-multipathd-add-missing-newline-to-cli_del_map-reply.patch new file mode 100644 index 0000000..085fd70 --- /dev/null +++ b/0004-multipathd-add-missing-newline-to-cli_del_map-reply.patch @@ -0,0 +1,24 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 20 Dec 2022 17:41:13 -0600 +Subject: [PATCH] multipathd: add missing newline to cli_del_map reply + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + multipathd/cli_handlers.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c +index ec5db1b8..44bf43df 100644 +--- a/multipathd/cli_handlers.c ++++ b/multipathd/cli_handlers.c +@@ -760,7 +760,7 @@ cli_del_map (void * v, struct strbuf *reply, void * data) + } + rc = ev_remove_map(param, alias, minor, vecs); + if (rc == 2) +- append_strbuf_str(reply, "delayed"); ++ append_strbuf_str(reply, "delayed\n"); + + free(alias); + return rc; diff --git a/0005-libmultipath-skip-extra-vector-work-in-remove_maps.patch b/0005-libmultipath-skip-extra-vector-work-in-remove_maps.patch new file mode 100644 index 0000000..ee08327 --- /dev/null +++ b/0005-libmultipath-skip-extra-vector-work-in-remove_maps.patch @@ -0,0 +1,33 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 20 Dec 2022 17:41:14 -0600 +Subject: [PATCH] libmultipath: skip extra vector work in remove_maps + +Instead of repeatedly removing the first vector element, and shifting +the rest to fill in, call remove_map() without a vector, so it just +frees the devices. The vector will be completely cleaned up by +vector_free() immediately afterwards. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/structs_vec.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c +index 5a618767..f3fdc5a6 100644 +--- a/libmultipath/structs_vec.c ++++ b/libmultipath/structs_vec.c +@@ -392,10 +392,8 @@ remove_maps(struct vectors * vecs) + if (!vecs) + return; + +- vector_foreach_slot (vecs->mpvec, mpp, i) { +- remove_map(mpp, vecs->pathvec, vecs->mpvec); +- i--; +- } ++ vector_foreach_slot (vecs->mpvec, mpp, i) ++ remove_map(mpp, vecs->pathvec, NULL); + + vector_free(vecs->mpvec); + vecs->mpvec = NULL; diff --git a/0005-multipath-tools-Makefile.inc-get-rid-of-RUN.patch b/0005-multipath-tools-Makefile.inc-get-rid-of-RUN.patch deleted file mode 100644 index c0543f5..0000000 --- a/0005-multipath-tools-Makefile.inc-get-rid-of-RUN.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 27 Oct 2022 15:25:31 +0200 -Subject: [PATCH] multipath-tools: Makefile.inc: get rid of RUN - -Just use $(runtimedir). Also, make the code more compact by using -the "if" function instead of a conditional. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 10 ++-------- - libmultipath/defaults.h | 2 +- - 2 files changed, 3 insertions(+), 9 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index d897ac7a..b4ec647c 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -34,12 +34,6 @@ else - LIB=lib - endif - --ifeq ($(shell test -L /var/run -o ! -d /var/run && echo 1),1) -- RUN=run --else -- RUN=var/run --endif -- - ifeq ($(shell $(PKGCONFIG) --modversion libsystemd >/dev/null 2>&1 && echo 1), 1) - SYSTEMD = $(shell $(PKGCONFIG) --modversion libsystemd | awk '{print $$1}') - else -@@ -99,7 +93,7 @@ includedir = $(usr_prefix)/include - pkgconfdir = $(usrlibdir)/pkgconfig - plugindir := $(prefix)/$(LIB)/multipath - configdir := $(prefix)/etc/multipath/conf.d --runtimedir := /$(RUN) -+runtimedir := $(if $(shell test -L /var/run -o ! -d /var/run && echo 1),/run,/var/run) - - GZIP_PROG = gzip -9 -c - RM = rm -f -@@ -143,7 +137,7 @@ WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implici - -Werror=implicit-function-declaration -Werror=format-security \ - $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) - CPPFLAGS := $(FORTIFY_OPT) \ -- -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" -DRUN_DIR=\"${RUN}\" \ -+ -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \ - -DRUNTIME_DIR=\"$(runtimedir)\" \ - -DCONFIG_DIR=\"$(configdir)\" -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP - CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe -diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h -index 3d552b33..a5e9ea0c 100644 ---- a/libmultipath/defaults.h -+++ b/libmultipath/defaults.h -@@ -62,7 +62,7 @@ - - #define DEV_LOSS_TMO_UNSET 0U - #define MAX_DEV_LOSS_TMO UINT_MAX --#define DEFAULT_PIDFILE "/" RUN_DIR "/multipathd.pid" -+#define DEFAULT_PIDFILE RUNTIME_DIR "/multipathd.pid" - #define DEFAULT_SOCKET "/org/kernel/linux/storage/multipathd" - #define DEFAULT_CONFIGFILE "/etc/multipath.conf" - #define DEFAULT_BINDINGS_FILE "/etc/multipath/bindings" diff --git a/0006-libmultipath-orphan-paths-if-coalesce_paths-frees-ne.patch b/0006-libmultipath-orphan-paths-if-coalesce_paths-frees-ne.patch new file mode 100644 index 0000000..f545df7 --- /dev/null +++ b/0006-libmultipath-orphan-paths-if-coalesce_paths-frees-ne.patch @@ -0,0 +1,41 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 20 Dec 2022 17:41:15 -0600 +Subject: [PATCH] libmultipath: orphan paths if coalesce_paths frees newmp + +If coalesce_paths() is called without a mpvec, it will free all the +multipath devices on newmp at the end. This will clear pp->mpp from the +path, but it doesn't completely unitialize them. cli_add_map() can call +coalsce_paths() this way, when adding a device that doesn't currently +exist. cli_add_map() first creates the device in the kernel, and then +calls ev_add_map() to add it to multipathd. If something goes wrong in +ev_add_map(), the paths will still be initialized, even though they're +orphans. + +Fix this by calling remove_map() to orphan the paths that belong to +the multipath devices being deleted by coalesce_paths(). + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/configure.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index e551047a..e689f8a7 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -1273,8 +1273,11 @@ int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid, + ret = CP_OK; + out: + free(size_mismatch_seen); +- if (!mpvec) +- free_multipathvec(newmp, KEEP_PATHS); ++ if (!mpvec) { ++ vector_foreach_slot (newmp, mpp, i) ++ remove_map(mpp, vecs->pathvec, NULL); ++ vector_free(newmp); ++ } + return ret; + } + diff --git a/0006-multipath-tools-Makefile.inc-more-compact-code-for-L.patch b/0006-multipath-tools-Makefile.inc-more-compact-code-for-L.patch deleted file mode 100644 index 2a0eda4..0000000 --- a/0006-multipath-tools-Makefile.inc-more-compact-code-for-L.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 27 Oct 2022 16:14:22 +0200 -Subject: [PATCH] multipath-tools: Makefile.inc: more compact code for LIB - -Use make's "if" function instead of a conditional. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 7 +------ - 1 file changed, 1 insertion(+), 6 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index b4ec647c..c39cec9b 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -28,12 +28,6 @@ ifeq ($(TOPDIR),) - TOPDIR = .. - endif - --ifeq ($(shell test -d /lib64 && echo 1),1) -- LIB=lib64 --else -- LIB=lib --endif -- - ifeq ($(shell $(PKGCONFIG) --modversion libsystemd >/dev/null 2>&1 && echo 1), 1) - SYSTEMD = $(shell $(PKGCONFIG) --modversion libsystemd | awk '{print $$1}') - else -@@ -80,6 +74,7 @@ mpathutildir = $(TOPDIR)/libmpathutil - man8dir = $(usr_prefix)/share/man/man8 - man5dir = $(usr_prefix)/share/man/man5 - man3dir = $(usr_prefix)/share/man/man3 -+LIB := $(if $(shell test -d /lib64 && echo 1),lib64,lib) - syslibdir = $(prefix)/$(LIB) - usrlibdir = $(usr_prefix)/$(LIB) - libdir = $(prefix)/$(LIB)/multipath diff --git a/0007-libmultipath-is_path_valid-check-if-device-is-in-use.patch b/0007-libmultipath-is_path_valid-check-if-device-is-in-use.patch new file mode 100644 index 0000000..6ffa6fc --- /dev/null +++ b/0007-libmultipath-is_path_valid-check-if-device-is-in-use.patch @@ -0,0 +1,609 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 9 Nov 2022 21:20:58 +0100 +Subject: [PATCH] libmultipath: is_path_valid(): check if device is in use + +To check whether we will be able to add a given device can be part +of a multipath map, we have two tests in check_path_valid(): +released_to_systemd() and the O_EXCL test. The former isn't helpful +if "multipath -u" is called for the first time for a given device, +and the latter is only used in the "find_multipaths smart" case, because +actively opening the device with O_EXCL, even for a very short time, is prone +to races with other processes. + +It turns out that this may cause issues in some scenarios. We saw problems in +once case where "find_multipaths greedy" was used with a single +non-multipahted root disk and a very large number of multipath LUNs. +The root disk would first be classified as multipath device. multipathd +would try to create a map, fail (because the disk was mounted) and +trigger another uevent. But because of the very large number of multipath +devices, this event was queued up behind thousands of other events, and +the root device timed out eventually. + +While a simple workaround for the given problem would be proper blacklisting +or using a different find_multipaths mode, I am proposing a different +solution here. An additional test is added in is_path_valid() which +checks whether the given device is currently in use by 1. sysfs holders, +2. mounts (from /proc/self/mountinfo) or 3. swaps (from /proc/swaps). 2. +and 3. are similar to systemd's device detection after switching root. +This must not only be done for the device itself, but also for all its +partitions. For mountinfo and swaps, libmount is utilized. + +With this patch, "multipath -u" will make devices with mounted or otherwise +used partitions available to systemd early, without waiting for multipathd +to fail setting up the map and re-triggering an uevent. This should avoid +the issue described above even without blacklisting. The downside of it +is a longer runtime of "multipath -u" for almost all devices, in particular +for real multipath devices. The runtime required for the new checks was in the +order of 0.1ms-1ms in my tests. Moreover, there is a certain risk that devices may +wrongly classified as non-multipath because of transient mounts or holders +created by other processes. + +To make this code compile on older distributions, we need some additional +checks in create-config.mk. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/build-and-unittest.yaml | 2 +- + create-config.mk | 11 +- + libmpathutil/libmpathutil.version | 6 + + libmpathutil/util.c | 12 + + libmpathutil/util.h | 2 + + libmultipath/Makefile | 2 +- + libmultipath/alias.c | 11 - + libmultipath/valid.c | 270 ++++++++++++++++++++++ + tests/Makefile | 2 +- + tests/valid.c | 48 ++++ + 10 files changed, 351 insertions(+), 15 deletions(-) + +diff --git a/.github/workflows/build-and-unittest.yaml b/.github/workflows/build-and-unittest.yaml +index abf17bf0..9e6c0e89 100644 +--- a/.github/workflows/build-and-unittest.yaml ++++ b/.github/workflows/build-and-unittest.yaml +@@ -31,7 +31,7 @@ jobs: + sudo apt-get install --yes gcc + make perl-base pkg-config valgrind + libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev +- libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev ++ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev libmount-dev + - name: build + run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) READLINE=${{ matrix.rl }} + - name: test +diff --git a/create-config.mk b/create-config.mk +index 2a95ec56..f128375f 100644 +--- a/create-config.mk ++++ b/create-config.mk +@@ -23,7 +23,7 @@ check_cmd = $(shell \ + + # Check whether a function with name $1 has been declared in header file $2. + check_func = $(shell \ +- if grep -Eq "^[^[:blank:]]+[[:blank:]]+$1[[:blank:]]*(.*)*" "$2"; then \ ++ if grep -Eq "^(extern[[:blank:]]+)?[^[:blank:]]+[[:blank:]]+$1[[:blank:]]*(.*)*" "$2"; then \ + found=1; \ + status="yes"; \ + else \ +@@ -104,6 +104,15 @@ ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(kernel_incdir)/scsi/fc/fc_els.h + FPIN_SUPPORT = 1 + endif + ++libmount_h := $(shell $(PKGCONFIG) --variable=includedir mount)/libmount/libmount.h ++ifneq ($(call check_func,mnt_unref_cache,$(libmount_h)),0) ++ DEFINES += LIBMOUNT_HAS_MNT_UNREF_CACHE ++endif ++ ++ifneq ($(call check_func,mnt_table_parse_swaps,$(libmount_h)),0) ++ DEFINES += LIBMOUNT_SUPPORTS_SWAP ++endif ++ + ifneq ($(call check_file,$(kernel_incdir)/linux/nvme_ioctl.h),0) + ANA_SUPPORT := 1 + endif +diff --git a/libmpathutil/libmpathutil.version b/libmpathutil/libmpathutil.version +index 1238fc93..dd007be4 100644 +--- a/libmpathutil/libmpathutil.version ++++ b/libmpathutil/libmpathutil.version +@@ -133,3 +133,9 @@ LIBMPATHUTIL_1.1 { + global: + cleanup_fd_ptr; + } LIBMPATHUTIL_1.0; ++ ++LIBMPATHUTIL_1.2 { ++global: ++ cleanup_vector_free; ++ cleanup_fclose; ++} LIBMPATHUTIL_1.0; +diff --git a/libmpathutil/util.c b/libmpathutil/util.c +index 9662e1ed..92f25a50 100644 +--- a/libmpathutil/util.c ++++ b/libmpathutil/util.c +@@ -386,6 +386,18 @@ void cleanup_mutex(void *arg) + pthread_mutex_unlock(arg); + } + ++void cleanup_vector_free(void *arg) ++{ ++ if (arg) ++ vector_free((vector)arg); ++} ++ ++void cleanup_fclose(void *p) ++{ ++ if (p) ++ fclose(p); ++} ++ + struct bitfield *alloc_bitfield(unsigned int maxbit) + { + unsigned int n; +diff --git a/libmpathutil/util.h b/libmpathutil/util.h +index 75e20fd8..99a471d0 100644 +--- a/libmpathutil/util.h ++++ b/libmpathutil/util.h +@@ -48,6 +48,8 @@ int should_exit(void); + void cleanup_fd_ptr(void *arg); + void cleanup_free_ptr(void *arg); + void cleanup_mutex(void *arg); ++void cleanup_vector_free(void *arg); ++void cleanup_fclose(void *p); + + struct scandir_result { + struct dirent **di; +diff --git a/libmultipath/Makefile b/libmultipath/Makefile +index 3df851e2..61aa611f 100644 +--- a/libmultipath/Makefile ++++ b/libmultipath/Makefile +@@ -7,7 +7,7 @@ DEVLIB := libmultipath.so + CPPFLAGS += -I$(mpathutildir) -I$(mpathcmddir) -I$(nvmedir) -D_GNU_SOURCE $(SYSTEMD_CPPFLAGS) + CFLAGS += $(LIB_CFLAGS) + LIBDEPS += -lpthread -ldl -ldevmapper -ludev -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd \ +- -lurcu -laio $(SYSTEMD_LIBDEPS) ++ -lmount -lurcu -laio $(SYSTEMD_LIBDEPS) + + # object files referencing MULTIPATH_DIR or CONFIG_DIR + # they need to be recompiled for unit tests +diff --git a/libmultipath/alias.c b/libmultipath/alias.c +index 05201224..c0139a2e 100644 +--- a/libmultipath/alias.c ++++ b/libmultipath/alias.c +@@ -667,11 +667,6 @@ static int _check_bindings_file(const struct config *conf, FILE *file, + return rc; + } + +-static void cleanup_fclose(void *p) +-{ +- fclose(p); +-} +- + static int alias_compar(const void *p1, const void *p2) + { + const char *alias1 = (*(struct mpentry * const *)p1)->alias; +@@ -684,12 +679,6 @@ static int alias_compar(const void *p1, const void *p2) + return alias1 ? -1 : alias2 ? 1 : 0; + } + +-static void cleanup_vector_free(void *arg) +-{ +- if (arg) +- vector_free((vector)arg); +-} +- + /* + * check_alias_settings(): test for inconsistent alias configuration + * +diff --git a/libmultipath/valid.c b/libmultipath/valid.c +index a6aa9215..d4dae3ed 100644 +--- a/libmultipath/valid.c ++++ b/libmultipath/valid.c +@@ -17,6 +17,8 @@ + #include + #include + #include ++#include ++#include + + #include "vector.h" + #include "config.h" +@@ -30,12 +32,271 @@ + #include "mpath_cmd.h" + #include "valid.h" + ++static int subdir_filter(const struct dirent *ent) ++{ ++ unsigned int j; ++ static char const *const skip[] = { ++ ".", ++ "..", ++ "holders", ++ "integrity", ++ "mq", ++ "power", ++ "queue", ++ "slaves", ++ "trace", ++ }; ++ ++ if (ent->d_type != DT_DIR) ++ return 0; ++ ++ for (j = 0; j < ARRAY_SIZE(skip); j++) ++ if (!strcmp(skip[j], ent->d_name)) ++ return 0; ++ return 1; ++} ++ ++static int read_partitions(const char *syspath, vector parts) ++{ ++ struct scandir_result sr = { .n = 0 }; ++ char path[PATH_MAX], *last; ++ char *prop; ++ int i; ++ ++ strlcpy(path, syspath, sizeof(path)); ++ sr.n = scandir(path, &sr.di, subdir_filter, NULL); ++ if (sr.n == -1) ++ return -errno; ++ ++ pthread_cleanup_push_cast(free_scandir_result, &sr); ++ ++ /* parts[0] is the whole disk */ ++ if ((prop = strdup(strrchr(path, '/') + 1)) != NULL) { ++ if (vector_alloc_slot(parts)) ++ vector_set_slot(parts, prop); ++ else ++ free(prop); ++ } ++ ++ last = path + strlen(path); ++ for (i = 0; i < sr.n; i++) { ++ struct stat st; ++ ++ /* only add dirs that have the "partition" attribute */ ++ snprintf(last, sizeof(path) - (last - path), "/%s/partition", ++ sr.di[i]->d_name); ++ ++ if (stat(path, &st) == 0 && ++ (prop = strdup(sr.di[i]->d_name)) != NULL) { ++ if (vector_alloc_slot(parts)) ++ vector_set_slot(parts, prop); ++ else ++ free(prop); ++ } ++ } ++ ++ pthread_cleanup_pop(1); ++ return 0; ++} ++ ++static int no_dots(const struct dirent *ent) ++{ ++ const char *name = ent->d_name; ++ ++ if (name[0] == '.' && ++ (name[1] == '\0' || (name[1] == '.' && name[2] == '\0'))) ++ return 0; ++ return 1; ++} ++ ++static int check_holders(const char *syspath) ++{ ++ struct scandir_result __attribute__((cleanup(free_scandir_result))) ++ sr = { .n = 0 }; ++ ++ sr.n = scandir(syspath, &sr.di, no_dots, NULL); ++ if (sr.n > 0) ++ condlog(4, "%s: found holders under %s", __func__, syspath); ++ return sr.n; ++} ++ ++static int check_all_holders(const struct _vector *parts) ++{ ++ char syspath[PATH_MAX]; ++ const char *sysname; ++ unsigned int j; ++ ++ if (VECTOR_SIZE(parts) == 0) ++ return 0; ++ ++ if (safe_sprintf(syspath, "/sys/class/block/%s/holders", ++ (const char *)VECTOR_SLOT(parts, 0))) ++ return -EOVERFLOW; ++ ++ if (check_holders(syspath) > 0) ++ return 1; ++ ++ j = 1; ++ vector_foreach_slot_after(parts, sysname, j) { ++ if (safe_sprintf(syspath, "/sys/class/block/%s/%s/holders", ++ (const char *)VECTOR_SLOT(parts, 0), sysname)) ++ return -EOVERFLOW; ++ if (check_holders(syspath) > 0) ++ return 1; ++ } ++ return 0; ++} ++ ++static void cleanup_table(void *arg) ++{ ++ if (arg) ++ mnt_free_table((struct libmnt_table *)arg); ++} ++ ++static void cleanup_cache(void *arg) ++{ ++ if (arg) ++#ifdef LIBMOUNT_HAS_MNT_UNREF_CACHE ++ mnt_unref_cache((struct libmnt_cache *)arg); ++#else ++ mnt_free_cache((struct libmnt_cache *)arg); ++#endif ++} ++ ++/* ++ * Passed a vector of partitions and a libmount table, ++ * check if any of the partitions in the vector is referenced in the table. ++ * Note that mnt_table_find_srcpath() also resolves mounts by symlinks. ++ */ ++static int check_mnt_table(const struct _vector *parts, ++ struct libmnt_table *tbl, ++ const char *table_name) ++{ ++ unsigned int i; ++ const char *sysname; ++ char devpath[PATH_MAX]; ++ ++ vector_foreach_slot(parts, sysname, i) { ++ if (!safe_sprintf(devpath, "/dev/%s", sysname) && ++ mnt_table_find_srcpath(tbl, devpath, ++ MNT_ITER_FORWARD) != NULL) { ++ condlog(4, "%s: found %s in %s", __func__, ++ sysname, table_name); ++ return 1; ++ } ++ } ++ return 0; ++} ++ ++static int check_mountinfo(const struct _vector *parts) ++{ ++ static const char mountinfo[] = "/proc/self/mountinfo"; ++ struct libmnt_table *tbl; ++ struct libmnt_cache *cache; ++ FILE *stream; ++ int used = 0, ret; ++ ++ tbl = mnt_new_table(); ++ if (!tbl ) ++ return -errno; ++ ++ pthread_cleanup_push(cleanup_table, tbl); ++ cache = mnt_new_cache(); ++ if (cache) { ++ pthread_cleanup_push(cleanup_cache, cache); ++ if (mnt_table_set_cache(tbl, cache) == 0) { ++ stream = fopen(mountinfo, "r"); ++ if (stream != NULL) { ++ pthread_cleanup_push(cleanup_fclose, stream); ++ ret = mnt_table_parse_stream(tbl, stream, mountinfo); ++ pthread_cleanup_pop(1); ++ ++ if (ret == 0) ++ used = check_mnt_table(parts, tbl, ++ "mountinfo"); ++ } ++ } ++ pthread_cleanup_pop(1); ++ } ++ pthread_cleanup_pop(1); ++ return used; ++} ++ ++#ifdef LIBMOUNT_SUPPORTS_SWAP ++static int check_swaps(const struct _vector *parts) ++{ ++ struct libmnt_table *tbl; ++ struct libmnt_cache *cache; ++ int used = 0, ret; ++ ++ tbl = mnt_new_table(); ++ if (!tbl ) ++ return -errno; ++ ++ pthread_cleanup_push(cleanup_table, tbl); ++ cache = mnt_new_cache(); ++ if (cache) { ++ pthread_cleanup_push(cleanup_cache, cache); ++ if (mnt_table_set_cache(tbl, cache) == 0) { ++ ret = mnt_table_parse_swaps(tbl, NULL); ++ if (ret == 0) ++ used = check_mnt_table(parts, tbl, "swaps"); ++ } ++ pthread_cleanup_pop(1); ++ } ++ pthread_cleanup_pop(1); ++ return used; ++} ++#else ++static int check_swaps(const struct _vector *parts __attribute__((unused))) ++{ ++ return 0; ++} ++#endif ++ ++ ++/* ++ * Given a block device, check if the device itself or any of its ++ * partitions is in use ++ * - by sysfs holders (e.g. LVM) ++ * - mounted according to /proc/self/mountinfo ++ * - used as swap ++ */ ++static int is_device_in_use(struct udev_device *udevice) ++{ ++ const char *syspath; ++ vector parts; ++ int used = 0, ret; ++ ++ syspath = udev_device_get_syspath(udevice); ++ if (!syspath) ++ return -ENOMEM; ++ ++ parts = vector_alloc(); ++ if (!parts) ++ return -ENOMEM; ++ ++ pthread_cleanup_push_cast(free_strvec, parts); ++ if ((ret = read_partitions(syspath, parts)) == 0) ++ used = check_all_holders(parts) > 0 || ++ check_mountinfo(parts) > 0 || ++ check_swaps(parts) > 0; ++ pthread_cleanup_pop(1); ++ ++ if (ret < 0) ++ return ret; ++ ++ condlog(3, "%s: %s is %sin use", __func__, syspath, used ? "" : "not "); ++ return used; ++} ++ + int + is_path_valid(const char *name, struct config *conf, struct path *pp, + bool check_multipathd) + { + int r; + int fd; ++ const char *prop; + + if (!pp || !name || !conf) + return PATH_IS_ERROR; +@@ -80,6 +341,10 @@ is_path_valid(const char *name, struct config *conf, struct path *pp, + if (!pp->udev) + return PATH_IS_ERROR; + ++ prop = udev_device_get_property_value(pp->udev, "DEVTYPE"); ++ if (prop == NULL || strcmp(prop, "disk")) ++ return PATH_IS_NOT_VALID; ++ + r = pathinfo(pp, conf, DI_SYSFS | DI_WWID | DI_BLACKLIST); + if (r == PATHINFO_SKIPPED) + return PATH_IS_NOT_VALID; +@@ -96,6 +361,11 @@ is_path_valid(const char *name, struct config *conf, struct path *pp, + return PATH_IS_ERROR; + } + ++ if ((conf->find_multipaths == FIND_MULTIPATHS_GREEDY || ++ conf->find_multipaths == FIND_MULTIPATHS_SMART) && ++ is_device_in_use(pp->udev) > 0) ++ return PATH_IS_NOT_VALID; ++ + if (conf->find_multipaths == FIND_MULTIPATHS_GREEDY) + return PATH_IS_VALID; + +diff --git a/tests/Makefile b/tests/Makefile +index 860338b2..1648ab9d 100644 +--- a/tests/Makefile ++++ b/tests/Makefile +@@ -55,7 +55,7 @@ vpd-test_LIBDEPS := -ludev -lpthread -ldl + alias-test_TESTDEPS := test-log.o + alias-test_LIBDEPS := -lpthread -ldl + valid-test_OBJDEPS := $(multipathdir)/valid.o $(multipathdir)/discovery.o +-valid-test_LIBDEPS := -ludev -lpthread -ldl ++valid-test_LIBDEPS := -lmount -ludev -lpthread -ldl + devt-test_LIBDEPS := -ludev + mpathvalid-test_LIBDEPS := -ludev -lpthread -ldl + mpathvalid-test_OBJDEPS := $(mpathvaliddir)/mpath_valid.o +diff --git a/tests/valid.c b/tests/valid.c +index 398b771e..70329324 100644 +--- a/tests/valid.c ++++ b/tests/valid.c +@@ -83,6 +83,13 @@ struct udev_device *__wrap_udev_device_new_from_subsystem_sysname(struct udev *u + return NULL; + } + ++/* For devtype check */ ++const char *__wrap_udev_device_get_property_value(struct udev_device *udev_device, const char *property) ++{ ++ check_expected(property); ++ return mock_ptr_type(char *); ++} ++ + /* For the "hidden" check in pathinfo() */ + const char *__wrap_udev_device_get_sysattr_value(struct udev_device *udev_device, + const char *sysattr) +@@ -97,6 +104,12 @@ int __wrap_add_foreign(struct udev_device *udev_device) + return mock_type(int); + } + ++/* For is_device_used() */ ++const char *__wrap_udev_device_get_sysname(struct udev_device *udev_device) ++{ ++ return mock_ptr_type(char *); ++} ++ + /* called from pathinfo() */ + int __wrap_filter_devnode(struct config *conf, const struct _vector *elist, + const char *vendor, const char * product, const char *dev) +@@ -165,6 +178,11 @@ int __wrap_is_failed_wwid(const char *wwid) + return ret; + } + ++const char *__wrap_udev_device_get_syspath(struct udev_device *udevice) ++{ ++ return mock_ptr_type(char *); ++} ++ + int __wrap_check_wwids_file(char *wwid, int write_wwid) + { + bool passed = mock_type(bool); +@@ -225,6 +243,8 @@ static void setup_passing(char *name, char *wwid, unsigned int check_multipathd, + will_return(__wrap_udev_device_new_from_subsystem_sysname, true); + will_return(__wrap_udev_device_new_from_subsystem_sysname, + name); ++ expect_string(__wrap_udev_device_get_property_value, property, "DEVTYPE"); ++ will_return(__wrap_udev_device_get_property_value, "disk"); + if (stage == STAGE_GET_UDEV_DEVICE) + return; + if (stage == STAGE_PATHINFO_REAL) { +@@ -250,6 +270,10 @@ static void setup_passing(char *name, char *wwid, unsigned int check_multipathd, + return; + will_return(__wrap_is_failed_wwid, WWID_IS_NOT_FAILED); + will_return(__wrap_is_failed_wwid, wwid); ++ /* avoid real is_device_in_use() check */ ++ if (conf.find_multipaths == FIND_MULTIPATHS_GREEDY || ++ conf.find_multipaths == FIND_MULTIPATHS_SMART) ++ will_return(__wrap_udev_device_get_syspath, NULL); + if (stage == STAGE_IS_FAILED) + return; + will_return(__wrap_check_wwids_file, false); +@@ -347,6 +371,30 @@ static void test_check_multipathd(void **state) + assert_int_equal(is_path_valid(name, &conf, &pp, true), + PATH_IS_ERROR); + assert_string_equal(pp.dev, name); ++ ++ /* test pass because connect succeeded. succeed getting udev. Wrong DEVTYPE */ ++ memset(&pp, 0, sizeof(pp)); ++ setup_passing(name, NULL, CHECK_MPATHD_RUNNING, STAGE_CHECK_MULTIPATHD); ++ will_return(__wrap_udev_device_new_from_subsystem_sysname, true); ++ will_return(__wrap_udev_device_new_from_subsystem_sysname, ++ name); ++ expect_string(__wrap_udev_device_get_property_value, property, "DEVTYPE"); ++ will_return(__wrap_udev_device_get_property_value, "partition"); ++ assert_int_equal(is_path_valid(name, &conf, &pp, true), ++ PATH_IS_NOT_VALID); ++ assert_string_equal(pp.dev, name); ++ ++ /* test pass because connect succeeded. succeed getting udev. Bad DEVTYPE */ ++ memset(&pp, 0, sizeof(pp)); ++ setup_passing(name, NULL, CHECK_MPATHD_RUNNING, STAGE_CHECK_MULTIPATHD); ++ will_return(__wrap_udev_device_new_from_subsystem_sysname, true); ++ will_return(__wrap_udev_device_new_from_subsystem_sysname, ++ name); ++ expect_string(__wrap_udev_device_get_property_value, property, "DEVTYPE"); ++ will_return(__wrap_udev_device_get_property_value, NULL); ++ assert_int_equal(is_path_valid(name, &conf, &pp, true), ++ PATH_IS_NOT_VALID); ++ assert_string_equal(pp.dev, name); + } + + static void test_pathinfo(void **state) diff --git a/0007-multipath-tools-Makefiles-simplify-code-for-include-.patch b/0007-multipath-tools-Makefiles-simplify-code-for-include-.patch deleted file mode 100644 index c6be343..0000000 --- a/0007-multipath-tools-Makefiles-simplify-code-for-include-.patch +++ /dev/null @@ -1,139 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 27 Oct 2022 16:17:40 +0200 -Subject: [PATCH] multipath-tools: Makefiles: simplify code for include dirs - -Use make's if function, and use lower-case latters for make variable -names that represent directories, such as elsewhere. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 16 +++------------- - kpartx/Makefile | 2 +- - libmultipath/Makefile | 14 +++++++------- - libmultipath/prioritizers/Makefile | 2 +- - multipathd/Makefile | 4 ++-- - 5 files changed, 14 insertions(+), 24 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index c39cec9b..38bd1d80 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -37,20 +37,7 @@ else - endif - endif - --ifeq ($(shell $(PKGCONFIG) --modversion devmapper >/dev/null 2>&1 && echo 1), 1) -- DEVMAPPER_INCDIR = $(shell $(PKGCONFIG) --variable=includedir devmapper) --else -- DEVMAPPER_INCDIR = /usr/include --endif -- --ifeq ($(shell $(PKGCONFIG) --modversion libudev >/dev/null 2>&1 && echo 1), 1) -- LIBUDEV_INCDIR = $(shell $(PKGCONFIG) --variable=includedir libudev) --else -- LIBUDEV_INCDIR = /usr/include --endif -- - # Allow user to override default location. --LINUX_HEADERS_INCDIR = /usr/include - - # Paths. All these can be overridden on the "make" command line. - prefix = -@@ -89,6 +76,9 @@ pkgconfdir = $(usrlibdir)/pkgconfig - plugindir := $(prefix)/$(LIB)/multipath - configdir := $(prefix)/etc/multipath/conf.d - runtimedir := $(if $(shell test -L /var/run -o ! -d /var/run && echo 1),/run,/var/run) -+devmapper_incdir := $(or $(shell $(PKGCONFIG) --variable=includedir devmapper),/usr/include) -+libudev_incdir := $(or $(shell $(PKGCONFIG) --variable=includedir libudev),/usr/include) -+kernel_incdir := /usr/include - - GZIP_PROG = gzip -9 -c - RM = rm -f -diff --git a/kpartx/Makefile b/kpartx/Makefile -index 742d3bcd..bdf2d035 100644 ---- a/kpartx/Makefile -+++ b/kpartx/Makefile -@@ -9,7 +9,7 @@ LDFLAGS += $(BIN_LDFLAGS) - - LIBDEPS += -ldevmapper - --ifneq ($(call check_func,dm_task_set_cookie,$(DEVMAPPER_INCDIR)/libdevmapper.h),0) -+ifneq ($(call check_func,dm_task_set_cookie,$(devmapper_incdir)/libdevmapper.h),0) - CPPFLAGS += -DLIBDM_API_COOKIE - endif - -diff --git a/libmultipath/Makefile b/libmultipath/Makefile -index 3b60a525..f0df27c0 100644 ---- a/libmultipath/Makefile -+++ b/libmultipath/Makefile -@@ -22,31 +22,31 @@ ifdef SYSTEMD - endif - endif - --ifneq ($(call check_func,dm_task_no_flush,$(DEVMAPPER_INCDIR)/libdevmapper.h),0) -+ifneq ($(call check_func,dm_task_no_flush,$(devmapper_incdir)/libdevmapper.h),0) - CPPFLAGS += -DLIBDM_API_FLUSH - endif - --ifneq ($(call check_func,dm_task_get_errno,$(DEVMAPPER_INCDIR)/libdevmapper.h),0) -+ifneq ($(call check_func,dm_task_get_errno,$(devmapper_incdir)/libdevmapper.h),0) - CPPFLAGS += -DLIBDM_API_GET_ERRNO - endif - --ifneq ($(call check_func,dm_task_set_cookie,$(DEVMAPPER_INCDIR)/libdevmapper.h),0) -+ifneq ($(call check_func,dm_task_set_cookie,$(devmapper_incdir)/libdevmapper.h),0) - CPPFLAGS += -DLIBDM_API_COOKIE - endif - --ifneq ($(call check_func,udev_monitor_set_receive_buffer_size,$(LIBUDEV_INCDIR)/libudev.h),0) -+ifneq ($(call check_func,udev_monitor_set_receive_buffer_size,$(libudev_incdir)/libudev.h),0) - CPPFLAGS += -DLIBUDEV_API_RECVBUF - endif - --ifneq ($(call check_func,dm_task_deferred_remove,$(DEVMAPPER_INCDIR)/libdevmapper.h),0) -+ifneq ($(call check_func,dm_task_deferred_remove,$(devmapper_incdir)/libdevmapper.h),0) - CPPFLAGS += -DLIBDM_API_DEFERRED - endif - --ifneq ($(call check_func,dm_hold_control_dev,$(DEVMAPPER_INCDIR)/libdevmapper.h),0) -+ifneq ($(call check_func,dm_hold_control_dev,$(devmapper_incdir)/libdevmapper.h),0) - CPPFLAGS += -DLIBDM_API_HOLD_CONTROL - endif - --ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(LINUX_HEADERS_INCDIR)/scsi/fc/fc_els.h),0) -+ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(kernel_incdir)/scsi/fc/fc_els.h),0) - CPPFLAGS += -DFPIN_EVENT_HANDLER - endif - -diff --git a/libmultipath/prioritizers/Makefile b/libmultipath/prioritizers/Makefile -index 400f7735..97155f51 100644 ---- a/libmultipath/prioritizers/Makefile -+++ b/libmultipath/prioritizers/Makefile -@@ -26,7 +26,7 @@ LIBS = \ - libpriopath_latency.so \ - libpriosysfs.so - --ifneq ($(call check_file,$(LINUX_HEADERS_INCDIR)/linux/nvme_ioctl.h),0) -+ifneq ($(call check_file,$(kernel_incdir)/linux/nvme_ioctl.h),0) - LIBS += libprioana.so - CPPFLAGS += -I../nvme - endif -diff --git a/multipathd/Makefile b/multipathd/Makefile -index 3ce9465e..c462d7b1 100644 ---- a/multipathd/Makefile -+++ b/multipathd/Makefile -@@ -1,10 +1,10 @@ - include ../Makefile.inc - --ifneq ($(call check_func,dm_task_get_errno,$(DEVMAPPER_INCDIR)/libdevmapper.h),0) -+ifneq ($(call check_func,dm_task_get_errno,$(devmapper_incdir)/libdevmapper.h),0) - CPPFLAGS += -DLIBDM_API_GET_ERRNO - endif - --ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(LINUX_HEADERS_INCDIR)/scsi/fc/fc_els.h),0) -+ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(kernel_incdir)/scsi/fc/fc_els.h),0) - CPPFLAGS += -DFPIN_EVENT_HANDLER - FPIN_SUPPORT = 1 - endif diff --git a/0008-libmpathpersist-use-conf-timeout-for-updating-persis.patch b/0008-libmpathpersist-use-conf-timeout-for-updating-persis.patch new file mode 100644 index 0000000..9f3dcb2 --- /dev/null +++ b/0008-libmpathpersist-use-conf-timeout-for-updating-persis.patch @@ -0,0 +1,55 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 2 Jan 2023 12:39:36 +0100 +Subject: [PATCH] libmpathpersist: use conf->timeout for updating persistent + reservations + +On systems with many LUNs, multipathd may fail to respond within the +default timeout to a "setprkey" command because the vecs lock is held +by the path checker. Honor the globally configured uxsock timeout in +libmpathpersist. + +Reported-by: boposki (github.com/opensvc/multipath-tools/pull/58) +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmpathpersist/mpath_updatepr.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/libmpathpersist/mpath_updatepr.c b/libmpathpersist/mpath_updatepr.c +index 4529a82b..36bd777e 100644 +--- a/libmpathpersist/mpath_updatepr.c ++++ b/libmpathpersist/mpath_updatepr.c +@@ -14,6 +14,9 @@ + #include + #include "debug.h" + #include "mpath_cmd.h" ++#include "vector.h" ++#include "globals.h" ++#include "config.h" + #include "uxsock.h" + #include "mpathpr.h" + +@@ -24,6 +27,12 @@ static int do_update_pr(char *alias, char *cmd, char *key) + char str[256]; + char *reply; + int ret = 0; ++ int timeout; ++ struct config *conf; ++ ++ conf = get_multipath_config(); ++ timeout = conf->uxsock_timeout; ++ put_multipath_config(conf); + + fd = mpath_connect(); + if (fd == -1) { +@@ -41,7 +50,7 @@ static int do_update_pr(char *alias, char *cmd, char *key) + mpath_disconnect(fd); + return -1; + } +- ret = recv_packet(fd, &reply, DEFAULT_REPLY_TIMEOUT); ++ ret = recv_packet(fd, &reply, timeout); + if (ret < 0) { + condlog(2, "%s: message=%s recv error=%d", alias, str, errno); + ret = -1; diff --git a/0008-multipath-tools-Makefiles-use-mandir.patch b/0008-multipath-tools-Makefiles-use-mandir.patch deleted file mode 100644 index 10e1ca8..0000000 --- a/0008-multipath-tools-Makefiles-use-mandir.patch +++ /dev/null @@ -1,185 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 27 Oct 2022 16:25:04 +0200 -Subject: [PATCH] multipath-tools: Makefiles: use $(mandir) - -Simply use $(mandir) rather than 3 different variables. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 4 +--- - kpartx/Makefile | 6 +++--- - libdmmp/Makefile | 8 ++++---- - libmpathpersist/Makefile | 10 +++++----- - mpathpersist/Makefile | 6 +++--- - multipath/Makefile | 12 ++++++------ - multipathd/Makefile | 10 +++++----- - 7 files changed, 27 insertions(+), 29 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 38bd1d80..f3c84771 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -58,9 +58,7 @@ bindir = $(exec_prefix)/sbin - multipathdir = $(TOPDIR)/libmultipath - daemondir = $(TOPDIR)/multipathd - mpathutildir = $(TOPDIR)/libmpathutil --man8dir = $(usr_prefix)/share/man/man8 --man5dir = $(usr_prefix)/share/man/man5 --man3dir = $(usr_prefix)/share/man/man3 -+mandir := $(usr_prefix)/share/man - LIB := $(if $(shell test -d /lib64 && echo 1),lib64,lib) - syslibdir = $(prefix)/$(LIB) - usrlibdir = $(usr_prefix)/$(LIB) -diff --git a/kpartx/Makefile b/kpartx/Makefile -index bdf2d035..464925ad 100644 ---- a/kpartx/Makefile -+++ b/kpartx/Makefile -@@ -32,12 +32,12 @@ install: $(EXEC) $(EXEC).8 - $(INSTALL_PROGRAM) -m 644 dm-parts.rules $(DESTDIR)$(libudevdir)/rules.d/11-dm-parts.rules - $(INSTALL_PROGRAM) -m 644 kpartx.rules $(DESTDIR)$(libudevdir)/rules.d/66-kpartx.rules - $(INSTALL_PROGRAM) -m 644 del-part-nodes.rules $(DESTDIR)$(libudevdir)/rules.d/68-del-part-nodes.rules -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(man8dir) -- $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(man8dir) -+ $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 -+ $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 - - uninstall: - $(RM) $(DESTDIR)$(bindir)/$(EXEC) -- $(RM) $(DESTDIR)$(man8dir)/$(EXEC).8 -+ $(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 - $(RM) $(DESTDIR)$(libudevdir)/kpartx_id - $(RM) $(DESTDIR)$(libudevdir)/rules.d/11-dm-parts.rules - $(RM) $(DESTDIR)$(libudevdir)/rules.d/66-kpartx.rules -diff --git a/libdmmp/Makefile b/libdmmp/Makefile -index e4589250..985b694b 100644 ---- a/libdmmp/Makefile -+++ b/libdmmp/Makefile -@@ -45,17 +45,17 @@ install: - $(DESTDIR)$(pkgconfdir)/$(PKGFILE) - perl -i -pe 's|__INCLUDEDIR__|$(includedir)|g' \ - $(DESTDIR)$(pkgconfdir)/$(PKGFILE) -- $(INSTALL_PROGRAM) -d 755 $(DESTDIR)$(man3dir) -- $(INSTALL_PROGRAM) -m 644 -t $(DESTDIR)$(man3dir) docs/man/*.3 -+ $(INSTALL_PROGRAM) -d 755 $(DESTDIR)$(mandir)/man3 -+ $(INSTALL_PROGRAM) -m 644 -t $(DESTDIR)$(mandir)/man3 docs/man/*.3 - - uninstall: - $(RM) $(DESTDIR)$(usrlibdir)/$(LIBS) - $(RM) $(DESTDIR)$(includedir)/$(HEADERS) - $(RM) $(DESTDIR)$(usrlibdir)/$(DEVLIB) -- @for file in $(DESTDIR)$(man3dir)/dmmp_*; do \ -+ @for file in $(DESTDIR)$(mandir)/man3/dmmp_*; do \ - $(RM) $$file; \ - done -- $(RM) $(DESTDIR)$(man3dir)/libdmmp.h* -+ $(RM) $(DESTDIR)$(mandir)/man3/libdmmp.h* - $(RM) $(DESTDIR)$(pkgconfdir)/$(PKGFILE) - - clean: dep_clean -diff --git a/libmpathpersist/Makefile b/libmpathpersist/Makefile -index 4e1717ef..479524d4 100644 ---- a/libmpathpersist/Makefile -+++ b/libmpathpersist/Makefile -@@ -36,17 +36,17 @@ install: all - $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) - $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) - $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(syslibdir) -- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(man3dir) -+ $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(mandir)/man3 - $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(includedir) - $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) -- $(INSTALL_PROGRAM) -m 644 mpath_persistent_reserve_in.3 $(DESTDIR)$(man3dir) -- $(INSTALL_PROGRAM) -m 644 mpath_persistent_reserve_out.3 $(DESTDIR)$(man3dir) -+ $(INSTALL_PROGRAM) -m 644 mpath_persistent_reserve_in.3 $(DESTDIR)$(mandir)/man3 -+ $(INSTALL_PROGRAM) -m 644 mpath_persistent_reserve_out.3 $(DESTDIR)$(mandir)/man3 - $(INSTALL_PROGRAM) -m 644 mpath_persist.h $(DESTDIR)$(includedir) - - uninstall: - $(RM) $(DESTDIR)$(syslibdir)/$(LIBS) -- $(RM) $(DESTDIR)$(man3dir)/mpath_persistent_reserve_in.3 -- $(RM) $(DESTDIR)$(man3dir)/mpath_persistent_reserve_out.3 -+ $(RM) $(DESTDIR)$(mandir)/man3/mpath_persistent_reserve_in.3 -+ $(RM) $(DESTDIR)$(mandir)/man3/mpath_persistent_reserve_out.3 - $(RM) $(DESTDIR)$(includedir)/mpath_persist.h - $(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) - -diff --git a/mpathpersist/Makefile b/mpathpersist/Makefile -index 2219c86a..d62537b5 100644 ---- a/mpathpersist/Makefile -+++ b/mpathpersist/Makefile -@@ -19,8 +19,8 @@ $(EXEC): $(OBJS) - install: - $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) - $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(man8dir) -- $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(man8dir) -+ $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 -+ $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 - - clean: dep_clean - $(RM) core *.o $(EXEC) -@@ -29,7 +29,7 @@ include $(wildcard $(OBJS:.o=.d)) - - uninstall: - $(RM) $(DESTDIR)$(bindir)/$(EXEC) -- $(RM) $(DESTDIR)$(man8dir)/$(EXEC).8 -+ $(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 - - dep_clean: - $(RM) $(OBJS:.o=.d) -diff --git a/multipath/Makefile b/multipath/Makefile -index 116348e2..1c4e7a52 100644 ---- a/multipath/Makefile -+++ b/multipath/Makefile -@@ -28,10 +28,10 @@ install: - $(INSTALL_PROGRAM) -m 644 modules-load.conf $(DESTDIR)$(modulesloaddir)/multipath.conf - $(INSTALL_PROGRAM) -d $(DESTDIR)$(tmpfilesdir) - $(INSTALL_PROGRAM) -m 644 tmpfiles.conf $(DESTDIR)$(tmpfilesdir)/multipath.conf -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(man8dir) -- $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(man8dir) -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(man5dir) -- $(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5 $(DESTDIR)$(man5dir) -+ $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 -+ $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 -+ $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man5 -+ $(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5 $(DESTDIR)$(mandir)/man5 - ifneq ($(SCSI_DH_MODULES_PRELOAD),) - $(INSTALL_PROGRAM) -m 644 scsi_dh.conf $(DESTDIR)$(modulesloaddir)/scsi_dh.conf - for _x in $(SCSI_DH_MODULES_PRELOAD); do echo "$$_x"; done \ -@@ -44,8 +44,8 @@ uninstall: - $(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf - $(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf - $(RM) $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules -- $(RM) $(DESTDIR)$(man8dir)/$(EXEC).8 -- $(RM) $(DESTDIR)$(man5dir)/$(EXEC).conf.5 -+ $(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 -+ $(RM) $(DESTDIR)$(mandir)/man5/$(EXEC).conf.5 - - clean: dep_clean - $(RM) core *.o $(EXEC) multipath.rules tmpfiles.conf -diff --git a/multipathd/Makefile b/multipathd/Makefile -index c462d7b1..78aefee0 100644 ---- a/multipathd/Makefile -+++ b/multipathd/Makefile -@@ -89,14 +89,14 @@ ifdef SYSTEMD - $(INSTALL_PROGRAM) -m 644 $(EXEC).service $(DESTDIR)$(unitdir) - $(INSTALL_PROGRAM) -m 644 $(EXEC).socket $(DESTDIR)$(unitdir) - endif -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(man8dir) -- $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(man8dir) -- $(INSTALL_PROGRAM) -m 644 $(CLI).8 $(DESTDIR)$(man8dir) -+ $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 -+ $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 -+ $(INSTALL_PROGRAM) -m 644 $(CLI).8 $(DESTDIR)$(mandir)/man8 - - uninstall: - $(RM) $(DESTDIR)$(bindir)/$(EXEC) $(DESTDIR)$(bindir)/$(CLI) -- $(RM) $(DESTDIR)$(man8dir)/$(EXEC).8 -- $(RM) $(DESTDIR)$(man8dir)/$(CLI).8 -+ $(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 -+ $(RM) $(DESTDIR)$(mandir)/man8/$(CLI).8 - $(RM) $(DESTDIR)$(unitdir)/$(EXEC).service - $(RM) $(DESTDIR)$(unitdir)/$(EXEC).socket - diff --git a/0009-libmultipath-pathinfo-don-t-fail-for-devices-lacking.patch b/0009-libmultipath-pathinfo-don-t-fail-for-devices-lacking.patch new file mode 100644 index 0000000..fe7f001 --- /dev/null +++ b/0009-libmultipath-pathinfo-don-t-fail-for-devices-lacking.patch @@ -0,0 +1,77 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 30 Nov 2022 21:07:45 +0100 +Subject: [PATCH] libmultipath: pathinfo: don't fail for devices lacking + INQUIRY properties +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Some SAS devices (e.g. Seagate factory recertified 'white label' drives) may +come with the Vendor field blank. This causes Multipath to fail to +complete the discovery of those devices. + +Such devices violate the SCSI Spec. From the SPC-6, §6.7.2: +"The T10 VENDOR IDENTIFICATION field contains eight bytes of left-aligned +ASCII data (see 4.3.1) identifying the manufacturer of the logical unit. The +T10 vendor identification shall be one assigned by INCITS.". + +But as we don't identify WWIDs by vendor and product, we don't need to discard +these devices right away. We can go ahead fingers crossed, and hope that the +the other VPD pages for the device are correct. + +We obviously can't look up reasonable device properties for such devices in +our hwtable. It would be up to the user to deal with that. + +Reported by: Allyn Malventano (github.com/opensvc/multipath-tools/issues/56) +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/discovery.c | 22 +++++++++++++--------- + 1 file changed, 13 insertions(+), 9 deletions(-) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index d9ee2cb9..67ac0e6d 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -1472,6 +1472,7 @@ scsi_sysfs_pathinfo (struct path *pp, const struct _vector *hwtable) + { + struct udev_device *parent; + const char *attr_path = NULL; ++ static const char unknown[] = "UNKNOWN"; + + parent = pp->udev; + while (parent) { +@@ -1492,19 +1493,22 @@ scsi_sysfs_pathinfo (struct path *pp, const struct _vector *hwtable) + if (!attr_path || pp->sg_id.host_no == -1) + return PATHINFO_FAILED; + +- if (sysfs_get_vendor(parent, pp->vendor_id, SCSI_VENDOR_SIZE) <= 0) +- return PATHINFO_FAILED;; +- ++ if (sysfs_get_vendor(parent, pp->vendor_id, SCSI_VENDOR_SIZE) <= 0) { ++ condlog(1, "%s: broken device without vendor ID", pp->dev); ++ strlcpy(pp->vendor_id, unknown, SCSI_VENDOR_SIZE); ++ } + condlog(3, "%s: vendor = %s", pp->dev, pp->vendor_id); + +- if (sysfs_get_model(parent, pp->product_id, PATH_PRODUCT_SIZE) <= 0) +- return PATHINFO_FAILED;; +- ++ if (sysfs_get_model(parent, pp->product_id, PATH_PRODUCT_SIZE) <= 0) { ++ condlog(1, "%s: broken device without product ID", pp->dev); ++ strlcpy(pp->product_id, unknown, PATH_PRODUCT_SIZE); ++ } + condlog(3, "%s: product = %s", pp->dev, pp->product_id); + +- if (sysfs_get_rev(parent, pp->rev, PATH_REV_SIZE) < 0) +- return PATHINFO_FAILED;; +- ++ if (sysfs_get_rev(parent, pp->rev, PATH_REV_SIZE) < 0) { ++ condlog(2, "%s: broken device without revision", pp->dev); ++ strlcpy(pp->rev, unknown, PATH_REV_SIZE); ++ } + condlog(3, "%s: rev = %s", pp->dev, pp->rev); + + /* diff --git a/0009-multipath-tools-Makefile.inc-simplify-expression-for.patch b/0009-multipath-tools-Makefile.inc-simplify-expression-for.patch deleted file mode 100644 index 9b0dbc5..0000000 --- a/0009-multipath-tools-Makefile.inc-simplify-expression-for.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 27 Oct 2022 16:34:34 +0200 -Subject: [PATCH] multipath-tools: Makefile.inc: simplify expression for - SYSTEMD - -Use a shell "or" function here. Note the use of "strip" to remove -the whitespace that are caused by the line break. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 10 ++-------- - 1 file changed, 2 insertions(+), 8 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index f3c84771..1a08b8fa 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -28,14 +28,8 @@ ifeq ($(TOPDIR),) - TOPDIR = .. - endif - --ifeq ($(shell $(PKGCONFIG) --modversion libsystemd >/dev/null 2>&1 && echo 1), 1) -- SYSTEMD = $(shell $(PKGCONFIG) --modversion libsystemd | awk '{print $$1}') --else -- ifeq ($(shell systemctl --version >/dev/null 2>&1 && echo 1), 1) -- SYSTEMD = $(shell systemctl --version 2> /dev/null | \ -- sed -n 's/systemd \([0-9]*\).*/\1/p') -- endif --endif -+SYSTEMD := $(strip $(or $(shell $(PKGCONFIG) --modversion libsystemd 2>/dev/null | awk '{print $$1}'), \ -+ $(shell systemctl --version 2>/dev/null | sed -n 's/systemd \([0-9]*\).*/\1/p'))) - - # Allow user to override default location. - diff --git a/0010-libmultipath-bump-ABI-version-to-18.0.0.patch b/0010-libmultipath-bump-ABI-version-to-18.0.0.patch new file mode 100644 index 0000000..0d9a3c1 --- /dev/null +++ b/0010-libmultipath-bump-ABI-version-to-18.0.0.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 25 Jan 2023 11:35:38 +0100 +Subject: [PATCH] libmultipath: bump ABI version to 18.0.0 + +Commit 6b81153 ("libmultipath: make prflag an enum") changed +the size and member offsets of struct multipath. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/libmultipath.version | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version +index faef2a2d..015623cc 100644 +--- a/libmultipath/libmultipath.version ++++ b/libmultipath/libmultipath.version +@@ -43,7 +43,7 @@ LIBMPATHCOMMON_1.0.0 { + put_multipath_config; + }; + +-LIBMULTIPATH_17.0.0 { ++LIBMULTIPATH_18.0.0 { + global: + /* symbols referenced by multipath and multipathd */ + add_foreign; diff --git a/0010-multipath-tools-Makefile.inc-untangle-paths-and-sour.patch b/0010-multipath-tools-Makefile.inc-untangle-paths-and-sour.patch deleted file mode 100644 index 8591ac4..0000000 --- a/0010-multipath-tools-Makefile.inc-untangle-paths-and-sour.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 27 Oct 2022 16:53:04 +0200 -Subject: [PATCH] multipath-tools: Makefile.inc: untangle paths and source - directories - -Only the installation paths can be customized. Move the definitions -of $(multipathdir) etc. further down. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 23 ++++++++++++----------- - 1 file changed, 12 insertions(+), 11 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 1a08b8fa..6ec8201b 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -31,8 +31,6 @@ endif - SYSTEMD := $(strip $(or $(shell $(PKGCONFIG) --modversion libsystemd 2>/dev/null | awk '{print $$1}'), \ - $(shell systemctl --version 2>/dev/null | sed -n 's/systemd \([0-9]*\).*/\1/p'))) - --# Allow user to override default location. -- - # Paths. All these can be overridden on the "make" command line. - prefix = - # Prefix for binaries -@@ -49,20 +47,11 @@ modulesloaddir := $(systemd_prefix)/lib/modules-load.d - libudevdir := $(systemd_prefix)/lib/udev - udevrulesdir := $(libudevdir)/rules.d - bindir = $(exec_prefix)/sbin --multipathdir = $(TOPDIR)/libmultipath --daemondir = $(TOPDIR)/multipathd --mpathutildir = $(TOPDIR)/libmpathutil - mandir := $(usr_prefix)/share/man - LIB := $(if $(shell test -d /lib64 && echo 1),lib64,lib) - syslibdir = $(prefix)/$(LIB) - usrlibdir = $(usr_prefix)/$(LIB) - libdir = $(prefix)/$(LIB)/multipath --mpathpersistdir = $(TOPDIR)/libmpathpersist --mpathcmddir = $(TOPDIR)/libmpathcmd --mpathvaliddir = $(TOPDIR)/libmpathvalid --thirdpartydir = $(TOPDIR)/third-party --libdmmpdir = $(TOPDIR)/libdmmp --nvmedir = $(TOPDIR)/libmultipath/nvme - includedir = $(usr_prefix)/include - pkgconfdir = $(usrlibdir)/pkgconfig - plugindir := $(prefix)/$(LIB)/multipath -@@ -124,6 +113,18 @@ SHARED_FLAGS = -shared - LDFLAGS := $(LDFLAGS) -Wl,-z,relro -Wl,-z,now -Wl,-z,defs - BIN_LDFLAGS = -pie - -+# Source code directories. Don't modify. -+ -+multipathdir = $(TOPDIR)/libmultipath -+daemondir = $(TOPDIR)/multipathd -+mpathutildir = $(TOPDIR)/libmpathutil -+mpathpersistdir = $(TOPDIR)/libmpathpersist -+mpathcmddir = $(TOPDIR)/libmpathcmd -+mpathvaliddir = $(TOPDIR)/libmpathvalid -+thirdpartydir = $(TOPDIR)/third-party -+libdmmpdir = $(TOPDIR)/libdmmp -+nvmedir = $(TOPDIR)/libmultipath/nvme -+ - # Check whether a function with name $1 has been declared in header file $2. - check_func = $(shell \ - if grep -Eq "^[^[:blank:]]+[[:blank:]]+$1[[:blank:]]*(.*)*" "$2"; then \ diff --git a/0033-RH-fixup-udev-rules-for-redhat.patch b/0011-RH-fixup-udev-rules-for-redhat.patch similarity index 98% rename from 0033-RH-fixup-udev-rules-for-redhat.patch rename to 0011-RH-fixup-udev-rules-for-redhat.patch index f0fc0d2..618603c 100644 --- a/0033-RH-fixup-udev-rules-for-redhat.patch +++ b/0011-RH-fixup-udev-rules-for-redhat.patch @@ -15,7 +15,7 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 866ab274..8c5a08a2 100644 +index 2e25d2ea..540e1dfc 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -34,9 +34,9 @@ endif diff --git a/0011-multipath-tools-Makefiles-replace-libdir-by-plugindi.patch b/0011-multipath-tools-Makefiles-replace-libdir-by-plugindi.patch deleted file mode 100644 index 82c63d1..0000000 --- a/0011-multipath-tools-Makefiles-replace-libdir-by-plugindi.patch +++ /dev/null @@ -1,110 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 27 Oct 2022 17:17:00 +0200 -Subject: [PATCH] multipath-tools: Makefiles: replace $(libdir) by $(plugindir) - -The make variables $(libdir) and $(plugindir) are redundant. -I overlooked that in af15832 ("multipath-tools: make multipath_dir a -compiled-in option"). While libdir has existed longer, I think -plugindir describes better what this path is used for, so replace -libdir by plugindir. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 1 - - libmpathutil/Makefile | 1 - - libmultipath/Makefile | 2 +- - libmultipath/checkers/Makefile | 4 ++-- - libmultipath/foreign/Makefile | 4 ++-- - libmultipath/prioritizers/Makefile | 4 ++-- - 6 files changed, 7 insertions(+), 9 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 6ec8201b..17707a3e 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -51,7 +51,6 @@ mandir := $(usr_prefix)/share/man - LIB := $(if $(shell test -d /lib64 && echo 1),lib64,lib) - syslibdir = $(prefix)/$(LIB) - usrlibdir = $(usr_prefix)/$(LIB) --libdir = $(prefix)/$(LIB)/multipath - includedir = $(usr_prefix)/include - pkgconfdir = $(usrlibdir)/pkgconfig - plugindir := $(prefix)/$(LIB)/multipath -diff --git a/libmpathutil/Makefile b/libmpathutil/Makefile -index 68b1c7d6..c913c761 100644 ---- a/libmpathutil/Makefile -+++ b/libmpathutil/Makefile -@@ -54,7 +54,6 @@ abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) - install: all - $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) - $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) -- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(libdir) - $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) - - uninstall: -diff --git a/libmultipath/Makefile b/libmultipath/Makefile -index f0df27c0..c7d4fc99 100644 ---- a/libmultipath/Makefile -+++ b/libmultipath/Makefile -@@ -119,7 +119,7 @@ test-lib: ../tests/$(LIBS) - install: all - $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) - $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) -- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(libdir) -+ $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(plugindir) - $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) - - uninstall: -diff --git a/libmultipath/checkers/Makefile b/libmultipath/checkers/Makefile -index c9a2c4ca..39ad76e0 100644 ---- a/libmultipath/checkers/Makefile -+++ b/libmultipath/checkers/Makefile -@@ -25,10 +25,10 @@ libcheck%.so: %.o - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) - - install: -- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(libdir) -+ $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(plugindir) - - uninstall: -- for file in $(LIBS); do $(RM) $(DESTDIR)$(libdir)/$$file; done -+ for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done - - clean: dep_clean - $(RM) core *.a *.o *.gz *.so -diff --git a/libmultipath/foreign/Makefile b/libmultipath/foreign/Makefile -index d0232f20..8bf9047b 100644 ---- a/libmultipath/foreign/Makefile -+++ b/libmultipath/foreign/Makefile -@@ -17,10 +17,10 @@ libforeign-%.so: %.o - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) - - install: -- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(libdir) -+ $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(plugindir) - - uninstall: -- for file in $(LIBS); do $(RM) $(DESTDIR)$(libdir)/$$file; done -+ for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done - - clean: dep_clean - $(RM) core *.a *.o *.gz *.so -diff --git a/libmultipath/prioritizers/Makefile b/libmultipath/prioritizers/Makefile -index 97155f51..72eefe49 100644 ---- a/libmultipath/prioritizers/Makefile -+++ b/libmultipath/prioritizers/Makefile -@@ -37,10 +37,10 @@ libprio%.so: %.o - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) - - install: $(LIBS) -- $(INSTALL_PROGRAM) -m 755 libprio*.so $(DESTDIR)$(libdir) -+ $(INSTALL_PROGRAM) -m 755 libprio*.so $(DESTDIR)$(plugindir) - - uninstall: -- for file in $(LIBS); do $(RM) $(DESTDIR)$(libdir)/$$file; done -+ for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done - - clean: dep_clean - $(RM) core *.a *.o *.gz *.so diff --git a/0034-RH-Remove-the-property-blacklist-exception-builtin.patch b/0012-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 96% rename from 0034-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0012-RH-Remove-the-property-blacklist-exception-builtin.patch index feef3f6..cbd2480 100644 --- a/0034-RH-Remove-the-property-blacklist-exception-builtin.patch +++ b/0012-RH-Remove-the-property-blacklist-exception-builtin.patch @@ -43,10 +43,10 @@ index 8d15d2ea..eff690fd 100644 udev_device_get_properties_list_entry(udev)) { diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 1fea9d5a..eef3c605 100644 +index b4dccd1b..284282c6 100644 --- a/multipath/multipath.conf.5 +++ b/multipath/multipath.conf.5 -@@ -1353,9 +1353,14 @@ keywords. Both are regular expressions. For a full description of these keywords +@@ -1367,9 +1367,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, @@ -62,7 +62,7 @@ index 1fea9d5a..eef3c605 100644 . .RS .PP -@@ -1366,10 +1371,6 @@ Blacklisting by missing properties is only applied to devices which do have the +@@ -1380,10 +1385,6 @@ Blacklisting by missing properties is only applied to devices which do have the property specified by \fIuid_attribute\fR (e.g. \fIID_SERIAL\fR) set. Previously, it was applied to every device, possibly causing devices to be blacklisted because of temporary I/O error conditions. diff --git a/0012-multipath-tools-Makefile.inc-use-simple-make-variabl.patch b/0012-multipath-tools-Makefile.inc-use-simple-make-variabl.patch deleted file mode 100644 index 16cca1e..0000000 --- a/0012-multipath-tools-Makefile.inc-use-simple-make-variabl.patch +++ /dev/null @@ -1,112 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 27 Oct 2022 17:35:48 +0200 -Subject: [PATCH] multipath-tools: Makefile.inc: use simple make variables - consistently - -"Simply expanded" make variables are generally preferred over "recursively -expanded" make variables, unless they reference other variables that are -defined over overwritten further down in the Makefile (see -https://www.gnu.org/software/make/manual/html_node/Flavors.html). -Using them makes the code easier to read and even somewhat faster. - -We've been adding simply expanded variables over time, but most older -code still uses recursively expanded ones. Try to be consistent, at least -in Makefile.inc. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 50 +++++++++++++++++++++++++------------------------- - 1 file changed, 25 insertions(+), 25 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 17707a3e..86602e2a 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -32,11 +32,11 @@ SYSTEMD := $(strip $(or $(shell $(PKGCONFIG) --modversion libsystemd 2>/dev/null - $(shell systemctl --version 2>/dev/null | sed -n 's/systemd \([0-9]*\).*/\1/p'))) - - # Paths. All these can be overridden on the "make" command line. --prefix = -+prefix := - # Prefix for binaries --exec_prefix = $(prefix) -+exec_prefix := $(prefix) - # Prefix for non-essential libraries (libdmmp) --usr_prefix = $(prefix) -+usr_prefix := $(prefix) - # Where to install systemd-related files. systemd is usually installed under /usr - # Note: some systemd installations use separate "prefix" and "rootprefix". - # In this case, override only unitdir to use systemd's "rootprefix" instead of $(systemd_prefix) -@@ -46,13 +46,13 @@ tmpfilesdir := $(systemd_prefix)/lib/tmpfiles.d - modulesloaddir := $(systemd_prefix)/lib/modules-load.d - libudevdir := $(systemd_prefix)/lib/udev - udevrulesdir := $(libudevdir)/rules.d --bindir = $(exec_prefix)/sbin -+bindir := $(exec_prefix)/sbin - mandir := $(usr_prefix)/share/man - LIB := $(if $(shell test -d /lib64 && echo 1),lib64,lib) --syslibdir = $(prefix)/$(LIB) --usrlibdir = $(usr_prefix)/$(LIB) --includedir = $(usr_prefix)/include --pkgconfdir = $(usrlibdir)/pkgconfig -+syslibdir := $(prefix)/$(LIB) -+usrlibdir := $(usr_prefix)/$(LIB) -+includedir := $(usr_prefix)/include -+pkgconfdir := $(usrlibdir)/pkgconfig - plugindir := $(prefix)/$(LIB)/multipath - configdir := $(prefix)/etc/multipath/conf.d - runtimedir := $(if $(shell test -L /var/run -o ! -d /var/run && echo 1),/run,/var/run) -@@ -60,10 +60,10 @@ devmapper_incdir := $(or $(shell $(PKGCONFIG) --variable=includedir devmapper),/ - libudev_incdir := $(or $(shell $(PKGCONFIG) --variable=includedir libudev),/usr/include) - kernel_incdir := /usr/include - --GZIP_PROG = gzip -9 -c --RM = rm -f --LN = ln -sf --INSTALL_PROGRAM = install -+GZIP_PROG := gzip -9 -c -+RM := rm -f -+LN := ln -sf -+INSTALL_PROGRAM := install - NV_VERSION_SCRIPT = $(VERSION_SCRIPT:%.version=%-nv.version) - - # $(call TEST_CC_OPTION,option,fallback) -@@ -106,23 +106,23 @@ CPPFLAGS := $(FORTIFY_OPT) \ - -DRUNTIME_DIR=\"$(runtimedir)\" \ - -DCONFIG_DIR=\"$(configdir)\" -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP - CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe --BIN_CFLAGS = -fPIE -DPIE --LIB_CFLAGS = -fPIC --SHARED_FLAGS = -shared -+BIN_CFLAGS := -fPIE -DPIE -+LIB_CFLAGS := -fPIC -+SHARED_FLAGS := -shared - LDFLAGS := $(LDFLAGS) -Wl,-z,relro -Wl,-z,now -Wl,-z,defs --BIN_LDFLAGS = -pie -+BIN_LDFLAGS := -pie - - # Source code directories. Don't modify. - --multipathdir = $(TOPDIR)/libmultipath --daemondir = $(TOPDIR)/multipathd --mpathutildir = $(TOPDIR)/libmpathutil --mpathpersistdir = $(TOPDIR)/libmpathpersist --mpathcmddir = $(TOPDIR)/libmpathcmd --mpathvaliddir = $(TOPDIR)/libmpathvalid --thirdpartydir = $(TOPDIR)/third-party --libdmmpdir = $(TOPDIR)/libdmmp --nvmedir = $(TOPDIR)/libmultipath/nvme -+multipathdir := $(TOPDIR)/libmultipath -+daemondir := $(TOPDIR)/multipathd -+mpathutildir := $(TOPDIR)/libmpathutil -+mpathpersistdir := $(TOPDIR)/libmpathpersist -+mpathcmddir := $(TOPDIR)/libmpathcmd -+mpathvaliddir := $(TOPDIR)/libmpathvalid -+thirdpartydir := $(TOPDIR)/third-party -+libdmmpdir := $(TOPDIR)/libdmmp -+nvmedir := $(TOPDIR)/libmultipath/nvme - - # Check whether a function with name $1 has been declared in header file $2. - check_func = $(shell \ diff --git a/0035-RH-don-t-start-without-a-config-file.patch b/0013-RH-don-t-start-without-a-config-file.patch similarity index 100% rename from 0035-RH-don-t-start-without-a-config-file.patch rename to 0013-RH-don-t-start-without-a-config-file.patch diff --git a/0013-multipath-tools-Makefile.inc-fix-a-log-message.patch b/0013-multipath-tools-Makefile.inc-fix-a-log-message.patch deleted file mode 100644 index 3e424dc..0000000 --- a/0013-multipath-tools-Makefile.inc-fix-a-log-message.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 27 Oct 2022 17:40:30 +0200 -Subject: [PATCH] multipath-tools: Makefile.inc: fix a log message - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 86602e2a..77790ddf 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -159,7 +159,7 @@ check_var = $(shell \ - found=0; \ - status="no"; \ - fi; \ -- echo 1>&2 "Checking for .. $1 in $2 ... $$status"; \ -+ echo 1>&2 "Checking for $1 in $2 ... $$status"; \ - echo "$$found" \ - ) - diff --git a/0036-RH-Fix-nvme-function-missing-argument.patch b/0014-RH-Fix-nvme-function-missing-argument.patch similarity index 100% rename from 0036-RH-Fix-nvme-function-missing-argument.patch rename to 0014-RH-Fix-nvme-function-missing-argument.patch diff --git a/0014-multipath-tools-Makefile.inc-set-systemd-specific-fl.patch b/0014-multipath-tools-Makefile.inc-set-systemd-specific-fl.patch deleted file mode 100644 index fa37b7c..0000000 --- a/0014-multipath-tools-Makefile.inc-set-systemd-specific-fl.patch +++ /dev/null @@ -1,129 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 27 Oct 2022 16:40:27 +0200 -Subject: [PATCH] multipath-tools: Makefile.inc: set systemd-specific flags - -Define SYSTEMD_CPPFLAGS and SYSTEMD_LIBDEPS, and use them in Makefiles. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 3 +++ - libmpathutil/Makefile | 13 ++----------- - libmultipath/Makefile | 14 +++----------- - multipathd/Makefile | 25 ++++++++----------------- - 4 files changed, 16 insertions(+), 39 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 77790ddf..2cf25745 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -97,6 +97,9 @@ ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers - WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered -Wno-error=clobbered,) - WFORMATOVERFLOW := $(call TEST_CC_OPTION,-Wformat-overflow=2,) - -+SYSTEMD_CPPFLAGS := $(if $(SYSTEMD),-DUSE_SYSTEMD=$(SYSTEMD)) -+SYSTEMD_LIBDEPS := $(if $(SYSTEMD),$(if $(shell test $(SYSTEMD) -gt 209 && echo 1),-lsystemd,-lsystemd-daemon)) -+ - OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 - WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int \ - -Werror=implicit-function-declaration -Werror=format-security \ -diff --git a/libmpathutil/Makefile b/libmpathutil/Makefile -index c913c761..4be75d2d 100644 ---- a/libmpathutil/Makefile -+++ b/libmpathutil/Makefile -@@ -8,19 +8,10 @@ DEVLIB = libmpathutil.so - LIBS = $(DEVLIB).$(SONAME) - VERSION_SCRIPT := libmpathutil.version - --CPPFLAGS += -I. -I$(multipathdir) -I$(mpathcmddir) -+CPPFLAGS += -I. -I$(multipathdir) -I$(mpathcmddir) $(SYSTEMD_CPPFLAGS) - CFLAGS += $(LIB_CFLAGS) -D_GNU_SOURCE - --LIBDEPS += -lpthread -ldl -ludev -L$(mpathcmddir) -lmpathcmd -- --ifdef SYSTEMD -- CPPFLAGS += -DUSE_SYSTEMD=$(SYSTEMD) -- ifeq ($(shell test $(SYSTEMD) -gt 209 && echo 1), 1) -- LIBDEPS += -lsystemd -- else -- LIBDEPS += -lsystemd-daemon -- endif --endif -+LIBDEPS += -lpthread -ldl -ludev -L$(mpathcmddir) -lmpathcmd $(SYSTEMD_LIBDEPS) - - # object files referencing MULTIPATH_DIR or CONFIG_DIR - # they need to be recompiled for unit tests -diff --git a/libmultipath/Makefile b/libmultipath/Makefile -index c7d4fc99..009f26a3 100644 ---- a/libmultipath/Makefile -+++ b/libmultipath/Makefile -@@ -8,19 +8,11 @@ DEVLIB = libmultipath.so - LIBS = $(DEVLIB).$(SONAME) - VERSION_SCRIPT := libmultipath.version - --CPPFLAGS += -I$(mpathutildir) -I$(mpathcmddir) -I$(nvmedir) -D_GNU_SOURCE -+CPPFLAGS += -I$(mpathutildir) -I$(mpathcmddir) -I$(nvmedir) -D_GNU_SOURCE $(SYSTEMD_CPPFLAGS) - CFLAGS += $(LIB_CFLAGS) - --LIBDEPS += -lpthread -ldl -ldevmapper -ludev -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd -lurcu -laio -- --ifdef SYSTEMD -- CPPFLAGS += -DUSE_SYSTEMD=$(SYSTEMD) -- ifeq ($(shell test $(SYSTEMD) -gt 209 && echo 1), 1) -- LIBDEPS += -lsystemd -- else -- LIBDEPS += -lsystemd-daemon -- endif --endif -+LIBDEPS += -lpthread -ldl -ldevmapper -ludev -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd \ -+ -lurcu -laio $(SYSTEMD_LIBDEPS) - - ifneq ($(call check_func,dm_task_no_flush,$(devmapper_incdir)/libdevmapper.h),0) - CPPFLAGS += -DLIBDM_API_FLUSH -diff --git a/multipathd/Makefile b/multipathd/Makefile -index 78aefee0..cdda371b 100644 ---- a/multipathd/Makefile -+++ b/multipathd/Makefile -@@ -18,14 +18,17 @@ endif - CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathpersistdir) -I$(mpathcmddir) -I$(thirdpartydir) \ - $(shell $(PKGCONFIG) --modversion liburcu 2>/dev/null | \ - awk -F. '{ printf("-DURCU_VERSION=0x%06x", 256 * ( 256 * $$1 + $$2) + $$3); }') \ -- -DBINDIR='"$(bindir)"' -+ -DBINDIR='"$(bindir)"' $(SYSTEMD_CPPFLAGS) -+ifeq ($(ENABLE_DMEVENTS_POLL),0) -+ CPPFLAGS += -DNO_DMEVENTS_POLL -+endif - CFLAGS += $(BIN_CFLAGS) - LDFLAGS += $(BIN_LDFLAGS) - --CLI_LIBDEPS := -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd -ludev -ldl -lurcu -lpthread --LIBDEPS += -L$(multipathdir) -lmultipath -L$(mpathpersistdir) -lmpathpersist \ -- -ldevmapper $(CLI_LIBDEPS) -- -+CLI_LIBDEPS := -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd \ -+ -ludev -ldl -lurcu -lpthread $(SYSTEMD_LIBDEPS) -+LIBDEPS := -L$(multipathdir) -lmultipath -L$(mpathpersistdir) -lmpathpersist \ -+ -ldevmapper $(CLI_LIBDEPS) - - ifeq ($(READLINE),libedit) - RL_CPPFLAGS = -DUSE_LIBEDIT -@@ -40,18 +43,6 @@ RL_CPPFLAGS += -DBROKEN_RL_COMPLETION_FUNC - endif - endif - --ifdef SYSTEMD -- CPPFLAGS += -DUSE_SYSTEMD=$(SYSTEMD) -- ifeq ($(shell test $(SYSTEMD) -gt 209 && echo 1), 1) -- CLI_LIBDEPS += -lsystemd -- else -- CLI_LIBDEPS += -lsystemd-daemon -- endif --endif --ifeq ($(ENABLE_DMEVENTS_POLL),0) -- CPPFLAGS += -DNO_DMEVENTS_POLL --endif -- - OBJS = main.o pidfile.o uxlsnr.o uxclnt.o cli.o cli_handlers.o waiter.o \ - dmevents.o init_unwinder.o - diff --git a/0037-RH-use-rpm-optflags-if-present.patch b/0015-RH-use-rpm-optflags-if-present.patch similarity index 78% rename from 0037-RH-use-rpm-optflags-if-present.patch rename to 0015-RH-use-rpm-optflags-if-present.patch index c844afe..6a7fdea 100644 --- a/0037-RH-use-rpm-optflags-if-present.patch +++ b/0015-RH-use-rpm-optflags-if-present.patch @@ -9,14 +9,14 @@ still being generic. Signed-off-by: Benjamin Marzinski --- - Makefile.inc | 24 ++++++++++++++++++------ - 1 file changed, 18 insertions(+), 6 deletions(-) + Makefile.inc | 22 +++++++++++++++++----- + 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 8c5a08a2..e6e7f7d7 100644 +index 540e1dfc..748911e2 100644 --- a/Makefile.inc +++ b/Makefile.inc -@@ -74,19 +74,31 @@ INSTALL_PROGRAM := install +@@ -78,11 +78,23 @@ ORIG_LDFLAGS := $(LDFLAGS) SYSTEMD_CPPFLAGS := $(if $(SYSTEMD),-DUSE_SYSTEMD=$(SYSTEMD)) SYSTEMD_LIBDEPS := $(if $(SYSTEMD),$(if $(shell test $(SYSTEMD) -gt 209 && echo 1),-lsystemd,-lsystemd-daemon)) @@ -37,15 +37,14 @@ index 8c5a08a2..e6e7f7d7 100644 +endif +WARNFLAGS := -Werror -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int \ -Werror=implicit-function-declaration -Werror=format-security \ -- $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) --CPPFLAGS := $(FORTIFY_OPT) \ -- -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \ -+ $(WNOCLOBBERED) -Werror=cast-qual \ -+ $(ERROR_DISCARDED_QUALIFIERS) -Wstrict-prototypes -+CPPFLAGS := -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \ +- $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) $(W_URCU_TYPE_LIMITS) +-CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) \ ++ $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) $(W_URCU_TYPE_LIMITS) -Wstrict-prototypes ++CPPFLAGS := $(CPPFLAGS) \ + -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \ -DRUNTIME_DIR=\"$(runtimedir)\" \ -DCONFIG_DIR=\"$(configdir)\" -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP - CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe +@@ -90,7 +102,7 @@ CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe BIN_CFLAGS := -fPIE -DPIE LIB_CFLAGS := -fPIC SHARED_FLAGS := -shared diff --git a/0015-multipathd-Makefile-fix-compilation-flags-for-libedi.patch b/0015-multipathd-Makefile-fix-compilation-flags-for-libedi.patch deleted file mode 100644 index 0013036..0000000 --- a/0015-multipathd-Makefile-fix-compilation-flags-for-libedi.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 27 Oct 2022 18:51:52 +0200 -Subject: [PATCH] multipathd: Makefile: fix compilation flags for libedit - -The workaround for the wrong prototype in older libedit versions -had ended up in the code for libreadline. Fix it, and use simple -make variables. - -Fixes: 2bd80f6 ("multipathd: fix incompatible pointer type error with libedit") -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - multipathd/Makefile | 16 +++++++--------- - 1 file changed, 7 insertions(+), 9 deletions(-) - -diff --git a/multipathd/Makefile b/multipathd/Makefile -index cdda371b..7221b6af 100644 ---- a/multipathd/Makefile -+++ b/multipathd/Makefile -@@ -31,17 +31,17 @@ LIBDEPS := -L$(multipathdir) -lmultipath -L$(mpathpersistdir) -lmpathpersist \ - -ldevmapper $(CLI_LIBDEPS) - - ifeq ($(READLINE),libedit) --RL_CPPFLAGS = -DUSE_LIBEDIT --RL_LIBDEPS += -ledit --endif --ifeq ($(READLINE),libreadline) --RL_CPPFLAGS += -DUSE_LIBREADLINE --RL_LIBDEPS += -lreadline --# See comment in uxclnt.c -+RL_CPPFLAGS := -DUSE_LIBEDIT -+RL_LIBDEPS := -ledit -+# See comment in multipathc.c - ifeq ($(shell sed -En 's/.*\ -Date: Thu, 27 Oct 2022 21:59:36 +0200 -Subject: [PATCH] multipath-tools Makefiles: clean up executable Makefiles - -Move the EXEC definition to the top, and use simple make variables -where possible. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - kpartx/Makefile | 15 +++++++-------- - multipath/Makefile | 6 +++--- - multipathd/Makefile | 30 ++++++++++++++---------------- - 3 files changed, 24 insertions(+), 27 deletions(-) - -diff --git a/kpartx/Makefile b/kpartx/Makefile -index 464925ad..7ceae96b 100644 ---- a/kpartx/Makefile -+++ b/kpartx/Makefile -@@ -3,20 +3,19 @@ - # - include ../Makefile.inc - --CPPFLAGS += -I. -I$(multipathdir) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 --CFLAGS += $(BIN_CFLAGS) --LDFLAGS += $(BIN_LDFLAGS) -- --LIBDEPS += -ldevmapper -+EXEC := kpartx - -+CPPFLAGS += -I. -I$(multipathdir) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 - ifneq ($(call check_func,dm_task_set_cookie,$(devmapper_incdir)/libdevmapper.h),0) - CPPFLAGS += -DLIBDM_API_COOKIE - endif - --OBJS = bsd.o dos.o kpartx.o solaris.o unixware.o dasd.o sun.o \ -- gpt.o mac.o ps3.o crc32.o lopart.o xstrncpy.o devmapper.o -+CFLAGS += $(BIN_CFLAGS) -+LDFLAGS += $(BIN_LDFLAGS) -+LIBDEPS += -ldevmapper - --EXEC = kpartx -+OBJS := bsd.o dos.o kpartx.o solaris.o unixware.o dasd.o sun.o \ -+ gpt.o mac.o ps3.o crc32.o lopart.o xstrncpy.o devmapper.o - - all: $(EXEC) - -diff --git a/multipath/Makefile b/multipath/Makefile -index 1c4e7a52..7f7b341d 100644 ---- a/multipath/Makefile -+++ b/multipath/Makefile -@@ -3,15 +3,15 @@ - # - include ../Makefile.inc - -+EXEC := multipath -+ - CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathcmddir) - CFLAGS += $(BIN_CFLAGS) - LDFLAGS += $(BIN_LDFLAGS) - LIBDEPS += -L$(multipathdir) -lmultipath -L$(mpathutildir) -lmpathutil \ - -L$(mpathcmddir) -lmpathcmd -lpthread -ldevmapper -ldl -ludev - --EXEC = multipath -- --OBJS = main.o -+OBJS := main.o - - all: $(EXEC) multipath.rules tmpfiles.conf - -diff --git a/multipathd/Makefile b/multipathd/Makefile -index 7221b6af..bb8f7770 100644 ---- a/multipathd/Makefile -+++ b/multipathd/Makefile -@@ -1,27 +1,30 @@ - include ../Makefile.inc - -+EXEC := multipathd -+CLI := multipathc -+ -+CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathpersistdir) -I$(mpathcmddir) -I$(thirdpartydir) \ -+ $(shell $(PKGCONFIG) --modversion liburcu 2>/dev/null | \ -+ awk -F. '{ printf("-DURCU_VERSION=0x%06x", 256 * ( 256 * $$1 + $$2) + $$3); }') \ -+ -DBINDIR='"$(bindir)"' $(SYSTEMD_CPPFLAGS) -+ -+ifeq ($(ENABLE_DMEVENTS_POLL),0) -+ CPPFLAGS += -DNO_DMEVENTS_POLL -+endif - ifneq ($(call check_func,dm_task_get_errno,$(devmapper_incdir)/libdevmapper.h),0) - CPPFLAGS += -DLIBDM_API_GET_ERRNO - endif -- - ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(kernel_incdir)/scsi/fc/fc_els.h),0) - CPPFLAGS += -DFPIN_EVENT_HANDLER - FPIN_SUPPORT = 1 - endif -+ - # - # debugging stuff - # - #CPPFLAGS += -DLCKDBG --#CPPFLAGS += -D_DEBUG_ - #CPPFLAGS += -DLOGDBG - --CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathpersistdir) -I$(mpathcmddir) -I$(thirdpartydir) \ -- $(shell $(PKGCONFIG) --modversion liburcu 2>/dev/null | \ -- awk -F. '{ printf("-DURCU_VERSION=0x%06x", 256 * ( 256 * $$1 + $$2) + $$3); }') \ -- -DBINDIR='"$(bindir)"' $(SYSTEMD_CPPFLAGS) --ifeq ($(ENABLE_DMEVENTS_POLL),0) -- CPPFLAGS += -DNO_DMEVENTS_POLL --endif - CFLAGS += $(BIN_CFLAGS) - LDFLAGS += $(BIN_LDFLAGS) - -@@ -43,18 +46,13 @@ RL_CPPFLAGS := -DUSE_LIBREADLINE - RL_LIBDEPS := -lreadline - endif - --OBJS = main.o pidfile.o uxlsnr.o uxclnt.o cli.o cli_handlers.o waiter.o \ -+CLI_OBJS := multipathc.o cli.o -+OBJS := main.o pidfile.o uxlsnr.o uxclnt.o cli.o cli_handlers.o waiter.o \ - dmevents.o init_unwinder.o -- --CLI_OBJS = multipathc.o cli.o -- - ifeq ($(FPIN_SUPPORT),1) - OBJS += fpin_handlers.o - endif - --EXEC = multipathd --CLI = multipathc -- - all : $(EXEC) $(CLI) - - $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so diff --git a/0039-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 100% rename from 0039-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 diff --git a/0017-multipath-tools-Makefiles-use-common-code-for-librar.patch b/0017-multipath-tools-Makefiles-use-common-code-for-librar.patch deleted file mode 100644 index 0b45e62..0000000 --- a/0017-multipath-tools-Makefiles-use-common-code-for-librar.patch +++ /dev/null @@ -1,261 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 27 Oct 2022 21:52:06 +0200 -Subject: [PATCH] multipath-tools: Makefiles: use common code for libraries - -Move shared code to Makefile.inc as far as possible. Use simple -make variables where possible. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 15 ++++++++++++++- - libdmmp/Makefile | 17 ++++++++--------- - libmpathcmd/Makefile | 14 ++------------ - libmpathpersist/Makefile | 14 ++------------ - libmpathutil/Makefile | 14 +------------- - libmpathvalid/Makefile | 14 ++------------ - libmultipath/Makefile | 12 +----------- - 7 files changed, 30 insertions(+), 70 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 2cf25745..fe6bc088 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -64,7 +64,6 @@ GZIP_PROG := gzip -9 -c - RM := rm -f - LN := ln -sf - INSTALL_PROGRAM := install --NV_VERSION_SCRIPT = $(VERSION_SCRIPT:%.version=%-nv.version) - - # $(call TEST_CC_OPTION,option,fallback) - # Test if the C compiler supports the option. -@@ -127,6 +126,13 @@ thirdpartydir := $(TOPDIR)/third-party - libdmmpdir := $(TOPDIR)/libdmmp - nvmedir := $(TOPDIR)/libmultipath/nvme - -+# Common code for libraries - library Makefiles just set DEVLIB -+# SONAME defaults to 0 (we use version scripts) -+SONAME := 0 -+LIBS = $(DEVLIB).$(SONAME) -+VERSION_SCRIPT = $(DEVLIB:%.so=%.version) -+NV_VERSION_SCRIPT = $(DEVLIB:%.so=%-nv.version) -+ - # Check whether a function with name $1 has been declared in header file $2. - check_func = $(shell \ - if grep -Eq "^[^[:blank:]]+[[:blank:]]+$1[[:blank:]]*(.*)*" "$2"; then \ -@@ -175,3 +181,10 @@ check_var = $(shell \ - - %.abi: %.so - abidw $< >$@ -+ -+%-nv.version: %.version -+ @echo creating $@ from $< -+ @printf 'NOVERSION {\nglobal:\n' >$@ -+ @grep -P '^[ \t]+[a-zA-Z_][a-zA-Z0-9_]*;' $< >>$@ -+ @printf 'local:\n\t*;\n};\n' >>$@ -+ -diff --git a/libdmmp/Makefile b/libdmmp/Makefile -index 985b694b..67b6f86f 100644 ---- a/libdmmp/Makefile -+++ b/libdmmp/Makefile -@@ -5,15 +5,14 @@ - # - include ../Makefile.inc - --LIBDMMP_VERSION=0.2.0 --SONAME=$(LIBDMMP_VERSION) --DEVLIB = libdmmp.so --LIBS = $(DEVLIB).$(SONAME) --PKGFILE = libdmmp.pc --EXTRA_MAN_FILES = libdmmp.h.3 --HEADERS = libdmmp/libdmmp.h -- --OBJS = libdmmp.o libdmmp_mp.o libdmmp_pg.o libdmmp_path.o libdmmp_misc.o -+LIBDMMP_VERSION := 0.2.0 -+SONAME := $(LIBDMMP_VERSION) -+DEVLIB := libdmmp.so -+PKGFILE := libdmmp.pc -+EXTRA_MAN_FILES := libdmmp.h.3 -+HEADERS := libdmmp/libdmmp.h -+ -+OBJS := libdmmp.o libdmmp_mp.o libdmmp_pg.o libdmmp_path.o libdmmp_misc.o - - CPPFLAGS += -I$(libdmmpdir) -I$(mpathcmddir) $(shell $(PKGCONFIG) --cflags json-c) - CFLAGS += $(LIB_CFLAGS) -fvisibility=hidden -diff --git a/libmpathcmd/Makefile b/libmpathcmd/Makefile -index 0f83fe7b..f705c7f0 100644 ---- a/libmpathcmd/Makefile -+++ b/libmpathcmd/Makefile -@@ -1,13 +1,8 @@ - include ../Makefile.inc - --SONAME = 0 --DEVLIB = libmpathcmd.so --LIBS = $(DEVLIB).$(SONAME) --VERSION_SCRIPT := libmpathcmd.version -- -+DEVLIB := libmpathcmd.so - CFLAGS += $(LIB_CFLAGS) -- --OBJS = mpath_cmd.o -+OBJS := mpath_cmd.o - - all: $(DEVLIB) - -@@ -15,11 +10,6 @@ $(LIBS): $(OBJS) $(VERSION_SCRIPT) - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ - -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) - --$(NV_VERSION_SCRIPT): $(VERSION_SCRIPT) -- @printf 'NOVERSION {\nglobal:\n' >$@ -- @grep -P '^[ \t]+[a-zA-Z_][a-zA-Z0-9_]*;' $< >>$@ -- @printf 'local:\n\t*;\n};\n' >>$@ -- - $(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ - -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) -diff --git a/libmpathpersist/Makefile b/libmpathpersist/Makefile -index 479524d4..6f69168f 100644 ---- a/libmpathpersist/Makefile -+++ b/libmpathpersist/Makefile -@@ -1,16 +1,11 @@ - include ../Makefile.inc - --SONAME = 0 --DEVLIB = libmpathpersist.so --LIBS = $(DEVLIB).$(SONAME) --VERSION_SCRIPT:= libmpathpersist.version -- -+DEVLIB := libmpathpersist.so - CFLAGS += $(LIB_CFLAGS) -I$(multipathdir) -I$(mpathutildir) -I$(mpathpersistdir) -I$(mpathcmddir) - LDFLAGS += -L$(multipathdir) -L$(mpathutildir) -L$(mpathcmddir) -- - LIBDEPS += -lmultipath -lmpathutil -lmpathcmd -ldevmapper -lpthread -ldl - --OBJS = mpath_persist.o mpath_updatepr.o mpath_pr_ioctl.o mpath_persist_int.o -+OBJS := mpath_persist.o mpath_updatepr.o mpath_pr_ioctl.o mpath_persist_int.o - - all: $(DEVLIB) - -@@ -18,11 +13,6 @@ $(LIBS): $(OBJS) $(VERSION_SCRIPT) - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ - -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) - --$(NV_VERSION_SCRIPT): $(VERSION_SCRIPT) -- @printf 'NOVERSION {\nglobal:\n' >$@ -- @grep -P '^[ \t]+[a-zA-Z_][a-zA-Z0-9_]*;' $< >>$@ -- @printf 'local:\n\t*;\n};\n' >>$@ -- - $(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ - -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) -diff --git a/libmpathutil/Makefile b/libmpathutil/Makefile -index 4be75d2d..5665af28 100644 ---- a/libmpathutil/Makefile -+++ b/libmpathutil/Makefile -@@ -3,14 +3,9 @@ - # - include ../Makefile.inc - --SONAME = 0 --DEVLIB = libmpathutil.so --LIBS = $(DEVLIB).$(SONAME) --VERSION_SCRIPT := libmpathutil.version -- -+DEVLIB := libmpathutil.so - CPPFLAGS += -I. -I$(multipathdir) -I$(mpathcmddir) $(SYSTEMD_CPPFLAGS) - CFLAGS += $(LIB_CFLAGS) -D_GNU_SOURCE -- - LIBDEPS += -lpthread -ldl -ludev -L$(mpathcmddir) -lmpathcmd $(SYSTEMD_LIBDEPS) - - # object files referencing MULTIPATH_DIR or CONFIG_DIR -@@ -22,8 +17,6 @@ OBJS := parser.o vector.o util.o debug.o time-util.o \ - - all: $(DEVLIB) - --make_static = $(shell sed '/^static/!s/^\([a-z]\{1,\} \)/static \1/' <$1 >$2) -- - $(LIBS): $(OBJS) $(VERSION_SCRIPT) - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ - -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) -@@ -31,11 +24,6 @@ $(LIBS): $(OBJS) $(VERSION_SCRIPT) - $(DEVLIB): $(LIBS) - $(LN) $(LIBS) $@ - --$(NV_VERSION_SCRIPT): $(VERSION_SCRIPT) -- @printf 'NOVERSION {\nglobal:\n' >$@ -- @grep -P '^[ \t]+[a-zA-Z_][a-zA-Z0-9_]*;' $< >>$@ -- @printf 'local:\n\t*;\n};\n' >>$@ -- - $(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ - -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) -diff --git a/libmpathvalid/Makefile b/libmpathvalid/Makefile -index 5dbfb923..bd4ccc0d 100644 ---- a/libmpathvalid/Makefile -+++ b/libmpathvalid/Makefile -@@ -1,17 +1,12 @@ - include ../Makefile.inc - --SONAME = 0 --DEVLIB = libmpathvalid.so --LIBS = $(DEVLIB).$(SONAME) --VERSION_SCRIPT := libmpathvalid.version -- -+DEVLIB := libmpathvalid.so - CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathcmddir) - CFLAGS += $(LIB_CFLAGS) -- - LIBDEPS += -lpthread -ldevmapper -ldl -L$(multipathdir) -lmultipath \ - -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd -ludev - --OBJS = mpath_valid.o -+OBJS := mpath_valid.o - - all: $(LIBS) - -@@ -20,11 +15,6 @@ $(LIBS): $(OBJS) $(VERSION_SCRIPT) - -Wl,--version-script=$(VERSION_SCRIPT) - $(LN) $(LIBS) $(DEVLIB) - --$(NV_VERSION_SCRIPT): $(VERSION_SCRIPT) -- @printf 'NOVERSION {\nglobal:\n' >$@ -- @grep -P '^[ \t]+[a-zA-Z_][a-zA-Z0-9_]*;' $< >>$@ -- @printf 'local:\n\t*;\n};\n' >>$@ -- - $(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ - -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) -diff --git a/libmultipath/Makefile b/libmultipath/Makefile -index 009f26a3..9dc229ae 100644 ---- a/libmultipath/Makefile -+++ b/libmultipath/Makefile -@@ -3,14 +3,9 @@ - # - include ../Makefile.inc - --SONAME = 0 --DEVLIB = libmultipath.so --LIBS = $(DEVLIB).$(SONAME) --VERSION_SCRIPT := libmultipath.version -- -+DEVLIB := libmultipath.so - CPPFLAGS += -I$(mpathutildir) -I$(mpathcmddir) -I$(nvmedir) -D_GNU_SOURCE $(SYSTEMD_CPPFLAGS) - CFLAGS += $(LIB_CFLAGS) -- - LIBDEPS += -lpthread -ldl -ldevmapper -ludev -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd \ - -lurcu -laio $(SYSTEMD_LIBDEPS) - -@@ -85,11 +80,6 @@ $(LIBS): $(OBJS) $(VERSION_SCRIPT) - $(DEVLIB): $(LIBS) - $(LN) $(LIBS) $@ - --$(NV_VERSION_SCRIPT): $(VERSION_SCRIPT) -- @printf 'NOVERSION {\nglobal:\n' >$@ -- @grep -P '^[ \t]+[a-zA-Z_][a-zA-Z0-9_]*;' $< >>$@ -- @printf 'local:\n\t*;\n};\n' >>$@ -- - $(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ - -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) diff --git a/0040-RH-reset-default-find_mutipaths-value-to-off.patch b/0018-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 100% rename from 0040-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0018-RH-reset-default-find_mutipaths-value-to-off.patch diff --git a/0018-multipath-tools-Makefiles-move-common-code-to-rules..patch b/0018-multipath-tools-Makefiles-move-common-code-to-rules..patch deleted file mode 100644 index 1a2069f..0000000 --- a/0018-multipath-tools-Makefiles-move-common-code-to-rules..patch +++ /dev/null @@ -1,172 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 27 Oct 2022 22:18:22 +0200 -Subject: [PATCH] multipath-tools: Makefiles: move common code to rules.mk - -The library Makefiles contain a lot of similar rules. Just -maintain them in a single file. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmpathcmd/Makefile | 13 +------------ - libmpathpersist/Makefile | 13 +------------ - libmpathutil/Makefile | 13 +------------ - libmpathvalid/Makefile | 13 ++----------- - libmultipath/Makefile | 16 ++-------------- - rules.mk | 15 +++++++++++++++ - 6 files changed, 22 insertions(+), 61 deletions(-) - create mode 100644 rules.mk - -diff --git a/libmpathcmd/Makefile b/libmpathcmd/Makefile -index f705c7f0..cfb202b8 100644 ---- a/libmpathcmd/Makefile -+++ b/libmpathcmd/Makefile -@@ -6,18 +6,7 @@ OBJS := mpath_cmd.o - - all: $(DEVLIB) - --$(LIBS): $(OBJS) $(VERSION_SCRIPT) -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ -- -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) -- --$(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ -- -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) -- --abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) -- --$(DEVLIB): $(LIBS) -- $(LN) $(LIBS) $@ -+include $(TOPDIR)/rules.mk - - install: all - $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) -diff --git a/libmpathpersist/Makefile b/libmpathpersist/Makefile -index 6f69168f..94672556 100644 ---- a/libmpathpersist/Makefile -+++ b/libmpathpersist/Makefile -@@ -9,18 +9,7 @@ OBJS := mpath_persist.o mpath_updatepr.o mpath_pr_ioctl.o mpath_persist_int.o - - all: $(DEVLIB) - --$(LIBS): $(OBJS) $(VERSION_SCRIPT) -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ -- -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) -- --$(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ -- -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) -- --abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) -- --$(DEVLIB): $(LIBS) -- $(LN) $(LIBS) $@ -+include $(TOPDIR)/rules.mk - - install: all - $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) -diff --git a/libmpathutil/Makefile b/libmpathutil/Makefile -index 5665af28..5ab33c09 100644 ---- a/libmpathutil/Makefile -+++ b/libmpathutil/Makefile -@@ -17,18 +17,7 @@ OBJS := parser.o vector.o util.o debug.o time-util.o \ - - all: $(DEVLIB) - --$(LIBS): $(OBJS) $(VERSION_SCRIPT) -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ -- -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) -- --$(DEVLIB): $(LIBS) -- $(LN) $(LIBS) $@ -- --$(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ -- -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) -- --abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) -+include $(TOPDIR)/rules.mk - - install: all - $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) -diff --git a/libmpathvalid/Makefile b/libmpathvalid/Makefile -index bd4ccc0d..88034df3 100644 ---- a/libmpathvalid/Makefile -+++ b/libmpathvalid/Makefile -@@ -8,18 +8,9 @@ LIBDEPS += -lpthread -ldevmapper -ldl -L$(multipathdir) -lmultipath \ - - OBJS := mpath_valid.o - --all: $(LIBS) -+all: $(DEVLIB) - --$(LIBS): $(OBJS) $(VERSION_SCRIPT) -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ -o $@ $(OBJS) $(LIBDEPS) \ -- -Wl,--version-script=$(VERSION_SCRIPT) -- $(LN) $(LIBS) $(DEVLIB) -- --$(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ -- -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) -- --abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) -+include $(TOPDIR)/rules.mk - - install: $(LIBS) - $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(syslibdir) -diff --git a/libmultipath/Makefile b/libmultipath/Makefile -index 9dc229ae..e24eab8a 100644 ---- a/libmultipath/Makefile -+++ b/libmultipath/Makefile -@@ -56,6 +56,8 @@ OBJS := $(OBJS-O) $(OBJS-U) - - all: $(DEVLIB) - -+include $(TOPDIR)/rules.mk -+ - nvme-lib.o: nvme-lib.c nvme-ioctl.c nvme-ioctl.h - $(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-function -c -o $@ $< - -@@ -72,20 +74,6 @@ nvme-ioctl.c: nvme/nvme-ioctl.c - nvme-ioctl.h: nvme/nvme-ioctl.h - $(call make_static,$<,$@) - -- --$(LIBS): $(OBJS) $(VERSION_SCRIPT) -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ -- -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) -- --$(DEVLIB): $(LIBS) -- $(LN) $(LIBS) $@ -- --$(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ -- -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) -- --abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) -- - ../tests/$(LIBS): $(OBJS-O) $(OBJS-T) $(VERSION_SCRIPT) - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=`basename $@` \ - -o $@ $(OBJS-O) $(OBJS-T) $(LIBDEPS) -diff --git a/rules.mk b/rules.mk -new file mode 100644 -index 00000000..c1d80820 ---- /dev/null -+++ b/rules.mk -@@ -0,0 +1,15 @@ -+# Copyright (c) SUSE LLC -+# SPDX-License-Identifier: GPL-2.0-or-later -+ -+$(DEVLIB): $(LIBS) -+ $(LN) $(LIBS) $@ -+ -+$(LIBS): $(OBJS) $(VERSION_SCRIPT) -+ $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ -+ -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) -+ -+$(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) -+ $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ -+ -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) -+ -+abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) diff --git a/0041-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0019-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 100% rename from 0041-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0019-RH-attempt-to-get-ANA-info-via-sysfs-first.patch diff --git a/0019-multipath-tools-Makefiles-create-config.mk.patch b/0019-multipath-tools-Makefiles-create-config.mk.patch deleted file mode 100644 index 4d403d0..0000000 --- a/0019-multipath-tools-Makefiles-create-config.mk.patch +++ /dev/null @@ -1,603 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 28 Oct 2022 00:01:46 +0200 -Subject: [PATCH] multipath-tools Makefiles: create config.mk - -Rather than running the test scripts for certain system features -every time "make" is called, save the configuration in "config.mk" -and "libmultipath/autoconfig.h", and reuse it later. This reduces -build time, especially in subsequent builds, and the build output is -less garbled by compiler options. - -It works by invoking the separate make file "create-config.mk" at -the beginning of the build process. Most of the complex makefile -functions are moved to "create-config.mk". - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/foreign.yaml | 2 +- - .gitignore | 2 + - Makefile | 19 +++- - Makefile.inc | 76 +-------------- - create-config.mk | 144 +++++++++++++++++++++++++++++ - kpartx/Makefile | 4 - - kpartx/devmapper.c | 1 + - kpartx/kpartx.c | 1 + - libdmmp/test/Makefile | 1 + - libmultipath/Makefile | 30 +----- - libmultipath/devmapper.h | 2 +- - libmultipath/dict.c | 1 + - libmultipath/prioritizers/Makefile | 2 +- - libmultipath/propsel.c | 1 + - libmultipath/uevent.c | 1 + - multipathd/Makefile | 11 --- - multipathd/fpin.h | 1 + - multipathd/main.c | 1 + - rules.mk | 3 + - tests/Makefile | 8 -- - 20 files changed, 179 insertions(+), 132 deletions(-) - create mode 100644 create-config.mk - -diff --git a/.github/workflows/foreign.yaml b/.github/workflows/foreign.yaml -index bd4e9c12..5a19913a 100644 ---- a/.github/workflows/foreign.yaml -+++ b/.github/workflows/foreign.yaml -@@ -30,7 +30,7 @@ jobs: - if: ${{ matrix.arch != '' && matrix.arch != '-i386' }} - run: > - tar cfv binaries.tar -- Makefile* -+ Makefile* config.mk - libmpathcmd/*.so* libmultipath/*.so* libmpathutil/*.so* - libmultipath/checkers/*.so libmultipath/prioritizers/*.so - libmultipath/foreign/*.so -diff --git a/.gitignore b/.gitignore -index 83f8a552..535353e5 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -8,6 +8,7 @@ - *.gz - *.d - \#* -+config.mk - cscope.files - cscope.out - kpartx/kpartx -@@ -35,5 +36,6 @@ tests/*.out - tests/*.vgr - libmultipath/nvme-ioctl.c - libmultipath/nvme-ioctl.h -+libmultipath/autoconfig.h - */*-nv.version - reference-abi -diff --git a/Makefile b/Makefile -index 27b4641f..1b28db62 100644 ---- a/Makefile -+++ b/Makefile -@@ -30,7 +30,14 @@ BUILDDIRS.clean := $(BUILDDIRS:=.clean) tests.clean - - all: $(BUILDDIRS) - --$(BUILDDIRS): -+config.mk libmultipath/autoconfig.h: -+ @$(MAKE) -f create-config.mk -+ @echo ==== config.mk ==== -+ @cat config.mk -+ @echo ==== autoconfig.h ==== -+ @cat libmultipath/autoconfig.h -+ -+$(BUILDDIRS): config.mk - $(MAKE) -C $@ - - $(LIB_BUILDDIRS:=.abi): $(LIB_BUILDDIRS) -@@ -83,7 +90,7 @@ libmultipath/checkers.install \ - libmultipath/prioritizers.install \ - libmultipath/foreign.install: libmultipath.install - --$(BUILDDIRS.clean): -+%.clean: - $(MAKE) -C ${@:.clean=} clean - - %.install: % -@@ -92,8 +99,12 @@ $(BUILDDIRS.clean): - $(BUILDDIRS:=.uninstall): - $(MAKE) -C ${@:.uninstall=} uninstall - --clean: $(BUILDDIRS.clean) -- rm -rf abi abi.tar.gz abi-test compile_commands.json -+# If config.mk is missing, "make clean" in subdir either fails, or tries to -+# build it. Both is undesirable. Avoid it by creating config.mk temporarily. -+clean: -+ @touch config.mk -+ $(MAKE) $(BUILDDIRS:=.clean) tests.clean || true -+ rm -rf abi abi.tar.gz abi-test compile_commands.json config.mk - - install: $(BUILDDIRS:=.install) - uninstall: $(BUILDDIRS:=.uninstall) -diff --git a/Makefile.inc b/Makefile.inc -index fe6bc088..415634f5 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -27,9 +27,9 @@ PKGCONFIG ?= pkg-config - ifeq ($(TOPDIR),) - TOPDIR = .. - endif -- --SYSTEMD := $(strip $(or $(shell $(PKGCONFIG) --modversion libsystemd 2>/dev/null | awk '{print $$1}'), \ -- $(shell systemctl --version 2>/dev/null | sed -n 's/systemd \([0-9]*\).*/\1/p'))) -+ifneq ($(CREATE_CONFIG),1) -+include $(TOPDIR)/config.mk -+endif - - # Paths. All these can be overridden on the "make" command line. - prefix := -@@ -65,37 +65,6 @@ RM := rm -f - LN := ln -sf - INSTALL_PROGRAM := install - --# $(call TEST_CC_OPTION,option,fallback) --# Test if the C compiler supports the option. --# Evaluates to "option" if yes, and "fallback" otherwise. --TEST_CC_OPTION = $(shell \ -- if echo 'int main(void){return 0;}' | \ -- $(CC) -o /dev/null -c -Werror "$(1)" -xc - >/dev/null 2>&1; \ -- then \ -- echo "$(1)"; \ -- else \ -- echo "$(2)"; \ -- fi) -- --# "make" on some distros will fail on explicit '#' or '\#' in the program text below --__HASH__ := \# --# Check if _DFORTIFY_SOURCE=3 is supported. --# On some distros (e.g. Debian Buster) it will be falsely reported as supported --# but it doesn't seem to make a difference wrt the compilation result. --FORTIFY_OPT := $(shell \ -- if /bin/echo -e '$(__HASH__)include \nint main(void) { return 0; }' | \ -- $(CC) -o /dev/null -c -O2 -Werror -D_FORTIFY_SOURCE=3 -xc - 2>/dev/null; \ -- then \ -- echo "-D_FORTIFY_SOURCE=3"; \ -- else \ -- echo "-D_FORTIFY_SOURCE=2"; \ -- fi) -- --STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector) --ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers,) --WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered -Wno-error=clobbered,) --WFORMATOVERFLOW := $(call TEST_CC_OPTION,-Wformat-overflow=2,) -- - SYSTEMD_CPPFLAGS := $(if $(SYSTEMD),-DUSE_SYSTEMD=$(SYSTEMD)) - SYSTEMD_LIBDEPS := $(if $(SYSTEMD),$(if $(shell test $(SYSTEMD) -gt 209 && echo 1),-lsystemd,-lsystemd-daemon)) - -@@ -133,45 +102,6 @@ LIBS = $(DEVLIB).$(SONAME) - VERSION_SCRIPT = $(DEVLIB:%.so=%.version) - NV_VERSION_SCRIPT = $(DEVLIB:%.so=%-nv.version) - --# Check whether a function with name $1 has been declared in header file $2. --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" \ -- ) -- --# Checker whether a file with name $1 exists --check_file = $(shell \ -- if [ -f "$1" ]; then \ -- found=1; \ -- status="yes"; \ -- else \ -- found=0; \ -- status="no"; \ -- fi; \ -- echo 1>&2 "Checking if $1 exists ... $$status"; \ -- echo "$$found" \ -- ) -- --# Check whether a file contains a variable with name $1 in header file $2 --check_var = $(shell \ -- if grep -Eq "(^|[[: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" \ -- ) -- - %.o: %.c - @echo building $@ because of $? - $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< -diff --git a/create-config.mk b/create-config.mk -new file mode 100644 -index 00000000..2cc5284f ---- /dev/null -+++ b/create-config.mk -@@ -0,0 +1,144 @@ -+# Copyright (c) SUSE LLC -+# SPDX-License-Identifier: GPL-2.0-or-later -+ -+TOPDIR := . -+CREATE_CONFIG := 1 -+include $(TOPDIR)/Makefile.inc -+ -+# Check whether a function with name $1 has been declared in header file $2. -+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" \ -+ ) -+ -+# Checker whether a file with name $1 exists -+check_file = $(shell \ -+ if [ -f "$1" ]; then \ -+ found=1; \ -+ status="yes"; \ -+ else \ -+ found=0; \ -+ status="no"; \ -+ fi; \ -+ echo 1>&2 "Checking if $1 exists ... $$status"; \ -+ echo "$$found" \ -+ ) -+ -+# Check whether a file contains a variable with name $1 in header file $2 -+check_var = $(shell \ -+ if grep -Eq "(^|[[: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" \ -+ ) -+ -+# Test special behavior of gcc 4.8 with nested initializers -+# gcc 4.8 compiles blacklist.c only with -Wno-missing-field-initializers -+TEST_MISSING_INITIALIZERS = $(shell \ -+ echo 'struct A {int a, b;}; struct B {struct A a; int b;} b = {.a.a=1};' | \ -+ $(CC) -c -Werror -Wmissing-field-initializers -o /dev/null -xc - >/dev/null 2>&1 \ -+ || echo -Wno-missing-field-initializers) -+ -+DEFINES := -+ -+ifneq ($(call check_func,dm_task_no_flush,$(devmapper_incdir)/libdevmapper.h),0) -+ DEFINES += LIBDM_API_FLUSH -+endif -+ -+ifneq ($(call check_func,dm_task_get_errno,$(devmapper_incdir)/libdevmapper.h),0) -+ DEFINES += LIBDM_API_GET_ERRNO -+endif -+ -+ifneq ($(call check_func,dm_task_set_cookie,$(devmapper_incdir)/libdevmapper.h),0) -+ DEFINES += LIBDM_API_COOKIE -+endif -+ -+ifneq ($(call check_func,udev_monitor_set_receive_buffer_size,$(libudev_incdir)/libudev.h),0) -+ DEFINES += LIBUDEV_API_RECVBUF -+endif -+ -+ifneq ($(call check_func,dm_task_deferred_remove,$(devmapper_incdir)/libdevmapper.h),0) -+ DEFINES += LIBDM_API_DEFERRED -+endif -+ -+ifneq ($(call check_func,dm_hold_control_dev,$(devmapper_incdir)/libdevmapper.h),0) -+ DEFINES += LIBDM_API_HOLD_CONTROL -+endif -+ -+ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(kernel_incdir)/scsi/fc/fc_els.h),0) -+ DEFINES += FPIN_EVENT_HANDLER -+ FPIN_SUPPORT = 1 -+endif -+ -+ifneq ($(call check_file,$(kernel_incdir)/linux/nvme_ioctl.h),0) -+ ANA_SUPPORT := 1 -+endif -+ -+ifeq ($(ENABLE_DMEVENTS_POLL),0) -+ DEFINES += -DNO_DMEVENTS_POLL -+endif -+ -+SYSTEMD := $(strip $(or $(shell $(PKGCONFIG) --modversion libsystemd 2>/dev/null | awk '{print $$1}'), \ -+ $(shell systemctl --version 2>/dev/null | sed -n 's/systemd \([0-9]*\).*/\1/p'))) -+ -+ -+# $(call TEST_CC_OPTION,option,fallback) -+# Test if the C compiler supports the option. -+# Evaluates to "option" if yes, and "fallback" otherwise. -+TEST_CC_OPTION = $(shell \ -+ if echo 'int main(void){return 0;}' | \ -+ $(CC) -o /dev/null -c -Werror "$(1)" -xc - >/dev/null 2>&1; \ -+ then \ -+ echo "$(1)"; \ -+ else \ -+ echo "$(2)"; \ -+ fi) -+ -+# "make" on some distros will fail on explicit '#' or '\#' in the program text below -+__HASH__ := \# -+# Check if _DFORTIFY_SOURCE=3 is supported. -+# On some distros (e.g. Debian Buster) it will be falsely reported as supported -+# but it doesn't seem to make a difference wrt the compilation result. -+FORTIFY_OPT := $(shell \ -+ if /bin/echo -e '$(__HASH__)include \nint main(void) { return 0; }' | \ -+ $(CC) -o /dev/null -c -O2 -Werror -D_FORTIFY_SOURCE=3 -xc - 2>/dev/null; \ -+ then \ -+ echo "-D_FORTIFY_SOURCE=3"; \ -+ else \ -+ echo "-D_FORTIFY_SOURCE=2"; \ -+ fi) -+ -+STACKPROT := -+ -+all: $(multipathdir)/autoconfig.h $(TOPDIR)/config.mk -+ -+$(multipathdir)/autoconfig.h: -+ @echo creating $@ -+ @echo '#ifndef _AUTOCONFIG_H' >$@ -+ @echo '#define _AUTOCONFIG_H' >>$@ -+ @for x in $(DEFINES); do echo "#define $$x" >>$@; done -+ @echo '#endif' >>$@ -+ -+$(TOPDIR)/config.mk: -+ @echo creating $@ -+ @echo "FPIN_SUPPORT := $(FPIN_SUPPORT)" >$@ -+ @echo "FORTIFY_OPT := $(FORTIFY_OPT)" >>$@ -+ @echo "SYSTEMD := $(SYSTEMD)" >>$@ -+ @echo "ANA_SUPPORT := $(ANA_SUPPORT)" >>$@ -+ @echo "STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector)" >>$@ -+ @echo "ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers,)" >>$@ -+ @echo "WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered -Wno-error=clobbered,)" >>$@ -+ @echo "WFORMATOVERFLOW := $(call TEST_CC_OPTION,-Wformat-overflow=2,)" >>$@ -+ @echo "W_MISSING_INITIALIZERS := $(call TEST_MISSING_INITIALIZERS)" >>$@ -diff --git a/kpartx/Makefile b/kpartx/Makefile -index 7ceae96b..31b1138a 100644 ---- a/kpartx/Makefile -+++ b/kpartx/Makefile -@@ -6,10 +6,6 @@ include ../Makefile.inc - EXEC := kpartx - - CPPFLAGS += -I. -I$(multipathdir) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 --ifneq ($(call check_func,dm_task_set_cookie,$(devmapper_incdir)/libdevmapper.h),0) -- CPPFLAGS += -DLIBDM_API_COOKIE --endif -- - CFLAGS += $(BIN_CFLAGS) - LDFLAGS += $(BIN_LDFLAGS) - LIBDEPS += -ldevmapper -diff --git a/kpartx/devmapper.c b/kpartx/devmapper.c -index bf14c784..f12762c5 100644 ---- a/kpartx/devmapper.c -+++ b/kpartx/devmapper.c -@@ -9,6 +9,7 @@ - #include - #include - #include -+#include "autoconfig.h" - #include "devmapper.h" - #include "kpartx.h" - -diff --git a/kpartx/kpartx.c b/kpartx/kpartx.c -index 1d568c9e..46cb76ba 100644 ---- a/kpartx/kpartx.c -+++ b/kpartx/kpartx.c -@@ -34,6 +34,7 @@ - #include - #include - -+#include "autoconfig.h" - #include "devmapper.h" - #include "crc32.h" - #include "lopart.h" -diff --git a/libdmmp/test/Makefile b/libdmmp/test/Makefile -index 76b24d61..93de64a0 100644 ---- a/libdmmp/test/Makefile -+++ b/libdmmp/test/Makefile -@@ -2,6 +2,7 @@ - # - # Copyright (C) 2015-2016 Gris Ge - # -+TOPDIR := ../.. - include ../../Makefile.inc - - _libdmmpdir=../$(libdmmpdir) -diff --git a/libmultipath/Makefile b/libmultipath/Makefile -index e24eab8a..1cc13577 100644 ---- a/libmultipath/Makefile -+++ b/libmultipath/Makefile -@@ -9,34 +9,6 @@ CFLAGS += $(LIB_CFLAGS) - LIBDEPS += -lpthread -ldl -ldevmapper -ludev -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd \ - -lurcu -laio $(SYSTEMD_LIBDEPS) - --ifneq ($(call check_func,dm_task_no_flush,$(devmapper_incdir)/libdevmapper.h),0) -- CPPFLAGS += -DLIBDM_API_FLUSH --endif -- --ifneq ($(call check_func,dm_task_get_errno,$(devmapper_incdir)/libdevmapper.h),0) -- CPPFLAGS += -DLIBDM_API_GET_ERRNO --endif -- --ifneq ($(call check_func,dm_task_set_cookie,$(devmapper_incdir)/libdevmapper.h),0) -- CPPFLAGS += -DLIBDM_API_COOKIE --endif -- --ifneq ($(call check_func,udev_monitor_set_receive_buffer_size,$(libudev_incdir)/libudev.h),0) -- CPPFLAGS += -DLIBUDEV_API_RECVBUF --endif -- --ifneq ($(call check_func,dm_task_deferred_remove,$(devmapper_incdir)/libdevmapper.h),0) -- CPPFLAGS += -DLIBDM_API_DEFERRED --endif -- --ifneq ($(call check_func,dm_hold_control_dev,$(devmapper_incdir)/libdevmapper.h),0) -- CPPFLAGS += -DLIBDM_API_HOLD_CONTROL --endif -- --ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(kernel_incdir)/scsi/fc/fc_els.h),0) -- CPPFLAGS += -DFPIN_EVENT_HANDLER --endif -- - # object files referencing MULTIPATH_DIR or CONFIG_DIR - # they need to be recompiled for unit tests - OBJS-U := prio.o checkers.o foreign.o config.o -@@ -97,7 +69,7 @@ uninstall: - $(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) - - clean: dep_clean -- $(RM) core *.a *.o *.so *.so.* *.abi nvme-ioctl.c nvme-ioctl.h $(NV_VERSION_SCRIPT) -+ $(RM) core *.a *.o *.so *.so.* *.abi nvme-ioctl.c nvme-ioctl.h autoconfig.h $(NV_VERSION_SCRIPT) - - include $(wildcard $(OBJS:.o=.d)) - -diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h -index 703f3bf8..42f8eccd 100644 ---- a/libmultipath/devmapper.h -+++ b/libmultipath/devmapper.h -@@ -1,6 +1,6 @@ - #ifndef _DEVMAPPER_H - #define _DEVMAPPER_H -- -+#include "autoconfig.h" - #include "structs.h" - - #define TGT_MPATH "multipath" -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index aa93fe43..6fc77315 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include "autoconfig.h" - #include "mpath_cmd.h" - #include "dict.h" - #include "strbuf.h" -diff --git a/libmultipath/prioritizers/Makefile b/libmultipath/prioritizers/Makefile -index 72eefe49..a699e8a6 100644 ---- a/libmultipath/prioritizers/Makefile -+++ b/libmultipath/prioritizers/Makefile -@@ -26,7 +26,7 @@ LIBS = \ - libpriopath_latency.so \ - libpriosysfs.so - --ifneq ($(call check_file,$(kernel_incdir)/linux/nvme_ioctl.h),0) -+ifneq ($(ANA_SUPPORT),1) - LIBS += libprioana.so - CPPFLAGS += -I../nvme - endif -diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c -index d4f19897..d1d5cc25 100644 ---- a/libmultipath/propsel.c -+++ b/libmultipath/propsel.c -@@ -5,6 +5,7 @@ - */ - #include - -+#include "autoconfig.h" - #include "nvme-lib.h" - #include "checkers.h" - #include "vector.h" -diff --git a/libmultipath/uevent.c b/libmultipath/uevent.c -index 57447ca0..bbc8e9e5 100644 ---- a/libmultipath/uevent.c -+++ b/libmultipath/uevent.c -@@ -42,6 +42,7 @@ - #include - #include - -+#include "autoconfig.h" - #include "debug.h" - #include "list.h" - #include "uevent.h" -diff --git a/multipathd/Makefile b/multipathd/Makefile -index bb8f7770..587bb916 100644 ---- a/multipathd/Makefile -+++ b/multipathd/Makefile -@@ -8,17 +8,6 @@ CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathpersistdir) -I$(mpathcm - awk -F. '{ printf("-DURCU_VERSION=0x%06x", 256 * ( 256 * $$1 + $$2) + $$3); }') \ - -DBINDIR='"$(bindir)"' $(SYSTEMD_CPPFLAGS) - --ifeq ($(ENABLE_DMEVENTS_POLL),0) -- CPPFLAGS += -DNO_DMEVENTS_POLL --endif --ifneq ($(call check_func,dm_task_get_errno,$(devmapper_incdir)/libdevmapper.h),0) -- CPPFLAGS += -DLIBDM_API_GET_ERRNO --endif --ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(kernel_incdir)/scsi/fc/fc_els.h),0) -- CPPFLAGS += -DFPIN_EVENT_HANDLER -- FPIN_SUPPORT = 1 --endif -- - # - # debugging stuff - # -diff --git a/multipathd/fpin.h b/multipathd/fpin.h -index bfcc1ce2..3c374441 100644 ---- a/multipathd/fpin.h -+++ b/multipathd/fpin.h -@@ -1,5 +1,6 @@ - #ifndef __FPIN_H__ - #define __FPIN_H__ -+#include "autoconfig.h" - - #ifdef FPIN_EVENT_HANDLER - void *fpin_fabric_notification_receiver(void *unused); -diff --git a/multipathd/main.c b/multipathd/main.c -index ba52d393..1e1b254f 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -4,6 +4,7 @@ - * Copyright (c) 2005 Benjamin Marzinski, Redhat - * Copyright (c) 2005 Edward Goggin, EMC - */ -+#include "autoconfig.h" - #include - #include - #include -diff --git a/rules.mk b/rules.mk -index c1d80820..d8612527 100644 ---- a/rules.mk -+++ b/rules.mk -@@ -13,3 +13,6 @@ $(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) - -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) - - abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) -+ -+$(TOPDIR)/config.mk $(multipathdir)/autoconfig.h: -+ $(MAKE) -C $(TOPDIR) -f create-config.mk -diff --git a/tests/Makefile b/tests/Makefile -index 3a5b161c..d9856d17 100644 ---- a/tests/Makefile -+++ b/tests/Makefile -@@ -3,14 +3,6 @@ include ../Makefile.inc - # directory where to run the tests - TESTDIR := $(CURDIR) - --# Test special behavior of gcc 4.8 with nested initializers --# gcc 4.8 compiles blacklist.c only with -Wno-missing-field-initializers --TEST_MISSING_INITIALIZERS = $(shell \ -- echo 'struct A {int a, b;}; struct B {struct A a; int b;} b = {.a.a=1};' | \ -- $(CC) -c -Werror -Wmissing-field-initializers -o /dev/null -xc - >/dev/null 2>&1 \ -- || echo -Wno-missing-field-initializers) --W_MISSING_INITIALIZERS := $(call TEST_MISSING_INITIALIZERS) -- - CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathcmddir) -I$(daemondir) \ - -DTESTCONFDIR=\"$(TESTDIR)/conf.d\" - CFLAGS += $(BIN_CFLAGS) -Wno-unused-parameter $(W_MISSING_INITIALIZERS) diff --git a/0042-RH-make-parse_vpd_pg83-match-scsi_id-output.patch b/0020-RH-make-parse_vpd_pg83-match-scsi_id-output.patch similarity index 94% rename from 0042-RH-make-parse_vpd_pg83-match-scsi_id-output.patch rename to 0020-RH-make-parse_vpd_pg83-match-scsi_id-output.patch index 5812a54..824c747 100644 --- a/0042-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +++ b/0020-RH-make-parse_vpd_pg83-match-scsi_id-output.patch @@ -14,10 +14,10 @@ Signed-off-by: Benjamin Marzinski 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index f3fccedd..c883fd02 100644 +index 67ac0e6d..7fdbc1c3 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c -@@ -1176,13 +1176,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, +@@ -1177,13 +1177,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, good_len = 8; break; case 2: @@ -33,7 +33,7 @@ index f3fccedd..c883fd02 100644 good_len = 8; break; default: -@@ -1200,10 +1196,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, +@@ -1201,10 +1197,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, break; case 0x8: /* SCSI Name: Prio 3 */ diff --git a/0020-multipath-tools-Makefiles-enable-quiet-build.patch b/0020-multipath-tools-Makefiles-enable-quiet-build.patch deleted file mode 100644 index dbe1129..0000000 --- a/0020-multipath-tools-Makefiles-enable-quiet-build.patch +++ /dev/null @@ -1,879 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 28 Oct 2022 12:39:06 +0200 -Subject: [PATCH] multipath-tools Makefiles: enable quiet build - -Like many other projects, make it possible to print much less -output during build. Verbose output is enabled with "make V=1", as -usual. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - Makefile | 12 +++---- - Makefile.inc | 10 +++--- - kpartx/Makefile | 41 ++++++++++++----------- - libdmmp/Makefile | 48 +++++++++++++------------- - libdmmp/test/Makefile | 8 ++--- - libmpathcmd/Makefile | 20 +++++------ - libmpathpersist/Makefile | 32 +++++++++--------- - libmpathutil/Makefile | 14 ++++---- - libmpathvalid/Makefile | 20 +++++------ - libmultipath/Makefile | 30 ++++++++--------- - libmultipath/checkers/Makefile | 8 ++--- - libmultipath/foreign/Makefile | 8 ++--- - libmultipath/prioritizers/Makefile | 8 ++--- - mpathpersist/Makefile | 18 +++++----- - multipath/Makefile | 54 ++++++++++++++++-------------- - multipathd/Makefile | 42 ++++++++++++----------- - rules.mk | 8 ++--- - tests/Makefile | 23 +++++++------ - 18 files changed, 206 insertions(+), 198 deletions(-) - -diff --git a/Makefile b/Makefile -index 1b28db62..e3ce1a8d 100644 ---- a/Makefile -+++ b/Makefile -@@ -38,17 +38,17 @@ config.mk libmultipath/autoconfig.h: - @cat libmultipath/autoconfig.h - - $(BUILDDIRS): config.mk -- $(MAKE) -C $@ -+ @$(MAKE) -C $@ - - $(LIB_BUILDDIRS:=.abi): $(LIB_BUILDDIRS) -- $(MAKE) -C ${@:.abi=} abi -+ @$(MAKE) -C ${@:.abi=} abi - - # Create formal representation of the ABI - # Useful for verifying ABI compatibility - # Requires abidw from the abigail suite (https://sourceware.org/libabigail/) - .PHONY: abi - abi: $(LIB_BUILDDIRS:=.abi) -- mkdir -p $@ -+ @mkdir -p $@ - ln -ft $@ $(LIB_BUILDDIRS:=/*.abi) - - abi.tar.gz: abi -@@ -91,13 +91,13 @@ libmultipath/checkers.install \ - libmultipath/foreign.install: libmultipath.install - - %.clean: -- $(MAKE) -C ${@:.clean=} clean -+ @$(MAKE) -C ${@:.clean=} clean - - %.install: % -- $(MAKE) -C ${@:.install=} install -+ @$(MAKE) -C ${@:.install=} install - - $(BUILDDIRS:=.uninstall): -- $(MAKE) -C ${@:.uninstall=} uninstall -+ @$(MAKE) -C ${@:.uninstall=} uninstall - - # If config.mk is missing, "make clean" in subdir either fails, or tries to - # build it. Both is undesirable. Avoid it by creating config.mk temporarily. -diff --git a/Makefile.inc b/Makefile.inc -index 415634f5..3e14cb8c 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -1,4 +1,4 @@ --# -+# -*- Makefile -*- - # Copyright (C) 2004 Christophe Varoqui, - # - -@@ -60,6 +60,8 @@ devmapper_incdir := $(or $(shell $(PKGCONFIG) --variable=includedir devmapper),/ - libudev_incdir := $(or $(shell $(PKGCONFIG) --variable=includedir libudev),/usr/include) - kernel_incdir := /usr/include - -+Q := $(if $(V),,@) -+ - GZIP_PROG := gzip -9 -c - RM := rm -f - LN := ln -sf -@@ -104,13 +106,13 @@ NV_VERSION_SCRIPT = $(DEVLIB:%.so=%-nv.version) - - %.o: %.c - @echo building $@ because of $? -- $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< -+ $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< - - %.abi: %.so.0 -- abidw $< >$@ -+ $(Q)abidw $< >$@ - - %.abi: %.so -- abidw $< >$@ -+ $(Q)abidw $< >$@ - - %-nv.version: %.version - @echo creating $@ from $< -diff --git a/kpartx/Makefile b/kpartx/Makefile -index 31b1138a..7720a740 100644 ---- a/kpartx/Makefile -+++ b/kpartx/Makefile -@@ -16,33 +16,34 @@ OBJS := bsd.o dos.o kpartx.o solaris.o unixware.o dasd.o sun.o \ - all: $(EXEC) - - $(EXEC): $(OBJS) -- $(CC) $(CFLAGS) $(OBJS) -o $(EXEC) $(LDFLAGS) $(LIBDEPS) -+ @echo building $@ because of $? -+ $(Q)$(CC) $(CFLAGS) $(OBJS) -o $(EXEC) $(LDFLAGS) $(LIBDEPS) - - install: $(EXEC) $(EXEC).8 -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) -- $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir) -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(libudevdir) -- $(INSTALL_PROGRAM) -m 755 kpartx_id $(DESTDIR)$(libudevdir) -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(libudevdir)/rules.d -- $(INSTALL_PROGRAM) -m 644 dm-parts.rules $(DESTDIR)$(libudevdir)/rules.d/11-dm-parts.rules -- $(INSTALL_PROGRAM) -m 644 kpartx.rules $(DESTDIR)$(libudevdir)/rules.d/66-kpartx.rules -- $(INSTALL_PROGRAM) -m 644 del-part-nodes.rules $(DESTDIR)$(libudevdir)/rules.d/68-del-part-nodes.rules -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 -- $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 -+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) -+ $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir) -+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(libudevdir) -+ $(Q)$(INSTALL_PROGRAM) -m 755 kpartx_id $(DESTDIR)$(libudevdir) -+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(libudevdir)/rules.d -+ $(Q)$(INSTALL_PROGRAM) -m 644 dm-parts.rules $(DESTDIR)$(libudevdir)/rules.d/11-dm-parts.rules -+ $(Q)$(INSTALL_PROGRAM) -m 644 kpartx.rules $(DESTDIR)$(libudevdir)/rules.d/66-kpartx.rules -+ $(Q)$(INSTALL_PROGRAM) -m 644 del-part-nodes.rules $(DESTDIR)$(libudevdir)/rules.d/68-del-part-nodes.rules -+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 -+ $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 - - uninstall: -- $(RM) $(DESTDIR)$(bindir)/$(EXEC) -- $(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 -- $(RM) $(DESTDIR)$(libudevdir)/kpartx_id -- $(RM) $(DESTDIR)$(libudevdir)/rules.d/11-dm-parts.rules -- $(RM) $(DESTDIR)$(libudevdir)/rules.d/66-kpartx.rules -- $(RM) $(DESTDIR)$(libudevdir)/rules.d/67-kpartx-compat.rules -- $(RM) $(DESTDIR)$(libudevdir)/rules.d/68-del-part-nodes.rules -+ $(Q)$(RM) $(DESTDIR)$(bindir)/$(EXEC) -+ $(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 -+ $(Q)$(RM) $(DESTDIR)$(libudevdir)/kpartx_id -+ $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/11-dm-parts.rules -+ $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/66-kpartx.rules -+ $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/67-kpartx-compat.rules -+ $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/68-del-part-nodes.rules - - clean: dep_clean -- $(RM) core *.o $(EXEC) -+ $(Q)$(RM) core *.o $(EXEC) - - include $(wildcard $(OBJS:.o=.d)) - - dep_clean: -- $(RM) $(OBJS:.o=.d) -+ $(Q)$(RM) $(OBJS:.o=.d) -diff --git a/libdmmp/Makefile b/libdmmp/Makefile -index 67b6f86f..7693facb 100644 ---- a/libdmmp/Makefile -+++ b/libdmmp/Makefile -@@ -23,62 +23,62 @@ all: $(LIBS) doc - .PHONY: doc clean install uninstall check speed_test dep_clean - - $(LIBS): $(OBJS) -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ -o $@ $(OBJS) $(LIBDEPS) -+ $(Q)$(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ -o $@ $(OBJS) $(LIBDEPS) - - $(DEVLIB): $(LIBS) -- $(LN) $(LIBS) $@ -+ $(Q)$(LN) $(LIBS) $@ - - abi: $(DEVLIB:%.so=%.abi) - - install: -- mkdir -p $(DESTDIR)$(usrlibdir) -- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(usrlibdir)/$(LIBS) -- $(INSTALL_PROGRAM) -m 644 -D \ -+ @mkdir -p $(DESTDIR)$(usrlibdir) -+ $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(usrlibdir)/$(LIBS) -+ $(Q)$(INSTALL_PROGRAM) -m 644 -D \ - $(HEADERS) $(DESTDIR)$(includedir)/$(HEADERS) -- $(LN) $(LIBS) $(DESTDIR)$(usrlibdir)/$(DEVLIB) -- $(INSTALL_PROGRAM) -m 644 -D \ -+ $(Q)$(LN) $(LIBS) $(DESTDIR)$(usrlibdir)/$(DEVLIB) -+ $(Q)$(INSTALL_PROGRAM) -m 644 -D \ - $(PKGFILE).in $(DESTDIR)$(pkgconfdir)/$(PKGFILE) -- perl -i -pe 's|__VERSION__|$(LIBDMMP_VERSION)|g' \ -+ $(Q)perl -i -pe 's|__VERSION__|$(LIBDMMP_VERSION)|g' \ - $(DESTDIR)$(pkgconfdir)/$(PKGFILE) -- perl -i -pe 's|__LIBDIR__|$(usrlibdir)|g' \ -+ $(Q)perl -i -pe 's|__LIBDIR__|$(usrlibdir)|g' \ - $(DESTDIR)$(pkgconfdir)/$(PKGFILE) -- perl -i -pe 's|__INCLUDEDIR__|$(includedir)|g' \ -+ $(Q)perl -i -pe 's|__INCLUDEDIR__|$(includedir)|g' \ - $(DESTDIR)$(pkgconfdir)/$(PKGFILE) -- $(INSTALL_PROGRAM) -d 755 $(DESTDIR)$(mandir)/man3 -- $(INSTALL_PROGRAM) -m 644 -t $(DESTDIR)$(mandir)/man3 docs/man/*.3 -+ $(Q)$(INSTALL_PROGRAM) -d 755 $(DESTDIR)$(mandir)/man3 -+ $(Q)$(INSTALL_PROGRAM) -m 644 -t $(DESTDIR)$(mandir)/man3 docs/man/*.3 - - uninstall: -- $(RM) $(DESTDIR)$(usrlibdir)/$(LIBS) -- $(RM) $(DESTDIR)$(includedir)/$(HEADERS) -- $(RM) $(DESTDIR)$(usrlibdir)/$(DEVLIB) -+ $(Q)$(RM) $(DESTDIR)$(usrlibdir)/$(LIBS) -+ $(Q)$(RM) $(DESTDIR)$(includedir)/$(HEADERS) -+ $(Q)$(RM) $(DESTDIR)$(usrlibdir)/$(DEVLIB) - @for file in $(DESTDIR)$(mandir)/man3/dmmp_*; do \ - $(RM) $$file; \ - done -- $(RM) $(DESTDIR)$(mandir)/man3/libdmmp.h* -- $(RM) $(DESTDIR)$(pkgconfdir)/$(PKGFILE) -+ $(Q)$(RM) $(DESTDIR)$(mandir)/man3/libdmmp.h* -+ $(Q)$(RM) $(DESTDIR)$(pkgconfdir)/$(PKGFILE) - - clean: dep_clean -- $(RM) core *.a *.o *.so *.so.* *.abi $(NV_VERSION_SCRIPT) -- $(MAKE) -C test clean -+ $(Q)$(RM) core *.a *.o *.so *.so.* *.abi $(NV_VERSION_SCRIPT) -+ @$(MAKE) -C test clean - - include $(wildcard $(OBJS:.o=.d)) - - check: all -- $(MAKE) -C test check -+ @$(MAKE) -C test check - - speed_test: all -- $(MAKE) -C test speed_test -+ @$(MAKE) -C test speed_test - - doc: docs/man/dmmp_strerror.3 - - docs/man/dmmp_strerror.3: $(HEADERS) -- TEMPFILE=$(shell mktemp); \ -+ $(Q)TEMPFILE=$(shell mktemp); \ - cat $^ | perl docs/doc-preclean.pl >$$TEMPFILE; \ - LC_ALL=C \ - KBUILD_BUILD_TIMESTAMP=`git log -n1 --pretty=%cd --date=iso -- $^` \ - perl docs/kernel-doc -man $$TEMPFILE | \ - perl docs/split-man.pl docs/man; \ -- rm -f $$TEMPFILE -+ $(RM) -f $$TEMPFILE - - dep_clean: -- $(RM) $(OBJS:.o=.d) -+ $(Q)$(RM) $(OBJS:.o=.d) -diff --git a/libdmmp/test/Makefile b/libdmmp/test/Makefile -index 93de64a0..9d0817c8 100644 ---- a/libdmmp/test/Makefile -+++ b/libdmmp/test/Makefile -@@ -16,7 +16,7 @@ LDFLAGS += -L$(_libdmmpdir) -ldmmp - all: $(TEST_EXEC) $(SPD_TEST_EXEC) - - check: $(TEST_EXEC) $(SPD_TEST_EXEC) -- sudo env LD_LIBRARY_PATH=$(_libdmmpdir):$(_mpathcmddir) \ -+ $(Q)sudo env LD_LIBRARY_PATH=$(_libdmmpdir):$(_mpathcmddir) \ - valgrind --quiet --leak-check=full \ - --show-reachable=no --show-possibly-lost=no \ - --trace-children=yes --error-exitcode=1 \ -@@ -24,15 +24,15 @@ check: $(TEST_EXEC) $(SPD_TEST_EXEC) - $(MAKE) speed_test - - speed_test: $(SPD_TEST_EXEC) -- sudo env LD_LIBRARY_PATH=$(_libdmmpdir):$(_mpathcmddir) \ -+ $(Q)sudo env LD_LIBRARY_PATH=$(_libdmmpdir):$(_mpathcmddir) \ - time -p ./$(SPD_TEST_EXEC) - - clean: dep_clean -- rm -f $(TEST_EXEC) $(SPD_TEST_EXEC) -+ $(Q)$(RM) -f $(TEST_EXEC) $(SPD_TEST_EXEC) - - OBJS = $(TEST_EXEC).o $(SPD_TEST_EXEC).o - include $(wildcard $(OBJS:.o=.d)) - - - dep_clean: -- $(RM) $(OBJS:.o=.d) -+ $(Q)$(RM) $(OBJS:.o=.d) -diff --git a/libmpathcmd/Makefile b/libmpathcmd/Makefile -index cfb202b8..be615c2f 100644 ---- a/libmpathcmd/Makefile -+++ b/libmpathcmd/Makefile -@@ -9,22 +9,22 @@ all: $(DEVLIB) - include $(TOPDIR)/rules.mk - - install: all -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) -- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) -- $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(includedir) -- $(INSTALL_PROGRAM) -m 644 mpath_cmd.h $(DESTDIR)$(includedir) -+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) -+ $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) -+ $(Q)$(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) -+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(includedir) -+ $(Q)$(INSTALL_PROGRAM) -m 644 mpath_cmd.h $(DESTDIR)$(includedir) - - uninstall: -- $(RM) $(DESTDIR)$(syslibdir)/$(LIBS) -- $(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) -- $(RM) $(DESTDIR)$(includedir)/mpath_cmd.h -+ $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(LIBS) -+ $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) -+ $(Q)$(RM) $(DESTDIR)$(includedir)/mpath_cmd.h - - clean: dep_clean -- $(RM) core *.a *.o *.so *.so.* *.abi $(NV_VERSION_SCRIPT) -+ $(Q)$(RM) core *.a *.o *.so *.so.* *.abi $(NV_VERSION_SCRIPT) - - include $(wildcard $(OBJS:.o=.d)) - - - dep_clean: -- $(RM) $(OBJS:.o=.d) -+ $(Q)$(RM) $(OBJS:.o=.d) -diff --git a/libmpathpersist/Makefile b/libmpathpersist/Makefile -index 94672556..8f9a43f6 100644 ---- a/libmpathpersist/Makefile -+++ b/libmpathpersist/Makefile -@@ -12,28 +12,28 @@ all: $(DEVLIB) - include $(TOPDIR)/rules.mk - - install: all -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) -- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) -- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(syslibdir) -- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(mandir)/man3 -- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(includedir) -- $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) -- $(INSTALL_PROGRAM) -m 644 mpath_persistent_reserve_in.3 $(DESTDIR)$(mandir)/man3 -- $(INSTALL_PROGRAM) -m 644 mpath_persistent_reserve_out.3 $(DESTDIR)$(mandir)/man3 -- $(INSTALL_PROGRAM) -m 644 mpath_persist.h $(DESTDIR)$(includedir) -+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) -+ $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) -+ $(Q)$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(syslibdir) -+ $(Q)$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(mandir)/man3 -+ $(Q)$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(includedir) -+ $(Q)$(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) -+ $(Q)$(INSTALL_PROGRAM) -m 644 mpath_persistent_reserve_in.3 $(DESTDIR)$(mandir)/man3 -+ $(Q)$(INSTALL_PROGRAM) -m 644 mpath_persistent_reserve_out.3 $(DESTDIR)$(mandir)/man3 -+ $(Q)$(INSTALL_PROGRAM) -m 644 mpath_persist.h $(DESTDIR)$(includedir) - - uninstall: -- $(RM) $(DESTDIR)$(syslibdir)/$(LIBS) -- $(RM) $(DESTDIR)$(mandir)/man3/mpath_persistent_reserve_in.3 -- $(RM) $(DESTDIR)$(mandir)/man3/mpath_persistent_reserve_out.3 -- $(RM) $(DESTDIR)$(includedir)/mpath_persist.h -- $(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) -+ $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(LIBS) -+ $(Q)$(RM) $(DESTDIR)$(mandir)/man3/mpath_persistent_reserve_in.3 -+ $(Q)$(RM) $(DESTDIR)$(mandir)/man3/mpath_persistent_reserve_out.3 -+ $(Q)$(RM) $(DESTDIR)$(includedir)/mpath_persist.h -+ $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) - - clean: dep_clean -- $(RM) core *.a *.o *.so *.so.* *.abi $(NV_VERSION_SCRIPT) -+ $(Q)$(RM) core *.a *.o *.so *.so.* *.abi $(NV_VERSION_SCRIPT) - - include $(wildcard $(OBJS:.o=.d)) - - - dep_clean: -- $(RM) $(OBJS:.o=.d) -+ $(Q)$(RM) $(OBJS:.o=.d) -diff --git a/libmpathutil/Makefile b/libmpathutil/Makefile -index 5ab33c09..f059de14 100644 ---- a/libmpathutil/Makefile -+++ b/libmpathutil/Makefile -@@ -20,18 +20,18 @@ all: $(DEVLIB) - include $(TOPDIR)/rules.mk - - install: all -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) -- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) -- $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) -+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) -+ $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) -+ $(Q)$(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) - - uninstall: -- $(RM) $(DESTDIR)$(syslibdir)/$(LIBS) -- $(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) -+ $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(LIBS) -+ $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) - - clean: dep_clean -- $(RM) core *.a *.o *.so *.so.* *.abi nvme-ioctl.c nvme-ioctl.h $(NV_VERSION_SCRIPT) -+ $(Q)$(RM) core *.a *.o *.so *.so.* *.abi nvme-ioctl.c nvme-ioctl.h $(NV_VERSION_SCRIPT) - - include $(wildcard $(OBJS:.o=.d)) - - dep_clean: -- $(RM) $(OBJS:.o=.d) -+ $(Q)$(RM) $(OBJS:.o=.d) -diff --git a/libmpathvalid/Makefile b/libmpathvalid/Makefile -index 88034df3..791a0398 100644 ---- a/libmpathvalid/Makefile -+++ b/libmpathvalid/Makefile -@@ -13,21 +13,21 @@ all: $(DEVLIB) - include $(TOPDIR)/rules.mk - - install: $(LIBS) -- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(syslibdir) -- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) -- $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) -- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(includedir) -- $(INSTALL_PROGRAM) -m 644 mpath_valid.h $(DESTDIR)$(includedir) -+ $(Q)$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(syslibdir) -+ $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) -+ $(Q)$(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) -+ $(Q)$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(includedir) -+ $(Q)$(INSTALL_PROGRAM) -m 644 mpath_valid.h $(DESTDIR)$(includedir) - - uninstall: -- $(RM) $(DESTDIR)$(syslibdir)/$(LIBS) -- $(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) -- $(RM) $(DESTDIR)$(includedir)/mpath_valid.h -+ $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(LIBS) -+ $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) -+ $(Q)$(RM) $(DESTDIR)$(includedir)/mpath_valid.h - - clean: dep_clean -- $(RM) core *.a *.o *.so *.so.* *.abi $(NV_VERSION_SCRIPT) -+ $(Q)$(RM) core *.a *.o *.so *.so.* *.abi $(NV_VERSION_SCRIPT) - - include $(wildcard $(OBJS:.o=.d)) - - dep_clean: -- $(RM) $(OBJS:.o=.d) -+ $(Q)$(RM) $(OBJS:.o=.d) -diff --git a/libmultipath/Makefile b/libmultipath/Makefile -index 1cc13577..3df851e2 100644 ---- a/libmultipath/Makefile -+++ b/libmultipath/Makefile -@@ -31,47 +31,47 @@ all: $(DEVLIB) - include $(TOPDIR)/rules.mk - - nvme-lib.o: nvme-lib.c nvme-ioctl.c nvme-ioctl.h -- $(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-function -c -o $@ $< -+ $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-function -c -o $@ $< - - # there are lots of "unused parameters" in dict.c - # because not all handler / snprint methods need all parameters - dict.o: dict.c -- $(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-parameter -c -o $@ $< -+ $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-parameter -c -o $@ $< - - make_static = $(shell sed '/^static/!s/^\([a-z]\{1,\} \)/static \1/' <$1 >$2) - - nvme-ioctl.c: nvme/nvme-ioctl.c -- $(call make_static,$<,$@) -+ $(Q)$(call make_static,$<,$@) - - nvme-ioctl.h: nvme/nvme-ioctl.h -- $(call make_static,$<,$@) -+ $(Q)$(call make_static,$<,$@) - - ../tests/$(LIBS): $(OBJS-O) $(OBJS-T) $(VERSION_SCRIPT) -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=`basename $@` \ -+ $(Q)$(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=`basename $@` \ - -o $@ $(OBJS-O) $(OBJS-T) $(LIBDEPS) -- $(LN) $@ ${@:.so.0=.so} -+ $(Q)$(LN) $@ ${@:.so.0=.so} - - # This rule is invoked from tests/Makefile, overriding configdir and plugindir - %-test.o: %.c - @echo building $@ because of $? -- $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< -+ $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< - - test-lib: ../tests/$(LIBS) - - install: all -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) -- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) -- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(plugindir) -- $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) -+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) -+ $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) -+ $(Q)$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(plugindir) -+ $(Q)$(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) - - uninstall: -- $(RM) $(DESTDIR)$(syslibdir)/$(LIBS) -- $(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) -+ $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(LIBS) -+ $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) - - clean: dep_clean -- $(RM) core *.a *.o *.so *.so.* *.abi nvme-ioctl.c nvme-ioctl.h autoconfig.h $(NV_VERSION_SCRIPT) -+ $(Q)$(RM) core *.a *.o *.so *.so.* *.abi nvme-ioctl.c nvme-ioctl.h autoconfig.h $(NV_VERSION_SCRIPT) - - include $(wildcard $(OBJS:.o=.d)) - - dep_clean: -- $(RM) $(OBJS:.o=.d) -+ $(Q)$(RM) $(OBJS:.o=.d) -diff --git a/libmultipath/checkers/Makefile b/libmultipath/checkers/Makefile -index 39ad76e0..b3120611 100644 ---- a/libmultipath/checkers/Makefile -+++ b/libmultipath/checkers/Makefile -@@ -22,16 +22,16 @@ LIBS= \ - all: $(LIBS) - - libcheck%.so: %.o -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) -+ $(Q)$(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) - - install: -- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(plugindir) -+ $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(plugindir) - - uninstall: - for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done - - clean: dep_clean -- $(RM) core *.a *.o *.gz *.so -+ $(Q)$(RM) core *.a *.o *.gz *.so - - OBJS := $(LIBS:libcheck%.so=%.o) - .SECONDARY: $(OBJS) -@@ -39,4 +39,4 @@ OBJS := $(LIBS:libcheck%.so=%.o) - include $(wildcard $(OBJS:.o=.d)) - - dep_clean: -- $(RM) $(OBJS:.o=.d) -+ $(Q)$(RM) $(OBJS:.o=.d) -diff --git a/libmultipath/foreign/Makefile b/libmultipath/foreign/Makefile -index 8bf9047b..0e245d6f 100644 ---- a/libmultipath/foreign/Makefile -+++ b/libmultipath/foreign/Makefile -@@ -14,16 +14,16 @@ LIBS = libforeign-nvme.so - all: $(LIBS) - - libforeign-%.so: %.o -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) -+ $(Q)$(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) - - install: -- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(plugindir) -+ $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(plugindir) - - uninstall: - for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done - - clean: dep_clean -- $(RM) core *.a *.o *.gz *.so -+ $(Q)$(RM) core *.a *.o *.gz *.so - - OBJS := $(LIBS:libforeign-%.so=%.o) - .SECONDARY: $(OBJS) -@@ -31,4 +31,4 @@ OBJS := $(LIBS:libforeign-%.so=%.o) - include $(wildcard $(OBJS:.o=.d)) - - dep_clean: -- $(RM) $(OBJS:.o=.d) -+ $(Q)$(RM) $(OBJS:.o=.d) -diff --git a/libmultipath/prioritizers/Makefile b/libmultipath/prioritizers/Makefile -index a699e8a6..e1688163 100644 ---- a/libmultipath/prioritizers/Makefile -+++ b/libmultipath/prioritizers/Makefile -@@ -34,16 +34,16 @@ endif - all: $(LIBS) - - libprio%.so: %.o -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) -+ $(Q)$(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) - - install: $(LIBS) -- $(INSTALL_PROGRAM) -m 755 libprio*.so $(DESTDIR)$(plugindir) -+ $(Q)$(INSTALL_PROGRAM) -m 755 libprio*.so $(DESTDIR)$(plugindir) - - uninstall: - for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done - - clean: dep_clean -- $(RM) core *.a *.o *.gz *.so -+ $(Q)$(RM) core *.a *.o *.gz *.so - - OBJS = $(LIBS:libprio%.so=%.o) alua_rtpg.o - .SECONDARY: $(OBJS) -@@ -51,4 +51,4 @@ OBJS = $(LIBS:libprio%.so=%.o) alua_rtpg.o - include $(wildcard $(OBJS:.o=.d)) - - dep_clean: -- $(RM) $(OBJS:.o=.d) -+ $(Q)$(RM) $(OBJS:.o=.d) -diff --git a/mpathpersist/Makefile b/mpathpersist/Makefile -index d62537b5..f57c105c 100644 ---- a/mpathpersist/Makefile -+++ b/mpathpersist/Makefile -@@ -14,22 +14,22 @@ OBJS = main.o - all: $(EXEC) - - $(EXEC): $(OBJS) -- $(CC) $(OBJS) -o $(EXEC) $(LDFLAGS) $(CFLAGS) $(LIBDEPS) -+ $(Q)$(CC) $(OBJS) -o $(EXEC) $(LDFLAGS) $(CFLAGS) $(LIBDEPS) - - install: -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) -- $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 -- $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 -+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) -+ $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ -+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 -+ $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 - - clean: dep_clean -- $(RM) core *.o $(EXEC) -+ $(Q)$(RM) core *.o $(EXEC) - - include $(wildcard $(OBJS:.o=.d)) - - uninstall: -- $(RM) $(DESTDIR)$(bindir)/$(EXEC) -- $(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 -+ $(Q)$(RM) $(DESTDIR)$(bindir)/$(EXEC) -+ $(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 - - dep_clean: -- $(RM) $(OBJS:.o=.d) -+ $(Q)$(RM) $(OBJS:.o=.d) -diff --git a/multipath/Makefile b/multipath/Makefile -index 7f7b341d..73db991a 100644 ---- a/multipath/Makefile -+++ b/multipath/Makefile -@@ -16,44 +16,46 @@ OBJS := main.o - all: $(EXEC) multipath.rules tmpfiles.conf - - $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so -- $(CC) $(CFLAGS) $(OBJS) -o $(EXEC) $(LDFLAGS) $(LIBDEPS) -+ @echo building $@ because of $? -+ $(Q)$(CC) $(CFLAGS) $(OBJS) -o $(EXEC) $(LDFLAGS) $(LIBDEPS) - - install: -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) -- $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) -- $(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) -- $(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)$(udevrulesdir)/56-multipath.rules -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(modulesloaddir) -- $(INSTALL_PROGRAM) -m 644 modules-load.conf $(DESTDIR)$(modulesloaddir)/multipath.conf -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(tmpfilesdir) -- $(INSTALL_PROGRAM) -m 644 tmpfiles.conf $(DESTDIR)$(tmpfilesdir)/multipath.conf -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 -- $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man5 -- $(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5 $(DESTDIR)$(mandir)/man5 -+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) -+ $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ -+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) -+ $(Q)$(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) -+ $(Q)$(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)$(udevrulesdir)/56-multipath.rules -+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(modulesloaddir) -+ $(Q)$(INSTALL_PROGRAM) -m 644 modules-load.conf $(DESTDIR)$(modulesloaddir)/multipath.conf -+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(tmpfilesdir) -+ $(Q)$(INSTALL_PROGRAM) -m 644 tmpfiles.conf $(DESTDIR)$(tmpfilesdir)/multipath.conf -+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 -+ $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 -+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man5 -+ $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5 $(DESTDIR)$(mandir)/man5 - ifneq ($(SCSI_DH_MODULES_PRELOAD),) -- $(INSTALL_PROGRAM) -m 644 scsi_dh.conf $(DESTDIR)$(modulesloaddir)/scsi_dh.conf -- for _x in $(SCSI_DH_MODULES_PRELOAD); do echo "$$_x"; done \ -+ $(Q)$(INSTALL_PROGRAM) -m 644 scsi_dh.conf $(DESTDIR)$(modulesloaddir)/scsi_dh.conf -+ $(Q)for _x in $(SCSI_DH_MODULES_PRELOAD); do echo "$$_x"; done \ - >>$(DESTDIR)$(modulesloaddir)/scsi_dh.conf - endif - - uninstall: -- $(RM) $(DESTDIR)$(bindir)/$(EXEC) -- $(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules -- $(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf -- $(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf -- $(RM) $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules -- $(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 -- $(RM) $(DESTDIR)$(mandir)/man5/$(EXEC).conf.5 -+ $(Q)$(RM) $(DESTDIR)$(bindir)/$(EXEC) -+ $(Q)$(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules -+ $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf -+ $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf -+ $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules -+ $(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 -+ $(Q)$(RM) $(DESTDIR)$(mandir)/man5/$(EXEC).conf.5 - - clean: dep_clean -- $(RM) core *.o $(EXEC) multipath.rules tmpfiles.conf -+ $(Q)$(RM) core *.o $(EXEC) multipath.rules tmpfiles.conf - - include $(wildcard $(OBJS:.o=.d)) - - dep_clean: -- $(RM) $(OBJS:.o=.d) -+ $(Q)$(RM) $(OBJS:.o=.d) - - %: %.in -- sed 's,@RUNTIME_DIR@,$(runtimedir),' $< >$@ -+ @echo creating $@ -+ $(Q)sed 's,@RUNTIME_DIR@,$(runtimedir),' $< >$@ -diff --git a/multipathd/Makefile b/multipathd/Makefile -index 587bb916..9d531329 100644 ---- a/multipathd/Makefile -+++ b/multipathd/Makefile -@@ -45,41 +45,43 @@ endif - all : $(EXEC) $(CLI) - - $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so -- $(CC) $(CFLAGS) $(OBJS) $(LDFLAGS) -o $(EXEC) $(LIBDEPS) -+ @echo building $@ because of $? -+ $(Q)$(CC) $(CFLAGS) $(OBJS) $(LDFLAGS) -o $(EXEC) $(LIBDEPS) - - multipathc.o: multipathc.c -- $(CC) $(CPPFLAGS) $(RL_CPPFLAGS) $(CFLAGS) -Wno-unused-parameter -c -o $@ $< -+ $(Q)$(CC) $(CPPFLAGS) $(RL_CPPFLAGS) $(CFLAGS) -Wno-unused-parameter -c -o $@ $< - - $(CLI): $(CLI_OBJS) -- $(CC) $(CFLAGS) $(CLI_OBJS) $(LDFLAGS) -o $@ $(CLI_LIBDEPS) $(RL_LIBDEPS) -+ @echo building $@ because of $? -+ $(Q)$(CC) $(CFLAGS) $(CLI_OBJS) $(LDFLAGS) -o $@ $(CLI_LIBDEPS) $(RL_LIBDEPS) - - cli_handlers.o: cli_handlers.c -- $(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-parameter -c -o $@ $< -+ $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-parameter -c -o $@ $< - - install: -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) -- $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir) -- $(INSTALL_PROGRAM) -m 755 $(CLI) $(DESTDIR)$(bindir) -+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) -+ $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir) -+ $(Q)$(INSTALL_PROGRAM) -m 755 $(CLI) $(DESTDIR)$(bindir) - ifdef SYSTEMD -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(unitdir) -- $(INSTALL_PROGRAM) -m 644 $(EXEC).service $(DESTDIR)$(unitdir) -- $(INSTALL_PROGRAM) -m 644 $(EXEC).socket $(DESTDIR)$(unitdir) -+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(unitdir) -+ $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).service $(DESTDIR)$(unitdir) -+ $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).socket $(DESTDIR)$(unitdir) - endif -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 -- $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 -- $(INSTALL_PROGRAM) -m 644 $(CLI).8 $(DESTDIR)$(mandir)/man8 -+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 -+ $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 -+ $(Q)$(INSTALL_PROGRAM) -m 644 $(CLI).8 $(DESTDIR)$(mandir)/man8 - - uninstall: -- $(RM) $(DESTDIR)$(bindir)/$(EXEC) $(DESTDIR)$(bindir)/$(CLI) -- $(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 -- $(RM) $(DESTDIR)$(mandir)/man8/$(CLI).8 -- $(RM) $(DESTDIR)$(unitdir)/$(EXEC).service -- $(RM) $(DESTDIR)$(unitdir)/$(EXEC).socket -+ $(Q)$(RM) $(DESTDIR)$(bindir)/$(EXEC) $(DESTDIR)$(bindir)/$(CLI) -+ $(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 -+ $(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(CLI).8 -+ $(Q)$(RM) $(DESTDIR)$(unitdir)/$(EXEC).service -+ $(Q)$(RM) $(DESTDIR)$(unitdir)/$(EXEC).socket - - clean: dep_clean -- $(RM) core *.o $(EXEC) $(CLI) -+ $(Q)$(RM) core *.o $(EXEC) $(CLI) - - include $(wildcard $(OBJS:.o=.d)) - - dep_clean: -- $(RM) $(OBJS:.o=.d) -+ $(Q)$(RM) $(OBJS:.o=.d) -diff --git a/rules.mk b/rules.mk -index d8612527..c3a8e7ac 100644 ---- a/rules.mk -+++ b/rules.mk -@@ -2,17 +2,17 @@ - # SPDX-License-Identifier: GPL-2.0-or-later - - $(DEVLIB): $(LIBS) -- $(LN) $(LIBS) $@ -+ $(Q)$(LN) $(LIBS) $@ - - $(LIBS): $(OBJS) $(VERSION_SCRIPT) -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ -+ $(Q)$(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ - -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) - - $(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ -+ $(Q)$(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ - -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) - - abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) - - $(TOPDIR)/config.mk $(multipathdir)/autoconfig.h: -- $(MAKE) -C $(TOPDIR) -f create-config.mk -+ $(Q)$(MAKE) -C $(TOPDIR) -f create-config.mk -diff --git a/tests/Makefile b/tests/Makefile -index d9856d17..021da0b0 100644 ---- a/tests/Makefile -+++ b/tests/Makefile -@@ -12,7 +12,6 @@ TESTS := uevent parser util dmevents hwtable blacklist unaligned vpd pgpolicy \ - alias directio valid devt mpathvalid strbuf sysfs features cli - HELPERS := test-lib.o test-log.o - --.SILENT: $(TESTS:%=%.o) - .PRECIOUS: $(TESTS:%=%-test) - - all: $(TESTS:%=%.out) -@@ -71,11 +70,12 @@ features-test_LIBDEPS := -ludev -lpthread - cli-test_OBJDEPS := $(daemondir)/cli.o - - %.o: %.c -- $(CC) $(CPPFLAGS) $(CFLAGS) $($*-test_FLAGS) -c -o $@ $< -+ @echo building $@ because of $? -+ $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) $($*-test_FLAGS) -c -o $@ $< - - lib/libchecktur.so: -- mkdir -p lib -- cd lib && ln -s ../$(multipathdir)/*/*.so . -+ @mkdir -p lib -+ $(Q)cd lib && ln -s ../$(multipathdir)/*/*.so . - - %.out: %-test lib/libchecktur.so - @echo == running $< == -@@ -89,34 +89,35 @@ lib/libchecktur.so: - OBJS = $(TESTS:%=%.o) $(HELPERS) - - test_clean: -- $(RM) $(TESTS:%=%.out) $(TESTS:%=%.vgr) *.so* -+ $(Q)$(RM) $(TESTS:%=%.out) $(TESTS:%=%.vgr) *.so* - - valgrind_clean: -- $(RM) $(TESTS:%=%.vgr) -+ $(Q)$(RM) $(TESTS:%=%.vgr) - - clean: test_clean valgrind_clean dep_clean -- $(RM) $(TESTS:%=%-test) $(OBJS) *.o.wrap -- $(RM) -rf lib conf.d -+ $(Q)$(RM) $(TESTS:%=%-test) $(OBJS) *.o.wrap -+ $(Q)$(RM) -rf lib conf.d - - .SECONDARY: $(OBJS) - - include $(wildcard $(OBJS:.o=.d)) - - dep_clean: -- $(RM) $(OBJS:.o=.d) -+ $(Q)$(RM) $(OBJS:.o=.d) - - %.o.wrap: %.c - @sed -n 's/^.*__wrap_\([a-zA-Z0-9_]*\).*$$/-Wl,--wrap=\1/p' $< | \ - sort -u | tr '\n' ' ' >$@ - - libmultipath.so.0: $(multipathdir)/libmultipath.so.0 -- make -C $(multipathdir) configdir=$(TESTDIR)/conf.d plugindir=$(TESTDIR)/lib test-lib -+ @make -C $(multipathdir) configdir=$(TESTDIR)/conf.d plugindir=$(TESTDIR)/lib test-lib - - # COLON will get expanded during second expansion below - COLON:=: - .SECONDEXPANSION: - %-test: %.o %.o.wrap $$($$@_OBJDEPS) $$($$@_TESTDEPS) $$($$@_TESTDEPS$$(COLON).o=.o.wrap) \ - libmultipath.so.0 $(mpathutildir)/libmpathutil.so.0 $(mpathcmddir)/libmpathcmd.so.0 Makefile -- $(CC) $(CFLAGS) -o $@ $(LDFLAGS) $< $($@_TESTDEPS) $($@_OBJDEPS) \ -+ @echo building $@ -+ $(Q)$(CC) $(CFLAGS) -o $@ $(LDFLAGS) $< $($@_TESTDEPS) $($@_OBJDEPS) \ - $(LIBDEPS) $($@_LIBDEPS) \ - $(shell cat $<.wrap) $(foreach dep,$($@_TESTDEPS),$(shell cat $(dep).wrap)) diff --git a/0043-RH-add-scsi-device-handlers-to-modules-load.d.patch b/0021-RH-add-scsi-device-handlers-to-modules-load.d.patch similarity index 96% rename from 0043-RH-add-scsi-device-handlers-to-modules-load.d.patch rename to 0021-RH-add-scsi-device-handlers-to-modules-load.d.patch index 72fbfe8..26b0d06 100644 --- a/0043-RH-add-scsi-device-handlers-to-modules-load.d.patch +++ b/0021-RH-add-scsi-device-handlers-to-modules-load.d.patch @@ -11,7 +11,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc -index e6e7f7d7..15f0b9f6 100644 +index 748911e2..c07bcb0c 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -16,7 +16,7 @@ READLINE := diff --git a/0021-multipath-tools-quiet-build-support-for-top-level-Ma.patch b/0021-multipath-tools-quiet-build-support-for-top-level-Ma.patch deleted file mode 100644 index d45f99f..0000000 --- a/0021-multipath-tools-quiet-build-support-for-top-level-Ma.patch +++ /dev/null @@ -1,183 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 28 Oct 2022 14:39:22 +0200 -Subject: [PATCH] multipath-tools: quiet build support for top-level Makefile - -This requires including "Makefile.inc" in the top-level Makefile, -too. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - Makefile | 32 ++++++++++++++++++------------ - Makefile.inc | 8 ++++++-- - create-config.mk | 1 - - libmultipath/checkers/Makefile | 2 +- - libmultipath/foreign/Makefile | 2 +- - libmultipath/prioritizers/Makefile | 2 +- - 6 files changed, 28 insertions(+), 19 deletions(-) - -diff --git a/Makefile b/Makefile -index e3ce1a8d..b9e30234 100644 ---- a/Makefile -+++ b/Makefile -@@ -2,6 +2,9 @@ - # Copyright (C) 2003 Christophe Varoqui, - # - -+TOPDIR := . -+include Makefile.inc -+ - LIB_BUILDDIRS := \ - libmpathcmd \ - libmpathutil \ -@@ -32,10 +35,12 @@ all: $(BUILDDIRS) - - config.mk libmultipath/autoconfig.h: - @$(MAKE) -f create-config.mk -+ifeq ($(V),1) - @echo ==== config.mk ==== - @cat config.mk - @echo ==== autoconfig.h ==== - @cat libmultipath/autoconfig.h -+endif - - $(BUILDDIRS): config.mk - @$(MAKE) -C $@ -@@ -48,11 +53,12 @@ $(LIB_BUILDDIRS:=.abi): $(LIB_BUILDDIRS) - # Requires abidw from the abigail suite (https://sourceware.org/libabigail/) - .PHONY: abi - abi: $(LIB_BUILDDIRS:=.abi) -+ @echo creating abi - @mkdir -p $@ -- ln -ft $@ $(LIB_BUILDDIRS:=/*.abi) -+ $(Q)ln -ft $@ $(LIB_BUILDDIRS:=/*.abi) - - abi.tar.gz: abi -- tar cfz $@ abi -+ $(Q)tar cfz $@ abi - - # Check the ABI against a reference. - # This requires the ABI from a previous run to be present -@@ -77,8 +83,8 @@ abi-test: abi reference-abi $(wildcard abi/*.abi) - # Create compile_commands.json, useful for using clangd with an IDE - # Requires bear (https://github.com/rizsotto/Bear) - compile_commands.json: Makefile Makefile.inc $(BUILDDIRS:=/Makefile) -- $(MAKE) clean -- bear -- $(MAKE) -+ $(Q)$(MAKE) clean -+ $(Q)bear -- $(MAKE) - - libmpathutil libdmmp: libmpathcmd - libmultipath: libmpathutil -@@ -103,24 +109,24 @@ $(BUILDDIRS:=.uninstall): - # build it. Both is undesirable. Avoid it by creating config.mk temporarily. - clean: - @touch config.mk -- $(MAKE) $(BUILDDIRS:=.clean) tests.clean || true -- rm -rf abi abi.tar.gz abi-test compile_commands.json config.mk -+ $(Q)$(MAKE) $(BUILDDIRS:=.clean) tests.clean || true -+ $(Q)$(RM) -r abi abi.tar.gz abi-test compile_commands.json config.mk - - install: $(BUILDDIRS:=.install) - uninstall: $(BUILDDIRS:=.uninstall) - - test-progs: all -- $(MAKE) -C tests progs -+ @$(MAKE) -C tests progs - - test: all -- $(MAKE) -C tests all -+ @$(MAKE) -C tests all - - valgrind-test: all -- $(MAKE) -C tests valgrind -+ @$(MAKE) -C tests valgrind - - .PHONY: TAGS - TAGS: -- etags -a libmultipath/*.c -- etags -a libmultipath/*.h -- etags -a multipathd/*.c -- etags -a multipathd/*.h -+ @etags -a libmultipath/*.c -+ @etags -a libmultipath/*.h -+ @etags -a multipathd/*.c -+ @etags -a multipathd/*.h -diff --git a/Makefile.inc b/Makefile.inc -index 3e14cb8c..866ab274 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -27,7 +27,7 @@ PKGCONFIG ?= pkg-config - ifeq ($(TOPDIR),) - TOPDIR = .. - endif --ifneq ($(CREATE_CONFIG),1) -+ifneq ($(TOPDIR),.) - include $(TOPDIR)/config.mk - endif - -@@ -60,7 +60,11 @@ devmapper_incdir := $(or $(shell $(PKGCONFIG) --variable=includedir devmapper),/ - libudev_incdir := $(or $(shell $(PKGCONFIG) --variable=includedir libudev),/usr/include) - kernel_incdir := /usr/include - --Q := $(if $(V),,@) -+ifeq ($(V),) -+Q := @ -+# make's "Entering directory" messages are confusing in parallel mode -+#MAKEFLAGS = --no-print-directory -+endif - - GZIP_PROG := gzip -9 -c - RM := rm -f -diff --git a/create-config.mk b/create-config.mk -index 2cc5284f..434dee06 100644 ---- a/create-config.mk -+++ b/create-config.mk -@@ -2,7 +2,6 @@ - # SPDX-License-Identifier: GPL-2.0-or-later - - TOPDIR := . --CREATE_CONFIG := 1 - include $(TOPDIR)/Makefile.inc - - # Check whether a function with name $1 has been declared in header file $2. -diff --git a/libmultipath/checkers/Makefile b/libmultipath/checkers/Makefile -index b3120611..6f7cfb95 100644 ---- a/libmultipath/checkers/Makefile -+++ b/libmultipath/checkers/Makefile -@@ -28,7 +28,7 @@ install: - $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(plugindir) - - uninstall: -- for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done -+ $(Q)for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done - - clean: dep_clean - $(Q)$(RM) core *.a *.o *.gz *.so -diff --git a/libmultipath/foreign/Makefile b/libmultipath/foreign/Makefile -index 0e245d6f..b83213d6 100644 ---- a/libmultipath/foreign/Makefile -+++ b/libmultipath/foreign/Makefile -@@ -20,7 +20,7 @@ install: - $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(plugindir) - - uninstall: -- for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done -+ $(Q)for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done - - clean: dep_clean - $(Q)$(RM) core *.a *.o *.gz *.so -diff --git a/libmultipath/prioritizers/Makefile b/libmultipath/prioritizers/Makefile -index e1688163..fdec36e7 100644 ---- a/libmultipath/prioritizers/Makefile -+++ b/libmultipath/prioritizers/Makefile -@@ -40,7 +40,7 @@ install: $(LIBS) - $(Q)$(INSTALL_PROGRAM) -m 755 libprio*.so $(DESTDIR)$(plugindir) - - uninstall: -- for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done -+ $(Q)for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done - - clean: dep_clean - $(Q)$(RM) core *.a *.o *.gz *.so diff --git a/0022-GitHub-workflows-use-make-j8-Orecurse.patch b/0022-GitHub-workflows-use-make-j8-Orecurse.patch deleted file mode 100644 index 33b7dcd..0000000 --- a/0022-GitHub-workflows-use-make-j8-Orecurse.patch +++ /dev/null @@ -1,132 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 28 Oct 2022 15:29:51 +0200 -Subject: [PATCH] GitHub workflows: use make -j8 -Orecurse - -Without -Orecurse, quiet make output is confusing in parallel mode -because make prints "Entering directory" and "Leaving directory" -messages before and after every target. - -Use parallel compilation also in native.yaml and foreign.yaml. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/abi.yaml | 2 +- - .github/workflows/build-and-unittest.yaml | 18 +++++++++--------- - .github/workflows/coverity.yaml | 2 +- - .github/workflows/foreign.yaml | 4 ++-- - .github/workflows/native.yaml | 6 +++--- - 5 files changed, 16 insertions(+), 16 deletions(-) - -diff --git a/.github/workflows/abi.yaml b/.github/workflows/abi.yaml -index 89b971cd..644fcb62 100644 ---- a/.github/workflows/abi.yaml -+++ b/.github/workflows/abi.yaml -@@ -32,7 +32,7 @@ jobs: - libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev - libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev - - name: create ABI -- run: make -O -j$(grep -c ^processor /proc/cpuinfo) abi.tar.gz -+ run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) abi.tar.gz - - name: save ABI - uses: actions/upload-artifact@v1 - with: -diff --git a/.github/workflows/build-and-unittest.yaml b/.github/workflows/build-and-unittest.yaml -index a5a0717d..8b6bb776 100644 ---- a/.github/workflows/build-and-unittest.yaml -+++ b/.github/workflows/build-and-unittest.yaml -@@ -32,11 +32,11 @@ jobs: - libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev - libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev - - name: build -- run: make -O -j$(grep -c ^processor /proc/cpuinfo) READLINE=${{ matrix.rl }} -+ run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) READLINE=${{ matrix.rl }} - - name: test -- run: make -O -j$(grep -c ^processor /proc/cpuinfo) test -+ run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) test - - name: valgrind-test -- run: make -O -j$(grep -c ^processor /proc/cpuinfo) valgrind-test -+ run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) valgrind-test - - name: valgrind-results - run: cat tests/*.vgr - - name: clean-nonroot-artifacts -@@ -65,11 +65,11 @@ jobs: - - name: set CC - run: echo CC=gcc-10 >> $GITHUB_ENV - - name: build -- run: make -O -j$(grep -c ^processor /proc/cpuinfo) READLINE=${{ matrix.rl }} -+ run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) READLINE=${{ matrix.rl }} - - name: test -- run: make -O -j$(grep -c ^processor /proc/cpuinfo) test -+ run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) test - - name: valgrind-test -- run: make -O -j$(grep -c ^processor /proc/cpuinfo) valgrind-test -+ run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) valgrind-test - - name: valgrind-results - run: cat tests/*.vgr - - name: clean-nonroot-artifacts -@@ -98,11 +98,11 @@ jobs: - - name: set CC - run: echo CC=clang >> $GITHUB_ENV - - name: build -- run: make -O -j$(grep -c ^processor /proc/cpuinfo) READLINE=${{ matrix.rl }} -+ run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) READLINE=${{ matrix.rl }} - - name: test -- run: make -O -j$(grep -c ^processor /proc/cpuinfo) test -+ run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) test - - name: valgrind-test -- run: make -O -j$(grep -c ^processor /proc/cpuinfo) valgrind-test -+ run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) valgrind-test - - name: valgrind-results - run: cat tests/*.vgr - - name: clean-nonroot-artifacts -diff --git a/.github/workflows/coverity.yaml b/.github/workflows/coverity.yaml -index 3c6b3824..321b94e0 100644 ---- a/.github/workflows/coverity.yaml -+++ b/.github/workflows/coverity.yaml -@@ -32,7 +32,7 @@ jobs: - - name: build with cov-build - run: > - PATH="$PWD/coverity/bin:$PATH" -- cov-build --dir cov-int make -O -j"$(grep -c ^processor /proc/cpuinfo)" -+ cov-build --dir cov-int make -Orecurse -j"$(grep -c ^processor /proc/cpuinfo)" - - name: pack results - run: tar cfz multipath-tools.tgz cov-int - - name: submit results -diff --git a/.github/workflows/foreign.yaml b/.github/workflows/foreign.yaml -index 5a19913a..72ac24fb 100644 ---- a/.github/workflows/foreign.yaml -+++ b/.github/workflows/foreign.yaml -@@ -21,11 +21,11 @@ jobs: - uses: actions/checkout@v1 - - name: build and test - if: ${{ matrix.arch == '' || matrix.arch == '-i386' }} -- run: make test -+ run: make -j8 -Orecurse test - - name: build - if: ${{ matrix.arch != '' && matrix.arch != '-i386' }} - # The build path is different between builder and runner -- run: make TESTDIR=${{ github.workspace }}/tests test-progs -+ run: make -j8 -Orecurse TESTDIR=${{ github.workspace }}/tests test-progs - - name: archive - if: ${{ matrix.arch != '' && matrix.arch != '-i386' }} - run: > -diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml -index 8b599209..68bf0984 100644 ---- a/.github/workflows/native.yaml -+++ b/.github/workflows/native.yaml -@@ -92,10 +92,10 @@ jobs: - - name: checkout - uses: actions/checkout@v1 - - name: build and test -- run: make test -+ run: make -j8 -Orecurse test - - name: clean -- run: make clean -+ run: make -j8 -Orecurse clean - - name: clang - env: - CC: clang -- run: make test -+ run: make -j8 -Orecurse test diff --git a/0044-RH-compile-with-libreadline-support.patch b/0022-RH-compile-with-libreadline-support.patch similarity index 96% rename from 0044-RH-compile-with-libreadline-support.patch rename to 0022-RH-compile-with-libreadline-support.patch index b6d59f5..df99295 100644 --- a/0044-RH-compile-with-libreadline-support.patch +++ b/0022-RH-compile-with-libreadline-support.patch @@ -12,7 +12,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc -index 15f0b9f6..881c1d52 100644 +index c07bcb0c..e59313c6 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -12,7 +12,7 @@ diff --git a/0023-README.md-Move-section-about-libedit-and-libreadline.patch b/0023-README.md-Move-section-about-libedit-and-libreadline.patch deleted file mode 100644 index b860971..0000000 --- a/0023-README.md-Move-section-about-libedit-and-libreadline.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 28 Oct 2022 15:40:16 +0200 -Subject: [PATCH] README.md: Move section about libedit and libreadline - -This paragraph belongs in the "Customiting build" section. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - README.md | 17 +++++++++-------- - 1 file changed, 9 insertions(+), 8 deletions(-) - -diff --git a/README.md b/README.md -index d003e1db..52ab776b 100644 ---- a/README.md -+++ b/README.md -@@ -53,14 +53,9 @@ Building multipath-tools - ======================== - - Prerequisites: development packages of for `libdevmapper`, `libaio`, `libudev`, --`libjson-c`, `liburcu`, and `libsystemd`. -- --To enable commandline history and TAB completion in the interactive mode *(which --is entered with `multipathd -k` or `multipathc`)* you might also set `READLINE` --make variable to `libedit` or `libreadline`, like `make READLINE=libreadline`. --That requires a development package for the library you chose. Note that using --libreadline may [make binary indistributable due to license --incompatibility](https://github.com/opensvc/multipath-tools/issues/36). -+`libjson-c`, `liburcu`, and `libsystemd`. If commandline editing is enabled -+(see below), the development package for either `libedit` or `libreadline` is -+required as well. - - Then, build and install multipath-tools with: - -@@ -82,6 +77,12 @@ The following variables can be passed to the `make` command line: - * `configdir="/some/path"` : directory to search for configuration files. - This used to be the run-time option `config_dir` in earlier versions. - The default is `/etc/multipath/conf.d`. -+ * `READLINE=libedit` or `READLINE=libreadline`: enable command line history -+ and TAB completion in the interactive mode *(which is entered with `multipathd -k` or `multipathc`)*. -+ The respective development package will be required for building. -+ By default, command line editing is disabled. -+ Note that using libreadline may -+ [make binary indistributable due to license incompatibility](https://github.com/opensvc/multipath-tools/issues/36). - * `ENABLE_LIBDMMP=0`: disable building libdmmp - * `ENABLE_DMEVENTS_POLL=0`: disable support for the device-mapper event - polling API. For use with pre-5.0 kernels that don't support dmevent polling diff --git a/0024-README.md-Fix-indentation-in-paragraph-about-device-.patch b/0024-README.md-Fix-indentation-in-paragraph-about-device-.patch deleted file mode 100644 index 63b6c2f..0000000 --- a/0024-README.md-Fix-indentation-in-paragraph-about-device-.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 28 Oct 2022 15:42:15 +0200 -Subject: [PATCH] README.md: Fix indentation in paragraph about device handlers - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - README.md | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - -diff --git a/README.md b/README.md -index 52ab776b..b1b78fbb 100644 ---- a/README.md -+++ b/README.md -@@ -94,12 +94,12 @@ The following variables can be passed to the `make` command line: - early. This option causes a *modules-load.d(5)* configuration file to be - created, thus it depends on functionality provided by *systemd*. - This variable only matters for `make install`. -- --Note: The usefulness of the preload list depends on the kernel configuration. --It's especially useful if `scsi_mod` is builtin but `scsi_dh_alua` and --other device handler modules are built as modules. If `scsi_mod` itself is compiled --as a module, it might make more sense to use a module softdep for the same --purpose. -+ -+ **Note**: The usefulness of the preload list depends on the kernel configuration. -+ It's especially useful if `scsi_mod` is builtin but `scsi_dh_alua` and -+ other device handler modules are built as modules. If `scsi_mod` itself is compiled -+ as a module, it might make more sense to use a module softdep for the same -+ purpose. - - See `Makefile.inc` for additional variables to customize paths and compiler - flags. diff --git a/0025-README.md-document-options-for-paths-and-optimizatio.patch b/0025-README.md-document-options-for-paths-and-optimizatio.patch deleted file mode 100644 index ca00d85..0000000 --- a/0025-README.md-document-options-for-paths-and-optimizatio.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 28 Oct 2022 16:01:17 +0200 -Subject: [PATCH] README.md: document options for paths and optimization - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - README.md | 25 +++++++++++++++++++++++-- - 1 file changed, 23 insertions(+), 2 deletions(-) - -diff --git a/README.md b/README.md -index b1b78fbb..ab7dc3c9 100644 ---- a/README.md -+++ b/README.md -@@ -101,8 +101,29 @@ The following variables can be passed to the `make` command line: - as a module, it might make more sense to use a module softdep for the same - purpose. - --See `Makefile.inc` for additional variables to customize paths and compiler --flags. -+### Installation Paths -+ -+ * `prefix`: The directory prefix for (almost) all files to be installed. -+ Distributions may want to set this to `/usr`. -+ **Note**: for multipath-tools, unlike many other packages, `prefix` -+ defaults to the empty string, which resolves to the root directory (`/`). -+ * `usr_prefix`: where to install those parts of the code that aren't necessary -+ for booting. You may want to set this to `/usr` if `prefix` is empty. -+ * `systemd_prefix`: Prefix for systemd-related files. It defaults to `/usr`. -+ Some systemd installations use separate `prefix` and `rootprefix`. On such -+ a distribution, set `prefix`, and override `unitdir` to use systemd's -+ `rootprefix`. -+ * `LIB`: the subdirectory under `prefix` where shared libraries will be -+ installed. By default, the makefile uses `/lib64` if this directory is -+ found on the build system, and `/lib` otherwise. -+ -+See also `configdir` and `plugindir` above. See `Makefile.inc` for more -+fine-grained control. -+ -+### Compiler Options -+ -+Use `OPTFLAGS` to change optimization-related compiler options; -+e.g. `OPTFLAGS="-g -O0"` to disable all optimizations. - - Special Makefile targets - ------------------------ diff --git a/0026-README.md-document-how-to-customize-build.patch b/0026-README.md-document-how-to-customize-build.patch deleted file mode 100644 index c3dfedb..0000000 --- a/0026-README.md-document-how-to-customize-build.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 28 Oct 2022 16:01:41 +0200 -Subject: [PATCH] README.md: document how to customize build - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - README.md | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/README.md b/README.md -index ab7dc3c9..bbeb44fe 100644 ---- a/README.md -+++ b/README.md -@@ -66,9 +66,21 @@ To uninstall, type: - - make uninstall - -+By default, the build will run quietly, just printing one-line messages -+about the files being built. To enable more verbose output, run `make V=1`. -+ - Customizing the build - --------------------- - -+**Note**: With very few exceptions, the build process does not read -+configuration from the environment. So using syntax like -+ -+ SOME_VAR=some_value make -+ -+will **not** have the intended effect. Use the following instead: -+ -+ make SOME_VAR=some_value -+ - The following variables can be passed to the `make` command line: - - * `plugindir="/some/path"`: directory where libmultipath plugins (path diff --git a/0027-libmultipath-avoid-Warray-bounds-error-with-gcc-12-a.patch b/0027-libmultipath-avoid-Warray-bounds-error-with-gcc-12-a.patch deleted file mode 100644 index 1ae51d8..0000000 --- a/0027-libmultipath-avoid-Warray-bounds-error-with-gcc-12-a.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 28 Oct 2022 21:10:41 +0200 -Subject: [PATCH] libmultipath: avoid -Warray-bounds error with gcc 12 and musl - libc -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The following error is observed with gcc 12, strangely only with -MUSL libc: - -In function ‘__uatomic_inc’, - inlined from ‘lock’ at ../libmultipath/lock.h:24:2, - inlined from ‘child’ at main.c:3523:3, - inlined from ‘main’ at main.c:3755:11: -/usr/include/urcu/uatomic/x86.h:439:17: error: array subscript ‘struct __uatomic_dummy[0]’ is partly outside array bounds of ‘unsigned char[72]’ [-Werror=array-bounds] - -The problem is that &(vecs->lock.waiters) is casted to a pointer to -struct { long[10]; } which goes beyond the "struct vectors". -We don't read or write from/to that memory, but the compiler complains either -way. - -latest liburcu has a patch for it: - -http://git.liburcu.org/?p=userspace-rcu.git;a=commitdiff;h=835b9ab3ca3777fe42e37e92096226ebd19ca75b - -For now, just disable the warning in lock.h, using a pragma. - -Signed-off-by: Martin Wilck -Reported-by: Xose Vasquez Perez -Signed-off-by: Benjamin Marzinski ---- - libmultipath/lock.h | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/libmultipath/lock.h b/libmultipath/lock.h -index 20ca77e6..9814be76 100644 ---- a/libmultipath/lock.h -+++ b/libmultipath/lock.h -@@ -13,6 +13,11 @@ struct mutex_lock { - int waiters; /* uatomic access only */ - }; - -+#if !defined(__GLIBC__) && defined(__GNUC__) && __GNUC__ == 12 -+#pragma GCC diagnostic push -+#pragma GCC diagnostic ignored "-Warray-bounds" -+#endif -+ - static inline void init_lock(struct mutex_lock *a) - { - pthread_mutex_init(&a->mutex, NULL); -@@ -46,6 +51,10 @@ static inline bool lock_has_waiters(struct mutex_lock *a) - return (uatomic_read(&a->waiters) > 0); - } - -+#if !defined(__GLIBC__) && defined(__GNUC__) && __GNUC__ == 12 -+#pragma GCC diagnostic pop -+#endif -+ - #define lock_cleanup_pop(a) pthread_cleanup_pop(1) - - void cleanup_lock (void * data); diff --git a/0028-multipath-avoid-NULL-string-in-released_to_systemd.patch b/0028-multipath-avoid-NULL-string-in-released_to_systemd.patch deleted file mode 100644 index 2be93fc..0000000 --- a/0028-multipath-avoid-NULL-string-in-released_to_systemd.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 27 Sep 2022 12:14:09 +0200 -Subject: [PATCH] multipath: avoid NULL string in released_to_systemd() - -Fixes: b28c406 ("multipath -u: don't grab devices already passed to system") -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - multipath/main.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/multipath/main.c b/multipath/main.c -index 7b69a3ce..b9f360b4 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -435,7 +435,8 @@ static bool released_to_systemd(void) - bool ret; - - ret = dm_mp_dev_path != NULL && !strcmp(dm_mp_dev_path, "0"); -- condlog(4, "%s: %s=%s -> %d", __func__, dmdp, dm_mp_dev_path, ret); -+ condlog(4, "%s: %s=%s -> %d", __func__, dmdp, -+ dm_mp_dev_path ? dm_mp_dev_path : "", ret); - return ret; - } - diff --git a/0029-libmultipath-avoid-NULL-string-in-is_udev_ready.patch b/0029-libmultipath-avoid-NULL-string-in-is_udev_ready.patch deleted file mode 100644 index e48d44c..0000000 --- a/0029-libmultipath-avoid-NULL-string-in-is_udev_ready.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 27 Sep 2022 12:28:26 +0200 -Subject: [PATCH] libmultipath: avoid NULL string in is_udev_ready() - -Fixes: 2b25a9e ("libmultipath: select_action(): force udev reload for uninitialized maps") -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index e5249fc1..e551047a 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -662,7 +662,8 @@ static bool is_udev_ready(struct multipath *cmpp) - env = udev_device_get_property_value(mpp_ud, "MPATH_DEVICE_READY"); - rc = (env != NULL && !strcmp(env, "1")); - udev_device_unref(mpp_ud); -- condlog(4, "%s: %s: \"%s\" -> %d\n", __func__, cmpp->alias, env, rc); -+ condlog(4, "%s: %s: \"%s\" -> %d\n", __func__, cmpp->alias, -+ env ? env : "", rc); - return rc; - } - diff --git a/0030-libmultipath-impove-add_feature-variable-names.patch b/0030-libmultipath-impove-add_feature-variable-names.patch deleted file mode 100644 index 9cc841d..0000000 --- a/0030-libmultipath-impove-add_feature-variable-names.patch +++ /dev/null @@ -1,115 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 9 Nov 2022 15:49:41 -0600 -Subject: [PATCH] libmultipath: impove add_feature() variable names - -Use descriptive names, instead of single letters. No functional changes. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/structs.c | 63 +++++++++++++++++++++--------------------- - 1 file changed, 32 insertions(+), 31 deletions(-) - -diff --git a/libmultipath/structs.c b/libmultipath/structs.c -index 7a2ff589..f90bd0b6 100644 ---- a/libmultipath/structs.c -+++ b/libmultipath/structs.c -@@ -604,65 +604,66 @@ first_path (const struct multipath * mpp) - return pgp?VECTOR_SLOT(pgp->paths, 0):NULL; - } - --int add_feature(char **f, const char *n) -+int add_feature(char **features_p, const char *new_feat) - { -- int c = 0, d, l; -- char *e, *t; -- const char *p; -+ int count = 0, new_count, len; -+ char *tmp, *feats; -+ const char *ptr; - -- if (!f) -+ if (!features_p) - return 1; - - /* Nothing to do */ -- if (!n || *n == '\0') -+ if (!new_feat || *new_feat == '\0') - return 0; - -- l = strlen(n); -- if (isspace(*n) || isspace(*(n + l - 1))) { -- condlog(0, "internal error: feature \"%s\" has leading or trailing spaces", n); -+ len = strlen(new_feat); -+ if (isspace(*new_feat) || isspace(*(new_feat + len - 1))) { -+ condlog(0, "internal error: feature \"%s\" has leading or trailing spaces", -+ new_feat); - return 1; - } - -- p = n; -- d = 1; -- while (*p != '\0') { -- if (isspace(*p) && !isspace(*(p + 1)) && *(p + 1) != '\0') -- d++; -- p++; -+ ptr = new_feat; -+ new_count = 1; -+ while (*ptr != '\0') { -+ if (isspace(*ptr) && !isspace(*(ptr + 1)) && *(ptr + 1) != '\0') -+ new_count++; -+ ptr++; - } - - /* default feature is null */ -- if(!*f) -+ if(!*features_p) - { -- l = asprintf(&t, "%0d %s", d, n); -- if(l == -1) -+ len = asprintf(&feats, "%0d %s", new_count, new_feat); -+ if(len == -1) - return 1; - -- *f = t; -+ *features_p = feats; - return 0; - } - - /* Check if feature is already present */ -- e = *f; -- while ((e = strstr(e, n)) != NULL) { -- if (isspace(*(e - 1)) && -- (isspace(*(e + l)) || *(e + l) == '\0')) -+ tmp = *features_p; -+ while ((tmp = strstr(tmp, new_feat)) != NULL) { -+ if (isspace(*(tmp - 1)) && -+ (isspace(*(tmp + len)) || *(tmp + len) == '\0')) - return 0; -- e += l; -+ tmp += len; - } - - /* Get feature count */ -- c = strtoul(*f, &e, 10); -- if (*f == e || (!isspace(*e) && *e != '\0')) { -- condlog(0, "parse error in feature string \"%s\"", *f); -+ count = strtoul(*features_p, &tmp, 10); -+ if (*features_p == tmp || (!isspace(*tmp) && *tmp != '\0')) { -+ condlog(0, "parse error in feature string \"%s\"", *features_p); - return 1; - } -- c += d; -- if (asprintf(&t, "%0d%s %s", c, e, n) < 0) -+ count += new_count; -+ if (asprintf(&feats, "%0d%s %s", count, tmp, new_feat) < 0) - return 1; - -- free(*f); -- *f = t; -+ free(*features_p); -+ *features_p = feats; - - return 0; - } diff --git a/0031-multipathd-don-t-initialize-the-field-width-in-show_.patch b/0031-multipathd-don-t-initialize-the-field-width-in-show_.patch deleted file mode 100644 index 6dc8a0e..0000000 --- a/0031-multipathd-don-t-initialize-the-field-width-in-show_.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 9 Nov 2022 15:49:42 -0600 -Subject: [PATCH] multipathd: don't initialize the field width in show_path() - -It's not used, so don't set it up. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - multipathd/cli_handlers.c | 7 +------ - 1 file changed, 1 insertion(+), 6 deletions(-) - -diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c -index 5f0dd04e..e65fb75c 100644 ---- a/multipathd/cli_handlers.c -+++ b/multipathd/cli_handlers.c -@@ -67,12 +67,7 @@ static int - show_path (struct strbuf *reply, struct vectors *vecs, struct path *pp, - char *style) - { -- fieldwidth_t *width __attribute__((cleanup(cleanup_ucharp))) = NULL; -- -- if ((width = alloc_path_layout()) == NULL) -- return 1; -- get_path_layout(vecs->pathvec, 1, width); -- if (snprint_path(reply, style, pp, 0) < 0) -+ if (snprint_path(reply, style, pp, NULL) < 0) - return 1; - return 0; - } diff --git a/0032-libmultipath-improve-remove_feature-variable-names.patch b/0032-libmultipath-improve-remove_feature-variable-names.patch deleted file mode 100644 index c1642d4..0000000 --- a/0032-libmultipath-improve-remove_feature-variable-names.patch +++ /dev/null @@ -1,144 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 9 Nov 2022 15:49:43 -0600 -Subject: [PATCH] libmultipath: improve remove_feature() variable names - -Use descriptive names, instead of single letters. No functional changes. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/structs.c | 80 +++++++++++++++++++++--------------------- - 1 file changed, 40 insertions(+), 40 deletions(-) - -diff --git a/libmultipath/structs.c b/libmultipath/structs.c -index f90bd0b6..87e84d5d 100644 ---- a/libmultipath/structs.c -+++ b/libmultipath/structs.c -@@ -668,86 +668,86 @@ int add_feature(char **features_p, const char *new_feat) - return 0; - } - --int remove_feature(char **f, const char *o) -+int remove_feature(char **features_p, const char *old_feat) - { -- int c = 0, d; -- char *e, *p, *n; -- const char *q; -+ int count = 0, len; -+ char *feats_start, *ptr, *new; - -- if (!f || !*f) -+ if (!features_p || !*features_p) - return 1; - - /* Nothing to do */ -- if (!o || *o == '\0') -+ if (!old_feat || *old_feat == '\0') - return 0; - -- d = strlen(o); -- if (isspace(*o) || isspace(*(o + d - 1))) { -- condlog(0, "internal error: feature \"%s\" has leading or trailing spaces", o); -+ len = strlen(old_feat); -+ if (isspace(*old_feat) || isspace(*(old_feat + len - 1))) { -+ condlog(0, "internal error: feature \"%s\" has leading or trailing spaces", -+ old_feat); - return 1; - } - - /* Check if present and not part of a larger feature token*/ -- p = *f + 1; /* the size must be at the start of the features string */ -- while ((p = strstr(p, o)) != NULL) { -- if (isspace(*(p - 1)) && -- (isspace(*(p + d)) || *(p + d) == '\0')) -+ ptr = *features_p + 1; -+ while ((ptr = strstr(ptr, old_feat)) != NULL) { -+ if (isspace(*(ptr - 1)) && -+ (isspace(*(ptr + len)) || *(ptr + len) == '\0')) - break; -- p += d; -+ ptr += len; - } -- if (!p) -+ if (!ptr) - return 0; - - /* Get feature count */ -- c = strtoul(*f, &e, 10); -- if (*f == e || !isspace(*e)) { -- condlog(0, "parse error in feature string \"%s\"", *f); -+ count = strtoul(*features_p, &feats_start, 10); -+ if (*features_p == feats_start || !isspace(*feats_start)) { -+ condlog(0, "parse error in feature string \"%s\"", *features_p); - return 1; - } - - /* Update feature count */ -- c--; -- q = o; -- while (*q != '\0') { -- if (isspace(*q) && !isspace(*(q + 1)) && *(q + 1) != '\0') -- c--; -- q++; -+ count--; -+ while (*old_feat != '\0') { -+ if (isspace(*old_feat) && !isspace(*(old_feat + 1)) && -+ *(old_feat + 1) != '\0') -+ count--; -+ old_feat++; - } - - /* Quick exit if all features have been removed */ -- if (c == 0) { -- n = malloc(2); -- if (!n) -+ if (count == 0) { -+ new = malloc(2); -+ if (!new) - return 1; -- strcpy(n, "0"); -+ strcpy(new, "0"); - goto out; - } - - /* Update feature count space */ -- n = malloc(strlen(*f) - d + 1); -- if (!n) -+ new = malloc(strlen(*features_p) - len + 1); -+ if (!new) - return 1; - - /* Copy the feature count */ -- sprintf(n, "%0d", c); -+ sprintf(new, "%0d", count); - /* - * Copy existing features up to the feature - * about to be removed - */ -- strncat(n, e, (size_t)(p - e)); -+ strncat(new, feats_start, (size_t)(ptr - feats_start)); - /* Skip feature to be removed */ -- p += d; -+ ptr += len; - /* Copy remaining features */ -- while (isspace(*p)) -- p++; -- if (*p != '\0') -- strcat(n, p); -+ while (isspace(*ptr)) -+ ptr++; -+ if (*ptr != '\0') -+ strcat(new, ptr); - else -- strchop(n); -+ strchop(new); - - out: -- free(*f); -- *f = n; -+ free(*features_p); -+ *features_p = new; - - return 0; - } diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 847d6b9..2933cbd 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,59 +1,37 @@ Name: device-mapper-multipath -Version: 0.9.3 -Release: 2%{?dist} +Version: 0.9.4 +Release: 1%{?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 -L https://github.com/opensvc/multipath-tools/archive/0.9.3.tar.gz -o multipath-tools-0.9.3.tgz -Source0: multipath-tools-0.9.3.tgz +# curl -L https://github.com/opensvc/multipath-tools/archive/0.9.4.tar.gz -o multipath-tools-0.9.4.tgz +Source0: multipath-tools-0.9.4.tgz Source1: multipath.conf -Patch0001: 0001-libmultipath-fix-show-paths-format-failure.patch -Patch0002: 0002-fixup-Makefile.inc-fix-man-and-include-paths.patch -Patch0003: 0003-multipath-tools-Makefile.inc-Fix-paths-for-systemd.patch -Patch0004: 0004-multipath-tools-Makefile.inc-don-t-take-values-from-.patch -Patch0005: 0005-multipath-tools-Makefile.inc-get-rid-of-RUN.patch -Patch0006: 0006-multipath-tools-Makefile.inc-more-compact-code-for-L.patch -Patch0007: 0007-multipath-tools-Makefiles-simplify-code-for-include-.patch -Patch0008: 0008-multipath-tools-Makefiles-use-mandir.patch -Patch0009: 0009-multipath-tools-Makefile.inc-simplify-expression-for.patch -Patch0010: 0010-multipath-tools-Makefile.inc-untangle-paths-and-sour.patch -Patch0011: 0011-multipath-tools-Makefiles-replace-libdir-by-plugindi.patch -Patch0012: 0012-multipath-tools-Makefile.inc-use-simple-make-variabl.patch -Patch0013: 0013-multipath-tools-Makefile.inc-fix-a-log-message.patch -Patch0014: 0014-multipath-tools-Makefile.inc-set-systemd-specific-fl.patch -Patch0015: 0015-multipathd-Makefile-fix-compilation-flags-for-libedi.patch -Patch0016: 0016-multipath-tools-Makefiles-clean-up-executable-Makefi.patch -Patch0017: 0017-multipath-tools-Makefiles-use-common-code-for-librar.patch -Patch0018: 0018-multipath-tools-Makefiles-move-common-code-to-rules..patch -Patch0019: 0019-multipath-tools-Makefiles-create-config.mk.patch -Patch0020: 0020-multipath-tools-Makefiles-enable-quiet-build.patch -Patch0021: 0021-multipath-tools-quiet-build-support-for-top-level-Ma.patch -Patch0022: 0022-GitHub-workflows-use-make-j8-Orecurse.patch -Patch0023: 0023-README.md-Move-section-about-libedit-and-libreadline.patch -Patch0024: 0024-README.md-Fix-indentation-in-paragraph-about-device-.patch -Patch0025: 0025-README.md-document-options-for-paths-and-optimizatio.patch -Patch0026: 0026-README.md-document-how-to-customize-build.patch -Patch0027: 0027-libmultipath-avoid-Warray-bounds-error-with-gcc-12-a.patch -Patch0028: 0028-multipath-avoid-NULL-string-in-released_to_systemd.patch -Patch0029: 0029-libmultipath-avoid-NULL-string-in-is_udev_ready.patch -Patch0030: 0030-libmultipath-impove-add_feature-variable-names.patch -Patch0031: 0031-multipathd-don-t-initialize-the-field-width-in-show_.patch -Patch0032: 0032-libmultipath-improve-remove_feature-variable-names.patch -Patch0033: 0033-RH-fixup-udev-rules-for-redhat.patch -Patch0034: 0034-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0035: 0035-RH-don-t-start-without-a-config-file.patch -Patch0036: 0036-RH-Fix-nvme-function-missing-argument.patch -Patch0037: 0037-RH-use-rpm-optflags-if-present.patch -Patch0038: 0038-RH-add-mpathconf.patch -Patch0039: 0039-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0040: 0040-RH-reset-default-find_mutipaths-value-to-off.patch -Patch0041: 0041-RH-attempt-to-get-ANA-info-via-sysfs-first.patch -Patch0042: 0042-RH-make-parse_vpd_pg83-match-scsi_id-output.patch -Patch0043: 0043-RH-add-scsi-device-handlers-to-modules-load.d.patch -Patch0044: 0044-RH-compile-with-libreadline-support.patch +Patch0001: 0001-multipathd-make-pr-registration-consistent.patch +Patch0002: 0002-libmultipath-make-prflag-an-enum.patch +Patch0003: 0003-multipathd-handle-no-active-paths-in-update_map_pr.patch +Patch0004: 0004-multipathd-add-missing-newline-to-cli_del_map-reply.patch +Patch0005: 0005-libmultipath-skip-extra-vector-work-in-remove_maps.patch +Patch0006: 0006-libmultipath-orphan-paths-if-coalesce_paths-frees-ne.patch +Patch0007: 0007-libmultipath-is_path_valid-check-if-device-is-in-use.patch +Patch0008: 0008-libmpathpersist-use-conf-timeout-for-updating-persis.patch +Patch0009: 0009-libmultipath-pathinfo-don-t-fail-for-devices-lacking.patch +Patch0010: 0010-libmultipath-bump-ABI-version-to-18.0.0.patch +Patch0011: 0011-RH-fixup-udev-rules-for-redhat.patch +Patch0012: 0012-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0013: 0013-RH-don-t-start-without-a-config-file.patch +Patch0014: 0014-RH-Fix-nvme-function-missing-argument.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-reset-default-find_mutipaths-value-to-off.patch +Patch0019: 0019-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0020: 0020-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +Patch0021: 0021-RH-add-scsi-device-handlers-to-modules-load.d.patch +Patch0022: 0022-RH-compile-with-libreadline-support.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -61,6 +39,7 @@ Requires: kpartx = %{version}-%{release} Requires: device-mapper >= 1.02.96 Requires: userspace-rcu Requires: readline +Requires: libmount Requires(post): systemd-units Requires(preun): systemd-units Requires(postun): systemd-units @@ -82,6 +61,7 @@ BuildRequires: readline-devel, ncurses-devel BuildRequires: systemd-units, systemd-devel BuildRequires: json-c-devel, perl-interpreter, pkgconfig, gcc BuildRequires: userspace-rcu-devel +BuildRequires: libmount-devel BuildRequires: make %description @@ -138,7 +118,7 @@ This package contains the files needed to develop applications that use device-mapper-multipath's libdmmp C API library %prep -%autosetup -n multipath-tools-0.9.3 -p1 +%autosetup -n multipath-tools-0.9.4 -p1 cp %{SOURCE1} . %build @@ -260,6 +240,14 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Thu Jan 26 2023 Benjamin Marzinski - 0.9.4-1 +- Update to the head of the upstream staging branch + * Previous patches 0001-0032 are intlcude in the source tarball + * Patches 0001-0010 are from the upstream staging branch +- Rename redhat patches + * Previous patches 0033-0044 are not patches 0011-0022 +- Add dependency on libmount + * Thu Jan 19 2023 Fedora Release Engineering - 0.9.3-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild diff --git a/sources b/sources index 0394f4e..462cab6 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (multipath-tools-0.9.3.tgz) = 4faa2ee5a96a9d5d752219931ebc885cb70ed6b022d45ede985ad7919c043a3aee166e6f126d32dffd187c5c32d5cbce91747d87d0b55557e2f7f68b279583da +SHA512 (multipath-tools-0.9.4.tgz) = 5e0dcea610fc215e345444c04453a38f39c73e493c2bc53f6b3a90cd701266aabdf7c4693dfc321099af836d0019bf27355e265ad5db5deff48f8bb94ed4719d SHA512 (multipath.conf) = 71953dce5a68adcf60a942305f5a66023e6f4c4baf53b1bfdb4edf65ed5b8e03db804363c36d1dcfd85591f4766f52b515269904c53b84d7b076da0b80b09942 From bbfe9b12298331b52b0d1de1f1087bc8eac1374a Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 2 Feb 2023 14:07:38 -0600 Subject: [PATCH 38/67] device-mapper-multipath-0.9.4-2 Update to the head of the upstream staging branch * Patches 0011-0015 are from the upstream staging branch Rename redhat patches * Previous patches 0011-0022 are now patches 0016-0027 --- ...-select_reload_action-in-select_acti.patch | 39 ++++ ...ect-resize-action-even-if-reload-is-.patch | 46 +++++ ...anup-ACT_CREATE-code-in-select_actio.patch | 68 +++++++ ...p-renames-from-stopping-other-multip.patch | 186 ++++++++++++++++++ ...t-fix-resource-leak-in-update_map_pr.patch | 68 +++++++ ... 0016-RH-fixup-udev-rules-for-redhat.patch | 0 ...property-blacklist-exception-builtin.patch | 0 ...RH-don-t-start-without-a-config-file.patch | 0 ...H-Fix-nvme-function-missing-argument.patch | 0 ... 0020-RH-use-rpm-optflags-if-present.patch | 0 ...hconf.patch => 0021-RH-add-mpathconf.patch | 0 ...om-kernel-cmdline-mpath.wwids-with-A.patch | 0 ...-default-find_mutipaths-value-to-off.patch | 0 ...empt-to-get-ANA-info-via-sysfs-first.patch | 0 ...-parse_vpd_pg83-match-scsi_id-output.patch | 0 ...si-device-handlers-to-modules-load.d.patch | 0 ...-RH-compile-with-libreadline-support.patch | 0 device-mapper-multipath.spec | 41 ++-- 18 files changed, 433 insertions(+), 15 deletions(-) create mode 100644 0011-libmultipath-use-select_reload_action-in-select_acti.patch create mode 100644 0012-libmultipath-select-resize-action-even-if-reload-is-.patch create mode 100644 0013-libmultipath-cleanup-ACT_CREATE-code-in-select_actio.patch create mode 100644 0014-libmultipath-keep-renames-from-stopping-other-multip.patch create mode 100644 0015-libmpathpersist-fix-resource-leak-in-update_map_pr.patch rename 0011-RH-fixup-udev-rules-for-redhat.patch => 0016-RH-fixup-udev-rules-for-redhat.patch (100%) rename 0012-RH-Remove-the-property-blacklist-exception-builtin.patch => 0017-RH-Remove-the-property-blacklist-exception-builtin.patch (100%) rename 0013-RH-don-t-start-without-a-config-file.patch => 0018-RH-don-t-start-without-a-config-file.patch (100%) rename 0014-RH-Fix-nvme-function-missing-argument.patch => 0019-RH-Fix-nvme-function-missing-argument.patch (100%) rename 0015-RH-use-rpm-optflags-if-present.patch => 0020-RH-use-rpm-optflags-if-present.patch (100%) rename 0016-RH-add-mpathconf.patch => 0021-RH-add-mpathconf.patch (100%) rename 0017-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch => 0022-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch (100%) rename 0018-RH-reset-default-find_mutipaths-value-to-off.patch => 0023-RH-reset-default-find_mutipaths-value-to-off.patch (100%) rename 0019-RH-attempt-to-get-ANA-info-via-sysfs-first.patch => 0024-RH-attempt-to-get-ANA-info-via-sysfs-first.patch (100%) rename 0020-RH-make-parse_vpd_pg83-match-scsi_id-output.patch => 0025-RH-make-parse_vpd_pg83-match-scsi_id-output.patch (100%) rename 0021-RH-add-scsi-device-handlers-to-modules-load.d.patch => 0026-RH-add-scsi-device-handlers-to-modules-load.d.patch (100%) rename 0022-RH-compile-with-libreadline-support.patch => 0027-RH-compile-with-libreadline-support.patch (100%) diff --git a/0011-libmultipath-use-select_reload_action-in-select_acti.patch b/0011-libmultipath-use-select_reload_action-in-select_acti.patch new file mode 100644 index 0000000..05cc2ce --- /dev/null +++ b/0011-libmultipath-use-select_reload_action-in-select_acti.patch @@ -0,0 +1,39 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 31 Jan 2023 13:34:18 -0600 +Subject: [PATCH] libmultipath: use select_reload_action in select_action + +Since we have a function to set the action to reload, use it. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/configure.c | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index e689f8a7..050b984a 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -729,9 +729,7 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, + + if (force_reload) { + mpp->force_udev_reload = 1; +- mpp->action = ACT_RELOAD; +- condlog(3, "%s: set ACT_RELOAD (forced by user)", +- mpp->alias); ++ select_reload_action(mpp, "forced by user"); + return; + } + if (cmpp->size != mpp->size) { +@@ -744,9 +742,7 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, + + if (!is_udev_ready(cmpp) && count_active_paths(mpp) > 0) { + mpp->force_udev_reload = 1; +- mpp->action = ACT_RELOAD; +- condlog(3, "%s: set ACT_RELOAD (udev incomplete)", +- mpp->alias); ++ select_reload_action(mpp, "udev incomplete"); + return; + } + diff --git a/0012-libmultipath-select-resize-action-even-if-reload-is-.patch b/0012-libmultipath-select-resize-action-even-if-reload-is-.patch new file mode 100644 index 0000000..39518c4 --- /dev/null +++ b/0012-libmultipath-select-resize-action-even-if-reload-is-.patch @@ -0,0 +1,46 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 31 Jan 2023 13:34:19 -0600 +Subject: [PATCH] libmultipath: select resize action even if reload is forced + +The ACT_RESIZE action is the same as the ACT_RELOAD action, except that +it flushes outstanding IO because the device size is changing and +the new size might be too small for some of the outstanding IO. If we've +detected a size change, and a forced reload is requested, we still need +to flush the IO because the reload will change the device size. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/configure.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index 050b984a..6811e661 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -727,11 +727,6 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, + return; + } + +- if (force_reload) { +- mpp->force_udev_reload = 1; +- select_reload_action(mpp, "forced by user"); +- return; +- } + if (cmpp->size != mpp->size) { + mpp->force_udev_reload = 1; + mpp->action = ACT_RESIZE; +@@ -740,6 +735,12 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, + return; + } + ++ if (force_reload) { ++ mpp->force_udev_reload = 1; ++ select_reload_action(mpp, "forced by user"); ++ return; ++ } ++ + if (!is_udev_ready(cmpp) && count_active_paths(mpp) > 0) { + mpp->force_udev_reload = 1; + select_reload_action(mpp, "udev incomplete"); diff --git a/0013-libmultipath-cleanup-ACT_CREATE-code-in-select_actio.patch b/0013-libmultipath-cleanup-ACT_CREATE-code-in-select_actio.patch new file mode 100644 index 0000000..3574bac --- /dev/null +++ b/0013-libmultipath-cleanup-ACT_CREATE-code-in-select_actio.patch @@ -0,0 +1,68 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 31 Jan 2023 13:34:20 -0600 +Subject: [PATCH] libmultipath: cleanup ACT_CREATE code in select_action + +Combine the two separate blocks that set ACT_CREATE into one. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/configure.c | 38 +++++++++++++++++--------------------- + 1 file changed, 17 insertions(+), 21 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index 6811e661..e870e0f6 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -686,33 +686,29 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, + if (mpp->need_reload || (cmpp && cmpp->need_reload)) + force_reload = 1; + +- if (!cmpp_by_name) { +- if (cmpp) { +- condlog(2, "%s: rename %s to %s", mpp->wwid, +- cmpp->alias, mpp->alias); +- strlcpy(mpp->alias_old, cmpp->alias, WWID_SIZE); +- mpp->action = ACT_RENAME; +- if (force_reload) { +- mpp->force_udev_reload = 1; +- mpp->action = ACT_FORCERENAME; +- } +- return; ++ if (!cmpp) { ++ if (cmpp_by_name) { ++ condlog(1, "%s: can't use alias \"%s\" used by %s, falling back to WWID", ++ mpp->wwid, mpp->alias, cmpp_by_name->wwid); ++ /* We can do this because wwid wasn't found */ ++ free(mpp->alias); ++ mpp->alias = strdup(mpp->wwid); + } + mpp->action = ACT_CREATE; +- condlog(3, "%s: set ACT_CREATE (map does not exist)", +- mpp->alias); ++ condlog(3, "%s: set ACT_CREATE (map does not exist%s)", ++ mpp->alias, cmpp_by_name ? ", name changed" : ""); + return; + } + +- if (!cmpp) { +- condlog(1, "%s: can't use alias \"%s\" used by %s, falling back to WWID", +- mpp->wwid, mpp->alias, cmpp_by_name->wwid); +- /* We can do this because wwid wasn't found */ +- free(mpp->alias); +- mpp->alias = strdup(mpp->wwid); +- mpp->action = ACT_CREATE; +- condlog(3, "%s: set ACT_CREATE (map does not exist, name changed)", ++ if (!cmpp_by_name) { ++ condlog(2, "%s: rename %s to %s", mpp->wwid, cmpp->alias, + mpp->alias); ++ strlcpy(mpp->alias_old, cmpp->alias, WWID_SIZE); ++ mpp->action = ACT_RENAME; ++ if (force_reload) { ++ mpp->force_udev_reload = 1; ++ mpp->action = ACT_FORCERENAME; ++ } + return; + } + diff --git a/0014-libmultipath-keep-renames-from-stopping-other-multip.patch b/0014-libmultipath-keep-renames-from-stopping-other-multip.patch new file mode 100644 index 0000000..f597e61 --- /dev/null +++ b/0014-libmultipath-keep-renames-from-stopping-other-multip.patch @@ -0,0 +1,186 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 31 Jan 2023 13:34:21 -0600 +Subject: [PATCH] libmultipath: keep renames from stopping other multipath + actions + +If select_action() is called and a multipath device needs to be renamed, +the code currently checks if force_reload is set, and if so, does the +reload after the rename. But if force_reload isn't set, only the rename +happens, regardless of what other actions are needed. This can happen if +multipathd starts up and a device needs both a reload and a rename. + +Make multipath check for resize, reload, and switch pathgroup along with +rename, and do both if necessary. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/configure.c | 62 +++++++++++++++++----------------------- + libmultipath/configure.h | 4 ++- + 2 files changed, 30 insertions(+), 36 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index e870e0f6..4a1c28bb 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -670,7 +670,8 @@ static bool is_udev_ready(struct multipath *cmpp) + static void + select_reload_action(struct multipath *mpp, const char *reason) + { +- mpp->action = ACT_RELOAD; ++ mpp->action = mpp->action == ACT_RENAME ? ACT_RELOAD_RENAME : ++ ACT_RELOAD; + condlog(3, "%s: set ACT_RELOAD (%s)", mpp->alias, reason); + } + +@@ -681,6 +682,7 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, + struct multipath * cmpp_by_name; + char * mpp_feat, * cmpp_feat; + ++ mpp->action = ACT_NOTHING; + cmpp = find_mp_by_wwid(curmp, mpp->wwid); + cmpp_by_name = find_mp_by_alias(curmp, mpp->alias); + if (mpp->need_reload || (cmpp && cmpp->need_reload)) +@@ -705,14 +707,8 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, + mpp->alias); + strlcpy(mpp->alias_old, cmpp->alias, WWID_SIZE); + mpp->action = ACT_RENAME; +- if (force_reload) { +- mpp->force_udev_reload = 1; +- mpp->action = ACT_FORCERENAME; +- } +- return; +- } +- +- if (cmpp != cmpp_by_name) { ++ /* don't return here. Check for other needed actions */ ++ } else if (cmpp != cmpp_by_name) { + condlog(2, "%s: unable to rename %s to %s (%s is used by %s)", + mpp->wwid, cmpp->alias, mpp->alias, + mpp->alias, cmpp_by_name->wwid); +@@ -720,12 +716,13 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, + free(mpp->alias); + mpp->alias = strdup(cmpp->alias); + mpp->action = ACT_IMPOSSIBLE; +- return; ++ /* don't return here. Check for other needed actions */ + } + + if (cmpp->size != mpp->size) { + mpp->force_udev_reload = 1; +- mpp->action = ACT_RESIZE; ++ mpp->action = mpp->action == ACT_RENAME ? ACT_RESIZE_RENAME : ++ ACT_RESIZE; + condlog(3, "%s: set ACT_RESIZE (size change)", + mpp->alias); + return; +@@ -801,14 +798,14 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, + return; + } + if (cmpp->nextpg != mpp->bestpg) { +- mpp->action = ACT_SWITCHPG; ++ mpp->action = mpp->action == ACT_RENAME ? ACT_SWITCHPG_RENAME : ++ ACT_SWITCHPG; + condlog(3, "%s: set ACT_SWITCHPG (next path group change)", + mpp->alias); + return; + } +- mpp->action = ACT_NOTHING; +- condlog(3, "%s: set ACT_NOTHING (map unchanged)", +- mpp->alias); ++ if (mpp->action == ACT_NOTHING) ++ condlog(3, "%s: set ACT_NOTHING (map unchanged)", mpp->alias); + return; + } + +@@ -909,6 +906,17 @@ int domap(struct multipath *mpp, char *params, int is_daemon) + } + } + ++ if (mpp->action == ACT_RENAME || mpp->action == ACT_SWITCHPG_RENAME || ++ mpp->action == ACT_RELOAD_RENAME || ++ mpp->action == ACT_RESIZE_RENAME) { ++ conf = get_multipath_config(); ++ pthread_cleanup_push(put_multipath_config, conf); ++ r = dm_rename(mpp->alias_old, mpp->alias, ++ conf->partition_delim, mpp->skip_kpartx); ++ pthread_cleanup_pop(1); ++ if (r == DOMAP_FAIL) ++ return r; ++ } + switch (mpp->action) { + case ACT_REJECT: + case ACT_NOTHING: +@@ -916,6 +924,7 @@ int domap(struct multipath *mpp, char *params, int is_daemon) + return DOMAP_EXIST; + + case ACT_SWITCHPG: ++ case ACT_SWITCHPG_RENAME: + dm_switchgroup(mpp->alias, mpp->bestpg); + /* + * we may have avoided reinstating paths because there where in +@@ -942,6 +951,7 @@ int domap(struct multipath *mpp, char *params, int is_daemon) + break; + + case ACT_RELOAD: ++ case ACT_RELOAD_RENAME: + sysfs_set_max_sectors_kb(mpp, 1); + if (mpp->ghost_delay_tick > 0 && pathcount(mpp, PATH_UP)) + mpp->ghost_delay_tick = 0; +@@ -949,6 +959,7 @@ int domap(struct multipath *mpp, char *params, int is_daemon) + break; + + case ACT_RESIZE: ++ case ACT_RESIZE_RENAME: + sysfs_set_max_sectors_kb(mpp, 1); + if (mpp->ghost_delay_tick > 0 && pathcount(mpp, PATH_UP)) + mpp->ghost_delay_tick = 0; +@@ -956,29 +967,10 @@ int domap(struct multipath *mpp, char *params, int is_daemon) + break; + + case ACT_RENAME: +- conf = get_multipath_config(); +- pthread_cleanup_push(put_multipath_config, conf); +- r = dm_rename(mpp->alias_old, mpp->alias, +- conf->partition_delim, mpp->skip_kpartx); +- pthread_cleanup_pop(1); +- break; +- +- case ACT_FORCERENAME: +- conf = get_multipath_config(); +- pthread_cleanup_push(put_multipath_config, conf); +- r = dm_rename(mpp->alias_old, mpp->alias, +- conf->partition_delim, mpp->skip_kpartx); +- pthread_cleanup_pop(1); +- if (r) { +- sysfs_set_max_sectors_kb(mpp, 1); +- if (mpp->ghost_delay_tick > 0 && +- pathcount(mpp, PATH_UP)) +- mpp->ghost_delay_tick = 0; +- r = dm_addmap_reload(mpp, params, 0); +- } + break; + + default: ++ r = DOMAP_FAIL; + break; + } + +diff --git a/libmultipath/configure.h b/libmultipath/configure.h +index 2bf73e65..9d935db3 100644 +--- a/libmultipath/configure.h ++++ b/libmultipath/configure.h +@@ -18,9 +18,11 @@ enum actions { + ACT_RENAME, + ACT_CREATE, + ACT_RESIZE, +- ACT_FORCERENAME, ++ ACT_RELOAD_RENAME, + ACT_DRY_RUN, + ACT_IMPOSSIBLE, ++ ACT_RESIZE_RENAME, ++ ACT_SWITCHPG_RENAME, + }; + + /* diff --git a/0015-libmpathpersist-fix-resource-leak-in-update_map_pr.patch b/0015-libmpathpersist-fix-resource-leak-in-update_map_pr.patch new file mode 100644 index 0000000..866080f --- /dev/null +++ b/0015-libmpathpersist-fix-resource-leak-in-update_map_pr.patch @@ -0,0 +1,68 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 2 Feb 2023 09:20:35 +0100 +Subject: [PATCH] libmpathpersist: fix resource leak in update_map_pr() + +The "no available paths" case would leak the memory resp points to. +Found by coverity. + +Fixes: 50e2c16 ("multipathd: handle no active paths in update_map_pr") + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmpathpersist/mpath_persist_int.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/libmpathpersist/mpath_persist_int.c b/libmpathpersist/mpath_persist_int.c +index 8b52b746..178c2f54 100644 +--- a/libmpathpersist/mpath_persist_int.c ++++ b/libmpathpersist/mpath_persist_int.c +@@ -733,7 +733,7 @@ int update_map_pr(struct multipath *mpp) + int noisy=0; + struct prin_resp *resp; + unsigned int i; +- int ret, isFound; ++ int ret = MPATH_PR_OTHER, isFound; + + if (!get_be64(mpp->reservation_key)) + { +@@ -754,7 +754,7 @@ int update_map_pr(struct multipath *mpp) + { + condlog(0,"%s: No available paths to check pr status", + mpp->alias); +- return MPATH_PR_OTHER; ++ goto out; + } + mpp->prflag = PRFLAG_UNSET; + ret = mpath_prin_activepath(mpp, MPATH_PRIN_RKEY_SA, resp, noisy); +@@ -762,15 +762,15 @@ int update_map_pr(struct multipath *mpp) + if (ret != MPATH_PR_SUCCESS ) + { + condlog(0,"%s : pr in read keys service action failed Error=%d", mpp->alias, ret); +- free(resp); +- return ret; ++ goto out; + } + ++ ret = MPATH_PR_SUCCESS; ++ + if (resp->prin_descriptor.prin_readkeys.additional_length == 0 ) + { + condlog(3,"%s: No key found. Device may not be registered. ", mpp->alias); +- free(resp); +- return MPATH_PR_SUCCESS; ++ goto out; + } + + condlog(2, "%s: Multipath reservation_key: 0x%" PRIx64 " ", mpp->alias, +@@ -795,6 +795,7 @@ int update_map_pr(struct multipath *mpp) + condlog(2, "%s: prflag flag set.", mpp->alias ); + } + ++out: + free(resp); +- return MPATH_PR_SUCCESS; ++ return ret; + } diff --git a/0011-RH-fixup-udev-rules-for-redhat.patch b/0016-RH-fixup-udev-rules-for-redhat.patch similarity index 100% rename from 0011-RH-fixup-udev-rules-for-redhat.patch rename to 0016-RH-fixup-udev-rules-for-redhat.patch diff --git a/0012-RH-Remove-the-property-blacklist-exception-builtin.patch b/0017-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 100% rename from 0012-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0017-RH-Remove-the-property-blacklist-exception-builtin.patch diff --git a/0013-RH-don-t-start-without-a-config-file.patch b/0018-RH-don-t-start-without-a-config-file.patch similarity index 100% rename from 0013-RH-don-t-start-without-a-config-file.patch rename to 0018-RH-don-t-start-without-a-config-file.patch diff --git a/0014-RH-Fix-nvme-function-missing-argument.patch b/0019-RH-Fix-nvme-function-missing-argument.patch similarity index 100% rename from 0014-RH-Fix-nvme-function-missing-argument.patch rename to 0019-RH-Fix-nvme-function-missing-argument.patch diff --git a/0015-RH-use-rpm-optflags-if-present.patch b/0020-RH-use-rpm-optflags-if-present.patch similarity index 100% rename from 0015-RH-use-rpm-optflags-if-present.patch rename to 0020-RH-use-rpm-optflags-if-present.patch diff --git a/0016-RH-add-mpathconf.patch b/0021-RH-add-mpathconf.patch similarity index 100% rename from 0016-RH-add-mpathconf.patch rename to 0021-RH-add-mpathconf.patch diff --git a/0017-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0022-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 100% rename from 0017-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0022-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch diff --git a/0018-RH-reset-default-find_mutipaths-value-to-off.patch b/0023-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 100% rename from 0018-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0023-RH-reset-default-find_mutipaths-value-to-off.patch diff --git a/0019-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0024-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 100% rename from 0019-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0024-RH-attempt-to-get-ANA-info-via-sysfs-first.patch diff --git a/0020-RH-make-parse_vpd_pg83-match-scsi_id-output.patch b/0025-RH-make-parse_vpd_pg83-match-scsi_id-output.patch similarity index 100% rename from 0020-RH-make-parse_vpd_pg83-match-scsi_id-output.patch rename to 0025-RH-make-parse_vpd_pg83-match-scsi_id-output.patch diff --git a/0021-RH-add-scsi-device-handlers-to-modules-load.d.patch b/0026-RH-add-scsi-device-handlers-to-modules-load.d.patch similarity index 100% rename from 0021-RH-add-scsi-device-handlers-to-modules-load.d.patch rename to 0026-RH-add-scsi-device-handlers-to-modules-load.d.patch diff --git a/0022-RH-compile-with-libreadline-support.patch b/0027-RH-compile-with-libreadline-support.patch similarity index 100% rename from 0022-RH-compile-with-libreadline-support.patch rename to 0027-RH-compile-with-libreadline-support.patch diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 2933cbd..a6fe03c 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.9.4 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -20,18 +20,23 @@ Patch0007: 0007-libmultipath-is_path_valid-check-if-device-is-in-use.patch Patch0008: 0008-libmpathpersist-use-conf-timeout-for-updating-persis.patch Patch0009: 0009-libmultipath-pathinfo-don-t-fail-for-devices-lacking.patch Patch0010: 0010-libmultipath-bump-ABI-version-to-18.0.0.patch -Patch0011: 0011-RH-fixup-udev-rules-for-redhat.patch -Patch0012: 0012-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0013: 0013-RH-don-t-start-without-a-config-file.patch -Patch0014: 0014-RH-Fix-nvme-function-missing-argument.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-reset-default-find_mutipaths-value-to-off.patch -Patch0019: 0019-RH-attempt-to-get-ANA-info-via-sysfs-first.patch -Patch0020: 0020-RH-make-parse_vpd_pg83-match-scsi_id-output.patch -Patch0021: 0021-RH-add-scsi-device-handlers-to-modules-load.d.patch -Patch0022: 0022-RH-compile-with-libreadline-support.patch +Patch0011: 0011-libmultipath-use-select_reload_action-in-select_acti.patch +Patch0012: 0012-libmultipath-select-resize-action-even-if-reload-is-.patch +Patch0013: 0013-libmultipath-cleanup-ACT_CREATE-code-in-select_actio.patch +Patch0014: 0014-libmultipath-keep-renames-from-stopping-other-multip.patch +Patch0015: 0015-libmpathpersist-fix-resource-leak-in-update_map_pr.patch +Patch0016: 0016-RH-fixup-udev-rules-for-redhat.patch +Patch0017: 0017-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0018: 0018-RH-don-t-start-without-a-config-file.patch +Patch0019: 0019-RH-Fix-nvme-function-missing-argument.patch +Patch0020: 0020-RH-use-rpm-optflags-if-present.patch +Patch0021: 0021-RH-add-mpathconf.patch +Patch0022: 0022-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0023: 0023-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0024: 0024-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0025: 0025-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +Patch0026: 0026-RH-add-scsi-device-handlers-to-modules-load.d.patch +Patch0027: 0027-RH-compile-with-libreadline-support.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -240,12 +245,18 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Thu Feb 2 2023 Benjamin Marzinski - 0.9.4-2 +- Update to the head of the upstream staging branch + * Patches 0011-0015 are from the upstream staging branch +- Rename redhat patches + * Previous patches 0011-0022 are now patches 0016-0027 + * Thu Jan 26 2023 Benjamin Marzinski - 0.9.4-1 - Update to the head of the upstream staging branch - * Previous patches 0001-0032 are intlcude in the source tarball + * Previous patches 0001-0032 are included in the source tarball * Patches 0001-0010 are from the upstream staging branch - Rename redhat patches - * Previous patches 0033-0044 are not patches 0011-0022 + * Previous patches 0033-0044 are now patches 0011-0022 - Add dependency on libmount * Thu Jan 19 2023 Fedora Release Engineering - 0.9.3-2 From 0761930b9e78736f3fe8d59b79f35a5754ea2929 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Tue, 16 May 2023 17:02:58 -0500 Subject: [PATCH 39/67] device-mapper-multipath-0.9.5-1 Update to the latest upstream release * Previous patches 0001-0015 are included in the source tarball Rename redhat patches * Previous patches 0016-0027 are now patches 0001-0012 --- .gitignore | 1 + ... 0001-RH-fixup-udev-rules-for-redhat.patch | 0 ...athd-make-pr-registration-consistent.patch | 159 ----- ...property-blacklist-exception-builtin.patch | 0 0002-libmultipath-make-prflag-an-enum.patch | 166 ----- ...RH-don-t-start-without-a-config-file.patch | 4 +- ...dle-no-active-paths-in-update_map_pr.patch | 152 ----- ...H-Fix-nvme-function-missing-argument.patch | 0 ...missing-newline-to-cli_del_map-reply.patch | 24 - ... 0005-RH-use-rpm-optflags-if-present.patch | 0 ...kip-extra-vector-work-in-remove_maps.patch | 33 - ...hconf.patch => 0006-RH-add-mpathconf.patch | 0 ...han-paths-if-coalesce_paths-frees-ne.patch | 41 -- ...om-kernel-cmdline-mpath.wwids-with-A.patch | 8 +- ...path_valid-check-if-device-is-in-use.patch | 609 ------------------ ...-default-find_mutipaths-value-to-off.patch | 0 ...use-conf-timeout-for-updating-persis.patch | 55 -- ...empt-to-get-ANA-info-via-sysfs-first.patch | 0 ...hinfo-don-t-fail-for-devices-lacking.patch | 77 --- ...-parse_vpd_pg83-match-scsi_id-output.patch | 4 +- ...multipath-bump-ABI-version-to-18.0.0.patch | 26 - ...si-device-handlers-to-modules-load.d.patch | 0 ...-select_reload_action-in-select_acti.patch | 39 -- ...-RH-compile-with-libreadline-support.patch | 0 ...ect-resize-action-even-if-reload-is-.patch | 46 -- ...anup-ACT_CREATE-code-in-select_actio.patch | 68 -- ...p-renames-from-stopping-other-multip.patch | 186 ------ ...t-fix-resource-leak-in-update_map_pr.patch | 68 -- device-mapper-multipath.spec | 55 +- sources | 2 +- 30 files changed, 33 insertions(+), 1790 deletions(-) rename 0016-RH-fixup-udev-rules-for-redhat.patch => 0001-RH-fixup-udev-rules-for-redhat.patch (100%) delete mode 100644 0001-multipathd-make-pr-registration-consistent.patch rename 0017-RH-Remove-the-property-blacklist-exception-builtin.patch => 0002-RH-Remove-the-property-blacklist-exception-builtin.patch (100%) delete mode 100644 0002-libmultipath-make-prflag-an-enum.patch rename 0018-RH-don-t-start-without-a-config-file.patch => 0003-RH-don-t-start-without-a-config-file.patch (98%) delete mode 100644 0003-multipathd-handle-no-active-paths-in-update_map_pr.patch rename 0019-RH-Fix-nvme-function-missing-argument.patch => 0004-RH-Fix-nvme-function-missing-argument.patch (100%) delete mode 100644 0004-multipathd-add-missing-newline-to-cli_del_map-reply.patch rename 0020-RH-use-rpm-optflags-if-present.patch => 0005-RH-use-rpm-optflags-if-present.patch (100%) delete mode 100644 0005-libmultipath-skip-extra-vector-work-in-remove_maps.patch rename 0021-RH-add-mpathconf.patch => 0006-RH-add-mpathconf.patch (100%) delete mode 100644 0006-libmultipath-orphan-paths-if-coalesce_paths-frees-ne.patch rename 0022-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch => 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch (96%) delete mode 100644 0007-libmultipath-is_path_valid-check-if-device-is-in-use.patch rename 0023-RH-reset-default-find_mutipaths-value-to-off.patch => 0008-RH-reset-default-find_mutipaths-value-to-off.patch (100%) delete mode 100644 0008-libmpathpersist-use-conf-timeout-for-updating-persis.patch rename 0024-RH-attempt-to-get-ANA-info-via-sysfs-first.patch => 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch (100%) delete mode 100644 0009-libmultipath-pathinfo-don-t-fail-for-devices-lacking.patch rename 0025-RH-make-parse_vpd_pg83-match-scsi_id-output.patch => 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch (97%) delete mode 100644 0010-libmultipath-bump-ABI-version-to-18.0.0.patch rename 0026-RH-add-scsi-device-handlers-to-modules-load.d.patch => 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch (100%) delete mode 100644 0011-libmultipath-use-select_reload_action-in-select_acti.patch rename 0027-RH-compile-with-libreadline-support.patch => 0012-RH-compile-with-libreadline-support.patch (100%) delete mode 100644 0012-libmultipath-select-resize-action-even-if-reload-is-.patch delete mode 100644 0013-libmultipath-cleanup-ACT_CREATE-code-in-select_actio.patch delete mode 100644 0014-libmultipath-keep-renames-from-stopping-other-multip.patch delete mode 100644 0015-libmpathpersist-fix-resource-leak-in-update_map_pr.patch diff --git a/.gitignore b/.gitignore index 1ca930c..18226b9 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,4 @@ multipath-tools-091027.tar.gz /multipath-tools-0.9.0.tgz /multipath-tools-0.9.3.tgz /multipath-tools-0.9.4.tgz +/multipath-tools-0.9.5.tgz diff --git a/0016-RH-fixup-udev-rules-for-redhat.patch b/0001-RH-fixup-udev-rules-for-redhat.patch similarity index 100% rename from 0016-RH-fixup-udev-rules-for-redhat.patch rename to 0001-RH-fixup-udev-rules-for-redhat.patch diff --git a/0001-multipathd-make-pr-registration-consistent.patch b/0001-multipathd-make-pr-registration-consistent.patch deleted file mode 100644 index 47c380a..0000000 --- a/0001-multipathd-make-pr-registration-consistent.patch +++ /dev/null @@ -1,159 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 20 Dec 2022 17:41:10 -0600 -Subject: [PATCH] multipathd: make pr registration consistent - -multipathd was inconsistent on what it did with persistent reservations -when a multipath device was created. If a multipath device with a -configured reservation key was created during configure(), multipathd -would try to read the registered keys using an active path. If it saw a -matching key, it would set the prflag, but not attempt to register the -key on any of the other paths. This means that if a new path had -appeared while multipathd was not running, it wouldn't register the key -on this path. - -If the multipath device was created during ev_add_path(), multipathd -would used the added path to check if there was a matching key and if -there was, register the key only on the added path and then set the -prflag. This could be problematic if the device was created with -multiple paths, for instance because find_mutipaths was set to "yes" and -a second path just appeared. In this case, if the device happened to be -only registered on the second path, it would not get registered on the -first path. - -If the multipath device was added to multipathd during a call to -ev_add_map(), multipathd wouldn't set the prflag or register the key on -any paths. - -After a device was created with the prflag set, if a new path appeared -before the creation uevent, and multipathd was forced to delay adding -it, when it finally updated the multipath device, the key would be -registered on all paths, fixing any paths missed during creation. -However, if a new path appeared after the creation uevent, the key would -only be registered on that new path. Any paths that were missed on -creation would stay missed. - -persistent key registration needs to be handled consistently. This -patch does so by making sure that however a multipath device is added to -multipathd, it will check to see if the configured key is registered. If -it is, multipathd will set the prflag and register the key on all the -currently active paths. - -When a new path is added, multipathd will use it to check for active -keys, as before. But if it finds a matching key and prflag isn't -currently set, it will register the key on all paths. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - multipathd/main.c | 43 +++++++++++++++++++++++++++++-------------- - 1 file changed, 29 insertions(+), 14 deletions(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 1e1b254f..f7212d7b 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -586,13 +586,26 @@ flush_map_nopaths(struct multipath *mpp, struct vectors *vecs) { - return false; - } - -+static void -+pr_register_active_paths(struct multipath *mpp) -+{ -+ unsigned int i, j; -+ struct path *pp; -+ struct pathgroup *pgp; -+ -+ vector_foreach_slot (mpp->pg, pgp, i) { -+ vector_foreach_slot (pgp->paths, pp, j) { -+ if ((pp->state == PATH_UP) || (pp->state == PATH_GHOST)) -+ mpath_pr_event_handle(pp); -+ } -+ } -+} -+ - static int - update_map (struct multipath *mpp, struct vectors *vecs, int new_map) - { - int retries = 3; - char *params __attribute__((cleanup(cleanup_charp))) = NULL; -- struct path *pp; -- int i; - - retry: - condlog(4, "%s: updating new map", mpp->alias); -@@ -609,15 +622,6 @@ retry: - - mpp->action = ACT_RELOAD; - -- if (mpp->prflag) { -- vector_foreach_slot(mpp->paths, pp, i) { -- if ((pp->state == PATH_UP) || (pp->state == PATH_GHOST)) { -- /* persistent reservation check*/ -- mpath_pr_event_handle(pp); -- } -- } -- } -- - if (setup_map(mpp, ¶ms, vecs)) { - condlog(0, "%s: failed to setup new map in update", mpp->alias); - retries = -1; -@@ -643,6 +647,11 @@ fail: - - sync_map_state(mpp); - -+ if (!mpp->prflag) -+ update_map_pr(mpp); -+ if (mpp->prflag) -+ pr_register_active_paths(mpp); -+ - if (retries < 0) - condlog(0, "%s: failed reload in new map update", mpp->alias); - return 0; -@@ -1191,6 +1200,7 @@ ev_add_path (struct path * pp, struct vectors * vecs, int need_do_map) - int start_waiter = 0; - int ret; - int ro; -+ unsigned char prflag = 0; - - /* - * need path UID to go any further -@@ -1234,6 +1244,8 @@ rescan: - - verify_paths(mpp); - mpp->action = ACT_RELOAD; -+ prflag = mpp->prflag; -+ mpath_pr_event_handle(pp); - } else { - if (!should_multipath(pp, vecs->pathvec, vecs->mpvec)) { - orphan_path(pp, "only one path"); -@@ -1252,9 +1264,6 @@ rescan: - goto fail; /* leave path added to pathvec */ - } - -- /* persistent reservation check*/ -- mpath_pr_event_handle(pp); -- - /* ro check - if new path is ro, force map to be ro as well */ - ro = sysfs_get_ro(pp); - if (ro == 1) -@@ -1319,6 +1328,10 @@ rescan: - sync_map_state(mpp); - - if (retries >= 0) { -+ if (start_waiter) -+ update_map_pr(mpp); -+ if (mpp->prflag && !prflag) -+ pr_register_active_paths(mpp); - condlog(2, "%s [%s]: path added to devmap %s", - pp->dev, pp->dev_t, mpp->alias); - return 0; -@@ -2852,6 +2865,8 @@ configure (struct vectors * vecs, enum force_reload_types reload_type) - if (remember_wwid(mpp->wwid) == 1) - trigger_paths_udev_change(mpp, true); - update_map_pr(mpp); -+ if (mpp->prflag) -+ pr_register_active_paths(mpp); - } - - /* diff --git a/0017-RH-Remove-the-property-blacklist-exception-builtin.patch b/0002-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 100% rename from 0017-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0002-RH-Remove-the-property-blacklist-exception-builtin.patch diff --git a/0002-libmultipath-make-prflag-an-enum.patch b/0002-libmultipath-make-prflag-an-enum.patch deleted file mode 100644 index 304f731..0000000 --- a/0002-libmultipath-make-prflag-an-enum.patch +++ /dev/null @@ -1,166 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 20 Dec 2022 17:41:11 -0600 -Subject: [PATCH] libmultipath: make prflag an enum - -In preparation for a future patch, make prflag an enum, and change the -reply of cli_getprstatus() to a string. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmpathpersist/mpath_persist_int.c | 2 +- - libmultipath/structs.h | 8 +++++++- - multipathd/cli_handlers.c | 17 +++++++++-------- - multipathd/main.c | 14 +++++++------- - 4 files changed, 24 insertions(+), 17 deletions(-) - -diff --git a/libmpathpersist/mpath_persist_int.c b/libmpathpersist/mpath_persist_int.c -index 6924b379..a84d9474 100644 ---- a/libmpathpersist/mpath_persist_int.c -+++ b/libmpathpersist/mpath_persist_int.c -@@ -783,7 +783,7 @@ int update_map_pr(struct multipath *mpp) - - if (isFound) - { -- mpp->prflag = 1; -+ mpp->prflag = PRFLAG_SET; - condlog(2, "%s: prflag flag set.", mpp->alias ); - } - -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index 9e2c1ab0..f2265300 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -375,6 +375,12 @@ struct path { - - typedef int (pgpolicyfn) (struct multipath *, vector); - -+ -+enum prflag_value { -+ PRFLAG_UNSET, -+ PRFLAG_SET, -+}; -+ - struct multipath { - char wwid[WWID_SIZE]; - char alias_old[WWID_SIZE]; -@@ -449,7 +455,7 @@ struct multipath { - int prkey_source; - struct be64 reservation_key; - uint8_t sa_flags; -- unsigned char prflag; -+ int prflag; - int all_tg_pt; - struct gen_multipath generic_mp; - bool fpin_must_reload; -diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c -index e65fb75c..7ee2729f 100644 ---- a/multipathd/cli_handlers.c -+++ b/multipathd/cli_handlers.c -@@ -1277,6 +1277,10 @@ cli_shutdown (void * v, struct strbuf *reply, void * data) - static int - cli_getprstatus (void * v, struct strbuf *reply, void * data) - { -+ static const char * const prflag_str[] = { -+ [PRFLAG_UNSET] = "unset\n", -+ [PRFLAG_SET] = "set\n", -+ }; - struct multipath * mpp; - struct vectors * vecs = (struct vectors *)data; - char * param = get_keyparam(v, KEY_MAP); -@@ -1287,10 +1291,7 @@ cli_getprstatus (void * v, struct strbuf *reply, void * data) - if (!mpp) - return 1; - -- condlog(3, "%s: prflag = %u", param, (unsigned int)mpp->prflag); -- -- if (print_strbuf(reply, "%d", mpp->prflag) < 0) -- return 1; -+ append_strbuf_str(reply, prflag_str[mpp->prflag]); - - condlog(3, "%s: reply = %s", param, get_strbuf_str(reply)); - -@@ -1310,8 +1311,8 @@ cli_setprstatus(void * v, struct strbuf *reply, void * data) - if (!mpp) - return 1; - -- if (!mpp->prflag) { -- mpp->prflag = 1; -+ if (mpp->prflag != PRFLAG_SET) { -+ mpp->prflag = PRFLAG_SET; - condlog(2, "%s: prflag set", param); - } - -@@ -1332,8 +1333,8 @@ cli_unsetprstatus(void * v, struct strbuf *reply, void * data) - if (!mpp) - return 1; - -- if (mpp->prflag) { -- mpp->prflag = 0; -+ if (mpp->prflag != PRFLAG_UNSET) { -+ mpp->prflag = PRFLAG_UNSET; - condlog(2, "%s: prflag unset", param); - } - -diff --git a/multipathd/main.c b/multipathd/main.c -index f7212d7b..722235c7 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -647,9 +647,9 @@ fail: - - sync_map_state(mpp); - -- if (!mpp->prflag) -+ if (mpp->prflag == PRFLAG_UNSET) - update_map_pr(mpp); -- if (mpp->prflag) -+ if (mpp->prflag == PRFLAG_SET) - pr_register_active_paths(mpp); - - if (retries < 0) -@@ -1200,7 +1200,7 @@ ev_add_path (struct path * pp, struct vectors * vecs, int need_do_map) - int start_waiter = 0; - int ret; - int ro; -- unsigned char prflag = 0; -+ unsigned char prflag = PRFLAG_UNSET; - - /* - * need path UID to go any further -@@ -1330,7 +1330,7 @@ rescan: - if (retries >= 0) { - if (start_waiter) - update_map_pr(mpp); -- if (mpp->prflag && !prflag) -+ if (mpp->prflag == PRFLAG_SET && prflag == PRFLAG_UNSET) - pr_register_active_paths(mpp); - condlog(2, "%s [%s]: path added to devmap %s", - pp->dev, pp->dev_t, mpp->alias); -@@ -2492,7 +2492,7 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) - } - - if (newstate == PATH_UP || newstate == PATH_GHOST) { -- if (pp->mpp->prflag) { -+ if (pp->mpp->prflag == PRFLAG_SET) { - /* - * Check Persistent Reservation. - */ -@@ -2865,7 +2865,7 @@ configure (struct vectors * vecs, enum force_reload_types reload_type) - if (remember_wwid(mpp->wwid) == 1) - trigger_paths_udev_change(mpp, true); - update_map_pr(mpp); -- if (mpp->prflag) -+ if (mpp->prflag == PRFLAG_SET) - pr_register_active_paths(mpp); - } - -@@ -3840,7 +3840,7 @@ void * mpath_pr_event_handler_fn (void * pathp ) - { - condlog(0,"%s: Reservation registration failed. Error: %d", pp->dev, ret); - } -- mpp->prflag = 1; -+ mpp->prflag = PRFLAG_SET; - - free(param); - out: diff --git a/0018-RH-don-t-start-without-a-config-file.patch b/0003-RH-don-t-start-without-a-config-file.patch similarity index 98% rename from 0018-RH-don-t-start-without-a-config-file.patch rename to 0003-RH-don-t-start-without-a-config-file.patch index c957e2f..e6e03b4 100644 --- a/0018-RH-don-t-start-without-a-config-file.patch +++ b/0003-RH-don-t-start-without-a-config-file.patch @@ -57,7 +57,7 @@ index 87947469..0dc89c16 100644 enum devtypes { DEV_NONE, diff --git a/multipath/multipath.rules.in b/multipath/multipath.rules.in -index 8d3cf33a..5c4447a2 100644 +index 6f123760..70b69a06 100644 --- a/multipath/multipath.rules.in +++ b/multipath/multipath.rules.in @@ -9,6 +9,7 @@ IMPORT{cmdline}="nompath" @@ -82,7 +82,7 @@ index bdf102eb..a16a0bd5 100644 . .\" ---------------------------------------------------------------------------- diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service -index aec62dbb..d76f94f9 100644 +index 5a9cde12..311f49c7 100644 --- a/multipathd/multipathd.service +++ b/multipathd/multipathd.service @@ -6,6 +6,7 @@ Wants=systemd-udevd-kernel.socket diff --git a/0003-multipathd-handle-no-active-paths-in-update_map_pr.patch b/0003-multipathd-handle-no-active-paths-in-update_map_pr.patch deleted file mode 100644 index 59dd10f..0000000 --- a/0003-multipathd-handle-no-active-paths-in-update_map_pr.patch +++ /dev/null @@ -1,152 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 20 Dec 2022 17:41:12 -0600 -Subject: [PATCH] multipathd: handle no active paths in update_map_pr - -When a multipath device is first created, if it has a reservation key -configured, update_map_pr() will check for a matching key on the active -paths. If there were no active paths to check with, multipathd was -leaving mpp->prflag in PRFLAG_UNSET, as if there were no matching keys. -It's possible that when update_map_pr() is called, all the paths will be -in the PATH_PENDING state because the checkers haven't completed yet. In -this case, multipathd was treating the device as having no registered -keys without ever checking. - -To solve this, multipath devices now start with prflag = PRFLAG_UNKNOWN. -It will remain in this state until multipathd actually tries to get the -registered keys down a path. If the map is in this state, it will check -newly active paths, and if it finds a matching key, it will register -the key down all active paths. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmpathpersist/mpath_persist_int.c | 8 ++++++++ - libmultipath/structs.h | 1 + - multipathd/cli_handlers.c | 1 + - multipathd/main.c | 19 ++++++++++++++----- - 4 files changed, 24 insertions(+), 5 deletions(-) - -diff --git a/libmpathpersist/mpath_persist_int.c b/libmpathpersist/mpath_persist_int.c -index a84d9474..8b52b746 100644 ---- a/libmpathpersist/mpath_persist_int.c -+++ b/libmpathpersist/mpath_persist_int.c -@@ -738,6 +738,7 @@ int update_map_pr(struct multipath *mpp) - if (!get_be64(mpp->reservation_key)) - { - /* Nothing to do. Assuming pr mgmt feature is disabled*/ -+ mpp->prflag = PRFLAG_UNSET; - condlog(4, "%s: reservation_key not set in multipath.conf", - mpp->alias); - return MPATH_PR_SUCCESS; -@@ -749,6 +750,13 @@ int update_map_pr(struct multipath *mpp) - condlog(0,"%s : failed to alloc resp in update_map_pr", mpp->alias); - return MPATH_PR_OTHER; - } -+ if (count_active_paths(mpp) == 0) -+ { -+ condlog(0,"%s: No available paths to check pr status", -+ mpp->alias); -+ return MPATH_PR_OTHER; -+ } -+ mpp->prflag = PRFLAG_UNSET; - ret = mpath_prin_activepath(mpp, MPATH_PRIN_RKEY_SA, resp, noisy); - - if (ret != MPATH_PR_SUCCESS ) -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index f2265300..e2294323 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -377,6 +377,7 @@ typedef int (pgpolicyfn) (struct multipath *, vector); - - - enum prflag_value { -+ PRFLAG_UNKNOWN, - PRFLAG_UNSET, - PRFLAG_SET, - }; -diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c -index 7ee2729f..ec5db1b8 100644 ---- a/multipathd/cli_handlers.c -+++ b/multipathd/cli_handlers.c -@@ -1278,6 +1278,7 @@ static int - cli_getprstatus (void * v, struct strbuf *reply, void * data) - { - static const char * const prflag_str[] = { -+ [PRFLAG_UNKNOWN] = "unknown\n", - [PRFLAG_UNSET] = "unset\n", - [PRFLAG_SET] = "set\n", - }; -diff --git a/multipathd/main.c b/multipathd/main.c -index 722235c7..bdeffe76 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -647,7 +647,7 @@ fail: - - sync_map_state(mpp); - -- if (mpp->prflag == PRFLAG_UNSET) -+ if (mpp->prflag != PRFLAG_SET) - update_map_pr(mpp); - if (mpp->prflag == PRFLAG_SET) - pr_register_active_paths(mpp); -@@ -1330,7 +1330,7 @@ rescan: - if (retries >= 0) { - if (start_waiter) - update_map_pr(mpp); -- if (mpp->prflag == PRFLAG_SET && prflag == PRFLAG_UNSET) -+ if (mpp->prflag == PRFLAG_SET && prflag != PRFLAG_SET) - pr_register_active_paths(mpp); - condlog(2, "%s [%s]: path added to devmap %s", - pp->dev, pp->dev_t, mpp->alias); -@@ -2492,13 +2492,17 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) - } - - if (newstate == PATH_UP || newstate == PATH_GHOST) { -- if (pp->mpp->prflag == PRFLAG_SET) { -+ if (pp->mpp->prflag != PRFLAG_UNSET) { -+ int prflag = pp->mpp->prflag; - /* - * Check Persistent Reservation. - */ - condlog(2, "%s: checking persistent " - "reservation registration", pp->dev); - mpath_pr_event_handle(pp); -+ if (pp->mpp->prflag == PRFLAG_SET && -+ prflag != PRFLAG_SET) -+ pr_register_active_paths(pp->mpp); - } - } - -@@ -3788,6 +3792,7 @@ void * mpath_pr_event_handler_fn (void * pathp ) - goto out; - } - -+ mpp->prflag = PRFLAG_UNSET; - ret = prin_do_scsi_ioctl(pp->dev, MPATH_PRIN_RKEY_SA, resp, 0); - if (ret != MPATH_PR_SUCCESS ) - { -@@ -3858,12 +3863,12 @@ int mpath_pr_event_handle(struct path *pp) - struct multipath * mpp; - - if (pp->bus != SYSFS_BUS_SCSI) -- return 0; -+ goto no_pr; - - mpp = pp->mpp; - - if (!get_be64(mpp->reservation_key)) -- return -1; -+ goto no_pr; - - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); -@@ -3876,4 +3881,8 @@ int mpath_pr_event_handle(struct path *pp) - pthread_attr_destroy(&attr); - rc = pthread_join(thread, NULL); - return 0; -+ -+no_pr: -+ pp->mpp->prflag = PRFLAG_UNSET; -+ return 0; - } diff --git a/0019-RH-Fix-nvme-function-missing-argument.patch b/0004-RH-Fix-nvme-function-missing-argument.patch similarity index 100% rename from 0019-RH-Fix-nvme-function-missing-argument.patch rename to 0004-RH-Fix-nvme-function-missing-argument.patch diff --git a/0004-multipathd-add-missing-newline-to-cli_del_map-reply.patch b/0004-multipathd-add-missing-newline-to-cli_del_map-reply.patch deleted file mode 100644 index 085fd70..0000000 --- a/0004-multipathd-add-missing-newline-to-cli_del_map-reply.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 20 Dec 2022 17:41:13 -0600 -Subject: [PATCH] multipathd: add missing newline to cli_del_map reply - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - multipathd/cli_handlers.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c -index ec5db1b8..44bf43df 100644 ---- a/multipathd/cli_handlers.c -+++ b/multipathd/cli_handlers.c -@@ -760,7 +760,7 @@ cli_del_map (void * v, struct strbuf *reply, void * data) - } - rc = ev_remove_map(param, alias, minor, vecs); - if (rc == 2) -- append_strbuf_str(reply, "delayed"); -+ append_strbuf_str(reply, "delayed\n"); - - free(alias); - return rc; diff --git a/0020-RH-use-rpm-optflags-if-present.patch b/0005-RH-use-rpm-optflags-if-present.patch similarity index 100% rename from 0020-RH-use-rpm-optflags-if-present.patch rename to 0005-RH-use-rpm-optflags-if-present.patch diff --git a/0005-libmultipath-skip-extra-vector-work-in-remove_maps.patch b/0005-libmultipath-skip-extra-vector-work-in-remove_maps.patch deleted file mode 100644 index ee08327..0000000 --- a/0005-libmultipath-skip-extra-vector-work-in-remove_maps.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 20 Dec 2022 17:41:14 -0600 -Subject: [PATCH] libmultipath: skip extra vector work in remove_maps - -Instead of repeatedly removing the first vector element, and shifting -the rest to fill in, call remove_map() without a vector, so it just -frees the devices. The vector will be completely cleaned up by -vector_free() immediately afterwards. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/structs_vec.c | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - -diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c -index 5a618767..f3fdc5a6 100644 ---- a/libmultipath/structs_vec.c -+++ b/libmultipath/structs_vec.c -@@ -392,10 +392,8 @@ remove_maps(struct vectors * vecs) - if (!vecs) - return; - -- vector_foreach_slot (vecs->mpvec, mpp, i) { -- remove_map(mpp, vecs->pathvec, vecs->mpvec); -- i--; -- } -+ vector_foreach_slot (vecs->mpvec, mpp, i) -+ remove_map(mpp, vecs->pathvec, NULL); - - vector_free(vecs->mpvec); - vecs->mpvec = NULL; diff --git a/0021-RH-add-mpathconf.patch b/0006-RH-add-mpathconf.patch similarity index 100% rename from 0021-RH-add-mpathconf.patch rename to 0006-RH-add-mpathconf.patch diff --git a/0006-libmultipath-orphan-paths-if-coalesce_paths-frees-ne.patch b/0006-libmultipath-orphan-paths-if-coalesce_paths-frees-ne.patch deleted file mode 100644 index f545df7..0000000 --- a/0006-libmultipath-orphan-paths-if-coalesce_paths-frees-ne.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 20 Dec 2022 17:41:15 -0600 -Subject: [PATCH] libmultipath: orphan paths if coalesce_paths frees newmp - -If coalesce_paths() is called without a mpvec, it will free all the -multipath devices on newmp at the end. This will clear pp->mpp from the -path, but it doesn't completely unitialize them. cli_add_map() can call -coalsce_paths() this way, when adding a device that doesn't currently -exist. cli_add_map() first creates the device in the kernel, and then -calls ev_add_map() to add it to multipathd. If something goes wrong in -ev_add_map(), the paths will still be initialized, even though they're -orphans. - -Fix this by calling remove_map() to orphan the paths that belong to -the multipath devices being deleted by coalesce_paths(). - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/configure.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index e551047a..e689f8a7 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -1273,8 +1273,11 @@ int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid, - ret = CP_OK; - out: - free(size_mismatch_seen); -- if (!mpvec) -- free_multipathvec(newmp, KEEP_PATHS); -+ if (!mpvec) { -+ vector_foreach_slot (newmp, mpp, i) -+ remove_map(mpp, vecs->pathvec, NULL); -+ vector_free(newmp); -+ } - return ret; - } - diff --git a/0022-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 96% rename from 0022-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch index c98543b..714a1bb 100644 --- a/0022-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +++ b/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch @@ -20,7 +20,7 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/multipath/main.c b/multipath/main.c -index b9f360b4..5eb752ee 100644 +index 90f940f1..3549740a 100644 --- a/multipath/main.c +++ b/multipath/main.c @@ -120,7 +120,7 @@ usage (char * progname) @@ -92,7 +92,7 @@ index b9f360b4..5eb752ee 100644 static int configure (struct config *conf, enum mpath_cmds cmd, enum devtypes dev_type, char *devpath) -@@ -840,7 +886,7 @@ main (int argc, char *argv[]) +@@ -842,7 +888,7 @@ main (int argc, char *argv[]) conf->force_sync = 1; if (atexit(cleanup_vecs)) condlog(1, "failed to register cleanup handler for vecs: %m"); @@ -101,7 +101,7 @@ index b9f360b4..5eb752ee 100644 switch(arg) { case 'v': if (!isdigit(optarg[0])) { -@@ -911,6 +957,10 @@ main (int argc, char *argv[]) +@@ -913,6 +959,10 @@ main (int argc, char *argv[]) case 'T': cmd = CMD_DUMP_CONFIG; break; @@ -138,7 +138,7 @@ index 88149d53..072a03ee 100644 Remove the WWID for the specified device from the WWIDs file. . diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service -index d76f94f9..bb5f383a 100644 +index 311f49c7..5324f4bc 100644 --- a/multipathd/multipathd.service +++ b/multipathd/multipathd.service @@ -17,6 +17,7 @@ ConditionVirtualization=!container diff --git a/0007-libmultipath-is_path_valid-check-if-device-is-in-use.patch b/0007-libmultipath-is_path_valid-check-if-device-is-in-use.patch deleted file mode 100644 index 6ffa6fc..0000000 --- a/0007-libmultipath-is_path_valid-check-if-device-is-in-use.patch +++ /dev/null @@ -1,609 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 9 Nov 2022 21:20:58 +0100 -Subject: [PATCH] libmultipath: is_path_valid(): check if device is in use - -To check whether we will be able to add a given device can be part -of a multipath map, we have two tests in check_path_valid(): -released_to_systemd() and the O_EXCL test. The former isn't helpful -if "multipath -u" is called for the first time for a given device, -and the latter is only used in the "find_multipaths smart" case, because -actively opening the device with O_EXCL, even for a very short time, is prone -to races with other processes. - -It turns out that this may cause issues in some scenarios. We saw problems in -once case where "find_multipaths greedy" was used with a single -non-multipahted root disk and a very large number of multipath LUNs. -The root disk would first be classified as multipath device. multipathd -would try to create a map, fail (because the disk was mounted) and -trigger another uevent. But because of the very large number of multipath -devices, this event was queued up behind thousands of other events, and -the root device timed out eventually. - -While a simple workaround for the given problem would be proper blacklisting -or using a different find_multipaths mode, I am proposing a different -solution here. An additional test is added in is_path_valid() which -checks whether the given device is currently in use by 1. sysfs holders, -2. mounts (from /proc/self/mountinfo) or 3. swaps (from /proc/swaps). 2. -and 3. are similar to systemd's device detection after switching root. -This must not only be done for the device itself, but also for all its -partitions. For mountinfo and swaps, libmount is utilized. - -With this patch, "multipath -u" will make devices with mounted or otherwise -used partitions available to systemd early, without waiting for multipathd -to fail setting up the map and re-triggering an uevent. This should avoid -the issue described above even without blacklisting. The downside of it -is a longer runtime of "multipath -u" for almost all devices, in particular -for real multipath devices. The runtime required for the new checks was in the -order of 0.1ms-1ms in my tests. Moreover, there is a certain risk that devices may -wrongly classified as non-multipath because of transient mounts or holders -created by other processes. - -To make this code compile on older distributions, we need some additional -checks in create-config.mk. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/build-and-unittest.yaml | 2 +- - create-config.mk | 11 +- - libmpathutil/libmpathutil.version | 6 + - libmpathutil/util.c | 12 + - libmpathutil/util.h | 2 + - libmultipath/Makefile | 2 +- - libmultipath/alias.c | 11 - - libmultipath/valid.c | 270 ++++++++++++++++++++++ - tests/Makefile | 2 +- - tests/valid.c | 48 ++++ - 10 files changed, 351 insertions(+), 15 deletions(-) - -diff --git a/.github/workflows/build-and-unittest.yaml b/.github/workflows/build-and-unittest.yaml -index abf17bf0..9e6c0e89 100644 ---- a/.github/workflows/build-and-unittest.yaml -+++ b/.github/workflows/build-and-unittest.yaml -@@ -31,7 +31,7 @@ jobs: - sudo apt-get install --yes gcc - make perl-base pkg-config valgrind - libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev -- libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev -+ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev libmount-dev - - name: build - run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) READLINE=${{ matrix.rl }} - - name: test -diff --git a/create-config.mk b/create-config.mk -index 2a95ec56..f128375f 100644 ---- a/create-config.mk -+++ b/create-config.mk -@@ -23,7 +23,7 @@ check_cmd = $(shell \ - - # Check whether a function with name $1 has been declared in header file $2. - check_func = $(shell \ -- if grep -Eq "^[^[:blank:]]+[[:blank:]]+$1[[:blank:]]*(.*)*" "$2"; then \ -+ if grep -Eq "^(extern[[:blank:]]+)?[^[:blank:]]+[[:blank:]]+$1[[:blank:]]*(.*)*" "$2"; then \ - found=1; \ - status="yes"; \ - else \ -@@ -104,6 +104,15 @@ ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(kernel_incdir)/scsi/fc/fc_els.h - FPIN_SUPPORT = 1 - endif - -+libmount_h := $(shell $(PKGCONFIG) --variable=includedir mount)/libmount/libmount.h -+ifneq ($(call check_func,mnt_unref_cache,$(libmount_h)),0) -+ DEFINES += LIBMOUNT_HAS_MNT_UNREF_CACHE -+endif -+ -+ifneq ($(call check_func,mnt_table_parse_swaps,$(libmount_h)),0) -+ DEFINES += LIBMOUNT_SUPPORTS_SWAP -+endif -+ - ifneq ($(call check_file,$(kernel_incdir)/linux/nvme_ioctl.h),0) - ANA_SUPPORT := 1 - endif -diff --git a/libmpathutil/libmpathutil.version b/libmpathutil/libmpathutil.version -index 1238fc93..dd007be4 100644 ---- a/libmpathutil/libmpathutil.version -+++ b/libmpathutil/libmpathutil.version -@@ -133,3 +133,9 @@ LIBMPATHUTIL_1.1 { - global: - cleanup_fd_ptr; - } LIBMPATHUTIL_1.0; -+ -+LIBMPATHUTIL_1.2 { -+global: -+ cleanup_vector_free; -+ cleanup_fclose; -+} LIBMPATHUTIL_1.0; -diff --git a/libmpathutil/util.c b/libmpathutil/util.c -index 9662e1ed..92f25a50 100644 ---- a/libmpathutil/util.c -+++ b/libmpathutil/util.c -@@ -386,6 +386,18 @@ void cleanup_mutex(void *arg) - pthread_mutex_unlock(arg); - } - -+void cleanup_vector_free(void *arg) -+{ -+ if (arg) -+ vector_free((vector)arg); -+} -+ -+void cleanup_fclose(void *p) -+{ -+ if (p) -+ fclose(p); -+} -+ - struct bitfield *alloc_bitfield(unsigned int maxbit) - { - unsigned int n; -diff --git a/libmpathutil/util.h b/libmpathutil/util.h -index 75e20fd8..99a471d0 100644 ---- a/libmpathutil/util.h -+++ b/libmpathutil/util.h -@@ -48,6 +48,8 @@ int should_exit(void); - void cleanup_fd_ptr(void *arg); - void cleanup_free_ptr(void *arg); - void cleanup_mutex(void *arg); -+void cleanup_vector_free(void *arg); -+void cleanup_fclose(void *p); - - struct scandir_result { - struct dirent **di; -diff --git a/libmultipath/Makefile b/libmultipath/Makefile -index 3df851e2..61aa611f 100644 ---- a/libmultipath/Makefile -+++ b/libmultipath/Makefile -@@ -7,7 +7,7 @@ DEVLIB := libmultipath.so - CPPFLAGS += -I$(mpathutildir) -I$(mpathcmddir) -I$(nvmedir) -D_GNU_SOURCE $(SYSTEMD_CPPFLAGS) - CFLAGS += $(LIB_CFLAGS) - LIBDEPS += -lpthread -ldl -ldevmapper -ludev -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd \ -- -lurcu -laio $(SYSTEMD_LIBDEPS) -+ -lmount -lurcu -laio $(SYSTEMD_LIBDEPS) - - # object files referencing MULTIPATH_DIR or CONFIG_DIR - # they need to be recompiled for unit tests -diff --git a/libmultipath/alias.c b/libmultipath/alias.c -index 05201224..c0139a2e 100644 ---- a/libmultipath/alias.c -+++ b/libmultipath/alias.c -@@ -667,11 +667,6 @@ static int _check_bindings_file(const struct config *conf, FILE *file, - return rc; - } - --static void cleanup_fclose(void *p) --{ -- fclose(p); --} -- - static int alias_compar(const void *p1, const void *p2) - { - const char *alias1 = (*(struct mpentry * const *)p1)->alias; -@@ -684,12 +679,6 @@ static int alias_compar(const void *p1, const void *p2) - return alias1 ? -1 : alias2 ? 1 : 0; - } - --static void cleanup_vector_free(void *arg) --{ -- if (arg) -- vector_free((vector)arg); --} -- - /* - * check_alias_settings(): test for inconsistent alias configuration - * -diff --git a/libmultipath/valid.c b/libmultipath/valid.c -index a6aa9215..d4dae3ed 100644 ---- a/libmultipath/valid.c -+++ b/libmultipath/valid.c -@@ -17,6 +17,8 @@ - #include - #include - #include -+#include -+#include - - #include "vector.h" - #include "config.h" -@@ -30,12 +32,271 @@ - #include "mpath_cmd.h" - #include "valid.h" - -+static int subdir_filter(const struct dirent *ent) -+{ -+ unsigned int j; -+ static char const *const skip[] = { -+ ".", -+ "..", -+ "holders", -+ "integrity", -+ "mq", -+ "power", -+ "queue", -+ "slaves", -+ "trace", -+ }; -+ -+ if (ent->d_type != DT_DIR) -+ return 0; -+ -+ for (j = 0; j < ARRAY_SIZE(skip); j++) -+ if (!strcmp(skip[j], ent->d_name)) -+ return 0; -+ return 1; -+} -+ -+static int read_partitions(const char *syspath, vector parts) -+{ -+ struct scandir_result sr = { .n = 0 }; -+ char path[PATH_MAX], *last; -+ char *prop; -+ int i; -+ -+ strlcpy(path, syspath, sizeof(path)); -+ sr.n = scandir(path, &sr.di, subdir_filter, NULL); -+ if (sr.n == -1) -+ return -errno; -+ -+ pthread_cleanup_push_cast(free_scandir_result, &sr); -+ -+ /* parts[0] is the whole disk */ -+ if ((prop = strdup(strrchr(path, '/') + 1)) != NULL) { -+ if (vector_alloc_slot(parts)) -+ vector_set_slot(parts, prop); -+ else -+ free(prop); -+ } -+ -+ last = path + strlen(path); -+ for (i = 0; i < sr.n; i++) { -+ struct stat st; -+ -+ /* only add dirs that have the "partition" attribute */ -+ snprintf(last, sizeof(path) - (last - path), "/%s/partition", -+ sr.di[i]->d_name); -+ -+ if (stat(path, &st) == 0 && -+ (prop = strdup(sr.di[i]->d_name)) != NULL) { -+ if (vector_alloc_slot(parts)) -+ vector_set_slot(parts, prop); -+ else -+ free(prop); -+ } -+ } -+ -+ pthread_cleanup_pop(1); -+ return 0; -+} -+ -+static int no_dots(const struct dirent *ent) -+{ -+ const char *name = ent->d_name; -+ -+ if (name[0] == '.' && -+ (name[1] == '\0' || (name[1] == '.' && name[2] == '\0'))) -+ return 0; -+ return 1; -+} -+ -+static int check_holders(const char *syspath) -+{ -+ struct scandir_result __attribute__((cleanup(free_scandir_result))) -+ sr = { .n = 0 }; -+ -+ sr.n = scandir(syspath, &sr.di, no_dots, NULL); -+ if (sr.n > 0) -+ condlog(4, "%s: found holders under %s", __func__, syspath); -+ return sr.n; -+} -+ -+static int check_all_holders(const struct _vector *parts) -+{ -+ char syspath[PATH_MAX]; -+ const char *sysname; -+ unsigned int j; -+ -+ if (VECTOR_SIZE(parts) == 0) -+ return 0; -+ -+ if (safe_sprintf(syspath, "/sys/class/block/%s/holders", -+ (const char *)VECTOR_SLOT(parts, 0))) -+ return -EOVERFLOW; -+ -+ if (check_holders(syspath) > 0) -+ return 1; -+ -+ j = 1; -+ vector_foreach_slot_after(parts, sysname, j) { -+ if (safe_sprintf(syspath, "/sys/class/block/%s/%s/holders", -+ (const char *)VECTOR_SLOT(parts, 0), sysname)) -+ return -EOVERFLOW; -+ if (check_holders(syspath) > 0) -+ return 1; -+ } -+ return 0; -+} -+ -+static void cleanup_table(void *arg) -+{ -+ if (arg) -+ mnt_free_table((struct libmnt_table *)arg); -+} -+ -+static void cleanup_cache(void *arg) -+{ -+ if (arg) -+#ifdef LIBMOUNT_HAS_MNT_UNREF_CACHE -+ mnt_unref_cache((struct libmnt_cache *)arg); -+#else -+ mnt_free_cache((struct libmnt_cache *)arg); -+#endif -+} -+ -+/* -+ * Passed a vector of partitions and a libmount table, -+ * check if any of the partitions in the vector is referenced in the table. -+ * Note that mnt_table_find_srcpath() also resolves mounts by symlinks. -+ */ -+static int check_mnt_table(const struct _vector *parts, -+ struct libmnt_table *tbl, -+ const char *table_name) -+{ -+ unsigned int i; -+ const char *sysname; -+ char devpath[PATH_MAX]; -+ -+ vector_foreach_slot(parts, sysname, i) { -+ if (!safe_sprintf(devpath, "/dev/%s", sysname) && -+ mnt_table_find_srcpath(tbl, devpath, -+ MNT_ITER_FORWARD) != NULL) { -+ condlog(4, "%s: found %s in %s", __func__, -+ sysname, table_name); -+ return 1; -+ } -+ } -+ return 0; -+} -+ -+static int check_mountinfo(const struct _vector *parts) -+{ -+ static const char mountinfo[] = "/proc/self/mountinfo"; -+ struct libmnt_table *tbl; -+ struct libmnt_cache *cache; -+ FILE *stream; -+ int used = 0, ret; -+ -+ tbl = mnt_new_table(); -+ if (!tbl ) -+ return -errno; -+ -+ pthread_cleanup_push(cleanup_table, tbl); -+ cache = mnt_new_cache(); -+ if (cache) { -+ pthread_cleanup_push(cleanup_cache, cache); -+ if (mnt_table_set_cache(tbl, cache) == 0) { -+ stream = fopen(mountinfo, "r"); -+ if (stream != NULL) { -+ pthread_cleanup_push(cleanup_fclose, stream); -+ ret = mnt_table_parse_stream(tbl, stream, mountinfo); -+ pthread_cleanup_pop(1); -+ -+ if (ret == 0) -+ used = check_mnt_table(parts, tbl, -+ "mountinfo"); -+ } -+ } -+ pthread_cleanup_pop(1); -+ } -+ pthread_cleanup_pop(1); -+ return used; -+} -+ -+#ifdef LIBMOUNT_SUPPORTS_SWAP -+static int check_swaps(const struct _vector *parts) -+{ -+ struct libmnt_table *tbl; -+ struct libmnt_cache *cache; -+ int used = 0, ret; -+ -+ tbl = mnt_new_table(); -+ if (!tbl ) -+ return -errno; -+ -+ pthread_cleanup_push(cleanup_table, tbl); -+ cache = mnt_new_cache(); -+ if (cache) { -+ pthread_cleanup_push(cleanup_cache, cache); -+ if (mnt_table_set_cache(tbl, cache) == 0) { -+ ret = mnt_table_parse_swaps(tbl, NULL); -+ if (ret == 0) -+ used = check_mnt_table(parts, tbl, "swaps"); -+ } -+ pthread_cleanup_pop(1); -+ } -+ pthread_cleanup_pop(1); -+ return used; -+} -+#else -+static int check_swaps(const struct _vector *parts __attribute__((unused))) -+{ -+ return 0; -+} -+#endif -+ -+ -+/* -+ * Given a block device, check if the device itself or any of its -+ * partitions is in use -+ * - by sysfs holders (e.g. LVM) -+ * - mounted according to /proc/self/mountinfo -+ * - used as swap -+ */ -+static int is_device_in_use(struct udev_device *udevice) -+{ -+ const char *syspath; -+ vector parts; -+ int used = 0, ret; -+ -+ syspath = udev_device_get_syspath(udevice); -+ if (!syspath) -+ return -ENOMEM; -+ -+ parts = vector_alloc(); -+ if (!parts) -+ return -ENOMEM; -+ -+ pthread_cleanup_push_cast(free_strvec, parts); -+ if ((ret = read_partitions(syspath, parts)) == 0) -+ used = check_all_holders(parts) > 0 || -+ check_mountinfo(parts) > 0 || -+ check_swaps(parts) > 0; -+ pthread_cleanup_pop(1); -+ -+ if (ret < 0) -+ return ret; -+ -+ condlog(3, "%s: %s is %sin use", __func__, syspath, used ? "" : "not "); -+ return used; -+} -+ - int - is_path_valid(const char *name, struct config *conf, struct path *pp, - bool check_multipathd) - { - int r; - int fd; -+ const char *prop; - - if (!pp || !name || !conf) - return PATH_IS_ERROR; -@@ -80,6 +341,10 @@ is_path_valid(const char *name, struct config *conf, struct path *pp, - if (!pp->udev) - return PATH_IS_ERROR; - -+ prop = udev_device_get_property_value(pp->udev, "DEVTYPE"); -+ if (prop == NULL || strcmp(prop, "disk")) -+ return PATH_IS_NOT_VALID; -+ - r = pathinfo(pp, conf, DI_SYSFS | DI_WWID | DI_BLACKLIST); - if (r == PATHINFO_SKIPPED) - return PATH_IS_NOT_VALID; -@@ -96,6 +361,11 @@ is_path_valid(const char *name, struct config *conf, struct path *pp, - return PATH_IS_ERROR; - } - -+ if ((conf->find_multipaths == FIND_MULTIPATHS_GREEDY || -+ conf->find_multipaths == FIND_MULTIPATHS_SMART) && -+ is_device_in_use(pp->udev) > 0) -+ return PATH_IS_NOT_VALID; -+ - if (conf->find_multipaths == FIND_MULTIPATHS_GREEDY) - return PATH_IS_VALID; - -diff --git a/tests/Makefile b/tests/Makefile -index 860338b2..1648ab9d 100644 ---- a/tests/Makefile -+++ b/tests/Makefile -@@ -55,7 +55,7 @@ vpd-test_LIBDEPS := -ludev -lpthread -ldl - alias-test_TESTDEPS := test-log.o - alias-test_LIBDEPS := -lpthread -ldl - valid-test_OBJDEPS := $(multipathdir)/valid.o $(multipathdir)/discovery.o --valid-test_LIBDEPS := -ludev -lpthread -ldl -+valid-test_LIBDEPS := -lmount -ludev -lpthread -ldl - devt-test_LIBDEPS := -ludev - mpathvalid-test_LIBDEPS := -ludev -lpthread -ldl - mpathvalid-test_OBJDEPS := $(mpathvaliddir)/mpath_valid.o -diff --git a/tests/valid.c b/tests/valid.c -index 398b771e..70329324 100644 ---- a/tests/valid.c -+++ b/tests/valid.c -@@ -83,6 +83,13 @@ struct udev_device *__wrap_udev_device_new_from_subsystem_sysname(struct udev *u - return NULL; - } - -+/* For devtype check */ -+const char *__wrap_udev_device_get_property_value(struct udev_device *udev_device, const char *property) -+{ -+ check_expected(property); -+ return mock_ptr_type(char *); -+} -+ - /* For the "hidden" check in pathinfo() */ - const char *__wrap_udev_device_get_sysattr_value(struct udev_device *udev_device, - const char *sysattr) -@@ -97,6 +104,12 @@ int __wrap_add_foreign(struct udev_device *udev_device) - return mock_type(int); - } - -+/* For is_device_used() */ -+const char *__wrap_udev_device_get_sysname(struct udev_device *udev_device) -+{ -+ return mock_ptr_type(char *); -+} -+ - /* called from pathinfo() */ - int __wrap_filter_devnode(struct config *conf, const struct _vector *elist, - const char *vendor, const char * product, const char *dev) -@@ -165,6 +178,11 @@ int __wrap_is_failed_wwid(const char *wwid) - return ret; - } - -+const char *__wrap_udev_device_get_syspath(struct udev_device *udevice) -+{ -+ return mock_ptr_type(char *); -+} -+ - int __wrap_check_wwids_file(char *wwid, int write_wwid) - { - bool passed = mock_type(bool); -@@ -225,6 +243,8 @@ static void setup_passing(char *name, char *wwid, unsigned int check_multipathd, - will_return(__wrap_udev_device_new_from_subsystem_sysname, true); - will_return(__wrap_udev_device_new_from_subsystem_sysname, - name); -+ expect_string(__wrap_udev_device_get_property_value, property, "DEVTYPE"); -+ will_return(__wrap_udev_device_get_property_value, "disk"); - if (stage == STAGE_GET_UDEV_DEVICE) - return; - if (stage == STAGE_PATHINFO_REAL) { -@@ -250,6 +270,10 @@ static void setup_passing(char *name, char *wwid, unsigned int check_multipathd, - return; - will_return(__wrap_is_failed_wwid, WWID_IS_NOT_FAILED); - will_return(__wrap_is_failed_wwid, wwid); -+ /* avoid real is_device_in_use() check */ -+ if (conf.find_multipaths == FIND_MULTIPATHS_GREEDY || -+ conf.find_multipaths == FIND_MULTIPATHS_SMART) -+ will_return(__wrap_udev_device_get_syspath, NULL); - if (stage == STAGE_IS_FAILED) - return; - will_return(__wrap_check_wwids_file, false); -@@ -347,6 +371,30 @@ static void test_check_multipathd(void **state) - assert_int_equal(is_path_valid(name, &conf, &pp, true), - PATH_IS_ERROR); - assert_string_equal(pp.dev, name); -+ -+ /* test pass because connect succeeded. succeed getting udev. Wrong DEVTYPE */ -+ memset(&pp, 0, sizeof(pp)); -+ setup_passing(name, NULL, CHECK_MPATHD_RUNNING, STAGE_CHECK_MULTIPATHD); -+ will_return(__wrap_udev_device_new_from_subsystem_sysname, true); -+ will_return(__wrap_udev_device_new_from_subsystem_sysname, -+ name); -+ expect_string(__wrap_udev_device_get_property_value, property, "DEVTYPE"); -+ will_return(__wrap_udev_device_get_property_value, "partition"); -+ assert_int_equal(is_path_valid(name, &conf, &pp, true), -+ PATH_IS_NOT_VALID); -+ assert_string_equal(pp.dev, name); -+ -+ /* test pass because connect succeeded. succeed getting udev. Bad DEVTYPE */ -+ memset(&pp, 0, sizeof(pp)); -+ setup_passing(name, NULL, CHECK_MPATHD_RUNNING, STAGE_CHECK_MULTIPATHD); -+ will_return(__wrap_udev_device_new_from_subsystem_sysname, true); -+ will_return(__wrap_udev_device_new_from_subsystem_sysname, -+ name); -+ expect_string(__wrap_udev_device_get_property_value, property, "DEVTYPE"); -+ will_return(__wrap_udev_device_get_property_value, NULL); -+ assert_int_equal(is_path_valid(name, &conf, &pp, true), -+ PATH_IS_NOT_VALID); -+ assert_string_equal(pp.dev, name); - } - - static void test_pathinfo(void **state) diff --git a/0023-RH-reset-default-find_mutipaths-value-to-off.patch b/0008-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 100% rename from 0023-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0008-RH-reset-default-find_mutipaths-value-to-off.patch diff --git a/0008-libmpathpersist-use-conf-timeout-for-updating-persis.patch b/0008-libmpathpersist-use-conf-timeout-for-updating-persis.patch deleted file mode 100644 index 9f3dcb2..0000000 --- a/0008-libmpathpersist-use-conf-timeout-for-updating-persis.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 2 Jan 2023 12:39:36 +0100 -Subject: [PATCH] libmpathpersist: use conf->timeout for updating persistent - reservations - -On systems with many LUNs, multipathd may fail to respond within the -default timeout to a "setprkey" command because the vecs lock is held -by the path checker. Honor the globally configured uxsock timeout in -libmpathpersist. - -Reported-by: boposki (github.com/opensvc/multipath-tools/pull/58) -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmpathpersist/mpath_updatepr.c | 11 ++++++++++- - 1 file changed, 10 insertions(+), 1 deletion(-) - -diff --git a/libmpathpersist/mpath_updatepr.c b/libmpathpersist/mpath_updatepr.c -index 4529a82b..36bd777e 100644 ---- a/libmpathpersist/mpath_updatepr.c -+++ b/libmpathpersist/mpath_updatepr.c -@@ -14,6 +14,9 @@ - #include - #include "debug.h" - #include "mpath_cmd.h" -+#include "vector.h" -+#include "globals.h" -+#include "config.h" - #include "uxsock.h" - #include "mpathpr.h" - -@@ -24,6 +27,12 @@ static int do_update_pr(char *alias, char *cmd, char *key) - char str[256]; - char *reply; - int ret = 0; -+ int timeout; -+ struct config *conf; -+ -+ conf = get_multipath_config(); -+ timeout = conf->uxsock_timeout; -+ put_multipath_config(conf); - - fd = mpath_connect(); - if (fd == -1) { -@@ -41,7 +50,7 @@ static int do_update_pr(char *alias, char *cmd, char *key) - mpath_disconnect(fd); - return -1; - } -- ret = recv_packet(fd, &reply, DEFAULT_REPLY_TIMEOUT); -+ ret = recv_packet(fd, &reply, timeout); - if (ret < 0) { - condlog(2, "%s: message=%s recv error=%d", alias, str, errno); - ret = -1; diff --git a/0024-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 100% rename from 0024-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch diff --git a/0009-libmultipath-pathinfo-don-t-fail-for-devices-lacking.patch b/0009-libmultipath-pathinfo-don-t-fail-for-devices-lacking.patch deleted file mode 100644 index fe7f001..0000000 --- a/0009-libmultipath-pathinfo-don-t-fail-for-devices-lacking.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 30 Nov 2022 21:07:45 +0100 -Subject: [PATCH] libmultipath: pathinfo: don't fail for devices lacking - INQUIRY properties -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Some SAS devices (e.g. Seagate factory recertified 'white label' drives) may -come with the Vendor field blank. This causes Multipath to fail to -complete the discovery of those devices. - -Such devices violate the SCSI Spec. From the SPC-6, §6.7.2: -"The T10 VENDOR IDENTIFICATION field contains eight bytes of left-aligned -ASCII data (see 4.3.1) identifying the manufacturer of the logical unit. The -T10 vendor identification shall be one assigned by INCITS.". - -But as we don't identify WWIDs by vendor and product, we don't need to discard -these devices right away. We can go ahead fingers crossed, and hope that the -the other VPD pages for the device are correct. - -We obviously can't look up reasonable device properties for such devices in -our hwtable. It would be up to the user to deal with that. - -Reported by: Allyn Malventano (github.com/opensvc/multipath-tools/issues/56) -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/discovery.c | 22 +++++++++++++--------- - 1 file changed, 13 insertions(+), 9 deletions(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index d9ee2cb9..67ac0e6d 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -1472,6 +1472,7 @@ scsi_sysfs_pathinfo (struct path *pp, const struct _vector *hwtable) - { - struct udev_device *parent; - const char *attr_path = NULL; -+ static const char unknown[] = "UNKNOWN"; - - parent = pp->udev; - while (parent) { -@@ -1492,19 +1493,22 @@ scsi_sysfs_pathinfo (struct path *pp, const struct _vector *hwtable) - if (!attr_path || pp->sg_id.host_no == -1) - return PATHINFO_FAILED; - -- if (sysfs_get_vendor(parent, pp->vendor_id, SCSI_VENDOR_SIZE) <= 0) -- return PATHINFO_FAILED;; -- -+ if (sysfs_get_vendor(parent, pp->vendor_id, SCSI_VENDOR_SIZE) <= 0) { -+ condlog(1, "%s: broken device without vendor ID", pp->dev); -+ strlcpy(pp->vendor_id, unknown, SCSI_VENDOR_SIZE); -+ } - condlog(3, "%s: vendor = %s", pp->dev, pp->vendor_id); - -- if (sysfs_get_model(parent, pp->product_id, PATH_PRODUCT_SIZE) <= 0) -- return PATHINFO_FAILED;; -- -+ if (sysfs_get_model(parent, pp->product_id, PATH_PRODUCT_SIZE) <= 0) { -+ condlog(1, "%s: broken device without product ID", pp->dev); -+ strlcpy(pp->product_id, unknown, PATH_PRODUCT_SIZE); -+ } - condlog(3, "%s: product = %s", pp->dev, pp->product_id); - -- if (sysfs_get_rev(parent, pp->rev, PATH_REV_SIZE) < 0) -- return PATHINFO_FAILED;; -- -+ if (sysfs_get_rev(parent, pp->rev, PATH_REV_SIZE) < 0) { -+ condlog(2, "%s: broken device without revision", pp->dev); -+ strlcpy(pp->rev, unknown, PATH_REV_SIZE); -+ } - condlog(3, "%s: rev = %s", pp->dev, pp->rev); - - /* diff --git a/0025-RH-make-parse_vpd_pg83-match-scsi_id-output.patch b/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch similarity index 97% rename from 0025-RH-make-parse_vpd_pg83-match-scsi_id-output.patch rename to 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch index 824c747..4e0b116 100644 --- a/0025-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +++ b/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch @@ -14,7 +14,7 @@ Signed-off-by: Benjamin Marzinski 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 67ac0e6d..7fdbc1c3 100644 +index 6865cd92..72825829 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c @@ -1177,13 +1177,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, @@ -45,7 +45,7 @@ index 67ac0e6d..7fdbc1c3 100644 case 0x1: /* T-10 Vendor ID: Prio 2 */ diff --git a/tests/vpd.c b/tests/vpd.c -index a7d2092c..2366cfba 100644 +index 1b2d62d6..7309b5c5 100644 --- a/tests/vpd.c +++ b/tests/vpd.c @@ -231,11 +231,13 @@ static const char * const str_prefix[] = { diff --git a/0010-libmultipath-bump-ABI-version-to-18.0.0.patch b/0010-libmultipath-bump-ABI-version-to-18.0.0.patch deleted file mode 100644 index 0d9a3c1..0000000 --- a/0010-libmultipath-bump-ABI-version-to-18.0.0.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 25 Jan 2023 11:35:38 +0100 -Subject: [PATCH] libmultipath: bump ABI version to 18.0.0 - -Commit 6b81153 ("libmultipath: make prflag an enum") changed -the size and member offsets of struct multipath. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/libmultipath.version | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version -index faef2a2d..015623cc 100644 ---- a/libmultipath/libmultipath.version -+++ b/libmultipath/libmultipath.version -@@ -43,7 +43,7 @@ LIBMPATHCOMMON_1.0.0 { - put_multipath_config; - }; - --LIBMULTIPATH_17.0.0 { -+LIBMULTIPATH_18.0.0 { - global: - /* symbols referenced by multipath and multipathd */ - add_foreign; diff --git a/0026-RH-add-scsi-device-handlers-to-modules-load.d.patch b/0011-RH-add-scsi-device-handlers-to-modules-load.d.patch similarity index 100% rename from 0026-RH-add-scsi-device-handlers-to-modules-load.d.patch rename to 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch diff --git a/0011-libmultipath-use-select_reload_action-in-select_acti.patch b/0011-libmultipath-use-select_reload_action-in-select_acti.patch deleted file mode 100644 index 05cc2ce..0000000 --- a/0011-libmultipath-use-select_reload_action-in-select_acti.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 31 Jan 2023 13:34:18 -0600 -Subject: [PATCH] libmultipath: use select_reload_action in select_action - -Since we have a function to set the action to reload, use it. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/configure.c | 8 ++------ - 1 file changed, 2 insertions(+), 6 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index e689f8a7..050b984a 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -729,9 +729,7 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, - - if (force_reload) { - mpp->force_udev_reload = 1; -- mpp->action = ACT_RELOAD; -- condlog(3, "%s: set ACT_RELOAD (forced by user)", -- mpp->alias); -+ select_reload_action(mpp, "forced by user"); - return; - } - if (cmpp->size != mpp->size) { -@@ -744,9 +742,7 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, - - if (!is_udev_ready(cmpp) && count_active_paths(mpp) > 0) { - mpp->force_udev_reload = 1; -- mpp->action = ACT_RELOAD; -- condlog(3, "%s: set ACT_RELOAD (udev incomplete)", -- mpp->alias); -+ select_reload_action(mpp, "udev incomplete"); - return; - } - diff --git a/0027-RH-compile-with-libreadline-support.patch b/0012-RH-compile-with-libreadline-support.patch similarity index 100% rename from 0027-RH-compile-with-libreadline-support.patch rename to 0012-RH-compile-with-libreadline-support.patch diff --git a/0012-libmultipath-select-resize-action-even-if-reload-is-.patch b/0012-libmultipath-select-resize-action-even-if-reload-is-.patch deleted file mode 100644 index 39518c4..0000000 --- a/0012-libmultipath-select-resize-action-even-if-reload-is-.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 31 Jan 2023 13:34:19 -0600 -Subject: [PATCH] libmultipath: select resize action even if reload is forced - -The ACT_RESIZE action is the same as the ACT_RELOAD action, except that -it flushes outstanding IO because the device size is changing and -the new size might be too small for some of the outstanding IO. If we've -detected a size change, and a forced reload is requested, we still need -to flush the IO because the reload will change the device size. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/configure.c | 11 ++++++----- - 1 file changed, 6 insertions(+), 5 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 050b984a..6811e661 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -727,11 +727,6 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, - return; - } - -- if (force_reload) { -- mpp->force_udev_reload = 1; -- select_reload_action(mpp, "forced by user"); -- return; -- } - if (cmpp->size != mpp->size) { - mpp->force_udev_reload = 1; - mpp->action = ACT_RESIZE; -@@ -740,6 +735,12 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, - return; - } - -+ if (force_reload) { -+ mpp->force_udev_reload = 1; -+ select_reload_action(mpp, "forced by user"); -+ return; -+ } -+ - if (!is_udev_ready(cmpp) && count_active_paths(mpp) > 0) { - mpp->force_udev_reload = 1; - select_reload_action(mpp, "udev incomplete"); diff --git a/0013-libmultipath-cleanup-ACT_CREATE-code-in-select_actio.patch b/0013-libmultipath-cleanup-ACT_CREATE-code-in-select_actio.patch deleted file mode 100644 index 3574bac..0000000 --- a/0013-libmultipath-cleanup-ACT_CREATE-code-in-select_actio.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 31 Jan 2023 13:34:20 -0600 -Subject: [PATCH] libmultipath: cleanup ACT_CREATE code in select_action - -Combine the two separate blocks that set ACT_CREATE into one. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/configure.c | 38 +++++++++++++++++--------------------- - 1 file changed, 17 insertions(+), 21 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 6811e661..e870e0f6 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -686,33 +686,29 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, - if (mpp->need_reload || (cmpp && cmpp->need_reload)) - force_reload = 1; - -- if (!cmpp_by_name) { -- if (cmpp) { -- condlog(2, "%s: rename %s to %s", mpp->wwid, -- cmpp->alias, mpp->alias); -- strlcpy(mpp->alias_old, cmpp->alias, WWID_SIZE); -- mpp->action = ACT_RENAME; -- if (force_reload) { -- mpp->force_udev_reload = 1; -- mpp->action = ACT_FORCERENAME; -- } -- return; -+ if (!cmpp) { -+ if (cmpp_by_name) { -+ condlog(1, "%s: can't use alias \"%s\" used by %s, falling back to WWID", -+ mpp->wwid, mpp->alias, cmpp_by_name->wwid); -+ /* We can do this because wwid wasn't found */ -+ free(mpp->alias); -+ mpp->alias = strdup(mpp->wwid); - } - mpp->action = ACT_CREATE; -- condlog(3, "%s: set ACT_CREATE (map does not exist)", -- mpp->alias); -+ condlog(3, "%s: set ACT_CREATE (map does not exist%s)", -+ mpp->alias, cmpp_by_name ? ", name changed" : ""); - return; - } - -- if (!cmpp) { -- condlog(1, "%s: can't use alias \"%s\" used by %s, falling back to WWID", -- mpp->wwid, mpp->alias, cmpp_by_name->wwid); -- /* We can do this because wwid wasn't found */ -- free(mpp->alias); -- mpp->alias = strdup(mpp->wwid); -- mpp->action = ACT_CREATE; -- condlog(3, "%s: set ACT_CREATE (map does not exist, name changed)", -+ if (!cmpp_by_name) { -+ condlog(2, "%s: rename %s to %s", mpp->wwid, cmpp->alias, - mpp->alias); -+ strlcpy(mpp->alias_old, cmpp->alias, WWID_SIZE); -+ mpp->action = ACT_RENAME; -+ if (force_reload) { -+ mpp->force_udev_reload = 1; -+ mpp->action = ACT_FORCERENAME; -+ } - return; - } - diff --git a/0014-libmultipath-keep-renames-from-stopping-other-multip.patch b/0014-libmultipath-keep-renames-from-stopping-other-multip.patch deleted file mode 100644 index f597e61..0000000 --- a/0014-libmultipath-keep-renames-from-stopping-other-multip.patch +++ /dev/null @@ -1,186 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 31 Jan 2023 13:34:21 -0600 -Subject: [PATCH] libmultipath: keep renames from stopping other multipath - actions - -If select_action() is called and a multipath device needs to be renamed, -the code currently checks if force_reload is set, and if so, does the -reload after the rename. But if force_reload isn't set, only the rename -happens, regardless of what other actions are needed. This can happen if -multipathd starts up and a device needs both a reload and a rename. - -Make multipath check for resize, reload, and switch pathgroup along with -rename, and do both if necessary. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/configure.c | 62 +++++++++++++++++----------------------- - libmultipath/configure.h | 4 ++- - 2 files changed, 30 insertions(+), 36 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index e870e0f6..4a1c28bb 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -670,7 +670,8 @@ static bool is_udev_ready(struct multipath *cmpp) - static void - select_reload_action(struct multipath *mpp, const char *reason) - { -- mpp->action = ACT_RELOAD; -+ mpp->action = mpp->action == ACT_RENAME ? ACT_RELOAD_RENAME : -+ ACT_RELOAD; - condlog(3, "%s: set ACT_RELOAD (%s)", mpp->alias, reason); - } - -@@ -681,6 +682,7 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, - struct multipath * cmpp_by_name; - char * mpp_feat, * cmpp_feat; - -+ mpp->action = ACT_NOTHING; - cmpp = find_mp_by_wwid(curmp, mpp->wwid); - cmpp_by_name = find_mp_by_alias(curmp, mpp->alias); - if (mpp->need_reload || (cmpp && cmpp->need_reload)) -@@ -705,14 +707,8 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, - mpp->alias); - strlcpy(mpp->alias_old, cmpp->alias, WWID_SIZE); - mpp->action = ACT_RENAME; -- if (force_reload) { -- mpp->force_udev_reload = 1; -- mpp->action = ACT_FORCERENAME; -- } -- return; -- } -- -- if (cmpp != cmpp_by_name) { -+ /* don't return here. Check for other needed actions */ -+ } else if (cmpp != cmpp_by_name) { - condlog(2, "%s: unable to rename %s to %s (%s is used by %s)", - mpp->wwid, cmpp->alias, mpp->alias, - mpp->alias, cmpp_by_name->wwid); -@@ -720,12 +716,13 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, - free(mpp->alias); - mpp->alias = strdup(cmpp->alias); - mpp->action = ACT_IMPOSSIBLE; -- return; -+ /* don't return here. Check for other needed actions */ - } - - if (cmpp->size != mpp->size) { - mpp->force_udev_reload = 1; -- mpp->action = ACT_RESIZE; -+ mpp->action = mpp->action == ACT_RENAME ? ACT_RESIZE_RENAME : -+ ACT_RESIZE; - condlog(3, "%s: set ACT_RESIZE (size change)", - mpp->alias); - return; -@@ -801,14 +798,14 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, - return; - } - if (cmpp->nextpg != mpp->bestpg) { -- mpp->action = ACT_SWITCHPG; -+ mpp->action = mpp->action == ACT_RENAME ? ACT_SWITCHPG_RENAME : -+ ACT_SWITCHPG; - condlog(3, "%s: set ACT_SWITCHPG (next path group change)", - mpp->alias); - return; - } -- mpp->action = ACT_NOTHING; -- condlog(3, "%s: set ACT_NOTHING (map unchanged)", -- mpp->alias); -+ if (mpp->action == ACT_NOTHING) -+ condlog(3, "%s: set ACT_NOTHING (map unchanged)", mpp->alias); - return; - } - -@@ -909,6 +906,17 @@ int domap(struct multipath *mpp, char *params, int is_daemon) - } - } - -+ if (mpp->action == ACT_RENAME || mpp->action == ACT_SWITCHPG_RENAME || -+ mpp->action == ACT_RELOAD_RENAME || -+ mpp->action == ACT_RESIZE_RENAME) { -+ conf = get_multipath_config(); -+ pthread_cleanup_push(put_multipath_config, conf); -+ r = dm_rename(mpp->alias_old, mpp->alias, -+ conf->partition_delim, mpp->skip_kpartx); -+ pthread_cleanup_pop(1); -+ if (r == DOMAP_FAIL) -+ return r; -+ } - switch (mpp->action) { - case ACT_REJECT: - case ACT_NOTHING: -@@ -916,6 +924,7 @@ int domap(struct multipath *mpp, char *params, int is_daemon) - return DOMAP_EXIST; - - case ACT_SWITCHPG: -+ case ACT_SWITCHPG_RENAME: - dm_switchgroup(mpp->alias, mpp->bestpg); - /* - * we may have avoided reinstating paths because there where in -@@ -942,6 +951,7 @@ int domap(struct multipath *mpp, char *params, int is_daemon) - break; - - case ACT_RELOAD: -+ case ACT_RELOAD_RENAME: - sysfs_set_max_sectors_kb(mpp, 1); - if (mpp->ghost_delay_tick > 0 && pathcount(mpp, PATH_UP)) - mpp->ghost_delay_tick = 0; -@@ -949,6 +959,7 @@ int domap(struct multipath *mpp, char *params, int is_daemon) - break; - - case ACT_RESIZE: -+ case ACT_RESIZE_RENAME: - sysfs_set_max_sectors_kb(mpp, 1); - if (mpp->ghost_delay_tick > 0 && pathcount(mpp, PATH_UP)) - mpp->ghost_delay_tick = 0; -@@ -956,29 +967,10 @@ int domap(struct multipath *mpp, char *params, int is_daemon) - break; - - case ACT_RENAME: -- conf = get_multipath_config(); -- pthread_cleanup_push(put_multipath_config, conf); -- r = dm_rename(mpp->alias_old, mpp->alias, -- conf->partition_delim, mpp->skip_kpartx); -- pthread_cleanup_pop(1); -- break; -- -- case ACT_FORCERENAME: -- conf = get_multipath_config(); -- pthread_cleanup_push(put_multipath_config, conf); -- r = dm_rename(mpp->alias_old, mpp->alias, -- conf->partition_delim, mpp->skip_kpartx); -- pthread_cleanup_pop(1); -- if (r) { -- sysfs_set_max_sectors_kb(mpp, 1); -- if (mpp->ghost_delay_tick > 0 && -- pathcount(mpp, PATH_UP)) -- mpp->ghost_delay_tick = 0; -- r = dm_addmap_reload(mpp, params, 0); -- } - break; - - default: -+ r = DOMAP_FAIL; - break; - } - -diff --git a/libmultipath/configure.h b/libmultipath/configure.h -index 2bf73e65..9d935db3 100644 ---- a/libmultipath/configure.h -+++ b/libmultipath/configure.h -@@ -18,9 +18,11 @@ enum actions { - ACT_RENAME, - ACT_CREATE, - ACT_RESIZE, -- ACT_FORCERENAME, -+ ACT_RELOAD_RENAME, - ACT_DRY_RUN, - ACT_IMPOSSIBLE, -+ ACT_RESIZE_RENAME, -+ ACT_SWITCHPG_RENAME, - }; - - /* diff --git a/0015-libmpathpersist-fix-resource-leak-in-update_map_pr.patch b/0015-libmpathpersist-fix-resource-leak-in-update_map_pr.patch deleted file mode 100644 index 866080f..0000000 --- a/0015-libmpathpersist-fix-resource-leak-in-update_map_pr.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 2 Feb 2023 09:20:35 +0100 -Subject: [PATCH] libmpathpersist: fix resource leak in update_map_pr() - -The "no available paths" case would leak the memory resp points to. -Found by coverity. - -Fixes: 50e2c16 ("multipathd: handle no active paths in update_map_pr") - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmpathpersist/mpath_persist_int.c | 15 ++++++++------- - 1 file changed, 8 insertions(+), 7 deletions(-) - -diff --git a/libmpathpersist/mpath_persist_int.c b/libmpathpersist/mpath_persist_int.c -index 8b52b746..178c2f54 100644 ---- a/libmpathpersist/mpath_persist_int.c -+++ b/libmpathpersist/mpath_persist_int.c -@@ -733,7 +733,7 @@ int update_map_pr(struct multipath *mpp) - int noisy=0; - struct prin_resp *resp; - unsigned int i; -- int ret, isFound; -+ int ret = MPATH_PR_OTHER, isFound; - - if (!get_be64(mpp->reservation_key)) - { -@@ -754,7 +754,7 @@ int update_map_pr(struct multipath *mpp) - { - condlog(0,"%s: No available paths to check pr status", - mpp->alias); -- return MPATH_PR_OTHER; -+ goto out; - } - mpp->prflag = PRFLAG_UNSET; - ret = mpath_prin_activepath(mpp, MPATH_PRIN_RKEY_SA, resp, noisy); -@@ -762,15 +762,15 @@ int update_map_pr(struct multipath *mpp) - if (ret != MPATH_PR_SUCCESS ) - { - condlog(0,"%s : pr in read keys service action failed Error=%d", mpp->alias, ret); -- free(resp); -- return ret; -+ goto out; - } - -+ ret = MPATH_PR_SUCCESS; -+ - if (resp->prin_descriptor.prin_readkeys.additional_length == 0 ) - { - condlog(3,"%s: No key found. Device may not be registered. ", mpp->alias); -- free(resp); -- return MPATH_PR_SUCCESS; -+ goto out; - } - - condlog(2, "%s: Multipath reservation_key: 0x%" PRIx64 " ", mpp->alias, -@@ -795,6 +795,7 @@ int update_map_pr(struct multipath *mpp) - condlog(2, "%s: prflag flag set.", mpp->alias ); - } - -+out: - free(resp); -- return MPATH_PR_SUCCESS; -+ return ret; - } diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index a6fe03c..ca8b8aa 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,42 +1,27 @@ Name: device-mapper-multipath -Version: 0.9.4 -Release: 2%{?dist} +Version: 0.9.5 +Release: 1%{?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 -L https://github.com/opensvc/multipath-tools/archive/0.9.4.tar.gz -o multipath-tools-0.9.4.tgz -Source0: multipath-tools-0.9.4.tgz +# curl -L https://github.com/opensvc/multipath-tools/archive/0.9.5.tar.gz -o multipath-tools-0.9.5.tgz +Source0: multipath-tools-0.9.5.tgz Source1: multipath.conf -Patch0001: 0001-multipathd-make-pr-registration-consistent.patch -Patch0002: 0002-libmultipath-make-prflag-an-enum.patch -Patch0003: 0003-multipathd-handle-no-active-paths-in-update_map_pr.patch -Patch0004: 0004-multipathd-add-missing-newline-to-cli_del_map-reply.patch -Patch0005: 0005-libmultipath-skip-extra-vector-work-in-remove_maps.patch -Patch0006: 0006-libmultipath-orphan-paths-if-coalesce_paths-frees-ne.patch -Patch0007: 0007-libmultipath-is_path_valid-check-if-device-is-in-use.patch -Patch0008: 0008-libmpathpersist-use-conf-timeout-for-updating-persis.patch -Patch0009: 0009-libmultipath-pathinfo-don-t-fail-for-devices-lacking.patch -Patch0010: 0010-libmultipath-bump-ABI-version-to-18.0.0.patch -Patch0011: 0011-libmultipath-use-select_reload_action-in-select_acti.patch -Patch0012: 0012-libmultipath-select-resize-action-even-if-reload-is-.patch -Patch0013: 0013-libmultipath-cleanup-ACT_CREATE-code-in-select_actio.patch -Patch0014: 0014-libmultipath-keep-renames-from-stopping-other-multip.patch -Patch0015: 0015-libmpathpersist-fix-resource-leak-in-update_map_pr.patch -Patch0016: 0016-RH-fixup-udev-rules-for-redhat.patch -Patch0017: 0017-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0018: 0018-RH-don-t-start-without-a-config-file.patch -Patch0019: 0019-RH-Fix-nvme-function-missing-argument.patch -Patch0020: 0020-RH-use-rpm-optflags-if-present.patch -Patch0021: 0021-RH-add-mpathconf.patch -Patch0022: 0022-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0023: 0023-RH-reset-default-find_mutipaths-value-to-off.patch -Patch0024: 0024-RH-attempt-to-get-ANA-info-via-sysfs-first.patch -Patch0025: 0025-RH-make-parse_vpd_pg83-match-scsi_id-output.patch -Patch0026: 0026-RH-add-scsi-device-handlers-to-modules-load.d.patch -Patch0027: 0027-RH-compile-with-libreadline-support.patch +Patch0001: 0001-RH-fixup-udev-rules-for-redhat.patch +Patch0002: 0002-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0003: 0003-RH-don-t-start-without-a-config-file.patch +Patch0004: 0004-RH-Fix-nvme-function-missing-argument.patch +Patch0005: 0005-RH-use-rpm-optflags-if-present.patch +Patch0006: 0006-RH-add-mpathconf.patch +Patch0007: 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0008: 0008-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0009: 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0010: 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +Patch0011: 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch +Patch0012: 0012-RH-compile-with-libreadline-support.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -123,7 +108,7 @@ This package contains the files needed to develop applications that use device-mapper-multipath's libdmmp C API library %prep -%autosetup -n multipath-tools-0.9.4 -p1 +%autosetup -n multipath-tools-0.9.5 -p1 cp %{SOURCE1} . %build @@ -245,6 +230,12 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Tue May 16 2023 Benjamin Marzinski - 0.9.5-1 +- Update to the latest upstream release + * Previous patches 0001-0015 are included in the source tarball +- Rename redhat patches + * Previous patches 0016-0027 are now patches 0001-0012 + * Thu Feb 2 2023 Benjamin Marzinski - 0.9.4-2 - Update to the head of the upstream staging branch * Patches 0011-0015 are from the upstream staging branch diff --git a/sources b/sources index 462cab6..ece6ffe 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (multipath-tools-0.9.4.tgz) = 5e0dcea610fc215e345444c04453a38f39c73e493c2bc53f6b3a90cd701266aabdf7c4693dfc321099af836d0019bf27355e265ad5db5deff48f8bb94ed4719d +SHA512 (multipath-tools-0.9.5.tgz) = 39c2e5d45542c6076eb3b17b9994629b4c1f74347aa43e0119001fa2d07d3a606fd5e617962906a11b313afb37a115bd8eec2ef24447e980e61b5900625f9146 SHA512 (multipath.conf) = 71953dce5a68adcf60a942305f5a66023e6f4c4baf53b1bfdb4edf65ed5b8e03db804363c36d1dcfd85591f4766f52b515269904c53b84d7b076da0b80b09942 From d88fe4b9560ffa9bd363b3e344f82e0705cbd169 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 19 Jul 2023 17:19:23 +0000 Subject: [PATCH 40/67] Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- device-mapper-multipath.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index ca8b8aa..268e4b9 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.9.5 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -230,6 +230,9 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Wed Jul 19 2023 Fedora Release Engineering - 0.9.5-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild + * Tue May 16 2023 Benjamin Marzinski - 0.9.5-1 - Update to the latest upstream release * Previous patches 0001-0015 are included in the source tarball From e5eddaae1a3d86387da90d35f7c9fddac02d03a4 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Fri, 22 Sep 2023 15:29:43 -0500 Subject: [PATCH 41/67] device-mapper-multipath-0.9.6-1 Update to the head of the upstream staging branch Rename redhat patches * Previous patches 0001-0012 are now patches 0041-0052 Add 0053-RH-Add-mpathcleanup.patch * add mpathcleanup program --- .gitignore | 1 + ...fs_set_scsi_tmo-do-nothing-for-ACT_D.patch | 51 + ...libmultipath-add-alias_already_taken.patch | 75 + ...fy-use_existing_alias-and-get_user_f.patch | 207 ++ ...er-allocate-an-alias-that-s-already-.patch | 101 + ...kup_binding-add-comment-about-the-al.patch | 61 + ...test-simplify-debugging-for-condlog-.patch | 35 + ...tests-add-tests-for-get_user_friendl.patch | 493 +++++ ...test-consistent-use-of-macros-in-ali.patch | 365 ++++ ...tests-convert-mock_-failed-used-_ali.patch | 246 +++ ...test-use-mock_bindings_file-consiste.patch | 500 +++++ ...-global-variable-for-current-binding.patch | 109 ++ ...ame-fix_bindings_file-to-update_bind.patch | 40 + ...lias.c-move-bindings-related-code-up.patch | 285 +++ ...ate_bindings_file-take-filename-argu.patch | 61 + ...ate_bindings_file-use-a-single-write.patch | 59 + ...ate_bindings_file-don-t-log-temp-fil.patch | 29 + ...path-alias.c-factor-out-read_binding.patch | 94 + ...libmultipath-keep-bindings-in-memory.patch | 545 ++++++ ...ultipath-tools-tests-fix-alias-tests.patch | 1698 +++++++++++++++++ ...get_uuid-return-emtpy-UUID-for-non-e.patch | 53 + ...dapt-to-new-semantics-of-dm_get_uuid.patch | 158 ++ ...th-sort-aliases-by-length-and-strcmp.patch | 98 + ...tests-fix-alias-test-after-sort-orde.patch | 90 + ...plify-get_free_id-assuming-total-ord.patch | 122 ++ ...tests-adapt-alias-tests-for-total-or.patch | 203 ++ ...tests-add-test-for-ordering-of-bindi.patch | 275 +++ ...-bindings-file-with-inotify-timestam.patch | 597 ++++++ ...tests-mock-pthread_mutex_-lock-unloc.patch | 102 + ...Makefile-sanitize-paths-for-configur.patch | 73 + ...add-compile-time-configuration-for-e.patch | 58 + ...man-pages-generate-with-correct-path.patch | 366 ++++ ...-Makefile-fix-bug-in-install-section.patch | 25 + ...README.md-improve-documentation-for-.patch | 75 + ...nt-built-in-values-for-deprecated-op.patch | 55 + 0035-multipath-add-a-missing-newline.patch | 25 + ...allow-prefixes-with-and-w-o-trailing.patch | 66 + ...recate-bindings_file-wwids_file-prke.patch | 897 +++++++++ ...id-Warray-bounds-error-in-uatomic-op.patch | 158 ++ 0039-multipath-tools-fix-spelling.patch | 52 + ...-support-to-handle-FPIN-Li-events-fo.patch | 300 +++ ... 0041-RH-fixup-udev-rules-for-redhat.patch | 14 +- ...property-blacklist-exception-builtin.patch | 41 +- ...RH-don-t-start-without-a-config-file.patch | 50 +- ...H-Fix-nvme-function-missing-argument.patch | 0 ... 0045-RH-use-rpm-optflags-if-present.patch | 14 +- ...hconf.patch => 0046-RH-add-mpathconf.patch | 14 +- ...om-kernel-cmdline-mpath.wwids-with-A.patch | 26 +- ...-default-find_mutipaths-value-to-off.patch | 2 +- ...empt-to-get-ANA-info-via-sysfs-first.patch | 4 +- ...-parse_vpd_pg83-match-scsi_id-output.patch | 2 +- ...si-device-handlers-to-modules-load.d.patch | 2 +- ...-RH-compile-with-libreadline-support.patch | 2 +- 0053-RH-Add-mpathcleanup.patch | 186 ++ device-mapper-multipath.spec | 83 +- sources | 2 +- 56 files changed, 9256 insertions(+), 89 deletions(-) create mode 100644 0001-libmultipath-sysfs_set_scsi_tmo-do-nothing-for-ACT_D.patch create mode 100644 0002-libmultipath-add-alias_already_taken.patch create mode 100644 0003-libmultipath-unify-use_existing_alias-and-get_user_f.patch create mode 100644 0004-libmultipath-never-allocate-an-alias-that-s-already-.patch create mode 100644 0005-libmultipath-lookup_binding-add-comment-about-the-al.patch create mode 100644 0006-multipath-tools-test-simplify-debugging-for-condlog-.patch create mode 100644 0007-multipath-tools-tests-add-tests-for-get_user_friendl.patch create mode 100644 0008-multipath-tools-test-consistent-use-of-macros-in-ali.patch create mode 100644 0009-multipath-tools-tests-convert-mock_-failed-used-_ali.patch create mode 100644 0010-multipath-tools-test-use-mock_bindings_file-consiste.patch create mode 100644 0011-libmultipath-add-global-variable-for-current-binding.patch create mode 100644 0012-libmultipath-rename-fix_bindings_file-to-update_bind.patch create mode 100644 0013-libmultipath-alias.c-move-bindings-related-code-up.patch create mode 100644 0014-libmultipath-update_bindings_file-take-filename-argu.patch create mode 100644 0015-libmultipath-update_bindings_file-use-a-single-write.patch create mode 100644 0016-libmultipath-update_bindings_file-don-t-log-temp-fil.patch create mode 100644 0017-libmultipath-alias.c-factor-out-read_binding.patch create mode 100644 0018-libmultipath-keep-bindings-in-memory.patch create mode 100644 0019-multipath-tools-tests-fix-alias-tests.patch create mode 100644 0020-libmultipath-dm_get_uuid-return-emtpy-UUID-for-non-e.patch create mode 100644 0021-libmultipath-adapt-to-new-semantics-of-dm_get_uuid.patch create mode 100644 0022-libmultipath-sort-aliases-by-length-and-strcmp.patch create mode 100644 0023-multipath-tools-tests-fix-alias-test-after-sort-orde.patch create mode 100644 0024-libmultipath-simplify-get_free_id-assuming-total-ord.patch create mode 100644 0025-multipath-tools-tests-adapt-alias-tests-for-total-or.patch create mode 100644 0026-multipath-tools-tests-add-test-for-ordering-of-bindi.patch create mode 100644 0027-multipathd-watch-bindings-file-with-inotify-timestam.patch create mode 100644 0028-multipath-tools-tests-mock-pthread_mutex_-lock-unloc.patch create mode 100644 0029-multipath-tools-Makefile-sanitize-paths-for-configur.patch create mode 100644 0030-multipath-tools-add-compile-time-configuration-for-e.patch create mode 100644 0031-multipath-tools-man-pages-generate-with-correct-path.patch create mode 100644 0032-libdmmp-Makefile-fix-bug-in-install-section.patch create mode 100644 0033-multipath-tools-README.md-improve-documentation-for-.patch create mode 100644 0034-libmultipath-print-built-in-values-for-deprecated-op.patch create mode 100644 0035-multipath-add-a-missing-newline.patch create mode 100644 0036-multipath-tools-allow-prefixes-with-and-w-o-trailing.patch create mode 100644 0037-libmultipath-deprecate-bindings_file-wwids_file-prke.patch create mode 100644 0038-libmultipath-avoid-Warray-bounds-error-in-uatomic-op.patch create mode 100644 0039-multipath-tools-fix-spelling.patch create mode 100644 0040-multipathd-Added-support-to-handle-FPIN-Li-events-fo.patch rename 0001-RH-fixup-udev-rules-for-redhat.patch => 0041-RH-fixup-udev-rules-for-redhat.patch (89%) rename 0002-RH-Remove-the-property-blacklist-exception-builtin.patch => 0042-RH-Remove-the-property-blacklist-exception-builtin.patch (79%) rename 0003-RH-don-t-start-without-a-config-file.patch => 0043-RH-don-t-start-without-a-config-file.patch (71%) rename 0004-RH-Fix-nvme-function-missing-argument.patch => 0044-RH-Fix-nvme-function-missing-argument.patch (100%) rename 0005-RH-use-rpm-optflags-if-present.patch => 0045-RH-use-rpm-optflags-if-present.patch (83%) rename 0006-RH-add-mpathconf.patch => 0046-RH-add-mpathconf.patch (98%) rename 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch => 0047-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch (87%) rename 0008-RH-reset-default-find_mutipaths-value-to-off.patch => 0048-RH-reset-default-find_mutipaths-value-to-off.patch (96%) rename 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch => 0049-RH-attempt-to-get-ANA-info-via-sysfs-first.patch (95%) rename 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch => 0050-RH-make-parse_vpd_pg83-match-scsi_id-output.patch (98%) rename 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch => 0051-RH-add-scsi-device-handlers-to-modules-load.d.patch (96%) rename 0012-RH-compile-with-libreadline-support.patch => 0052-RH-compile-with-libreadline-support.patch (96%) create mode 100644 0053-RH-Add-mpathcleanup.patch diff --git a/.gitignore b/.gitignore index 18226b9..75c4abc 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,4 @@ multipath-tools-091027.tar.gz /multipath-tools-0.9.3.tgz /multipath-tools-0.9.4.tgz /multipath-tools-0.9.5.tgz +/multipath-tools-0.9.6.tgz diff --git a/0001-libmultipath-sysfs_set_scsi_tmo-do-nothing-for-ACT_D.patch b/0001-libmultipath-sysfs_set_scsi_tmo-do-nothing-for-ACT_D.patch new file mode 100644 index 0000000..9b8a486 --- /dev/null +++ b/0001-libmultipath-sysfs_set_scsi_tmo-do-nothing-for-ACT_D.patch @@ -0,0 +1,51 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 22 Aug 2023 16:21:43 +0200 +Subject: [PATCH] libmultipath: sysfs_set_scsi_tmo: do nothing for ACT_DRY_RUN + +"multipath -d" might change sysfs timeouts of SCSI devices. +Make sure it doesn't. + +Signed-off-by: Martin Wilck +Cc: Jehan Singh +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/configure.c | 4 ++-- + libmultipath/discovery.c | 3 +++ + 2 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index 9513baae..029fbbd2 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -1193,13 +1193,13 @@ int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid, + + if (cmpp) + mpp->queue_mode = cmpp->queue_mode; ++ if (cmd == CMD_DRY_RUN && mpp->action == ACT_UNDEF) ++ mpp->action = ACT_DRY_RUN; + if (setup_map(mpp, ¶ms, vecs)) { + remove_map(mpp, vecs->pathvec, NULL); + continue; + } + +- if (cmd == CMD_DRY_RUN) +- mpp->action = ACT_DRY_RUN; + if (mpp->action == ACT_UNDEF) + select_action(mpp, curmp, + force_reload == FORCE_RELOAD_YES ? 1 : 0); +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index e4de48e7..84ce5fe7 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -857,6 +857,9 @@ sysfs_set_scsi_tmo (struct config *conf, struct multipath *mpp) + bool warn_dev_loss = false; + bool warn_fast_io_fail = false; + ++ if (mpp->action == ACT_DRY_RUN || mpp->action == ACT_REJECT) ++ return 0; ++ + if (mpp->no_path_retry > 0) { + uint64_t no_path_retry_tmo = + (uint64_t)mpp->no_path_retry * conf->checkint; diff --git a/0002-libmultipath-add-alias_already_taken.patch b/0002-libmultipath-add-alias_already_taken.patch new file mode 100644 index 0000000..8ed3c7b --- /dev/null +++ b/0002-libmultipath-add-alias_already_taken.patch @@ -0,0 +1,75 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 22 Aug 2023 21:36:11 +0200 +Subject: [PATCH] libmultipath: add alias_already_taken() + +Factor out a trivial helper function. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/alias.c | 32 +++++++++++++++++++------------- + 1 file changed, 19 insertions(+), 13 deletions(-) + +diff --git a/libmultipath/alias.c b/libmultipath/alias.c +index c0139a2e..83ded886 100644 +--- a/libmultipath/alias.c ++++ b/libmultipath/alias.c +@@ -8,6 +8,7 @@ + #include + #include + #include ++#include + + #include "debug.h" + #include "util.h" +@@ -109,30 +110,35 @@ scan_devname(const char *alias, const char *prefix) + return n; + } + +-static int +-id_already_taken(int id, const char *prefix, const char *map_wwid) ++static bool alias_already_taken(const char *alias, const char *map_wwid) + { +- STRBUF_ON_STACK(buf); +- const char *alias; +- +- if (append_strbuf_str(&buf, prefix) < 0 || +- format_devname(&buf, id) < 0) +- return 0; + +- alias = get_strbuf_str(&buf); + if (dm_map_present(alias)) { + char wwid[WWID_SIZE]; + + /* If both the name and the wwid match, then it's fine.*/ + if (dm_get_uuid(alias, wwid, sizeof(wwid)) == 0 && + strncmp(map_wwid, wwid, sizeof(wwid)) == 0) +- return 0; +- condlog(3, "%s: alias '%s' already taken, but not in bindings file. reselecting alias", map_wwid, alias); +- return 1; ++ return false; ++ condlog(3, "%s: alias '%s' already taken, but not in bindings file. reselecting alias", ++ map_wwid, alias); ++ return true; + } +- return 0; ++ return false; + } + ++static bool id_already_taken(int id, const char *prefix, const char *map_wwid) ++{ ++ STRBUF_ON_STACK(buf); ++ const char *alias; ++ ++ if (append_strbuf_str(&buf, prefix) < 0 || ++ format_devname(&buf, id) < 0) ++ return false; ++ ++ alias = get_strbuf_str(&buf); ++ return alias_already_taken(alias, map_wwid); ++} + + /* + * Returns: 0 if matching entry in WWIDs file found diff --git a/0003-libmultipath-unify-use_existing_alias-and-get_user_f.patch b/0003-libmultipath-unify-use_existing_alias-and-get_user_f.patch new file mode 100644 index 0000000..5beb1fe --- /dev/null +++ b/0003-libmultipath-unify-use_existing_alias-and-get_user_f.patch @@ -0,0 +1,207 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 22 Aug 2023 22:00:58 +0200 +Subject: [PATCH] libmultipath: unify use_existing_alias() and + get_user_friendly_alias() + +These functions are only called from select_alias(). The logic +is more obvious when unified in a single function. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/alias.c | 82 ++++++++++++------------------------------ + libmultipath/alias.h | 9 ++--- + libmultipath/propsel.c | 19 +++++----- + 3 files changed, 34 insertions(+), 76 deletions(-) + +diff --git a/libmultipath/alias.c b/libmultipath/alias.c +index 83ded886..68f5d848 100644 +--- a/libmultipath/alias.c ++++ b/libmultipath/alias.c +@@ -329,13 +329,13 @@ allocate_binding(int fd, const char *wwid, int id, const char *prefix) + return alias; + } + +-char * +-use_existing_alias (const char *wwid, const char *file, const char *alias_old, +- const char *prefix, int bindings_read_only) ++char *get_user_friendly_alias(const char *wwid, const char *file, const char *alias_old, ++ const char *prefix, bool bindings_read_only) + { + char *alias = NULL; + int id = 0; + int fd, can_write; ++ bool new_binding = false; + char buff[WWID_SIZE]; + FILE *f; + +@@ -349,6 +349,10 @@ use_existing_alias (const char *wwid, const char *file, const char *alias_old, + close(fd); + return NULL; + } ++ ++ if (!strlen(alias_old)) ++ goto new_alias; ++ + /* lookup the binding. if it exists, the wwid will be in buff + * either way, id contains the id for the alias + */ +@@ -358,14 +362,14 @@ use_existing_alias (const char *wwid, const char *file, const char *alias_old, + /* if buff is our wwid, it's already + * allocated correctly + */ +- if (strcmp(buff, wwid) == 0) ++ if (strcmp(buff, wwid) == 0) { + alias = strdup(alias_old); +- else { +- alias = NULL; ++ goto out; ++ } else { + condlog(0, "alias %s already bound to wwid %s, cannot reuse", + alias_old, buff); ++ goto new_alias; + } +- goto out; + } + + id = lookup_binding(f, wwid, &alias, NULL, 0); +@@ -377,8 +381,15 @@ use_existing_alias (const char *wwid, const char *file, const char *alias_old, + + /* allocate the existing alias in the bindings file */ + id = scan_devname(alias_old, prefix); +- if (id <= 0) +- goto out; ++ ++new_alias: ++ if (id <= 0) { ++ id = lookup_binding(f, wwid, &alias, prefix, 1); ++ if (id <= 0) ++ goto out; ++ else ++ new_binding = true; ++ } + + if (fflush(f) != 0) { + condlog(0, "cannot fflush bindings file stream : %s", +@@ -388,8 +399,9 @@ use_existing_alias (const char *wwid, const char *file, const char *alias_old, + + if (can_write && !bindings_read_only) { + alias = allocate_binding(fd, wwid, id, prefix); +- condlog(0, "Allocated existing binding [%s] for WWID [%s]", +- alias, wwid); ++ if (alias && !new_binding) ++ condlog(2, "Allocated existing binding [%s] for WWID [%s]", ++ alias, wwid); + } + + out: +@@ -399,54 +411,6 @@ out: + return alias; + } + +-char * +-get_user_friendly_alias(const char *wwid, const char *file, const char *prefix, +- int bindings_read_only) +-{ +- char *alias; +- int fd, id; +- FILE *f; +- int can_write; +- +- if (!wwid || *wwid == '\0') { +- condlog(3, "Cannot find binding for empty WWID"); +- return NULL; +- } +- +- fd = open_file(file, &can_write, bindings_file_header); +- if (fd < 0) +- return NULL; +- +- f = fdopen(fd, "r"); +- if (!f) { +- condlog(0, "cannot fdopen on bindings file descriptor : %s", +- strerror(errno)); +- close(fd); +- return NULL; +- } +- +- id = lookup_binding(f, wwid, &alias, prefix, 1); +- if (id < 0) { +- fclose(f); +- return NULL; +- } +- +- pthread_cleanup_push(free, alias); +- +- if (fflush(f) != 0) { +- condlog(0, "cannot fflush bindings file stream : %s", +- strerror(errno)); +- free(alias); +- alias = NULL; +- } else if (can_write && !bindings_read_only && !alias) +- alias = allocate_binding(fd, wwid, id, prefix); +- +- fclose(f); +- +- pthread_cleanup_pop(0); +- return alias; +-} +- + int + get_user_friendly_wwid(const char *alias, char *buff, const char *file) + { +diff --git a/libmultipath/alias.h b/libmultipath/alias.h +index dbc950c4..fa332233 100644 +--- a/libmultipath/alias.h ++++ b/libmultipath/alias.h +@@ -2,13 +2,10 @@ + #define _ALIAS_H + + int valid_alias(const char *alias); +-char *get_user_friendly_alias(const char *wwid, const char *file, +- const char *prefix, +- int bindings_readonly); + int get_user_friendly_wwid(const char *alias, char *buff, const char *file); +-char *use_existing_alias (const char *wwid, const char *file, +- const char *alias_old, +- const char *prefix, int bindings_read_only); ++char *get_user_friendly_alias(const char *wwid, const char *file, ++ const char *alias_old, ++ const char *prefix, bool bindings_read_only); + + struct config; + int check_alias_settings(const struct config *); +diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c +index d6bce129..354e883f 100644 +--- a/libmultipath/propsel.c ++++ b/libmultipath/propsel.c +@@ -401,19 +401,16 @@ int select_alias(struct config *conf, struct multipath * mp) + + select_alias_prefix(conf, mp); + +- if (strlen(mp->alias_old) > 0) { +- mp->alias = use_existing_alias(mp->wwid, conf->bindings_file, +- mp->alias_old, mp->alias_prefix, +- conf->bindings_read_only); +- memset (mp->alias_old, 0, WWID_SIZE); +- origin = "(setting: using existing alias)"; +- } ++ mp->alias = get_user_friendly_alias(mp->wwid, conf->bindings_file, ++ mp->alias_old, mp->alias_prefix, ++ conf->bindings_read_only); + +- if (mp->alias == NULL) { +- mp->alias = get_user_friendly_alias(mp->wwid, +- conf->bindings_file, mp->alias_prefix, conf->bindings_read_only); ++ if (mp->alias && !strncmp(mp->alias, mp->alias_old, WWID_SIZE)) ++ origin = "(setting: using existing alias)"; ++ else if (mp->alias) + origin = "(setting: user_friendly_name)"; +- } ++ memset (mp->alias_old, 0, WWID_SIZE); ++ + out: + if (mp->alias == NULL) { + mp->alias = strdup(mp->wwid); diff --git a/0004-libmultipath-never-allocate-an-alias-that-s-already-.patch b/0004-libmultipath-never-allocate-an-alias-that-s-already-.patch new file mode 100644 index 0000000..3d05b85 --- /dev/null +++ b/0004-libmultipath-never-allocate-an-alias-that-s-already-.patch @@ -0,0 +1,101 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 22 Aug 2023 22:23:29 +0200 +Subject: [PATCH] libmultipath: never allocate an alias that's already taken + +If the bindings file is changed in a way that multipathd can't handle +(e.g. by swapping the aliases of two maps), multipathd must not try +to re-use an alias that is already used by another map. Creating +or renaming a map with such an alias will fail. We already avoid +this for some cases, but not for all. Fix it. + +Signed-off-by: Martin Wilck +Cc: David Bond +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/alias.c | 31 +++++++++++++++++++++++-------- + tests/alias.c | 2 +- + 2 files changed, 24 insertions(+), 9 deletions(-) + +diff --git a/libmultipath/alias.c b/libmultipath/alias.c +index 68f5d848..3e3dfe98 100644 +--- a/libmultipath/alias.c ++++ b/libmultipath/alias.c +@@ -120,7 +120,7 @@ static bool alias_already_taken(const char *alias, const char *map_wwid) + if (dm_get_uuid(alias, wwid, sizeof(wwid)) == 0 && + strncmp(map_wwid, wwid, sizeof(wwid)) == 0) + return false; +- condlog(3, "%s: alias '%s' already taken, but not in bindings file. reselecting alias", ++ condlog(3, "%s: alias '%s' already taken, reselecting alias", + map_wwid, alias); + return true; + } +@@ -359,12 +359,11 @@ char *get_user_friendly_alias(const char *wwid, const char *file, const char *al + rlookup_binding(f, buff, alias_old); + + if (strlen(buff) > 0) { +- /* if buff is our wwid, it's already +- * allocated correctly +- */ ++ /* If buff is our wwid, it's already allocated correctly. */ + if (strcmp(buff, wwid) == 0) { + alias = strdup(alias_old); + goto out; ++ + } else { + condlog(0, "alias %s already bound to wwid %s, cannot reuse", + alias_old, buff); +@@ -372,19 +371,35 @@ char *get_user_friendly_alias(const char *wwid, const char *file, const char *al + } + } + +- id = lookup_binding(f, wwid, &alias, NULL, 0); ++ /* ++ * Look for an existing alias in the bindings file. ++ * Pass prefix = NULL, so lookup_binding() won't try to allocate a new id. ++ */ ++ lookup_binding(f, wwid, &alias, NULL, 0); + if (alias) { +- condlog(3, "Use existing binding [%s] for WWID [%s]", +- alias, wwid); ++ if (alias_already_taken(alias, wwid)) { ++ free(alias); ++ alias = NULL; ++ } else ++ condlog(3, "Use existing binding [%s] for WWID [%s]", ++ alias, wwid); + goto out; + } + +- /* allocate the existing alias in the bindings file */ ++ /* alias_old is already taken by our WWID, update bindings file. */ + id = scan_devname(alias_old, prefix); + + new_alias: + if (id <= 0) { ++ /* ++ * no existing alias was provided, or allocating it ++ * failed. Try a new one. ++ */ + id = lookup_binding(f, wwid, &alias, prefix, 1); ++ if (id == 0 && alias_already_taken(alias, wwid)) { ++ free(alias); ++ alias = NULL; ++ } + if (id <= 0) + goto out; + else +diff --git a/tests/alias.c b/tests/alias.c +index 3ca6c28b..11f209e0 100644 +--- a/tests/alias.c ++++ b/tests/alias.c +@@ -398,7 +398,7 @@ static void mock_self_alias(const char *alias, const char *wwid) + will_return(__wrap_dm_get_uuid, wwid); + } + +-#define USED_STR(alias_str, wwid_str) wwid_str ": alias '" alias_str "' already taken, but not in bindings file. reselecting alias\n" ++#define USED_STR(alias_str, wwid_str) wwid_str ": alias '" alias_str "' already taken, reselecting alias\n" + + static void mock_failed_alias(const char *alias, char *msg) + { diff --git a/0005-libmultipath-lookup_binding-add-comment-about-the-al.patch b/0005-libmultipath-lookup_binding-add-comment-about-the-al.patch new file mode 100644 index 0000000..71d077a --- /dev/null +++ b/0005-libmultipath-lookup_binding-add-comment-about-the-al.patch @@ -0,0 +1,61 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 22 Aug 2023 22:30:16 +0200 +Subject: [PATCH] libmultipath: lookup_binding: add comment about the algorithm + +When I read this code, I always get confused. Adding comments to +explain the algorithm. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/alias.c | 35 +++++++++++++++++++++++++++++++++++ + 1 file changed, 35 insertions(+) + +diff --git a/libmultipath/alias.c b/libmultipath/alias.c +index 3e3dfe98..9e9ac563 100644 +--- a/libmultipath/alias.c ++++ b/libmultipath/alias.c +@@ -172,6 +172,41 @@ lookup_binding(FILE *f, const char *map_wwid, char **map_alias, + alias = strtok_r(buf, " \t", &saveptr); + if (!alias) /* blank line */ + continue; ++ ++ /* ++ * Find an unused index - explanation of the algorithm ++ * ++ * ID: 1 = mpatha, 2 = mpathb, ... ++ * ++ * We assume the bindings are unsorted. The only constraint ++ * is that no ID occurs more than once. IDs that occur in the ++ * bindings are called "used". ++ * ++ * We call the list 1,2,3,..., exactly in this order, the list ++ * of "expected" IDs. The variable "id" always holds the next ++ * "expected" ID, IOW the last "expected" ID encountered plus 1. ++ * Thus all IDs below "id" are known to be used. However, at the ++ * end of the loop, the value of "id" isn't necessarily unused. ++ * ++ * "smallest_bigger_id" is the smallest used ID that was ++ * encountered while it was larger than the next "expected" ID ++ * at that iteration. Let X be some used ID. If all IDs below X ++ * are used and encountered in the right sequence before X, "id" ++ * will be > X when the loop ends. Otherwise, X was encountered ++ * "out of order", the condition (X > id) holds when X is ++ * encountered, and "smallest_bigger_id" will be set to X; i.e. ++ * it will be less or equal than X when the loop ends. ++ * ++ * At the end of the loop, (id < smallest_bigger_id) means that ++ * the value of "id" had been encountered neither in order nor ++ * out of order, and is thus unused. (id >= smallest_bigger_id) ++ * means that "id"'s value is in use. In this case, we play safe ++ * and use "biggest_id + 1" as the next value to try. ++ * ++ * biggest_id is always > smallest_bigger_id, except in the ++ * "perfectly ordered" case. ++ */ ++ + curr_id = scan_devname(alias, prefix); + if (curr_id == id) { + if (id < INT_MAX) diff --git a/0006-multipath-tools-test-simplify-debugging-for-condlog-.patch b/0006-multipath-tools-test-simplify-debugging-for-condlog-.patch new file mode 100644 index 0000000..a206358 --- /dev/null +++ b/0006-multipath-tools-test-simplify-debugging-for-condlog-.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 23 Aug 2023 22:56:41 +0200 +Subject: [PATCH] multipath-tools test: simplify debugging for condlog mismatch + +If there's a mismatch between expected and actual log message, +print both messages. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + tests/test-log.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/tests/test-log.c b/tests/test-log.c +index c1745872..63516999 100644 +--- a/tests/test-log.c ++++ b/tests/test-log.c +@@ -16,12 +16,14 @@ void __wrap_dlog (int prio, const char * fmt, ...) + va_list ap; + char *expected; + +- check_expected(prio); + va_start(ap, fmt); + vsnprintf(buff, MAX_MSG_SIZE, fmt, ap); + va_end(ap); + fprintf(stderr, "%s(%d): %s", __func__, prio, buff); + expected = mock_ptr_type(char *); ++ if (memcmp(expected, buff, strlen(expected))) ++ fprintf(stderr, "%s(expected): %s", __func__, expected); ++ check_expected(prio); + assert_memory_equal(buff, expected, strlen(expected)); + } + diff --git a/0007-multipath-tools-tests-add-tests-for-get_user_friendl.patch b/0007-multipath-tools-tests-add-tests-for-get_user_friendl.patch new file mode 100644 index 0000000..f829db4 --- /dev/null +++ b/0007-multipath-tools-tests-add-tests-for-get_user_friendl.patch @@ -0,0 +1,493 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 23 Aug 2023 22:57:29 +0200 +Subject: [PATCH] multipath-tools tests: add tests for + get_user_friendly_alias() + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + tests/alias.c | 441 ++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 441 insertions(+) + +diff --git a/tests/alias.c b/tests/alias.c +index 11f209e0..7e443b06 100644 +--- a/tests/alias.c ++++ b/tests/alias.c +@@ -81,6 +81,35 @@ int __wrap_dm_get_uuid(const char *name, char *uuid, int uuid_len) + return ret; + } + ++#define TEST_FDNO 1234 ++#define TEST_FPTR ((FILE *) 0xaffe) ++ ++int __wrap_open_file(const char *file, int *can_write, const char *header) ++{ ++ int cw = mock_type(int); ++ ++ *can_write = cw; ++ return TEST_FDNO; ++} ++ ++FILE *__wrap_fdopen(int fd, const char *mode) ++{ ++ assert_int_equal(fd, TEST_FDNO); ++ return TEST_FPTR; ++} ++ ++int __wrap_fflush(FILE *f) ++{ ++ assert_ptr_equal(f, TEST_FPTR); ++ return 0; ++} ++ ++int __wrap_fclose(FILE *f) ++{ ++ assert_ptr_equal(f, TEST_FPTR); ++ return 0; ++} ++ + /* strbuf wrapper for the old format_devname() */ + static int __format_devname(char *name, int id, size_t len, const char *prefix) + { +@@ -399,6 +428,22 @@ static void mock_self_alias(const char *alias, const char *wwid) + } + + #define USED_STR(alias_str, wwid_str) wwid_str ": alias '" alias_str "' already taken, reselecting alias\n" ++#define NOMATCH_STR(alias_str) ("No matching alias [" alias_str "] in bindings file.\n") ++#define FOUND_STR(alias_str, wwid_str) \ ++ "Found matching wwid [" wwid_str "] in bindings file." \ ++ " Setting alias to " alias_str "\n" ++#define FOUND_ALIAS_STR(alias_str, wwid_str) \ ++ "Found matching alias [" alias_str "] in bindings file." \ ++ " Setting wwid to " wwid_str "\n" ++#define NOMATCH_WWID_STR(wwid_str) ("No matching wwid [" wwid_str "] in bindings file.\n") ++#define NEW_STR(alias_str, wwid_str) ("Created new binding [" alias_str "] for WWID [" wwid_str "]\n") ++#define EXISTING_STR(alias_str, wwid_str) ("Use existing binding [" alias_str "] for WWID [" wwid_str "]\n") ++#define ALLOC_STR(alias_str, wwid_str) ("Allocated existing binding [" alias_str "] for WWID [" wwid_str "]\n") ++#define BINDING_STR(alias_str, wwid_str) (alias_str " " wwid_str "\n") ++#define BOUND_STR(alias_str, wwid_str) ("alias "alias_str " already bound to wwid " wwid_str ", cannot reuse") ++#define ERR_STR(alias_str, wwid_str) ("ERROR: old alias [" alias_str "] for wwid [" wwid_str "] is used by other map\n") ++#define REUSE_STR(alias_str, wwid_str) ("alias " alias_str " already bound to wwid " wwid_str ", cannot reuse\n") ++#define NOMORE_STR "no more available user_friendly_names\n" + + static void mock_failed_alias(const char *alias, char *msg) + { +@@ -421,6 +466,24 @@ static void mock_used_alias(const char *alias, char *msg) + expect_condlog(3, msg); + } + ++static void mock_bindings_file(const char *content, int match_line) ++{ ++ static char cnt[1024]; ++ char *token; ++ int i; ++ ++ assert_in_range(strlcpy(cnt, content, sizeof(cnt)), 0, sizeof(cnt) - 1); ++ ++ for (token = strtok(cnt, "\n"), i = 0; ++ token && *token; ++ token = strtok(NULL, "\n"), i++) { ++ will_return(__wrap_fgets, token); ++ if (match_line == i) ++ return; ++ } ++ will_return(__wrap_fgets, NULL); ++} ++ + static void lb_empty(void **state) + { + int rc; +@@ -1147,6 +1210,382 @@ static int test_allocate_binding(void) + return cmocka_run_group_tests(tests, NULL, NULL); + } + ++#define mock_allocate_binding(alias, wwid) \ ++ do { \ ++ static const char ln[] = BINDING_STR(alias, wwid); \ ++ \ ++ will_return(__wrap_lseek, 0); \ ++ expect_value(__wrap_write, count, strlen(ln)); \ ++ expect_string(__wrap_write, buf, ln); \ ++ will_return(__wrap_write, strlen(ln)); \ ++ expect_condlog(3, NEW_STR(alias, wwid)); \ ++ } while (0) ++ ++static void gufa_empty_new_rw(void **state) { ++ char *alias; ++ ++ will_return(__wrap_open_file, true); ++ ++ will_return(__wrap_fgets, NULL); ++ mock_unused_alias("MPATHa"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); ++ ++ mock_allocate_binding("MPATHa", "WWID0"); ++ alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false); ++ assert_string_equal(alias, "MPATHa"); ++ free(alias); ++} ++ ++static void gufa_empty_new_ro_1(void **state) { ++ char *alias; ++ will_return(__wrap_open_file, false); ++ will_return(__wrap_fgets, NULL); ++ mock_unused_alias("MPATHa"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); ++ ++ alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false); ++ assert_ptr_equal(alias, NULL); ++} ++ ++static void gufa_empty_new_ro_2(void **state) { ++ char *alias; ++ ++ will_return(__wrap_open_file, true); ++ ++ will_return(__wrap_fgets, NULL); ++ mock_unused_alias("MPATHa"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); ++ ++ alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); ++ assert_ptr_equal(alias, NULL); ++} ++ ++static void gufa_match_a_unused(void **state) { ++ char *alias; ++ ++ will_return(__wrap_open_file, true); ++ ++ will_return(__wrap_fgets, BINDING_STR("MPATHa", "WWID0")); ++ expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); ++ mock_unused_alias("MPATHa"); ++ ++ alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); ++ assert_string_equal(alias, "MPATHa"); ++ free(alias); ++} ++ ++static void gufa_match_a_self(void **state) { ++ char *alias; ++ ++ will_return(__wrap_open_file, true); ++ ++ will_return(__wrap_fgets, BINDING_STR("MPATHa", "WWID0")); ++ expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); ++ mock_self_alias("MPATHa", "WWID0"); ++ ++ alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); ++ assert_string_equal(alias, "MPATHa"); ++ free(alias); ++} ++ ++static void gufa_match_a_used(void **state) { ++ char *alias; ++ ++ will_return(__wrap_open_file, true); ++ ++ will_return(__wrap_fgets, BINDING_STR("MPATHa", "WWID0")); ++ expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); ++ mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); ++ ++ alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); ++ assert_ptr_equal(alias, NULL); ++} ++ ++static void gufa_nomatch_a_c(void **state) { ++ char *alias; ++ will_return(__wrap_open_file, true); ++ ++ mock_bindings_file("MPATHa WWID0\n" ++ "MPATHc WWID2", ++ -1); ++ mock_unused_alias("MPATHb"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID1")); ++ ++ mock_allocate_binding("MPATHb", "WWID1"); ++ ++ alias = get_user_friendly_alias("WWID1", "x", "", "MPATH", false); ++ assert_string_equal(alias, "MPATHb"); ++ free(alias); ++} ++ ++static void gufa_nomatch_c_a(void **state) { ++ char *alias; ++ will_return(__wrap_open_file, true); ++ ++ mock_bindings_file("MPATHc WWID2\n" ++ "MPATHa WWID0", ++ -1); ++ mock_unused_alias("MPATHb"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID1")); ++ ++ mock_allocate_binding("MPATHb", "WWID1"); ++ ++ alias = get_user_friendly_alias("WWID1", "x", "", "MPATH", false); ++ assert_string_equal(alias, "MPATHb"); ++ free(alias); ++} ++ ++static void gufa_nomatch_c_b(void **state) { ++ char *alias; ++ will_return(__wrap_open_file, true); ++ ++ mock_bindings_file("MPATHc WWID2\n" ++ "MPATHb WWID1\n", ++ -1); ++ mock_unused_alias("MPATHa"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); ++ ++ mock_allocate_binding("MPATHa", "WWID0"); ++ ++ alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false); ++ assert_string_equal(alias, "MPATHa"); ++ free(alias); ++} ++ ++static void gufa_nomatch_c_b_used(void **state) { ++ char *alias; ++ will_return(__wrap_open_file, true); ++ ++ mock_bindings_file("MPATHc WWID2\n" ++ "MPATHb WWID1", ++ -1); ++ mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID4")); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID4")); ++ mock_unused_alias("MPATHd"); ++ ++ mock_allocate_binding("MPATHd", "WWID4"); ++ ++ alias = get_user_friendly_alias("WWID4", "x", "", "MPATH", false); ++ assert_string_equal(alias, "MPATHd"); ++ free(alias); ++} ++ ++static void gufa_nomatch_b_f_a(void **state) { ++ char *alias; ++ will_return(__wrap_open_file, true); ++ ++ mock_bindings_file("MPATHb WWID1\n" ++ "MPATHf WWID6\n" ++ "MPATHa WWID0\n", ++ -1); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID7")); ++ mock_unused_alias("MPATHg"); ++ ++ mock_allocate_binding("MPATHg", "WWID7"); ++ ++ alias = get_user_friendly_alias("WWID7", "x", "", "MPATH", false); ++ assert_string_equal(alias, "MPATHg"); ++ free(alias); ++} ++ ++static void gufa_old_empty(void **state) { ++ char *alias; ++ will_return(__wrap_open_file, true); ++ ++ /* rlookup_binding for ALIAS */ ++ will_return(__wrap_fgets, NULL); ++ expect_condlog(3, NOMATCH_STR("MPATHz")); ++ ++ /* lookup_binding */ ++ will_return(__wrap_fgets, NULL); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); ++ ++ mock_allocate_binding("MPATHz", "WWID0"); ++ expect_condlog(2, ALLOC_STR("MPATHz", "WWID0")); ++ ++ alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); ++ assert_string_equal(alias, "MPATHz"); ++ free(alias); ++} ++ ++static void gufa_old_match(void **state) { ++ char *alias; ++ will_return(__wrap_open_file, true); ++ ++ mock_bindings_file("MPATHb WWID1\n" ++ "MPATHz WWID0", ++ 1); ++ expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID0")); ++ ++ alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); ++ assert_string_equal(alias, "MPATHz"); ++ free(alias); ++} ++ ++static void gufa_old_match_other(void **state) { ++ char *alias; ++ static const char bindings[] = "MPATHz WWID9"; ++ ++ will_return(__wrap_open_file, true); ++ ++ mock_bindings_file(bindings, 0); ++ expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID9")); ++ expect_condlog(0, REUSE_STR("MPATHz", "WWID9")); ++ ++ mock_bindings_file(bindings, -1); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); ++ mock_unused_alias("MPATHa"); ++ ++ mock_allocate_binding("MPATHa", "WWID0"); ++ ++ alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); ++ assert_string_equal(alias, "MPATHa"); ++ free(alias); ++} ++ ++static void gufa_old_match_other_used(void **state) { ++ char *alias; ++ static const char bindings[] = "MPATHz WWID9"; ++ ++ will_return(__wrap_open_file, true); ++ ++ mock_bindings_file(bindings, 0); ++ expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID9")); ++ expect_condlog(0, REUSE_STR("MPATHz", "WWID9")); ++ ++ mock_bindings_file(bindings, -1); ++ mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); ++ mock_unused_alias("MPATHb"); ++ ++ mock_allocate_binding("MPATHb", "WWID0"); ++ ++ alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); ++ assert_string_equal(alias, "MPATHb"); ++ free(alias); ++} ++ ++static void gufa_old_match_other_wwidmatch(void **state) { ++ char *alias; ++ static const char bindings[] = ("MPATHz WWID9\n" ++ "MPATHc WWID2"); ++ will_return(__wrap_open_file, true); ++ ++ mock_bindings_file(bindings, 0); ++ expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID9")); ++ expect_condlog(0, REUSE_STR("MPATHz", "WWID9")); ++ ++ mock_bindings_file(bindings, 1); ++ expect_condlog(3, FOUND_STR("MPATHc", "WWID2")); ++ mock_unused_alias("MPATHc"); ++ ++ alias = get_user_friendly_alias("WWID2", "x", "MPATHz", "MPATH", false); ++ assert_string_equal(alias, "MPATHc"); ++ free(alias); ++} ++ ++static void gufa_old_match_other_wwidmatch_used(void **state) { ++ char *alias; ++ static const char bindings[] = ("MPATHz WWID9\n" ++ "MPATHc WWID2"); ++ ++ will_return(__wrap_open_file, true); ++ ++ mock_bindings_file(bindings, 0); ++ expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID9")); ++ expect_condlog(0, REUSE_STR("MPATHz", "WWID9")); ++ ++ mock_bindings_file(bindings, 1); ++ expect_condlog(3, FOUND_STR("MPATHc", "WWID2")); ++ mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID2")); ++ ++ alias = get_user_friendly_alias("WWID2", "x", "MPATHz", "MPATH", false); ++ assert_ptr_equal(alias, NULL); ++} ++ ++static void gufa_old_nomatch_wwidmatch(void **state) { ++ char *alias; ++ static const char bindings[] = "MPATHa WWID0"; ++ ++ will_return(__wrap_open_file, true); ++ ++ mock_bindings_file(bindings, -1); ++ expect_condlog(3, NOMATCH_STR("MPATHz")); ++ ++ mock_bindings_file(bindings, 0); ++ expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); ++ mock_unused_alias("MPATHa"); ++ expect_condlog(3, EXISTING_STR("MPATHa", "WWID0")); ++ ++ alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); ++ assert_string_equal(alias, "MPATHa"); ++ free(alias); ++} ++ ++static void gufa_old_nomatch_wwidmatch_used(void **state) { ++ char *alias; ++ static const char bindings[] = "MPATHa WWID0"; ++ will_return(__wrap_open_file, true); ++ ++ mock_bindings_file(bindings, -1); ++ expect_condlog(3, NOMATCH_STR("MPATHz")); ++ ++ mock_bindings_file(bindings, 0); ++ expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); ++ mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); ++ ++ alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); ++ assert_ptr_equal(alias, NULL); ++} ++ ++static void gufa_old_nomatch_nowwidmatch(void **state) { ++ char *alias; ++ static const char bindings[] = "MPATHb WWID1"; ++ ++ will_return(__wrap_open_file, true); ++ ++ mock_bindings_file(bindings, -1); ++ expect_condlog(3, NOMATCH_STR("MPATHz")); ++ ++ mock_bindings_file(bindings, -1); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); ++ ++ mock_allocate_binding("MPATHz", "WWID0"); ++ expect_condlog(2, ALLOC_STR("MPATHz", "WWID0")); ++ ++ alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); ++ assert_string_equal(alias, "MPATHz"); ++ free(alias); ++} ++ ++static int test_get_user_friendly_alias() ++{ ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test(gufa_empty_new_rw), ++ cmocka_unit_test(gufa_empty_new_ro_1), ++ cmocka_unit_test(gufa_empty_new_ro_2), ++ cmocka_unit_test(gufa_match_a_unused), ++ cmocka_unit_test(gufa_match_a_self), ++ cmocka_unit_test(gufa_match_a_used), ++ cmocka_unit_test(gufa_nomatch_a_c), ++ cmocka_unit_test(gufa_nomatch_c_a), ++ cmocka_unit_test(gufa_nomatch_c_b), ++ cmocka_unit_test(gufa_nomatch_c_b_used), ++ cmocka_unit_test(gufa_nomatch_b_f_a), ++ cmocka_unit_test(gufa_old_empty), ++ cmocka_unit_test(gufa_old_match), ++ cmocka_unit_test(gufa_old_match_other), ++ cmocka_unit_test(gufa_old_match_other_used), ++ cmocka_unit_test(gufa_old_match_other_wwidmatch), ++ cmocka_unit_test(gufa_old_match_other_wwidmatch_used), ++ cmocka_unit_test(gufa_old_nomatch_wwidmatch), ++ cmocka_unit_test(gufa_old_nomatch_wwidmatch_used), ++ cmocka_unit_test(gufa_old_nomatch_nowwidmatch), ++ }; ++ ++ return cmocka_run_group_tests(tests, NULL, NULL); ++} ++ + int main(void) + { + int ret = 0; +@@ -1157,6 +1596,8 @@ int main(void) + ret += test_lookup_binding(); + ret += test_rlookup_binding(); + ret += test_allocate_binding(); ++ ret += test_allocate_binding(); ++ ret += test_get_user_friendly_alias(); + + return ret; + } diff --git a/0008-multipath-tools-test-consistent-use-of-macros-in-ali.patch b/0008-multipath-tools-test-consistent-use-of-macros-in-ali.patch new file mode 100644 index 0000000..430ceaf --- /dev/null +++ b/0008-multipath-tools-test-consistent-use-of-macros-in-ali.patch @@ -0,0 +1,365 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 24 Aug 2023 10:40:32 +0200 +Subject: [PATCH] multipath-tools test: consistent use of macros in alias test + +Use the macros introduced with the tests for get_user_friendly_alias() +also in the previously existing tests. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + tests/alias.c | 80 ++++++++++++++++++++++++--------------------------- + 1 file changed, 38 insertions(+), 42 deletions(-) + +diff --git a/tests/alias.c b/tests/alias.c +index 7e443b06..427b2814 100644 +--- a/tests/alias.c ++++ b/tests/alias.c +@@ -490,7 +490,7 @@ static void lb_empty(void **state) + char *alias; + + will_return(__wrap_fgets, NULL); +- expect_condlog(3, "No matching wwid [WWID0] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + rc = lookup_binding(NULL, "WWID0", &alias, NULL, 0); + assert_int_equal(rc, 1); + assert_ptr_equal(alias, NULL); +@@ -503,7 +503,7 @@ static void lb_empty_unused(void **state) + + will_return(__wrap_fgets, NULL); + mock_unused_alias("MPATHa"); +- expect_condlog(3, "No matching wwid [WWID0] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); + assert_int_equal(rc, 1); + assert_ptr_equal(alias, NULL); +@@ -518,7 +518,7 @@ static void lb_empty_failed(void **state) + will_return(__wrap_fgets, NULL); + mock_failed_alias("MPATHa", USED_STR("MPATHa", "WWID0")); + mock_unused_alias("MPATHb"); +- expect_condlog(3, "No matching wwid [WWID0] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); + assert_int_equal(rc, 2); + assert_ptr_equal(alias, NULL); +@@ -533,7 +533,7 @@ static void lb_empty_1_used(void **state) + will_return(__wrap_fgets, NULL); + mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); + mock_unused_alias("MPATHb"); +- expect_condlog(3, "No matching wwid [WWID0] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); + assert_int_equal(rc, 2); + assert_ptr_equal(alias, NULL); +@@ -548,7 +548,7 @@ static void lb_empty_1_used_self(void **state) + will_return(__wrap_fgets, NULL); + mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); + mock_self_alias("MPATHb", "WWID0"); +- expect_condlog(3, "No matching wwid [WWID0] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); + assert_int_equal(rc, 2); + assert_ptr_equal(alias, NULL); +@@ -561,8 +561,7 @@ static void lb_match_a(void **state) + char *alias; + + will_return(__wrap_fgets, "MPATHa WWID0\n"); +- expect_condlog(3, "Found matching wwid [WWID0] in bindings file." +- " Setting alias to MPATHa\n"); ++ expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); + rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 0); + assert_int_equal(rc, 0); + assert_ptr_not_equal(alias, NULL); +@@ -577,7 +576,7 @@ static void lb_nomatch_a(void **state) + + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, NULL); +- expect_condlog(3, "No matching wwid [WWID1] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID1")); + rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 0); + assert_int_equal(rc, 2); + assert_ptr_equal(alias, NULL); +@@ -590,7 +589,7 @@ static void lb_nomatch_a_bad_check(void **state) + + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, NULL); +- expect_condlog(0, "no more available user_friendly_names\n"); ++ expect_condlog(0, NOMORE_STR); + rc = lookup_binding(NULL, "WWID1", &alias, NULL, 1); + assert_int_equal(rc, -1); + assert_ptr_equal(alias, NULL); +@@ -604,7 +603,7 @@ static void lb_nomatch_a_unused(void **state) + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, NULL); + mock_unused_alias("MPATHb"); +- expect_condlog(3, "No matching wwid [WWID1] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID1")); + rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1); + assert_int_equal(rc, 2); + assert_ptr_equal(alias, NULL); +@@ -622,7 +621,7 @@ static void lb_nomatch_a_3_used_failed_self(void **state) + mock_used_alias("MPATHd", USED_STR("MPATHd", "WWID1")); + mock_failed_alias("MPATHe", USED_STR("MPATHe", "WWID1")); + mock_self_alias("MPATHf", "WWID1"); +- expect_condlog(3, "No matching wwid [WWID1] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID1")); + rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1); + assert_int_equal(rc, 6); + assert_ptr_equal(alias, NULL); +@@ -635,8 +634,7 @@ static void do_lb_match_c(void **state, int check_if_taken) + + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, "MPATHc WWID1\n"); +- expect_condlog(3, "Found matching wwid [WWID1] in bindings file." +- " Setting alias to MPATHc\n"); ++ expect_condlog(3, FOUND_STR("MPATHc", "WWID1")); + rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", check_if_taken); + assert_int_equal(rc, 0); + assert_ptr_not_equal(alias, NULL); +@@ -662,7 +660,7 @@ static void lb_nomatch_a_c(void **state) + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, "MPATHc WWID1\n"); + will_return(__wrap_fgets, NULL); +- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); + assert_int_equal(rc, 2); + assert_ptr_equal(alias, NULL); +@@ -677,7 +675,7 @@ static void lb_nomatch_a_d_unused(void **state) + will_return(__wrap_fgets, "MPATHd WWID1\n"); + will_return(__wrap_fgets, NULL); + mock_unused_alias("MPATHb"); +- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, 2); + assert_ptr_equal(alias, NULL); +@@ -693,7 +691,7 @@ static void lb_nomatch_a_d_1_used(void **state) + will_return(__wrap_fgets, NULL); + mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2")); + mock_unused_alias("MPATHc"); +- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, 3); + assert_ptr_equal(alias, NULL); +@@ -710,7 +708,7 @@ static void lb_nomatch_a_d_2_used(void **state) + mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2")); + mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID2")); + mock_unused_alias("MPATHe"); +- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, 5); + assert_ptr_equal(alias, NULL); +@@ -728,7 +726,7 @@ static void lb_nomatch_a_d_3_used(void **state) + mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID2")); + mock_used_alias("MPATHe", USED_STR("MPATHe", "WWID2")); + mock_unused_alias("MPATHf"); +- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, 6); + assert_ptr_equal(alias, NULL); +@@ -742,7 +740,7 @@ static void lb_nomatch_c_a(void **state) + will_return(__wrap_fgets, "MPATHc WWID1\n"); + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, NULL); +- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); + assert_int_equal(rc, 2); + assert_ptr_equal(alias, NULL); +@@ -758,7 +756,7 @@ static void lb_nomatch_d_a_unused(void **state) + will_return(__wrap_fgets, "MPATHd WWID0\n"); + will_return(__wrap_fgets, NULL); + mock_unused_alias("MPATHb"); +- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, 2); + assert_ptr_equal(alias, NULL); +@@ -775,7 +773,7 @@ static void lb_nomatch_d_a_1_used(void **state) + will_return(__wrap_fgets, NULL); + mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2")); + mock_unused_alias("MPATHe"); +- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, 5); + assert_ptr_equal(alias, NULL); +@@ -790,7 +788,7 @@ static void lb_nomatch_a_b(void **state) + will_return(__wrap_fgets, "MPATHz WWID26\n"); + will_return(__wrap_fgets, "MPATHb WWID1\n"); + will_return(__wrap_fgets, NULL); +- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); + assert_int_equal(rc, 3); + assert_ptr_equal(alias, NULL); +@@ -806,7 +804,7 @@ static void lb_nomatch_a_b_bad(void **state) + will_return(__wrap_fgets, "MPATHb\n"); + will_return(__wrap_fgets, NULL); + expect_condlog(3, "Ignoring malformed line 3 in bindings file\n"); +- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); + assert_int_equal(rc, 3); + assert_ptr_equal(alias, NULL); +@@ -823,7 +821,7 @@ static void lb_nomatch_a_b_bad_self(void **state) + will_return(__wrap_fgets, NULL); + expect_condlog(3, "Ignoring malformed line 3 in bindings file\n"); + mock_self_alias("MPATHc", "WWID2"); +- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, 3); + assert_ptr_equal(alias, NULL); +@@ -838,7 +836,7 @@ static void lb_nomatch_b_a(void **state) + will_return(__wrap_fgets, "MPATHz WWID26\n"); + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, NULL); +- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); + assert_int_equal(rc, 27); + assert_ptr_equal(alias, NULL); +@@ -857,7 +855,7 @@ static void lb_nomatch_b_a_3_used(void **state) + mock_used_alias("MPATHab", USED_STR("MPATHab", "WWID2")); + mock_used_alias("MPATHac", USED_STR("MPATHac", "WWID2")); + mock_unused_alias("MPATHad"); +- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, 30); + assert_ptr_equal(alias, NULL); +@@ -873,7 +871,7 @@ static void do_lb_nomatch_int_max(void **state, int check_if_taken) + will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n"); + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, NULL); +- expect_condlog(0, "no more available user_friendly_names\n"); ++ expect_condlog(0, NOMORE_STR); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", check_if_taken); + assert_int_equal(rc, -1); + assert_ptr_equal(alias, NULL); +@@ -898,7 +896,7 @@ static void lb_nomatch_int_max_used(void **state) + will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n"); + will_return(__wrap_fgets, NULL); + mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID2")); +- expect_condlog(0, "no more available user_friendly_names\n"); ++ expect_condlog(0, NOMORE_STR); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, -1); + assert_ptr_equal(alias, NULL); +@@ -913,7 +911,7 @@ static void lb_nomatch_int_max_m1(void **state) + will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"); + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, NULL); +- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); + assert_int_equal(rc, INT_MAX); + assert_ptr_equal(alias, NULL); +@@ -929,7 +927,7 @@ static void lb_nomatch_int_max_m1_used(void **state) + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, NULL); + mock_used_alias("MPATH" MPATH_ID_INT_MAX, USED_STR("MPATH" MPATH_ID_INT_MAX, "WWID2")); +- expect_condlog(0, "no more available user_friendly_names\n"); ++ expect_condlog(0, NOMORE_STR); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, -1); + assert_ptr_equal(alias, NULL); +@@ -945,7 +943,7 @@ static void lb_nomatch_int_max_m1_1_used(void **state) + will_return(__wrap_fgets, NULL); + mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID2")); + mock_unused_alias("MPATH" MPATH_ID_INT_MAX); +- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, INT_MAX); + assert_ptr_equal(alias, NULL); +@@ -961,7 +959,7 @@ static void lb_nomatch_int_max_m1_2_used(void **state) + will_return(__wrap_fgets, NULL); + mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID2")); + mock_used_alias("MPATH" MPATH_ID_INT_MAX, USED_STR("MPATH" MPATH_ID_INT_MAX, "WWID2")); +- expect_condlog(0, "no more available user_friendly_names\n"); ++ expect_condlog(0, NOMORE_STR); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, -1); + assert_ptr_equal(alias, NULL); +@@ -1017,7 +1015,7 @@ static void rl_empty(void **state) + + buf[0] = '\0'; + will_return(__wrap_fgets, NULL); +- expect_condlog(3, "No matching alias [MPATHa] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_STR("MPATHa")); + rc = rlookup_binding(NULL, buf, "MPATHa"); + assert_int_equal(rc, -1); + assert_string_equal(buf, ""); +@@ -1030,8 +1028,7 @@ static void rl_match_a(void **state) + + buf[0] = '\0'; + will_return(__wrap_fgets, "MPATHa WWID0\n"); +- expect_condlog(3, "Found matching alias [MPATHa] in bindings file. " +- "Setting wwid to WWID0\n"); ++ expect_condlog(3, FOUND_ALIAS_STR("MPATHa", "WWID0")); + rc = rlookup_binding(NULL, buf, "MPATHa"); + assert_int_equal(rc, 0); + assert_string_equal(buf, "WWID0"); +@@ -1045,7 +1042,7 @@ static void rl_nomatch_a(void **state) + buf[0] = '\0'; + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, NULL); +- expect_condlog(3, "No matching alias [MPATHb] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_STR("MPATHb")); + rc = rlookup_binding(NULL, buf, "MPATHb"); + assert_int_equal(rc, -1); + assert_string_equal(buf, ""); +@@ -1060,7 +1057,7 @@ static void rl_malformed_a(void **state) + will_return(__wrap_fgets, "MPATHa \n"); + will_return(__wrap_fgets, NULL); + expect_condlog(3, "Ignoring malformed line 1 in bindings file\n"); +- expect_condlog(3, "No matching alias [MPATHa] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_STR("MPATHa")); + rc = rlookup_binding(NULL, buf, "MPATHa"); + assert_int_equal(rc, -1); + assert_string_equal(buf, ""); +@@ -1080,7 +1077,7 @@ static void rl_overlong_a(void **state) + will_return(__wrap_fgets, line); + will_return(__wrap_fgets, NULL); + expect_condlog(3, "Ignoring too large wwid at 1 in bindings file\n"); +- expect_condlog(3, "No matching alias [MPATHa] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_STR("MPATHa")); + rc = rlookup_binding(NULL, buf, "MPATHa"); + assert_int_equal(rc, -1); + assert_string_equal(buf, ""); +@@ -1095,8 +1092,7 @@ static void rl_match_b(void **state) + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, "MPATHz WWID26\n"); + will_return(__wrap_fgets, "MPATHb WWID2\n"); +- expect_condlog(3, "Found matching alias [MPATHb] in bindings file. " +- "Setting wwid to WWID2\n"); ++ expect_condlog(3, FOUND_ALIAS_STR("MPATHb", "WWID2")); + rc = rlookup_binding(NULL, buf, "MPATHb"); + assert_int_equal(rc, 0); + assert_string_equal(buf, "WWID2"); +@@ -1125,7 +1121,7 @@ static void al_a(void **state) + expect_value(__wrap_write, count, strlen(ln)); + expect_string(__wrap_write, buf, ln); + will_return(__wrap_write, strlen(ln)); +- expect_condlog(3, "Created new binding [MPATHa] for WWID [WWIDa]\n"); ++ expect_condlog(3, NEW_STR("MPATHa", "WWIDa")); + + alias = allocate_binding(0, "WWIDa", 1, "MPATH"); + assert_ptr_not_equal(alias, NULL); +@@ -1142,7 +1138,7 @@ static void al_zz(void **state) + expect_value(__wrap_write, count, strlen(ln)); + expect_string(__wrap_write, buf, ln); + will_return(__wrap_write, strlen(ln)); +- expect_condlog(3, "Created new binding [MPATHzz] for WWID [WWIDzz]\n"); ++ expect_condlog(3, NEW_STR("MPATHzz", "WWIDzz")); + + alias = allocate_binding(0, "WWIDzz", 26*26 + 26, "MPATH"); + assert_ptr_not_equal(alias, NULL); diff --git a/0009-multipath-tools-tests-convert-mock_-failed-used-_ali.patch b/0009-multipath-tools-tests-convert-mock_-failed-used-_ali.patch new file mode 100644 index 0000000..9d71adf --- /dev/null +++ b/0009-multipath-tools-tests-convert-mock_-failed-used-_ali.patch @@ -0,0 +1,246 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 24 Aug 2023 10:49:32 +0200 +Subject: [PATCH] multipath-tools tests: convert mock_{failed,used}_alias to + macros + +This way we can further improve readability of the individual test +cases. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + tests/alias.c | 92 +++++++++++++++++++++++++-------------------------- + 1 file changed, 46 insertions(+), 46 deletions(-) + +diff --git a/tests/alias.c b/tests/alias.c +index 427b2814..a32b43e8 100644 +--- a/tests/alias.c ++++ b/tests/alias.c +@@ -445,26 +445,26 @@ static void mock_self_alias(const char *alias, const char *wwid) + #define REUSE_STR(alias_str, wwid_str) ("alias " alias_str " already bound to wwid " wwid_str ", cannot reuse\n") + #define NOMORE_STR "no more available user_friendly_names\n" + +-static void mock_failed_alias(const char *alias, char *msg) +-{ +- expect_string(__wrap_dm_map_present, str, alias); +- will_return(__wrap_dm_map_present, 1); +- expect_string(__wrap_dm_get_uuid, name, alias); +- expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); +- will_return(__wrap_dm_get_uuid, 1); +- expect_condlog(3, msg); +-} ++#define mock_failed_alias(alias, wwid) \ ++ do { \ ++ expect_string(__wrap_dm_map_present, str, alias); \ ++ will_return(__wrap_dm_map_present, 1); \ ++ expect_string(__wrap_dm_get_uuid, name, alias); \ ++ expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); \ ++ will_return(__wrap_dm_get_uuid, 1); \ ++ expect_condlog(3, USED_STR(alias, wwid)); \ ++ } while (0) + +-static void mock_used_alias(const char *alias, char *msg) +-{ +- expect_string(__wrap_dm_map_present, str, alias); +- will_return(__wrap_dm_map_present, 1); +- expect_string(__wrap_dm_get_uuid, name, alias); +- expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); +- will_return(__wrap_dm_get_uuid, 0); +- will_return(__wrap_dm_get_uuid, "WWID_USED"); +- expect_condlog(3, msg); +-} ++#define mock_used_alias(alias, wwid) \ ++ do { \ ++ expect_string(__wrap_dm_map_present, str, alias); \ ++ will_return(__wrap_dm_map_present, 1); \ ++ expect_string(__wrap_dm_get_uuid, name, alias); \ ++ expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); \ ++ will_return(__wrap_dm_get_uuid, 0); \ ++ will_return(__wrap_dm_get_uuid, "WWID_USED"); \ ++ expect_condlog(3, USED_STR(alias, wwid)); \ ++ } while(0) + + static void mock_bindings_file(const char *content, int match_line) + { +@@ -516,7 +516,7 @@ static void lb_empty_failed(void **state) + char *alias; + + will_return(__wrap_fgets, NULL); +- mock_failed_alias("MPATHa", USED_STR("MPATHa", "WWID0")); ++ mock_failed_alias("MPATHa", "WWID0"); + mock_unused_alias("MPATHb"); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); +@@ -531,7 +531,7 @@ static void lb_empty_1_used(void **state) + char *alias; + + will_return(__wrap_fgets, NULL); +- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); ++ mock_used_alias("MPATHa", "WWID0"); + mock_unused_alias("MPATHb"); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); +@@ -546,7 +546,7 @@ static void lb_empty_1_used_self(void **state) + char *alias; + + will_return(__wrap_fgets, NULL); +- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); ++ mock_used_alias("MPATHa", "WWID0"); + mock_self_alias("MPATHb", "WWID0"); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); +@@ -616,10 +616,10 @@ static void lb_nomatch_a_3_used_failed_self(void **state) + + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, NULL); +- mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID1")); +- mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID1")); +- mock_used_alias("MPATHd", USED_STR("MPATHd", "WWID1")); +- mock_failed_alias("MPATHe", USED_STR("MPATHe", "WWID1")); ++ mock_used_alias("MPATHb", "WWID1"); ++ mock_used_alias("MPATHc", "WWID1"); ++ mock_used_alias("MPATHd", "WWID1"); ++ mock_failed_alias("MPATHe", "WWID1"); + mock_self_alias("MPATHf", "WWID1"); + expect_condlog(3, NOMATCH_WWID_STR("WWID1")); + rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1); +@@ -689,7 +689,7 @@ static void lb_nomatch_a_d_1_used(void **state) + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, "MPATHd WWID1\n"); + will_return(__wrap_fgets, NULL); +- mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2")); ++ mock_used_alias("MPATHb", "WWID2"); + mock_unused_alias("MPATHc"); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); +@@ -705,8 +705,8 @@ static void lb_nomatch_a_d_2_used(void **state) + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, "MPATHd WWID1\n"); + will_return(__wrap_fgets, NULL); +- mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2")); +- mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID2")); ++ mock_used_alias("MPATHb", "WWID2"); ++ mock_used_alias("MPATHc", "WWID2"); + mock_unused_alias("MPATHe"); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); +@@ -722,9 +722,9 @@ static void lb_nomatch_a_d_3_used(void **state) + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, "MPATHd WWID1\n"); + will_return(__wrap_fgets, NULL); +- mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2")); +- mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID2")); +- mock_used_alias("MPATHe", USED_STR("MPATHe", "WWID2")); ++ mock_used_alias("MPATHb", "WWID2"); ++ mock_used_alias("MPATHc", "WWID2"); ++ mock_used_alias("MPATHe", "WWID2"); + mock_unused_alias("MPATHf"); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); +@@ -771,7 +771,7 @@ static void lb_nomatch_d_a_1_used(void **state) + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, "MPATHd WWID0\n"); + will_return(__wrap_fgets, NULL); +- mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2")); ++ mock_used_alias("MPATHb", "WWID2"); + mock_unused_alias("MPATHe"); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); +@@ -851,9 +851,9 @@ static void lb_nomatch_b_a_3_used(void **state) + will_return(__wrap_fgets, "MPATHz WWID26\n"); + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, NULL); +- mock_used_alias("MPATHaa", USED_STR("MPATHaa", "WWID2")); +- mock_used_alias("MPATHab", USED_STR("MPATHab", "WWID2")); +- mock_used_alias("MPATHac", USED_STR("MPATHac", "WWID2")); ++ mock_used_alias("MPATHaa", "WWID2"); ++ mock_used_alias("MPATHab", "WWID2"); ++ mock_used_alias("MPATHac", "WWID2"); + mock_unused_alias("MPATHad"); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); +@@ -895,7 +895,7 @@ static void lb_nomatch_int_max_used(void **state) + will_return(__wrap_fgets, "MPATHb WWID1\n"); + will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n"); + will_return(__wrap_fgets, NULL); +- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID2")); ++ mock_used_alias("MPATHa", "WWID2"); + expect_condlog(0, NOMORE_STR); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, -1); +@@ -926,7 +926,7 @@ static void lb_nomatch_int_max_m1_used(void **state) + will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"); + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, NULL); +- mock_used_alias("MPATH" MPATH_ID_INT_MAX, USED_STR("MPATH" MPATH_ID_INT_MAX, "WWID2")); ++ mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWID2"); + expect_condlog(0, NOMORE_STR); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, -1); +@@ -941,7 +941,7 @@ static void lb_nomatch_int_max_m1_1_used(void **state) + will_return(__wrap_fgets, "MPATHb WWID1\n"); + will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"); + will_return(__wrap_fgets, NULL); +- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID2")); ++ mock_used_alias("MPATHa", "WWID2"); + mock_unused_alias("MPATH" MPATH_ID_INT_MAX); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); +@@ -957,8 +957,8 @@ static void lb_nomatch_int_max_m1_2_used(void **state) + will_return(__wrap_fgets, "MPATHb WWID1\n"); + will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"); + will_return(__wrap_fgets, NULL); +- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID2")); +- mock_used_alias("MPATH" MPATH_ID_INT_MAX, USED_STR("MPATH" MPATH_ID_INT_MAX, "WWID2")); ++ mock_used_alias("MPATHa", "WWID2"); ++ mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWID2"); + expect_condlog(0, NOMORE_STR); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, -1); +@@ -1291,7 +1291,7 @@ static void gufa_match_a_used(void **state) { + + will_return(__wrap_fgets, BINDING_STR("MPATHa", "WWID0")); + expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); +- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); ++ mock_used_alias("MPATHa", "WWID0"); + + alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); + assert_ptr_equal(alias, NULL); +@@ -1355,7 +1355,7 @@ static void gufa_nomatch_c_b_used(void **state) { + mock_bindings_file("MPATHc WWID2\n" + "MPATHb WWID1", + -1); +- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID4")); ++ mock_used_alias("MPATHa", "WWID4"); + expect_condlog(3, NOMATCH_WWID_STR("WWID4")); + mock_unused_alias("MPATHd"); + +@@ -1450,7 +1450,7 @@ static void gufa_old_match_other_used(void **state) { + expect_condlog(0, REUSE_STR("MPATHz", "WWID9")); + + mock_bindings_file(bindings, -1); +- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); ++ mock_used_alias("MPATHa", "WWID0"); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + mock_unused_alias("MPATHb"); + +@@ -1493,7 +1493,7 @@ static void gufa_old_match_other_wwidmatch_used(void **state) { + + mock_bindings_file(bindings, 1); + expect_condlog(3, FOUND_STR("MPATHc", "WWID2")); +- mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID2")); ++ mock_used_alias("MPATHc", "WWID2"); + + alias = get_user_friendly_alias("WWID2", "x", "MPATHz", "MPATH", false); + assert_ptr_equal(alias, NULL); +@@ -1528,7 +1528,7 @@ static void gufa_old_nomatch_wwidmatch_used(void **state) { + + mock_bindings_file(bindings, 0); + expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); +- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); ++ mock_used_alias("MPATHa", "WWID0"); + + alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); + assert_ptr_equal(alias, NULL); diff --git a/0010-multipath-tools-test-use-mock_bindings_file-consiste.patch b/0010-multipath-tools-test-use-mock_bindings_file-consiste.patch new file mode 100644 index 0000000..2105f5a --- /dev/null +++ b/0010-multipath-tools-test-use-mock_bindings_file-consiste.patch @@ -0,0 +1,500 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 24 Aug 2023 11:13:44 +0200 +Subject: [PATCH] multipath-tools test: use mock_bindings_file() consistently + +Further improve test readablity. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + tests/alias.c | 178 +++++++++++++++++++++----------------------------- + 1 file changed, 76 insertions(+), 102 deletions(-) + +diff --git a/tests/alias.c b/tests/alias.c +index a32b43e8..f334f928 100644 +--- a/tests/alias.c ++++ b/tests/alias.c +@@ -489,7 +489,7 @@ static void lb_empty(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("", -1); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + rc = lookup_binding(NULL, "WWID0", &alias, NULL, 0); + assert_int_equal(rc, 1); +@@ -501,7 +501,7 @@ static void lb_empty_unused(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("", -1); + mock_unused_alias("MPATHa"); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); +@@ -515,7 +515,7 @@ static void lb_empty_failed(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("", -1); + mock_failed_alias("MPATHa", "WWID0"); + mock_unused_alias("MPATHb"); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); +@@ -530,7 +530,7 @@ static void lb_empty_1_used(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("", -1); + mock_used_alias("MPATHa", "WWID0"); + mock_unused_alias("MPATHb"); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); +@@ -545,7 +545,7 @@ static void lb_empty_1_used_self(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("", -1); + mock_used_alias("MPATHa", "WWID0"); + mock_self_alias("MPATHb", "WWID0"); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); +@@ -560,7 +560,7 @@ static void lb_match_a(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHa WWID0\n"); ++ mock_bindings_file("MPATHa WWID0\n", 0); + expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); + rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 0); + assert_int_equal(rc, 0); +@@ -574,8 +574,7 @@ static void lb_nomatch_a(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHa WWID0\n", -1); + expect_condlog(3, NOMATCH_WWID_STR("WWID1")); + rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 0); + assert_int_equal(rc, 2); +@@ -587,8 +586,7 @@ static void lb_nomatch_a_bad_check(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHa WWID0\n", -1); + expect_condlog(0, NOMORE_STR); + rc = lookup_binding(NULL, "WWID1", &alias, NULL, 1); + assert_int_equal(rc, -1); +@@ -600,8 +598,7 @@ static void lb_nomatch_a_unused(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHa WWID0\n", -1); + mock_unused_alias("MPATHb"); + expect_condlog(3, NOMATCH_WWID_STR("WWID1")); + rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1); +@@ -614,8 +611,7 @@ static void lb_nomatch_a_3_used_failed_self(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHa WWID0\n", -1); + mock_used_alias("MPATHb", "WWID1"); + mock_used_alias("MPATHc", "WWID1"); + mock_used_alias("MPATHd", "WWID1"); +@@ -632,8 +628,8 @@ static void do_lb_match_c(void **state, int check_if_taken) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, "MPATHc WWID1\n"); ++ mock_bindings_file("MPATHa WWID0\n" ++ "MPATHc WWID1", 1); + expect_condlog(3, FOUND_STR("MPATHc", "WWID1")); + rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", check_if_taken); + assert_int_equal(rc, 0); +@@ -657,9 +653,8 @@ static void lb_nomatch_a_c(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, "MPATHc WWID1\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHa WWID0\n" ++ "MPATHc WWID1", -1); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); + assert_int_equal(rc, 2); +@@ -671,9 +666,8 @@ static void lb_nomatch_a_d_unused(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, "MPATHd WWID1\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHa WWID0\n" ++ "MPATHd WWID1", -1); + mock_unused_alias("MPATHb"); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); +@@ -686,9 +680,8 @@ static void lb_nomatch_a_d_1_used(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, "MPATHd WWID1\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHa WWID0\n" ++ "MPATHd WWID1", -1); + mock_used_alias("MPATHb", "WWID2"); + mock_unused_alias("MPATHc"); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); +@@ -702,9 +695,8 @@ static void lb_nomatch_a_d_2_used(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, "MPATHd WWID1\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHa WWID0\n" ++ "MPATHd WWID1", -1); + mock_used_alias("MPATHb", "WWID2"); + mock_used_alias("MPATHc", "WWID2"); + mock_unused_alias("MPATHe"); +@@ -719,9 +711,8 @@ static void lb_nomatch_a_d_3_used(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, "MPATHd WWID1\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHa WWID0\n" ++ "MPATHd WWID1", -1); + mock_used_alias("MPATHb", "WWID2"); + mock_used_alias("MPATHc", "WWID2"); + mock_used_alias("MPATHe", "WWID2"); +@@ -737,9 +728,8 @@ static void lb_nomatch_c_a(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHc WWID1\n"); +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHc WWID1\n" ++ "MPATHa WWID0\n", -1); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); + assert_int_equal(rc, 2); +@@ -751,10 +741,9 @@ static void lb_nomatch_d_a_unused(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHc WWID1\n"); +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, "MPATHd WWID0\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHc WWID1\n" ++ "MPATHa WWID0\n" ++ "MPATHd WWID0\n", -1); + mock_unused_alias("MPATHb"); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); +@@ -767,10 +756,9 @@ static void lb_nomatch_d_a_1_used(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHc WWID1\n"); +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, "MPATHd WWID0\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHc WWID1\n" ++ "MPATHa WWID0\n" ++ "MPATHd WWID0\n", -1); + mock_used_alias("MPATHb", "WWID2"); + mock_unused_alias("MPATHe"); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); +@@ -784,10 +772,9 @@ static void lb_nomatch_a_b(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, "MPATHz WWID26\n"); +- will_return(__wrap_fgets, "MPATHb WWID1\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHa WWID0\n" ++ "MPATHz WWID26\n" ++ "MPATHb WWID1\n", -1); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); + assert_int_equal(rc, 3); +@@ -799,10 +786,9 @@ static void lb_nomatch_a_b_bad(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, "MPATHz WWID26\n"); +- will_return(__wrap_fgets, "MPATHb\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHa WWID0\n" ++ "MPATHz WWID26\n" ++ "MPATHb\n", -1); + expect_condlog(3, "Ignoring malformed line 3 in bindings file\n"); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); +@@ -815,10 +801,9 @@ static void lb_nomatch_a_b_bad_self(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, "MPATHz WWID26\n"); +- will_return(__wrap_fgets, "MPATHb\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHa WWID0\n" ++ "MPATHz WWID26\n" ++ "MPATHb\n", -1); + expect_condlog(3, "Ignoring malformed line 3 in bindings file\n"); + mock_self_alias("MPATHc", "WWID2"); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); +@@ -832,10 +817,9 @@ static void lb_nomatch_b_a(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHb WWID1\n"); +- will_return(__wrap_fgets, "MPATHz WWID26\n"); +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHb WWID1\n" ++ "MPATHz WWID26\n" ++ "MPATHa WWID0\n", -1); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); + assert_int_equal(rc, 27); +@@ -847,10 +831,9 @@ static void lb_nomatch_b_a_3_used(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHb WWID1\n"); +- will_return(__wrap_fgets, "MPATHz WWID26\n"); +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHb WWID1\n" ++ "MPATHz WWID26\n" ++ "MPATHa WWID0\n", -1); + mock_used_alias("MPATHaa", "WWID2"); + mock_used_alias("MPATHab", "WWID2"); + mock_used_alias("MPATHac", "WWID2"); +@@ -867,10 +850,9 @@ static void do_lb_nomatch_int_max(void **state, int check_if_taken) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHb WWID1\n"); +- will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n"); +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHb WWID1\n" ++ "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n" ++ "MPATHa WWID0\n", -1); + expect_condlog(0, NOMORE_STR); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", check_if_taken); + assert_int_equal(rc, -1); +@@ -892,9 +874,8 @@ static void lb_nomatch_int_max_used(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHb WWID1\n"); +- will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHb WWID1\n" ++ "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n", -1); + mock_used_alias("MPATHa", "WWID2"); + expect_condlog(0, NOMORE_STR); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); +@@ -907,10 +888,9 @@ static void lb_nomatch_int_max_m1(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHb WWID1\n"); +- will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"); +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHb WWID1\n" ++ "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n" ++ "MPATHa WWID0\n", -1); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); + assert_int_equal(rc, INT_MAX); +@@ -922,10 +902,9 @@ static void lb_nomatch_int_max_m1_used(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHb WWID1\n"); +- will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"); +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHb WWID1\n" ++ "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n" ++ "MPATHa WWID0\n", -1); + mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWID2"); + expect_condlog(0, NOMORE_STR); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); +@@ -938,9 +917,8 @@ static void lb_nomatch_int_max_m1_1_used(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHb WWID1\n"); +- will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHb WWID1\n" ++ "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n", -1); + mock_used_alias("MPATHa", "WWID2"); + mock_unused_alias("MPATH" MPATH_ID_INT_MAX); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); +@@ -954,9 +932,8 @@ static void lb_nomatch_int_max_m1_2_used(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHb WWID1\n"); +- will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHb WWID1\n" ++ "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n", -1); + mock_used_alias("MPATHa", "WWID2"); + mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWID2"); + expect_condlog(0, NOMORE_STR); +@@ -1014,7 +991,7 @@ static void rl_empty(void **state) + char buf[WWID_SIZE]; + + buf[0] = '\0'; +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("", -1); + expect_condlog(3, NOMATCH_STR("MPATHa")); + rc = rlookup_binding(NULL, buf, "MPATHa"); + assert_int_equal(rc, -1); +@@ -1027,7 +1004,7 @@ static void rl_match_a(void **state) + char buf[WWID_SIZE]; + + buf[0] = '\0'; +- will_return(__wrap_fgets, "MPATHa WWID0\n"); ++ mock_bindings_file("MPATHa WWID0\n", 0); + expect_condlog(3, FOUND_ALIAS_STR("MPATHa", "WWID0")); + rc = rlookup_binding(NULL, buf, "MPATHa"); + assert_int_equal(rc, 0); +@@ -1040,8 +1017,7 @@ static void rl_nomatch_a(void **state) + char buf[WWID_SIZE]; + + buf[0] = '\0'; +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHa WWID0\n", -1); + expect_condlog(3, NOMATCH_STR("MPATHb")); + rc = rlookup_binding(NULL, buf, "MPATHb"); + assert_int_equal(rc, -1); +@@ -1054,8 +1030,7 @@ static void rl_malformed_a(void **state) + char buf[WWID_SIZE]; + + buf[0] = '\0'; +- will_return(__wrap_fgets, "MPATHa \n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHa \n", -1); + expect_condlog(3, "Ignoring malformed line 1 in bindings file\n"); + expect_condlog(3, NOMATCH_STR("MPATHa")); + rc = rlookup_binding(NULL, buf, "MPATHa"); +@@ -1074,8 +1049,7 @@ static void rl_overlong_a(void **state) + snprintf(line + sizeof(line) - 2, 2, "\n"); + + buf[0] = '\0'; +- will_return(__wrap_fgets, line); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file(line, -1); + expect_condlog(3, "Ignoring too large wwid at 1 in bindings file\n"); + expect_condlog(3, NOMATCH_STR("MPATHa")); + rc = rlookup_binding(NULL, buf, "MPATHa"); +@@ -1089,9 +1063,9 @@ static void rl_match_b(void **state) + char buf[WWID_SIZE]; + + buf[0] = '\0'; +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, "MPATHz WWID26\n"); +- will_return(__wrap_fgets, "MPATHb WWID2\n"); ++ mock_bindings_file("MPATHa WWID0\n" ++ "MPATHz WWID26\n" ++ "MPATHb WWID2\n", 2); + expect_condlog(3, FOUND_ALIAS_STR("MPATHb", "WWID2")); + rc = rlookup_binding(NULL, buf, "MPATHb"); + assert_int_equal(rc, 0); +@@ -1222,7 +1196,7 @@ static void gufa_empty_new_rw(void **state) { + + will_return(__wrap_open_file, true); + +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("", -1); + mock_unused_alias("MPATHa"); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + +@@ -1235,7 +1209,7 @@ static void gufa_empty_new_rw(void **state) { + static void gufa_empty_new_ro_1(void **state) { + char *alias; + will_return(__wrap_open_file, false); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("", -1); + mock_unused_alias("MPATHa"); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + +@@ -1248,7 +1222,7 @@ static void gufa_empty_new_ro_2(void **state) { + + will_return(__wrap_open_file, true); + +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("", -1); + mock_unused_alias("MPATHa"); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + +@@ -1261,7 +1235,7 @@ static void gufa_match_a_unused(void **state) { + + will_return(__wrap_open_file, true); + +- will_return(__wrap_fgets, BINDING_STR("MPATHa", "WWID0")); ++ mock_bindings_file("MPATHa WWID0", 0); + expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); + mock_unused_alias("MPATHa"); + +@@ -1275,7 +1249,7 @@ static void gufa_match_a_self(void **state) { + + will_return(__wrap_open_file, true); + +- will_return(__wrap_fgets, BINDING_STR("MPATHa", "WWID0")); ++ mock_bindings_file("MPATHa WWID0", 0); + expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); + mock_self_alias("MPATHa", "WWID0"); + +@@ -1289,7 +1263,7 @@ static void gufa_match_a_used(void **state) { + + will_return(__wrap_open_file, true); + +- will_return(__wrap_fgets, BINDING_STR("MPATHa", "WWID0")); ++ mock_bindings_file("MPATHa WWID0", 0); + expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); + mock_used_alias("MPATHa", "WWID0"); + +@@ -1389,11 +1363,11 @@ static void gufa_old_empty(void **state) { + will_return(__wrap_open_file, true); + + /* rlookup_binding for ALIAS */ +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("", -1); + expect_condlog(3, NOMATCH_STR("MPATHz")); + + /* lookup_binding */ +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("", -1); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + + mock_allocate_binding("MPATHz", "WWID0"); diff --git a/0011-libmultipath-add-global-variable-for-current-binding.patch b/0011-libmultipath-add-global-variable-for-current-binding.patch new file mode 100644 index 0000000..c91259d --- /dev/null +++ b/0011-libmultipath-add-global-variable-for-current-binding.patch @@ -0,0 +1,109 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 22 Aug 2023 15:32:17 +0200 +Subject: [PATCH] libmultipath: add global variable for current bindings + +Add a variable global_bindings that holds the currently active vector of +bindings. This variable is freed at program exit. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/alias.c | 11 +++++++++-- + libmultipath/alias.h | 1 + + libmultipath/libmultipath.version | 1 + + multipath/main.c | 2 ++ + multipathd/main.c | 1 + + 5 files changed, 14 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/alias.c b/libmultipath/alias.c +index 9e9ac563..dd363fd8 100644 +--- a/libmultipath/alias.c ++++ b/libmultipath/alias.c +@@ -511,6 +511,7 @@ static void _free_binding(struct binding *bdg) + * an abstract type. + */ + typedef struct _vector Bindings; ++static Bindings global_bindings = { .allocated = 0 }; + + static void free_bindings(Bindings *bindings) + { +@@ -522,6 +523,11 @@ static void free_bindings(Bindings *bindings) + vector_reset(bindings); + } + ++void cleanup_bindings(void) ++{ ++ free_bindings(&global_bindings); ++} ++ + enum { + BINDING_EXISTS, + BINDING_CONFLICT, +@@ -751,7 +757,6 @@ int check_alias_settings(const struct config *conf) + pthread_cleanup_pop(1); + pthread_cleanup_pop(1); + +- pthread_cleanup_push_cast(free_bindings, &bindings); + fd = open_file(conf->bindings_file, &can_write, BINDINGS_FILE_HEADER); + if (fd != -1) { + FILE *file = fdopen(fd, "r"); +@@ -771,6 +776,8 @@ int check_alias_settings(const struct config *conf) + close(fd); + } + } +- pthread_cleanup_pop(1); ++ ++ cleanup_bindings(); ++ global_bindings = bindings; + return rc; + } +diff --git a/libmultipath/alias.h b/libmultipath/alias.h +index fa332233..37b49d9c 100644 +--- a/libmultipath/alias.h ++++ b/libmultipath/alias.h +@@ -9,5 +9,6 @@ char *get_user_friendly_alias(const char *wwid, const char *file, + + struct config; + int check_alias_settings(const struct config *); ++void cleanup_bindings(void); + + #endif /* _ALIAS_H */ +diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version +index a7b8c337..ddd302f5 100644 +--- a/libmultipath/libmultipath.version ++++ b/libmultipath/libmultipath.version +@@ -64,6 +64,7 @@ global: + checker_name; + checker_state_name; + check_foreign; ++ cleanup_bindings; + cleanup_lock; + coalesce_paths; + count_active_paths; +diff --git a/multipath/main.c b/multipath/main.c +index b78f3162..45e9745f 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -843,6 +843,8 @@ main (int argc, char *argv[]) + conf->force_sync = 1; + if (atexit(cleanup_vecs)) + condlog(1, "failed to register cleanup handler for vecs: %m"); ++ if (atexit(cleanup_bindings)) ++ condlog(1, "failed to register cleanup handler for bindings: %m"); + while ((arg = getopt(argc, argv, ":adDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { + switch(arg) { + case 'v': +diff --git a/multipathd/main.c b/multipathd/main.c +index 2e02a548..214ed4ae 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -3325,6 +3325,7 @@ static void cleanup_child(void) + { + cleanup_threads(); + cleanup_vecs(); ++ cleanup_bindings(); + if (poll_dmevents) + cleanup_dmevent_waiter(); + diff --git a/0012-libmultipath-rename-fix_bindings_file-to-update_bind.patch b/0012-libmultipath-rename-fix_bindings_file-to-update_bind.patch new file mode 100644 index 0000000..e0f8673 --- /dev/null +++ b/0012-libmultipath-rename-fix_bindings_file-to-update_bind.patch @@ -0,0 +1,40 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 22 Aug 2023 15:37:15 +0200 +Subject: [PATCH] libmultipath: rename fix_bindings_file() to + update_bindings_file() + +We will use this function in a more generic way, give it a more +generic name. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/alias.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/libmultipath/alias.c b/libmultipath/alias.c +index dd363fd8..0aac2393 100644 +--- a/libmultipath/alias.c ++++ b/libmultipath/alias.c +@@ -595,8 +595,8 @@ static int write_bindings_file(const Bindings *bindings, int fd) + return 0; + } + +-static int fix_bindings_file(const struct config *conf, +- const Bindings *bindings) ++static int update_bindings_file(const struct config *conf, ++ const Bindings *bindings) + { + int rc; + int fd = -1; +@@ -766,7 +766,7 @@ int check_alias_settings(const struct config *conf) + rc = _check_bindings_file(conf, file, &bindings); + pthread_cleanup_pop(1); + if (rc == -1 && can_write && !conf->bindings_read_only) +- rc = fix_bindings_file(conf, &bindings); ++ rc = update_bindings_file(conf, &bindings); + else if (rc == -1) + condlog(0, "ERROR: bad settings in read-only bindings file %s", + conf->bindings_file); diff --git a/0013-libmultipath-alias.c-move-bindings-related-code-up.patch b/0013-libmultipath-alias.c-move-bindings-related-code-up.patch new file mode 100644 index 0000000..1ad7b9e --- /dev/null +++ b/0013-libmultipath-alias.c-move-bindings-related-code-up.patch @@ -0,0 +1,285 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 22 Aug 2023 16:54:54 +0200 +Subject: [PATCH] libmultipath: alias.c: move bindings related code up + +No code changes, just moving code. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/alias.c | 239 ++++++++++++++++++++++--------------------- + 1 file changed, 120 insertions(+), 119 deletions(-) + +diff --git a/libmultipath/alias.c b/libmultipath/alias.c +index 0aac2393..7af403da 100644 +--- a/libmultipath/alias.c ++++ b/libmultipath/alias.c +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + + #include "debug.h" + #include "util.h" +@@ -51,6 +52,125 @@ + + static const char bindings_file_header[] = BINDINGS_FILE_HEADER; + ++struct binding { ++ char *alias; ++ char *wwid; ++}; ++ ++/* ++ * Perhaps one day we'll implement this more efficiently, thus use ++ * an abstract type. ++ */ ++typedef struct _vector Bindings; ++static Bindings global_bindings = { .allocated = 0 }; ++ ++enum { ++ BINDING_EXISTS, ++ BINDING_CONFLICT, ++ BINDING_ADDED, ++ BINDING_DELETED, ++ BINDING_NOTFOUND, ++ BINDING_ERROR, ++}; ++ ++static void _free_binding(struct binding *bdg) ++{ ++ free(bdg->wwid); ++ free(bdg->alias); ++ free(bdg); ++} ++ ++static int add_binding(Bindings *bindings, const char *alias, const char *wwid) ++{ ++ struct binding *bdg; ++ int i, cmp = 0; ++ ++ /* ++ * Keep the bindings array sorted by alias. ++ * Optimization: Search backwards, assuming that the bindings file is ++ * sorted already. ++ */ ++ vector_foreach_slot_backwards(bindings, bdg, i) { ++ if ((cmp = strcmp(bdg->alias, alias)) <= 0) ++ break; ++ } ++ ++ /* Check for exact match */ ++ if (i >= 0 && cmp == 0) ++ return strcmp(bdg->wwid, wwid) ? ++ BINDING_CONFLICT : BINDING_EXISTS; ++ ++ i++; ++ bdg = calloc(1, sizeof(*bdg)); ++ if (bdg) { ++ bdg->wwid = strdup(wwid); ++ bdg->alias = strdup(alias); ++ if (bdg->wwid && bdg->alias && ++ vector_insert_slot(bindings, i, bdg)) ++ return BINDING_ADDED; ++ else ++ _free_binding(bdg); ++ } ++ ++ return BINDING_ERROR; ++} ++ ++static int write_bindings_file(const Bindings *bindings, int fd) ++{ ++ struct binding *bnd; ++ STRBUF_ON_STACK(line); ++ int i; ++ ++ if (write(fd, BINDINGS_FILE_HEADER, sizeof(BINDINGS_FILE_HEADER) - 1) ++ != sizeof(BINDINGS_FILE_HEADER) - 1) ++ return -1; ++ ++ vector_foreach_slot(bindings, bnd, i) { ++ int len; ++ ++ if ((len = print_strbuf(&line, "%s %s\n", ++ bnd->alias, bnd->wwid)) < 0) ++ return -1; ++ if (write(fd, get_strbuf_str(&line), len) != len) ++ return -1; ++ truncate_strbuf(&line, 0); ++ } ++ return 0; ++} ++ ++static int update_bindings_file(const struct config *conf, ++ const Bindings *bindings) ++{ ++ int rc; ++ int fd = -1; ++ char tempname[PATH_MAX]; ++ mode_t old_umask; ++ ++ if (safe_sprintf(tempname, "%s.XXXXXX", conf->bindings_file)) ++ return -1; ++ /* coverity: SECURE_TEMP */ ++ old_umask = umask(0077); ++ if ((fd = mkstemp(tempname)) == -1) { ++ condlog(1, "%s: mkstemp: %m", __func__); ++ return -1; ++ } ++ umask(old_umask); ++ pthread_cleanup_push(cleanup_fd_ptr, &fd); ++ rc = write_bindings_file(bindings, fd); ++ pthread_cleanup_pop(1); ++ if (rc == -1) { ++ condlog(1, "failed to write new bindings file %s", ++ tempname); ++ unlink(tempname); ++ return rc; ++ } ++ if ((rc = rename(tempname, conf->bindings_file)) == -1) ++ condlog(0, "%s: rename: %m", __func__); ++ else ++ condlog(1, "updated bindings file %s", conf->bindings_file); ++ return rc; ++} ++ + int + valid_alias(const char *alias) + { +@@ -494,25 +614,6 @@ get_user_friendly_wwid(const char *alias, char *buff, const char *file) + return 0; + } + +-struct binding { +- char *alias; +- char *wwid; +-}; +- +-static void _free_binding(struct binding *bdg) +-{ +- free(bdg->wwid); +- free(bdg->alias); +- free(bdg); +-} +- +-/* +- * Perhaps one day we'll implement this more efficiently, thus use +- * an abstract type. +- */ +-typedef struct _vector Bindings; +-static Bindings global_bindings = { .allocated = 0 }; +- + static void free_bindings(Bindings *bindings) + { + struct binding *bdg; +@@ -528,106 +629,6 @@ void cleanup_bindings(void) + free_bindings(&global_bindings); + } + +-enum { +- BINDING_EXISTS, +- BINDING_CONFLICT, +- BINDING_ADDED, +- BINDING_DELETED, +- BINDING_NOTFOUND, +- BINDING_ERROR, +-}; +- +-static int add_binding(Bindings *bindings, const char *alias, const char *wwid) +-{ +- struct binding *bdg; +- int i, cmp = 0; +- +- /* +- * Keep the bindings array sorted by alias. +- * Optimization: Search backwards, assuming that the bindings file is +- * sorted already. +- */ +- vector_foreach_slot_backwards(bindings, bdg, i) { +- if ((cmp = strcmp(bdg->alias, alias)) <= 0) +- break; +- } +- +- /* Check for exact match */ +- if (i >= 0 && cmp == 0) +- return strcmp(bdg->wwid, wwid) ? +- BINDING_CONFLICT : BINDING_EXISTS; +- +- i++; +- bdg = calloc(1, sizeof(*bdg)); +- if (bdg) { +- bdg->wwid = strdup(wwid); +- bdg->alias = strdup(alias); +- if (bdg->wwid && bdg->alias && +- vector_insert_slot(bindings, i, bdg)) +- return BINDING_ADDED; +- else +- _free_binding(bdg); +- } +- +- return BINDING_ERROR; +-} +- +-static int write_bindings_file(const Bindings *bindings, int fd) +-{ +- struct binding *bnd; +- STRBUF_ON_STACK(line); +- int i; +- +- if (write(fd, BINDINGS_FILE_HEADER, sizeof(BINDINGS_FILE_HEADER) - 1) +- != sizeof(BINDINGS_FILE_HEADER) - 1) +- return -1; +- +- vector_foreach_slot(bindings, bnd, i) { +- int len; +- +- if ((len = print_strbuf(&line, "%s %s\n", +- bnd->alias, bnd->wwid)) < 0) +- return -1; +- if (write(fd, get_strbuf_str(&line), len) != len) +- return -1; +- truncate_strbuf(&line, 0); +- } +- return 0; +-} +- +-static int update_bindings_file(const struct config *conf, +- const Bindings *bindings) +-{ +- int rc; +- int fd = -1; +- char tempname[PATH_MAX]; +- mode_t old_umask; +- +- if (safe_sprintf(tempname, "%s.XXXXXX", conf->bindings_file)) +- return -1; +- /* coverity: SECURE_TEMP */ +- old_umask = umask(0077); +- if ((fd = mkstemp(tempname)) == -1) { +- condlog(1, "%s: mkstemp: %m", __func__); +- return -1; +- } +- umask(old_umask); +- pthread_cleanup_push(cleanup_fd_ptr, &fd); +- rc = write_bindings_file(bindings, fd); +- pthread_cleanup_pop(1); +- if (rc == -1) { +- condlog(1, "failed to write new bindings file %s", +- tempname); +- unlink(tempname); +- return rc; +- } +- if ((rc = rename(tempname, conf->bindings_file)) == -1) +- condlog(0, "%s: rename: %m", __func__); +- else +- condlog(1, "updated bindings file %s", conf->bindings_file); +- return rc; +-} +- + static int _check_bindings_file(const struct config *conf, FILE *file, + Bindings *bindings) + { diff --git a/0014-libmultipath-update_bindings_file-take-filename-argu.patch b/0014-libmultipath-update_bindings_file-take-filename-argu.patch new file mode 100644 index 0000000..6b9d2e8 --- /dev/null +++ b/0014-libmultipath-update_bindings_file-take-filename-argu.patch @@ -0,0 +1,61 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 24 Aug 2023 15:53:49 +0200 +Subject: [PATCH] libmultipath: update_bindings_file: take filename argument + +This function just uses the file name, no other configuration +parameters. Also, pass the Bindings argument first to use the +same convention as the other functions in this file. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/alias.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/libmultipath/alias.c b/libmultipath/alias.c +index 7af403da..9bd3875e 100644 +--- a/libmultipath/alias.c ++++ b/libmultipath/alias.c +@@ -138,15 +138,15 @@ static int write_bindings_file(const Bindings *bindings, int fd) + return 0; + } + +-static int update_bindings_file(const struct config *conf, +- const Bindings *bindings) ++static int update_bindings_file(const Bindings *bindings, ++ const char *bindings_file) + { + int rc; + int fd = -1; + char tempname[PATH_MAX]; + mode_t old_umask; + +- if (safe_sprintf(tempname, "%s.XXXXXX", conf->bindings_file)) ++ if (safe_sprintf(tempname, "%s.XXXXXX", bindings_file)) + return -1; + /* coverity: SECURE_TEMP */ + old_umask = umask(0077); +@@ -164,10 +164,10 @@ static int update_bindings_file(const struct config *conf, + unlink(tempname); + return rc; + } +- if ((rc = rename(tempname, conf->bindings_file)) == -1) ++ if ((rc = rename(tempname, bindings_file)) == -1) + condlog(0, "%s: rename: %m", __func__); + else +- condlog(1, "updated bindings file %s", conf->bindings_file); ++ condlog(1, "updated bindings file %s", bindings_file); + return rc; + } + +@@ -767,7 +767,7 @@ int check_alias_settings(const struct config *conf) + rc = _check_bindings_file(conf, file, &bindings); + pthread_cleanup_pop(1); + if (rc == -1 && can_write && !conf->bindings_read_only) +- rc = update_bindings_file(conf, &bindings); ++ rc = update_bindings_file(&bindings, conf->bindings_file); + else if (rc == -1) + condlog(0, "ERROR: bad settings in read-only bindings file %s", + conf->bindings_file); diff --git a/0015-libmultipath-update_bindings_file-use-a-single-write.patch b/0015-libmultipath-update_bindings_file-use-a-single-write.patch new file mode 100644 index 0000000..1e1fd15 --- /dev/null +++ b/0015-libmultipath-update_bindings_file-use-a-single-write.patch @@ -0,0 +1,59 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 24 Aug 2023 15:54:45 +0200 +Subject: [PATCH] libmultipath: update_bindings_file: use a single write() + +Save code and syscalls by assembling the content in memory first. +write() may return less bytes written than expected. Deal with it. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/alias.c | 26 +++++++++++++++++--------- + 1 file changed, 17 insertions(+), 9 deletions(-) + +diff --git a/libmultipath/alias.c b/libmultipath/alias.c +index 9bd3875e..92f90f05 100644 +--- a/libmultipath/alias.c ++++ b/libmultipath/alias.c +@@ -118,22 +118,30 @@ static int add_binding(Bindings *bindings, const char *alias, const char *wwid) + static int write_bindings_file(const Bindings *bindings, int fd) + { + struct binding *bnd; +- STRBUF_ON_STACK(line); ++ STRBUF_ON_STACK(content); + int i; ++ size_t len; + +- if (write(fd, BINDINGS_FILE_HEADER, sizeof(BINDINGS_FILE_HEADER) - 1) +- != sizeof(BINDINGS_FILE_HEADER) - 1) ++ if (__append_strbuf_str(&content, BINDINGS_FILE_HEADER, ++ sizeof(BINDINGS_FILE_HEADER) - 1) == -1) + return -1; + + vector_foreach_slot(bindings, bnd, i) { +- int len; +- +- if ((len = print_strbuf(&line, "%s %s\n", +- bnd->alias, bnd->wwid)) < 0) ++ if (print_strbuf(&content, "%s %s\n", ++ bnd->alias, bnd->wwid) < 0) + return -1; +- if (write(fd, get_strbuf_str(&line), len) != len) ++ } ++ len = get_strbuf_len(&content); ++ while (len > 0) { ++ ssize_t n = write(fd, get_strbuf_str(&content), len); ++ ++ if (n < 0) ++ return n; ++ else if (n == 0) { ++ condlog(2, "%s: short write", __func__); + return -1; +- truncate_strbuf(&line, 0); ++ } ++ len -= n; + } + return 0; + } diff --git a/0016-libmultipath-update_bindings_file-don-t-log-temp-fil.patch b/0016-libmultipath-update_bindings_file-don-t-log-temp-fil.patch new file mode 100644 index 0000000..1126b95 --- /dev/null +++ b/0016-libmultipath-update_bindings_file-don-t-log-temp-fil.patch @@ -0,0 +1,29 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 24 Aug 2023 22:33:39 +0200 +Subject: [PATCH] libmultipath: update_bindings_file: don't log temp file name + +The name of the temp file is unlikely to be helpful for users, +and hard to predict in the unit test. Omit it. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/alias.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/libmultipath/alias.c b/libmultipath/alias.c +index 92f90f05..afa5879e 100644 +--- a/libmultipath/alias.c ++++ b/libmultipath/alias.c +@@ -167,8 +167,7 @@ static int update_bindings_file(const Bindings *bindings, + rc = write_bindings_file(bindings, fd); + pthread_cleanup_pop(1); + if (rc == -1) { +- condlog(1, "failed to write new bindings file %s", +- tempname); ++ condlog(1, "failed to write new bindings file"); + unlink(tempname); + return rc; + } diff --git a/0017-libmultipath-alias.c-factor-out-read_binding.patch b/0017-libmultipath-alias.c-factor-out-read_binding.patch new file mode 100644 index 0000000..8c9cb08 --- /dev/null +++ b/0017-libmultipath-alias.c-factor-out-read_binding.patch @@ -0,0 +1,94 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 24 Aug 2023 21:17:25 +0200 +Subject: [PATCH] libmultipath: alias.c: factor out read_binding() + +This way we can test the parsing of input lines from the bindings +file more easily. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/alias.c | 58 ++++++++++++++++++++++++++++++-------------- + 1 file changed, 40 insertions(+), 18 deletions(-) + +diff --git a/libmultipath/alias.c b/libmultipath/alias.c +index afa5879e..ecf4a2ac 100644 +--- a/libmultipath/alias.c ++++ b/libmultipath/alias.c +@@ -636,6 +636,43 @@ void cleanup_bindings(void) + free_bindings(&global_bindings); + } + ++enum { ++ READ_BINDING_OK, ++ READ_BINDING_SKIP, ++}; ++ ++static int read_binding(char *line, unsigned int linenr, char **alias, ++ char **wwid) { ++ char *c, *saveptr; ++ ++ c = strpbrk(line, "#\n\r"); ++ if (c) ++ *c = '\0'; ++ ++ *alias = strtok_r(line, " \t", &saveptr); ++ if (!*alias) /* blank line */ ++ return READ_BINDING_SKIP; ++ ++ *wwid = strtok_r(NULL, " \t", &saveptr); ++ if (!*wwid) { ++ condlog(1, "invalid line %u in bindings file, missing WWID", ++ linenr); ++ return READ_BINDING_SKIP; ++ } ++ if (strlen(*wwid) > WWID_SIZE - 1) { ++ condlog(3, ++ "Ignoring too large wwid at %u in bindings file", ++ linenr); ++ return READ_BINDING_SKIP; ++ } ++ c = strtok_r(NULL, " \t", &saveptr); ++ if (c) ++ /* This is non-fatal */ ++ condlog(1, "invalid line %d in bindings file, extra args \"%s\"", ++ linenr, c); ++ return READ_BINDING_OK; ++} ++ + static int _check_bindings_file(const struct config *conf, FILE *file, + Bindings *bindings) + { +@@ -647,27 +684,12 @@ static int _check_bindings_file(const struct config *conf, FILE *file, + + pthread_cleanup_push(cleanup_free_ptr, &line); + while ((n = getline(&line, &line_len, file)) >= 0) { +- char *c, *alias, *wwid, *saveptr; ++ char *alias, *wwid; + const char *mpe_wwid; + +- linenr++; +- c = strpbrk(line, "#\n\r"); +- if (c) +- *c = '\0'; +- alias = strtok_r(line, " \t", &saveptr); +- if (!alias) /* blank line */ +- continue; +- wwid = strtok_r(NULL, " \t", &saveptr); +- if (!wwid) { +- condlog(1, "invalid line %d in bindings file, missing WWID", +- linenr); ++ if (read_binding(line, ++linenr, &alias, &wwid) ++ == READ_BINDING_SKIP) + continue; +- } +- c = strtok_r(NULL, " \t", &saveptr); +- if (c) +- /* This is non-fatal */ +- condlog(1, "invalid line %d in bindings file, extra args \"%s\"", +- linenr, c); + + mpe_wwid = get_mpe_wwid(conf->mptable, alias); + if (mpe_wwid && strcmp(mpe_wwid, wwid)) { diff --git a/0018-libmultipath-keep-bindings-in-memory.patch b/0018-libmultipath-keep-bindings-in-memory.patch new file mode 100644 index 0000000..bb26ea2 --- /dev/null +++ b/0018-libmultipath-keep-bindings-in-memory.patch @@ -0,0 +1,545 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 22 Aug 2023 21:14:51 +0200 +Subject: [PATCH] libmultipath: keep bindings in memory + +Rather than opening the bindings file every time we must retrieve +a binding, keep the contents in memory and write the file only +if additions have been made. This simplifies the code, and should speed up +alias lookups significantly. As a side effect, the aliases will be stored +sorted by alias, which changes the way aliases are allocated if there are +unused "holes" in the sequence of aliases. For example, if the bindings file +contains mpathb, mpathy, and mpatha, in this order, the next new alias used to +be mpathz and is now mpathc. + +Another side effect is that multipathd will not automatically pick up changes +to the bindings file at runtime without a reconfigure operation. It is +questionable whether these on-the-fly changes were a good idea in the first +place, as inconsistent configurations may easily come to pass. It desired, +it would be feasible to implement automatic update of the bindings using the +existing inotify approach. + +The new implementation of get_user_friendly_alias() is slightly different +than before. The logic is summarized in a comment in the code. Unit tests +will be provided that illustrate the changes. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/alias.c | 351 ++++++++++++++++----------------------- + libmultipath/alias.h | 2 +- + libmultipath/configure.c | 3 +- + 3 files changed, 144 insertions(+), 212 deletions(-) + +diff --git a/libmultipath/alias.c b/libmultipath/alias.c +index ecf4a2ac..d6563749 100644 +--- a/libmultipath/alias.c ++++ b/libmultipath/alias.c +@@ -50,8 +50,6 @@ + "# alias wwid\n" \ + "#\n" + +-static const char bindings_file_header[] = BINDINGS_FILE_HEADER; +- + struct binding { + char *alias; + char *wwid; +@@ -80,6 +78,45 @@ static void _free_binding(struct binding *bdg) + free(bdg); + } + ++static const struct binding *get_binding_for_alias(const Bindings *bindings, ++ const char *alias) ++{ ++ const struct binding *bdg; ++ int i; ++ ++ if (!alias) ++ return NULL; ++ vector_foreach_slot(bindings, bdg, i) { ++ if (!strncmp(bdg->alias, alias, WWID_SIZE)) { ++ condlog(3, "Found matching alias [%s] in bindings file." ++ " Setting wwid to %s", alias, bdg->wwid); ++ return bdg; ++ } ++ } ++ ++ condlog(3, "No matching alias [%s] in bindings file.", alias); ++ return NULL; ++} ++ ++static const struct binding *get_binding_for_wwid(const Bindings *bindings, ++ const char *wwid) ++{ ++ const struct binding *bdg; ++ int i; ++ ++ if (!wwid) ++ return NULL; ++ vector_foreach_slot(bindings, bdg, i) { ++ if (!strncmp(bdg->wwid, wwid, WWID_SIZE)) { ++ condlog(3, "Found matching wwid [%s] in bindings file." ++ " Setting alias to %s", wwid, bdg->alias); ++ return bdg; ++ } ++ } ++ condlog(3, "No matching wwid [%s] in bindings file.", wwid); ++ return NULL; ++} ++ + static int add_binding(Bindings *bindings, const char *alias, const char *wwid) + { + struct binding *bdg; +@@ -115,6 +152,24 @@ static int add_binding(Bindings *bindings, const char *alias, const char *wwid) + return BINDING_ERROR; + } + ++static int delete_binding(Bindings *bindings, const char *wwid) ++{ ++ struct binding *bdg; ++ int i; ++ ++ vector_foreach_slot(bindings, bdg, i) { ++ if (!strncmp(bdg->wwid, wwid, WWID_SIZE)) { ++ _free_binding(bdg); ++ break; ++ } ++ } ++ if (i >= VECTOR_SIZE(bindings)) ++ return BINDING_NOTFOUND; ++ ++ vector_del_slot(bindings, i); ++ return BINDING_DELETED; ++} ++ + static int write_bindings_file(const Bindings *bindings, int fd) + { + struct binding *bnd; +@@ -267,38 +322,15 @@ static bool id_already_taken(int id, const char *prefix, const char *map_wwid) + return alias_already_taken(alias, map_wwid); + } + +-/* +- * Returns: 0 if matching entry in WWIDs file found +- * -1 if an error occurs +- * >0 a free ID that could be used for the WWID at hand +- * *map_alias is set to a freshly allocated string with the matching alias if +- * the function returns 0, or to NULL otherwise. +- */ +-static int +-lookup_binding(FILE *f, const char *map_wwid, char **map_alias, +- const char *prefix, int check_if_taken) ++int get_free_id(const Bindings *bindings, const char *prefix, const char *map_wwid) + { +- char buf[LINE_MAX]; +- unsigned int line_nr = 0; +- int id = 1; ++ const struct binding *bdg; ++ int i, id = 1; + int biggest_id = 1; + int smallest_bigger_id = INT_MAX; + +- *map_alias = NULL; +- +- rewind(f); +- while (fgets(buf, LINE_MAX, f)) { +- const char *alias, *wwid; +- char *c, *saveptr; +- int curr_id; +- +- line_nr++; +- c = strpbrk(buf, "#\n\r"); +- if (c) +- *c = '\0'; +- alias = strtok_r(buf, " \t", &saveptr); +- if (!alias) /* blank line */ +- continue; ++ vector_foreach_slot(bindings, bdg, i) { ++ int curr_id = scan_devname(bdg->alias, prefix); + + /* + * Find an unused index - explanation of the algorithm +@@ -333,8 +365,6 @@ lookup_binding(FILE *f, const char *map_wwid, char **map_alias, + * biggest_id is always > smallest_bigger_id, except in the + * "perfectly ordered" case. + */ +- +- curr_id = scan_devname(alias, prefix); + if (curr_id == id) { + if (id < INT_MAX) + id++; +@@ -345,36 +375,15 @@ lookup_binding(FILE *f, const char *map_wwid, char **map_alias, + } + if (curr_id > biggest_id) + biggest_id = curr_id; ++ + if (curr_id > id && curr_id < smallest_bigger_id) + smallest_bigger_id = curr_id; +- wwid = strtok_r(NULL, " \t", &saveptr); +- if (!wwid){ +- condlog(3, +- "Ignoring malformed line %u in bindings file", +- line_nr); +- continue; +- } +- if (strcmp(wwid, map_wwid) == 0){ +- condlog(3, "Found matching wwid [%s] in bindings file." +- " Setting alias to %s", wwid, alias); +- *map_alias = strdup(alias); +- if (*map_alias == NULL) { +- condlog(0, "Cannot copy alias from bindings " +- "file: out of memory"); +- return -1; +- } +- return 0; +- } +- } +- if (!prefix && check_if_taken) +- id = -1; +- if (id >= smallest_bigger_id) { +- if (biggest_id < INT_MAX) +- id = biggest_id + 1; +- else +- id = -1; + } +- if (id > 0 && check_if_taken) { ++ ++ if (id >= smallest_bigger_id) ++ id = biggest_id < INT_MAX ? biggest_id + 1 : -1; ++ ++ if (id > 0) { + while(id_already_taken(id, prefix, map_wwid)) { + if (id == INT_MAX) { + id = -1; +@@ -391,64 +400,17 @@ lookup_binding(FILE *f, const char *map_wwid, char **map_alias, + } + } + } +- if (id < 0) { ++ ++ if (id < 0) + condlog(0, "no more available user_friendly_names"); +- return -1; +- } else +- condlog(3, "No matching wwid [%s] in bindings file.", map_wwid); + return id; + } + +-static int +-rlookup_binding(FILE *f, char *buff, const char *map_alias) +-{ +- char line[LINE_MAX]; +- unsigned int line_nr = 0; +- +- buff[0] = '\0'; +- +- while (fgets(line, LINE_MAX, f)) { +- char *c, *saveptr; +- const char *alias, *wwid; +- +- line_nr++; +- c = strpbrk(line, "#\n\r"); +- if (c) +- *c = '\0'; +- alias = strtok_r(line, " \t", &saveptr); +- if (!alias) /* blank line */ +- continue; +- wwid = strtok_r(NULL, " \t", &saveptr); +- if (!wwid){ +- condlog(3, +- "Ignoring malformed line %u in bindings file", +- line_nr); +- continue; +- } +- if (strlen(wwid) > WWID_SIZE - 1) { +- condlog(3, +- "Ignoring too large wwid at %u in bindings file", line_nr); +- continue; +- } +- if (strcmp(alias, map_alias) == 0){ +- condlog(3, "Found matching alias [%s] in bindings file." +- " Setting wwid to %s", alias, wwid); +- strlcpy(buff, wwid, WWID_SIZE); +- return 0; +- } +- } +- condlog(3, "No matching alias [%s] in bindings file.", map_alias); +- +- return -1; +-} +- + static char * +-allocate_binding(int fd, const char *wwid, int id, const char *prefix) ++allocate_binding(const char *filename, const char *wwid, int id, const char *prefix) + { + STRBUF_ON_STACK(buf); +- off_t offset; +- ssize_t len; +- char *alias, *c; ++ char *alias; + + if (id <= 0) { + condlog(0, "%s: cannot allocate new binding for id %d", +@@ -460,164 +422,135 @@ allocate_binding(int fd, const char *wwid, int id, const char *prefix) + format_devname(&buf, id) == -1) + return NULL; + +- if (print_strbuf(&buf, " %s\n", wwid) < 0) +- return NULL; ++ alias = steal_strbuf_str(&buf); + +- offset = lseek(fd, 0, SEEK_END); +- if (offset < 0){ +- condlog(0, "Cannot seek to end of bindings file : %s", +- strerror(errno)); ++ if (add_binding(&global_bindings, alias, wwid) != BINDING_ADDED) { ++ condlog(0, "%s: cannot allocate new binding %s for %s", ++ __func__, alias, wwid); ++ free(alias); + return NULL; + } + +- len = get_strbuf_len(&buf); +- alias = steal_strbuf_str(&buf); +- +- if (write(fd, alias, len) != len) { +- condlog(0, "Cannot write binding to bindings file : %s", +- strerror(errno)); +- /* clear partial write */ +- if (ftruncate(fd, offset)) +- condlog(0, "Cannot truncate the header : %s", +- strerror(errno)); ++ if (update_bindings_file(&global_bindings, filename) == -1) { ++ condlog(1, "%s: deleting binding %s for %s", __func__, alias, wwid); ++ delete_binding(&global_bindings, wwid); + free(alias); + return NULL; + } +- c = strchr(alias, ' '); +- if (c) +- *c = '\0'; + + condlog(3, "Created new binding [%s] for WWID [%s]", alias, wwid); + return alias; + } + ++/* ++ * get_user_friendly_alias() action table ++ * ++ * The table shows the various cases, the actions taken, and the CI ++ * functions from tests/alias.c that represent them. ++ * ++ * - O: old alias given ++ * - A: old alias in table (y: yes, correct WWID; X: yes, wrong WWID) ++ * - W: wwid in table ++ * ++ * | No | O | A | W | action | function gufa_X | ++ * |----+---+---+---+--------------------------------------------+------------------------------| ++ * | 1 | n | - | n | get new alias | nomatch_Y | ++ * | 2 | n | - | y | use alias from bindings | match_a_Y | ++ * | 3 | y | n | n | add binding for old alias | old_nomatch_nowwidmatch | ++ * | 4 | y | n | y | use alias from bindings (avoid duplicates) | old_nomatch_wwidmatch | ++ * | 5 | y | y | n | [ impossible ] | - | ++ * | 6 | y | y | y | use old alias == alias from bindings | old_match | ++ * | 7 | y | X | n | get new alias | old_match_other | ++ * | 8 | y | X | y | use alias from bindings | old_match_other_wwidmatch | ++ * ++ * Notes: ++ * - "use alias from bindings" means that the alias from the bindings file will ++ * be tried; if it is in use, the alias selection will fail. No other ++ * bindings will be attempted. ++ * - "get new alias" fails if all aliases are used up, or if writing the ++ * bindings file fails. ++ * - if "alias_old" is set, it can't be bound to a different map. alias_old is ++ * initialized in find_existing_alias() by scanning the mpvec. We trust ++ * that the mpvec corrcectly represents kernel state. ++ */ ++ + char *get_user_friendly_alias(const char *wwid, const char *file, const char *alias_old, + const char *prefix, bool bindings_read_only) + { + char *alias = NULL; + int id = 0; +- int fd, can_write; + bool new_binding = false; +- char buff[WWID_SIZE]; +- FILE *f; +- +- fd = open_file(file, &can_write, bindings_file_header); +- if (fd < 0) +- return NULL; +- +- f = fdopen(fd, "r"); +- if (!f) { +- condlog(0, "cannot fdopen on bindings file descriptor"); +- close(fd); +- return NULL; +- } ++ const struct binding *bdg; + +- if (!strlen(alias_old)) ++ if (!*alias_old) + goto new_alias; + +- /* lookup the binding. if it exists, the wwid will be in buff +- * either way, id contains the id for the alias +- */ +- rlookup_binding(f, buff, alias_old); +- +- if (strlen(buff) > 0) { +- /* If buff is our wwid, it's already allocated correctly. */ +- if (strcmp(buff, wwid) == 0) { ++ /* See if there's a binding matching both alias_old and wwid */ ++ bdg = get_binding_for_alias(&global_bindings, alias_old); ++ if (bdg) { ++ if (!strcmp(bdg->wwid, wwid)) { + alias = strdup(alias_old); + goto out; +- + } else { + condlog(0, "alias %s already bound to wwid %s, cannot reuse", +- alias_old, buff); ++ alias_old, bdg->wwid); + goto new_alias; + } + } + +- /* +- * Look for an existing alias in the bindings file. +- * Pass prefix = NULL, so lookup_binding() won't try to allocate a new id. +- */ +- lookup_binding(f, wwid, &alias, NULL, 0); +- if (alias) { +- if (alias_already_taken(alias, wwid)) { +- free(alias); +- alias = NULL; +- } else ++ /* allocate the existing alias in the bindings file */ ++ id = scan_devname(alias_old, prefix); ++ ++new_alias: ++ /* Check for existing binding of WWID */ ++ bdg = get_binding_for_wwid(&global_bindings, wwid); ++ if (bdg) { ++ if (!alias_already_taken(bdg->alias, wwid)) { + condlog(3, "Use existing binding [%s] for WWID [%s]", +- alias, wwid); ++ bdg->alias, wwid); ++ alias = strdup(bdg->alias); ++ } + goto out; + } + +- /* alias_old is already taken by our WWID, update bindings file. */ +- id = scan_devname(alias_old, prefix); +- +-new_alias: + if (id <= 0) { + /* + * no existing alias was provided, or allocating it + * failed. Try a new one. + */ +- id = lookup_binding(f, wwid, &alias, prefix, 1); +- if (id == 0 && alias_already_taken(alias, wwid)) { +- free(alias); +- alias = NULL; +- } ++ id = get_free_id(&global_bindings, prefix, wwid); + if (id <= 0) + goto out; + else + new_binding = true; + } + +- if (fflush(f) != 0) { +- condlog(0, "cannot fflush bindings file stream : %s", +- strerror(errno)); +- goto out; +- } ++ if (!bindings_read_only && id > 0) ++ alias = allocate_binding(file, wwid, id, prefix); + +- if (can_write && !bindings_read_only) { +- alias = allocate_binding(fd, wwid, id, prefix); +- if (alias && !new_binding) +- condlog(2, "Allocated existing binding [%s] for WWID [%s]", +- alias, wwid); +- } ++ if (alias && !new_binding) ++ condlog(2, "Allocated existing binding [%s] for WWID [%s]", ++ alias, wwid); + + out: +- pthread_cleanup_push(free, alias); +- fclose(f); +- pthread_cleanup_pop(0); + return alias; + } + +-int +-get_user_friendly_wwid(const char *alias, char *buff, const char *file) ++int get_user_friendly_wwid(const char *alias, char *buff) + { +- int fd, unused; +- FILE *f; ++ const struct binding *bdg; + + if (!alias || *alias == '\0') { + condlog(3, "Cannot find binding for empty alias"); + return -1; + } + +- fd = open_file(file, &unused, bindings_file_header); +- if (fd < 0) +- return -1; +- +- f = fdopen(fd, "r"); +- if (!f) { +- condlog(0, "cannot fdopen on bindings file descriptor : %s", +- strerror(errno)); +- close(fd); ++ bdg = get_binding_for_alias(&global_bindings, alias); ++ if (!bdg) { ++ *buff = '\0'; + return -1; + } +- +- rlookup_binding(f, buff, alias); +- if (!strlen(buff)) { +- fclose(f); +- return -1; +- } +- +- fclose(f); ++ strlcpy(buff, bdg->wwid, WWID_SIZE); + return 0; + } + +diff --git a/libmultipath/alias.h b/libmultipath/alias.h +index 37b49d9c..5ef6720b 100644 +--- a/libmultipath/alias.h ++++ b/libmultipath/alias.h +@@ -2,7 +2,7 @@ + #define _ALIAS_H + + int valid_alias(const char *alias); +-int get_user_friendly_wwid(const char *alias, char *buff, const char *file); ++int get_user_friendly_wwid(const char *alias, char *buff); + char *get_user_friendly_alias(const char *wwid, const char *file, + const char *alias_old, + const char *prefix, bool bindings_read_only); +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index 029fbbd2..d8094903 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -1378,8 +1378,7 @@ static int _get_refwwid(enum mpath_cmds cmd, const char *dev, + refwwid = tmpwwid; + + /* or may be a binding */ +- else if (get_user_friendly_wwid(dev, tmpwwid, +- conf->bindings_file) == 0) ++ else if (get_user_friendly_wwid(dev, tmpwwid) == 0) + refwwid = tmpwwid; + + /* or may be an alias */ diff --git a/0019-multipath-tools-tests-fix-alias-tests.patch b/0019-multipath-tools-tests-fix-alias-tests.patch new file mode 100644 index 0000000..da618f6 --- /dev/null +++ b/0019-multipath-tools-tests-fix-alias-tests.patch @@ -0,0 +1,1698 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 25 Aug 2023 17:55:55 +0200 +Subject: [PATCH] multipath-tools tests: fix alias tests + +The different implementation of get_user_friendly_alias() and its helpers +necessitates changes in the unit tests. It would be nice if it didn't, but the +unit tests are too closely bound to the implementation to make this possible. + +- The bindings table is held in memory in alphabetically sorted order, which + may change the result of looking for free alias IDs if the entries in the + bindings file were unordered initially. In particular, if only a small + number of bindings exists, "holes" in the file will be detected more easily. + But because the sort order of the aliases differs from simple alphabetic + sorting ("mpathz" precedes "mpathaa"), a bindings file that contains all + bindings from "a" to "aa" (or more) will appear unsorted. + As an extra check, some of the unit tests deliberately use a different + implementation of add_binding() that does not order the bindings + table. + +- Broken lines in the bindings file never make it to the in-memory + representation. An alias that appeard "used" because it occurred in a broken + line will not appear used any more. Warnings about malformed lines will only + be printed while the bindings file is read, not from get_user_friendly_alias(). + +- The match_line argument of mock_bindings_file() is obsolete. + +- lookup_binding() and rlookup_binding() have been removed from + libmultipath. They are now emulated in the unit test code. + +- lookup_binding() didn't check for used alias in all cases previously, but it does now. + +- prefix != NULL and check_if_taken == false is not supported any more + in lookup_binding(). + +- allocate_binding() uses a very different sequence of systems calls now, as + it's implemented using update_bindings_file(). In particular, it's now more + difficult to predict the content of the write() call that creates the + bindings file. See comments for __wrap_write(). + +- some unit tests for get_user_friendly_alias() had to call + mock_bindings_file() twice, because the old implementation would read the + file twice (first rlookup_binding() and then lookup_binding()). This is not + necessary any more. + +- The unit tests need a teardown function to clear the bindings table in memory. + +- Minor changes are necessary because of changed ordering of the log messages. + Previously, lookup_binding() combined check for an existing entry and the + search for a new ID. The new algorithm does this in two separate steps and + tests for used aliases in between, which causes a change in the order in which + log messages are emitted. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + tests/alias.c | 957 ++++++++++++++++++++++++++++++++------------------ + 1 file changed, 614 insertions(+), 343 deletions(-) + +diff --git a/tests/alias.c b/tests/alias.c +index f334f928..50a21ecf 100644 +--- a/tests/alias.c ++++ b/tests/alias.c +@@ -3,10 +3,12 @@ + #include + #include + #include ++#include "strbuf.h" + #include "util.h" + #include "alias.h" + #include "test-log.h" + #include ++#include + + #include "globals.c" + #include "../libmultipath/alias.c" +@@ -20,18 +22,6 @@ + #define MPATH_ID_INT_MAX_p1 "fxshrxx" + #endif + +-void __wrap_rewind(FILE *stream) +-{} +- +-char *__wrap_fgets(char *buf, int n, FILE *stream) +-{ +- char *val = mock_ptr_type(char *); +- if (!val) +- return NULL; +- strlcpy(buf, val, n); +- return buf; +-} +- + static int __set_errno(int err) + { + if (err >= 0) { +@@ -43,23 +33,44 @@ static int __set_errno(int err) + } + } + +-off_t __wrap_lseek(int fd, off_t offset, int whence) ++/* ++ * allocate_binding -> write_bindings_file() writes the entire file, i.e. the ++ * header, any pre-existing bindings, and the new binding. The complete content ++ * depends on history and is different to predict here. Therefore we check only ++ * the newly added binding. Because add_binding() sorts entries, this new ++ * binding isn't necessarily the last one; receive it from will_return() and ++ * search for it with strstr(). ++ * If the string to be written doesn't start with the bindings file ++ * header, it's a test of a partial write. ++ */ ++ssize_t __wrap_write(int fd, const void *buf, size_t count) + { +- return __set_errno(mock_type(int)); ++ const char *binding, *start; + ++#if DEBUG_WRITE ++ fprintf(stderr, "%s: %zx exp %zx\n===\n%s\n===\n", __func__, strlen(buf), ++ count, (const char *)buf); ++#endif ++ if (!strncmp((const char *)buf, BINDINGS_FILE_HEADER, ++ sizeof(BINDINGS_FILE_HEADER) - 1)) ++ start = (const char *)buf + sizeof(BINDINGS_FILE_HEADER) - 1; ++ else ++ start = buf; ++ binding = mock_ptr_type(char *); ++ start = strstr(start, binding); ++ check_expected(count); ++ assert_ptr_not_equal(start, NULL); ++ return __set_errno(mock_type(int)); + } + +-ssize_t __wrap_write(int fd, const void *buf, size_t count) ++int __wrap_rename(const char *old, const char *new) + { +- check_expected(count); +- check_expected(buf); + return __set_errno(mock_type(int)); + } + +-int __wrap_ftruncate(int fd, off_t length) ++int __wrap_mkstemp(char *template) + { +- check_expected(length); +- return __set_errno(mock_type(int)); ++ return 10; + } + + int __wrap_dm_map_present(const char * str) +@@ -84,32 +95,6 @@ int __wrap_dm_get_uuid(const char *name, char *uuid, int uuid_len) + #define TEST_FDNO 1234 + #define TEST_FPTR ((FILE *) 0xaffe) + +-int __wrap_open_file(const char *file, int *can_write, const char *header) +-{ +- int cw = mock_type(int); +- +- *can_write = cw; +- return TEST_FDNO; +-} +- +-FILE *__wrap_fdopen(int fd, const char *mode) +-{ +- assert_int_equal(fd, TEST_FDNO); +- return TEST_FPTR; +-} +- +-int __wrap_fflush(FILE *f) +-{ +- assert_ptr_equal(f, TEST_FPTR); +- return 0; +-} +- +-int __wrap_fclose(FILE *f) +-{ +- assert_ptr_equal(f, TEST_FPTR); +- return 0; +-} +- + /* strbuf wrapper for the old format_devname() */ + static int __format_devname(char *name, int id, size_t len, const char *prefix) + { +@@ -466,22 +451,85 @@ static void mock_self_alias(const char *alias, const char *wwid) + expect_condlog(3, USED_STR(alias, wwid)); \ + } while(0) + +-static void mock_bindings_file(const char *content, int match_line) ++static int add_binding_unsorted(Bindings *bindings, ++ const char *alias, const char *wwid) ++{ ++ struct binding *bdg = calloc(1, sizeof(*bdg)); ++ ++ if (!bdg) ++ return -1; ++ bdg->wwid = strdup(wwid); ++ bdg->alias = strdup(alias); ++ if (!bdg->wwid || !bdg->alias || !vector_alloc_slot(bindings)) { ++ free(bdg->alias); ++ free(bdg->wwid); ++ free(bdg); ++ return BINDING_ERROR; ++ } ++ vector_set_slot(bindings, bdg); ++ return BINDING_ADDED; ++} ++ ++static void __mock_bindings_file(const char *content, ++ int (*add)(Bindings *, const char *, const char *)) + { +- static char cnt[1024]; +- char *token; ++ char *cnt __attribute__((cleanup(cleanup_charp))) = NULL; ++ char *token, *savep = NULL; + int i; + +- assert_in_range(strlcpy(cnt, content, sizeof(cnt)), 0, sizeof(cnt) - 1); ++ cnt = strdup(content); ++ assert_ptr_not_equal(cnt, NULL); + +- for (token = strtok(cnt, "\n"), i = 0; ++ for (token = strtok_r(cnt, "\n", &savep), i = 0; + token && *token; +- token = strtok(NULL, "\n"), i++) { +- will_return(__wrap_fgets, token); +- if (match_line == i) +- return; ++ token = strtok_r(NULL, "\n", &savep), i++) { ++ char *alias, *wwid; ++ int rc; ++ ++ if (read_binding(token, i + 1, &alias, &wwid) ++ == READ_BINDING_SKIP) ++ continue; ++ ++ rc = add(&global_bindings, alias, wwid); ++ assert_int_equal(rc, BINDING_ADDED); + } +- will_return(__wrap_fgets, NULL); ++} ++ ++static void mock_bindings_file(const char *content) { ++ return __mock_bindings_file(content, add_binding); ++} ++ ++static void mock_bindings_file_unsorted(const char *content) { ++ return __mock_bindings_file(content, add_binding_unsorted); ++} ++ ++static int teardown_bindings(void **state) ++{ ++ cleanup_bindings(); ++ return 0; ++} ++ ++static int lookup_binding(FILE *dummy, const char *wwid, char **alias, ++ const char *prefix, int check_if_taken) ++{ ++ const struct binding *bdg; ++ int id; ++ ++ /* ++ * get_free_id() always checks if aliases are taken. ++ * Therefore if prefix is non-null, check_if_taken must be true. ++ */ ++ assert_true(!prefix || check_if_taken); ++ *alias = NULL; ++ bdg = get_binding_for_wwid(&global_bindings, wwid); ++ if (bdg) { ++ *alias = strdup(bdg->alias); ++ return 0; ++ } else if (!prefix && check_if_taken) ++ return -1; ++ ++ id = get_free_id(&global_bindings, prefix, wwid); ++ return id; + } + + static void lb_empty(void **state) +@@ -489,7 +537,7 @@ static void lb_empty(void **state) + int rc; + char *alias; + +- mock_bindings_file("", -1); ++ mock_bindings_file(""); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + rc = lookup_binding(NULL, "WWID0", &alias, NULL, 0); + assert_int_equal(rc, 1); +@@ -501,7 +549,7 @@ static void lb_empty_unused(void **state) + int rc; + char *alias; + +- mock_bindings_file("", -1); ++ mock_bindings_file(""); + mock_unused_alias("MPATHa"); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); +@@ -515,10 +563,10 @@ static void lb_empty_failed(void **state) + int rc; + char *alias; + +- mock_bindings_file("", -1); ++ mock_bindings_file(""); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + mock_failed_alias("MPATHa", "WWID0"); + mock_unused_alias("MPATHb"); +- expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); + assert_int_equal(rc, 2); + assert_ptr_equal(alias, NULL); +@@ -530,10 +578,10 @@ static void lb_empty_1_used(void **state) + int rc; + char *alias; + +- mock_bindings_file("", -1); ++ mock_bindings_file(""); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + mock_used_alias("MPATHa", "WWID0"); + mock_unused_alias("MPATHb"); +- expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); + assert_int_equal(rc, 2); + assert_ptr_equal(alias, NULL); +@@ -545,10 +593,10 @@ static void lb_empty_1_used_self(void **state) + int rc; + char *alias; + +- mock_bindings_file("", -1); ++ mock_bindings_file(""); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + mock_used_alias("MPATHa", "WWID0"); + mock_self_alias("MPATHb", "WWID0"); +- expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); + assert_int_equal(rc, 2); + assert_ptr_equal(alias, NULL); +@@ -560,9 +608,9 @@ static void lb_match_a(void **state) + int rc; + char *alias; + +- mock_bindings_file("MPATHa WWID0\n", 0); ++ mock_bindings_file("MPATHa WWID0\n"); + expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); +- rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 0); ++ rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); + assert_int_equal(rc, 0); + assert_ptr_not_equal(alias, NULL); + assert_string_equal(alias, "MPATHa"); +@@ -574,9 +622,10 @@ static void lb_nomatch_a(void **state) + int rc; + char *alias; + +- mock_bindings_file("MPATHa WWID0\n", -1); ++ mock_bindings_file("MPATHa WWID0\n"); + expect_condlog(3, NOMATCH_WWID_STR("WWID1")); +- rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 0); ++ mock_unused_alias("MPATHb"); ++ rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1); + assert_int_equal(rc, 2); + assert_ptr_equal(alias, NULL); + } +@@ -586,8 +635,8 @@ static void lb_nomatch_a_bad_check(void **state) + int rc; + char *alias; + +- mock_bindings_file("MPATHa WWID0\n", -1); +- expect_condlog(0, NOMORE_STR); ++ mock_bindings_file("MPATHa WWID0\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID1")); + rc = lookup_binding(NULL, "WWID1", &alias, NULL, 1); + assert_int_equal(rc, -1); + assert_ptr_equal(alias, NULL); +@@ -598,7 +647,7 @@ static void lb_nomatch_a_unused(void **state) + int rc; + char *alias; + +- mock_bindings_file("MPATHa WWID0\n", -1); ++ mock_bindings_file("MPATHa WWID0\n"); + mock_unused_alias("MPATHb"); + expect_condlog(3, NOMATCH_WWID_STR("WWID1")); + rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1); +@@ -611,27 +660,27 @@ static void lb_nomatch_a_3_used_failed_self(void **state) + int rc; + char *alias; + +- mock_bindings_file("MPATHa WWID0\n", -1); ++ mock_bindings_file("MPATHa WWID0\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID1")); + mock_used_alias("MPATHb", "WWID1"); + mock_used_alias("MPATHc", "WWID1"); + mock_used_alias("MPATHd", "WWID1"); + mock_failed_alias("MPATHe", "WWID1"); + mock_self_alias("MPATHf", "WWID1"); +- expect_condlog(3, NOMATCH_WWID_STR("WWID1")); + rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1); + assert_int_equal(rc, 6); + assert_ptr_equal(alias, NULL); + } + +-static void do_lb_match_c(void **state, int check_if_taken) ++static void do_lb_match_c(void **state) + { + int rc; + char *alias; + + mock_bindings_file("MPATHa WWID0\n" +- "MPATHc WWID1", 1); ++ "MPATHc WWID1"); + expect_condlog(3, FOUND_STR("MPATHc", "WWID1")); +- rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", check_if_taken); ++ rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1); + assert_int_equal(rc, 0); + assert_ptr_not_equal(alias, NULL); + assert_string_equal(alias, "MPATHc"); +@@ -640,12 +689,12 @@ static void do_lb_match_c(void **state, int check_if_taken) + + static void lb_match_c(void **state) + { +- do_lb_match_c(state, 0); ++ do_lb_match_c(state); + } + + static void lb_match_c_check(void **state) + { +- do_lb_match_c(state, 1); ++ do_lb_match_c(state); + } + + static void lb_nomatch_a_c(void **state) +@@ -654,9 +703,10 @@ static void lb_nomatch_a_c(void **state) + char *alias; + + mock_bindings_file("MPATHa WWID0\n" +- "MPATHc WWID1", -1); ++ "MPATHc WWID1"); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); +- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); ++ mock_unused_alias("MPATHb"); ++ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, 2); + assert_ptr_equal(alias, NULL); + } +@@ -667,7 +717,7 @@ static void lb_nomatch_a_d_unused(void **state) + char *alias; + + mock_bindings_file("MPATHa WWID0\n" +- "MPATHd WWID1", -1); ++ "MPATHd WWID1"); + mock_unused_alias("MPATHb"); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); +@@ -681,10 +731,10 @@ static void lb_nomatch_a_d_1_used(void **state) + char *alias; + + mock_bindings_file("MPATHa WWID0\n" +- "MPATHd WWID1", -1); ++ "MPATHd WWID1"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + mock_used_alias("MPATHb", "WWID2"); + mock_unused_alias("MPATHc"); +- expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, 3); + assert_ptr_equal(alias, NULL); +@@ -696,11 +746,11 @@ static void lb_nomatch_a_d_2_used(void **state) + char *alias; + + mock_bindings_file("MPATHa WWID0\n" +- "MPATHd WWID1", -1); ++ "MPATHd WWID1"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + mock_used_alias("MPATHb", "WWID2"); + mock_used_alias("MPATHc", "WWID2"); + mock_unused_alias("MPATHe"); +- expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, 5); + assert_ptr_equal(alias, NULL); +@@ -712,12 +762,12 @@ static void lb_nomatch_a_d_3_used(void **state) + char *alias; + + mock_bindings_file("MPATHa WWID0\n" +- "MPATHd WWID1", -1); ++ "MPATHd WWID1"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + mock_used_alias("MPATHb", "WWID2"); + mock_used_alias("MPATHc", "WWID2"); + mock_used_alias("MPATHe", "WWID2"); + mock_unused_alias("MPATHf"); +- expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, 6); + assert_ptr_equal(alias, NULL); +@@ -729,9 +779,10 @@ static void lb_nomatch_c_a(void **state) + char *alias; + + mock_bindings_file("MPATHc WWID1\n" +- "MPATHa WWID0\n", -1); ++ "MPATHa WWID0\n"); ++ mock_unused_alias("MPATHb"); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); +- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); ++ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, 2); + assert_ptr_equal(alias, NULL); + } +@@ -743,7 +794,7 @@ static void lb_nomatch_d_a_unused(void **state) + + mock_bindings_file("MPATHc WWID1\n" + "MPATHa WWID0\n" +- "MPATHd WWID0\n", -1); ++ "MPATHd WWID0\n"); + mock_unused_alias("MPATHb"); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); +@@ -758,10 +809,10 @@ static void lb_nomatch_d_a_1_used(void **state) + + mock_bindings_file("MPATHc WWID1\n" + "MPATHa WWID0\n" +- "MPATHd WWID0\n", -1); ++ "MPATHd WWID0\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + mock_used_alias("MPATHb", "WWID2"); + mock_unused_alias("MPATHe"); +- expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, 5); + assert_ptr_equal(alias, NULL); +@@ -774,9 +825,10 @@ static void lb_nomatch_a_b(void **state) + + mock_bindings_file("MPATHa WWID0\n" + "MPATHz WWID26\n" +- "MPATHb WWID1\n", -1); ++ "MPATHb WWID1\n"); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); +- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); ++ mock_unused_alias("MPATHc"); ++ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, 3); + assert_ptr_equal(alias, NULL); + } +@@ -786,13 +838,19 @@ static void lb_nomatch_a_b_bad(void **state) + int rc; + char *alias; + ++ expect_condlog(1, "invalid line 3 in bindings file, missing WWID\n"); ++ /* ++ * The broken line will be ignored when constructing the bindings vector. ++ * Thus in lookup_binding() MPATHb is never encountered, ++ * and MPATHb appears usable. ++ */ + mock_bindings_file("MPATHa WWID0\n" + "MPATHz WWID26\n" +- "MPATHb\n", -1); +- expect_condlog(3, "Ignoring malformed line 3 in bindings file\n"); ++ "MPATHb\n"); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); +- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); +- assert_int_equal(rc, 3); ++ mock_unused_alias("MPATHb"); ++ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); ++ assert_int_equal(rc, 2); + assert_ptr_equal(alias, NULL); + } + +@@ -801,84 +859,200 @@ static void lb_nomatch_a_b_bad_self(void **state) + int rc; + char *alias; + ++ expect_condlog(1, "invalid line 3 in bindings file, missing WWID\n"); + mock_bindings_file("MPATHa WWID0\n" + "MPATHz WWID26\n" +- "MPATHb\n", -1); +- expect_condlog(3, "Ignoring malformed line 3 in bindings file\n"); +- mock_self_alias("MPATHc", "WWID2"); ++ "MPATHb\n"); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); ++ mock_self_alias("MPATHb", "WWID2"); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); +- assert_int_equal(rc, 3); ++ assert_int_equal(rc, 2); + assert_ptr_equal(alias, NULL); + } + +-static void lb_nomatch_b_a(void **state) ++static void lb_nomatch_b_z_a(void **state) + { + int rc; + char *alias; + ++ /* ++ * add_bindings() sorts alphabetically. Therefore get_free_id() ++ * finds MPATHc as a free entry. ++ */ + mock_bindings_file("MPATHb WWID1\n" + "MPATHz WWID26\n" +- "MPATHa WWID0\n", -1); ++ "MPATHa WWID0\n"); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); +- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); +- assert_int_equal(rc, 27); ++ mock_unused_alias("MPATHc"); ++ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); ++ assert_int_equal(rc, 3); + assert_ptr_equal(alias, NULL); + } + +-static void lb_nomatch_b_a_3_used(void **state) ++static void lb_nomatch_b_aa_a(void **state) + { + int rc; + char *alias; + ++ /* ++ * add_bindings() sorts alphabetically. ("a", "aa", b"). ++ * The get_free_id() algorithm finds the "hole" after "b". ++ */ + mock_bindings_file("MPATHb WWID1\n" + "MPATHz WWID26\n" +- "MPATHa WWID0\n", -1); +- mock_used_alias("MPATHaa", "WWID2"); +- mock_used_alias("MPATHab", "WWID2"); +- mock_used_alias("MPATHac", "WWID2"); +- mock_unused_alias("MPATHad"); ++ "MPATHa WWID0\n"); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); ++ mock_unused_alias("MPATHc"); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); +- assert_int_equal(rc, 30); ++ assert_int_equal(rc, 3); + assert_ptr_equal(alias, NULL); + } + +-#ifdef MPATH_ID_INT_MAX +-static void do_lb_nomatch_int_max(void **state, int check_if_taken) ++static void fill_bindings(struct strbuf *buf, int start, int end) ++{ ++ int i; ++ ++ for (i = start; i <= end; i++) { ++ print_strbuf(buf, "MPATH"); ++ format_devname(buf, i + 1); ++ print_strbuf(buf, " WWID%d\n", i); ++ } ++} ++ ++static void lb_nomatch_b_a_aa(void **state) ++{ ++ int rc; ++ char *alias; ++ STRBUF_ON_STACK(buf); ++ ++ /* ++ * add_bindings() sorts alphabetically. ("a", "aa", "ab", "b", "c", ...) ++ * lookup_binding finds MPATHac as next free entry. ++ */ ++ fill_bindings(&buf, 0, 26); ++ mock_bindings_file(get_strbuf_str(&buf)); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID28")); ++ mock_unused_alias("MPATHab"); ++ rc = lookup_binding(NULL, "WWID28", &alias, "MPATH", 1); ++ assert_int_equal(rc, 28); ++ assert_ptr_equal(alias, NULL); ++} ++ ++static void lb_nomatch_b_a_aa_zz(void **state) ++{ ++ int rc, i; ++ char *alias; ++ STRBUF_ON_STACK(buf); ++ ++ /* ++ * add_bindings() sorts alphabetically. ("a", "aa", "ab", "b", "c", ...) ++ * lookup_binding finds MPATHaaa as next free entry, because MPATHaa is ++ * found before MPATHb, and MPATHzz was in the bindings, too. ++ */ ++ for (i = 0; i <= 26; i++) { ++ print_strbuf(&buf, "MPATH"); ++ format_devname(&buf, i + 1); ++ print_strbuf(&buf, " WWID%d\n", i); ++ } ++ print_strbuf(&buf, "MPATHzz WWID676\n"); ++ mock_bindings_file(get_strbuf_str(&buf)); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID703")); ++ mock_unused_alias("MPATHaaa"); ++ rc = lookup_binding(NULL, "WWID703", &alias, "MPATH", 1); ++ assert_int_equal(rc, 703); ++ assert_ptr_equal(alias, NULL); ++} ++ ++static void lb_nomatch_b_z_a_unsorted(void **state) ++{ ++ int rc; ++ char *alias; ++ ++ /* ++ * With unsorted bindings (shouldn't happen normally), get_free_id() ++ * plays safe and returns MPATHaa as first free entry. ++ */ ++ mock_bindings_file_unsorted("MPATHb WWID1\n" ++ "MPATHz WWID26\n" ++ "MPATHa WWID0\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); ++ mock_unused_alias("MPATHaa"); ++ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); ++ assert_int_equal(rc, 27); ++ assert_ptr_equal(alias, NULL); ++} ++ ++static void lb_nomatch_b_a(void **state) + { + int rc; + char *alias; + + mock_bindings_file("MPATHb WWID1\n" +- "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n" +- "MPATHa WWID0\n", -1); +- expect_condlog(0, NOMORE_STR); +- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", check_if_taken); +- assert_int_equal(rc, -1); ++ "MPATHa WWID0\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); ++ mock_unused_alias("MPATHc"); ++ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); ++ assert_int_equal(rc, 3); + assert_ptr_equal(alias, NULL); + } + +-static void lb_nomatch_int_max(void **state) ++static void lb_nomatch_b_a_3_used(void **state) + { +- do_lb_nomatch_int_max(state, 0); ++ int rc; ++ char *alias; ++ STRBUF_ON_STACK(buf); ++ ++ fill_bindings(&buf, 0, 26); ++ mock_bindings_file(get_strbuf_str(&buf)); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID31")); ++ mock_used_alias("MPATHab", "WWID31"); ++ mock_used_alias("MPATHac", "WWID31"); ++ mock_used_alias("MPATHad", "WWID31"); ++ mock_unused_alias("MPATHae"); ++ rc = lookup_binding(NULL, "WWID31", &alias, "MPATH", 1); ++ assert_int_equal(rc, 31); ++ assert_ptr_equal(alias, NULL); + } + +-static void lb_nomatch_int_max_check(void **state) ++#ifdef MPATH_ID_INT_MAX ++/* ++ * The bindings will be sorted by alias, alphabetically, which is not ++ * the same as the "numeric" sort order for user-friendly aliases. ++ * get_free_id() selects the highest used ID + 1 if an unsorted entry ++ * is encountered in the bindings table and it's id is equal to the ++ * next "expected" id. This happens if all IDs from "a" to "aa" are ++ * in the table. If the INT_MAX entry is in the table, too, it will ++ * overflow. ++ */ ++static void lb_nomatch_int_max(void **state) + { +- do_lb_nomatch_int_max(state, 1); ++ int rc; ++ char *alias; ++ STRBUF_ON_STACK(buf); ++ ++ fill_bindings(&buf, 0, 26); ++ print_strbuf(&buf, "MPATH%s WWIDMAX\n", MPATH_ID_INT_MAX); ++ mock_bindings_file(get_strbuf_str(&buf)); ++ expect_condlog(3, NOMATCH_WWID_STR("WWIDNOMORE")); ++ expect_condlog(0, NOMORE_STR); ++ rc = lookup_binding(NULL, "WWIDNOMORE", &alias, "MPATH", 1); ++ assert_int_equal(rc, -1); ++ assert_ptr_equal(alias, NULL); + } + + static void lb_nomatch_int_max_used(void **state) + { + int rc; + char *alias; ++ STRBUF_ON_STACK(buf); + +- mock_bindings_file("MPATHb WWID1\n" +- "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n", -1); +- mock_used_alias("MPATHa", "WWID2"); ++ fill_bindings(&buf, 1, 26); ++ print_strbuf(&buf, "MPATH%s WWIDMAX\n", MPATH_ID_INT_MAX); ++ mock_bindings_file(get_strbuf_str(&buf)); ++ expect_condlog(3, NOMATCH_WWID_STR("WWIDNOMORE")); ++ mock_used_alias("MPATHa", "WWIDNOMORE"); + expect_condlog(0, NOMORE_STR); +- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); ++ rc = lookup_binding(NULL, "WWIDNOMORE", &alias, "MPATH", 1); + assert_int_equal(rc, -1); + assert_ptr_equal(alias, NULL); + } +@@ -887,12 +1061,14 @@ static void lb_nomatch_int_max_m1(void **state) + { + int rc; + char *alias; ++ STRBUF_ON_STACK(buf); + +- mock_bindings_file("MPATHb WWID1\n" +- "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n" +- "MPATHa WWID0\n", -1); +- expect_condlog(3, NOMATCH_WWID_STR("WWID2")); +- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); ++ fill_bindings(&buf, 0, 26); ++ print_strbuf(&buf, "MPATH%s WWIDMAXM1\n", MPATH_ID_INT_MAX_m1); ++ mock_bindings_file(get_strbuf_str(&buf)); ++ expect_condlog(3, NOMATCH_WWID_STR("WWIDMAX")); ++ mock_unused_alias("MPATH" MPATH_ID_INT_MAX); ++ rc = lookup_binding(NULL, "WWIDMAX", &alias, "MPATH", 1); + assert_int_equal(rc, INT_MAX); + assert_ptr_equal(alias, NULL); + } +@@ -901,13 +1077,15 @@ static void lb_nomatch_int_max_m1_used(void **state) + { + int rc; + char *alias; ++ STRBUF_ON_STACK(buf); + +- mock_bindings_file("MPATHb WWID1\n" +- "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n" +- "MPATHa WWID0\n", -1); +- mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWID2"); ++ fill_bindings(&buf, 0, 26); ++ print_strbuf(&buf, "MPATH%s WWIDMAXM1\n", MPATH_ID_INT_MAX_m1); ++ mock_bindings_file(get_strbuf_str(&buf)); ++ expect_condlog(3, NOMATCH_WWID_STR("WWIDMAX")); ++ mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWIDMAX"); + expect_condlog(0, NOMORE_STR); +- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); ++ rc = lookup_binding(NULL, "WWIDMAX", &alias, "MPATH", 1); + assert_int_equal(rc, -1); + assert_ptr_equal(alias, NULL); + } +@@ -916,13 +1094,15 @@ static void lb_nomatch_int_max_m1_1_used(void **state) + { + int rc; + char *alias; ++ STRBUF_ON_STACK(buf); + +- mock_bindings_file("MPATHb WWID1\n" +- "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n", -1); +- mock_used_alias("MPATHa", "WWID2"); ++ fill_bindings(&buf, 1, 26); ++ print_strbuf(&buf, "MPATH%s WWIDMAXM1\n", MPATH_ID_INT_MAX_m1); ++ mock_bindings_file(get_strbuf_str(&buf)); ++ expect_condlog(3, NOMATCH_WWID_STR("WWIDMAX")); ++ mock_used_alias("MPATHa", "WWIDMAX"); + mock_unused_alias("MPATH" MPATH_ID_INT_MAX); +- expect_condlog(3, NOMATCH_WWID_STR("WWID2")); +- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); ++ rc = lookup_binding(NULL, "WWIDMAX", &alias, "MPATH", 1); + assert_int_equal(rc, INT_MAX); + assert_ptr_equal(alias, NULL); + } +@@ -931,13 +1111,17 @@ static void lb_nomatch_int_max_m1_2_used(void **state) + { + int rc; + char *alias; ++ STRBUF_ON_STACK(buf); + +- mock_bindings_file("MPATHb WWID1\n" +- "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n", -1); +- mock_used_alias("MPATHa", "WWID2"); +- mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWID2"); ++ fill_bindings(&buf, 1, 26); ++ print_strbuf(&buf, "MPATH%s WWIDMAXM1\n", MPATH_ID_INT_MAX_m1); ++ mock_bindings_file(get_strbuf_str(&buf)); ++ ++ expect_condlog(3, NOMATCH_WWID_STR("WWIDMAX")); ++ mock_used_alias("MPATHa", "WWIDMAX"); ++ mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWIDMAX"); + expect_condlog(0, NOMORE_STR); +- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); ++ rc = lookup_binding(NULL, "WWIDMAX", &alias, "MPATH", 1); + assert_int_equal(rc, -1); + assert_ptr_equal(alias, NULL); + } +@@ -946,52 +1130,68 @@ static void lb_nomatch_int_max_m1_2_used(void **state) + static int test_lookup_binding(void) + { + const struct CMUnitTest tests[] = { +- cmocka_unit_test(lb_empty), +- cmocka_unit_test(lb_empty_unused), +- cmocka_unit_test(lb_empty_failed), +- cmocka_unit_test(lb_empty_1_used), +- cmocka_unit_test(lb_empty_1_used_self), +- cmocka_unit_test(lb_match_a), +- cmocka_unit_test(lb_nomatch_a), +- cmocka_unit_test(lb_nomatch_a_bad_check), +- cmocka_unit_test(lb_nomatch_a_unused), +- cmocka_unit_test(lb_nomatch_a_3_used_failed_self), +- cmocka_unit_test(lb_match_c), +- cmocka_unit_test(lb_match_c_check), +- cmocka_unit_test(lb_nomatch_a_c), +- cmocka_unit_test(lb_nomatch_a_d_unused), +- cmocka_unit_test(lb_nomatch_a_d_1_used), +- cmocka_unit_test(lb_nomatch_a_d_2_used), +- cmocka_unit_test(lb_nomatch_a_d_3_used), +- cmocka_unit_test(lb_nomatch_c_a), +- cmocka_unit_test(lb_nomatch_d_a_unused), +- cmocka_unit_test(lb_nomatch_d_a_1_used), +- cmocka_unit_test(lb_nomatch_a_b), +- cmocka_unit_test(lb_nomatch_a_b_bad), +- cmocka_unit_test(lb_nomatch_a_b_bad_self), +- cmocka_unit_test(lb_nomatch_b_a), +- cmocka_unit_test(lb_nomatch_b_a_3_used), ++ cmocka_unit_test_teardown(lb_empty, teardown_bindings), ++ cmocka_unit_test_teardown(lb_empty_unused, teardown_bindings), ++ cmocka_unit_test_teardown(lb_empty_failed, teardown_bindings), ++ cmocka_unit_test_teardown(lb_empty_1_used, teardown_bindings), ++ cmocka_unit_test_teardown(lb_empty_1_used_self, teardown_bindings), ++ cmocka_unit_test_teardown(lb_match_a, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_a, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_a_bad_check, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_a_unused, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_a_3_used_failed_self, teardown_bindings), ++ cmocka_unit_test_teardown(lb_match_c, teardown_bindings), ++ cmocka_unit_test_teardown(lb_match_c_check, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_a_c, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_a_d_unused, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_a_d_1_used, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_a_d_2_used, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_a_d_3_used, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_c_a, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_d_a_unused, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_d_a_1_used, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_a_b, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_a_b_bad, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_a_b_bad_self, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_b_z_a, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_b_aa_a, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_b_a_aa, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_b_a_aa_zz, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_b_z_a_unsorted, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_b_a, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_b_a_3_used, teardown_bindings), + #ifdef MPATH_ID_INT_MAX +- cmocka_unit_test(lb_nomatch_int_max), +- cmocka_unit_test(lb_nomatch_int_max_check), +- cmocka_unit_test(lb_nomatch_int_max_used), +- cmocka_unit_test(lb_nomatch_int_max_m1), +- cmocka_unit_test(lb_nomatch_int_max_m1_used), +- cmocka_unit_test(lb_nomatch_int_max_m1_1_used), +- cmocka_unit_test(lb_nomatch_int_max_m1_2_used), ++ cmocka_unit_test_teardown(lb_nomatch_int_max, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_int_max_used, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_int_max_m1, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_int_max_m1_used, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_int_max_m1_1_used, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_int_max_m1_2_used, teardown_bindings), + #endif + }; + + return cmocka_run_group_tests(tests, NULL, NULL); + } + ++static int rlookup_binding(FILE *dummy, char *buf, const char *alias) { ++ ++ const struct binding *bdg; ++ ++ bdg = get_binding_for_alias(&global_bindings, alias); ++ if (!bdg) { ++ return -1; ++ } ++ strlcpy(buf, bdg->wwid, WWID_SIZE); ++ return 0; ++} ++ + static void rl_empty(void **state) + { + int rc; + char buf[WWID_SIZE]; + + buf[0] = '\0'; +- mock_bindings_file("", -1); ++ mock_bindings_file(""); + expect_condlog(3, NOMATCH_STR("MPATHa")); + rc = rlookup_binding(NULL, buf, "MPATHa"); + assert_int_equal(rc, -1); +@@ -1004,7 +1204,7 @@ static void rl_match_a(void **state) + char buf[WWID_SIZE]; + + buf[0] = '\0'; +- mock_bindings_file("MPATHa WWID0\n", 0); ++ mock_bindings_file("MPATHa WWID0\n"); + expect_condlog(3, FOUND_ALIAS_STR("MPATHa", "WWID0")); + rc = rlookup_binding(NULL, buf, "MPATHa"); + assert_int_equal(rc, 0); +@@ -1017,7 +1217,7 @@ static void rl_nomatch_a(void **state) + char buf[WWID_SIZE]; + + buf[0] = '\0'; +- mock_bindings_file("MPATHa WWID0\n", -1); ++ mock_bindings_file("MPATHa WWID0\n"); + expect_condlog(3, NOMATCH_STR("MPATHb")); + rc = rlookup_binding(NULL, buf, "MPATHb"); + assert_int_equal(rc, -1); +@@ -1030,8 +1230,8 @@ static void rl_malformed_a(void **state) + char buf[WWID_SIZE]; + + buf[0] = '\0'; +- mock_bindings_file("MPATHa \n", -1); +- expect_condlog(3, "Ignoring malformed line 1 in bindings file\n"); ++ expect_condlog(1, "invalid line 1 in bindings file, missing WWID\n"); ++ mock_bindings_file("MPATHa \n"); + expect_condlog(3, NOMATCH_STR("MPATHa")); + rc = rlookup_binding(NULL, buf, "MPATHa"); + assert_int_equal(rc, -1); +@@ -1049,8 +1249,8 @@ static void rl_overlong_a(void **state) + snprintf(line + sizeof(line) - 2, 2, "\n"); + + buf[0] = '\0'; +- mock_bindings_file(line, -1); + expect_condlog(3, "Ignoring too large wwid at 1 in bindings file\n"); ++ mock_bindings_file(line); + expect_condlog(3, NOMATCH_STR("MPATHa")); + rc = rlookup_binding(NULL, buf, "MPATHa"); + assert_int_equal(rc, -1); +@@ -1065,7 +1265,7 @@ static void rl_match_b(void **state) + buf[0] = '\0'; + mock_bindings_file("MPATHa WWID0\n" + "MPATHz WWID26\n" +- "MPATHb WWID2\n", 2); ++ "MPATHb WWID2\n"); + expect_condlog(3, FOUND_ALIAS_STR("MPATHb", "WWID2")); + rc = rlookup_binding(NULL, buf, "MPATHb"); + assert_int_equal(rc, 0); +@@ -1075,31 +1275,41 @@ static void rl_match_b(void **state) + static int test_rlookup_binding(void) + { + const struct CMUnitTest tests[] = { +- cmocka_unit_test(rl_empty), +- cmocka_unit_test(rl_match_a), +- cmocka_unit_test(rl_nomatch_a), +- cmocka_unit_test(rl_malformed_a), +- cmocka_unit_test(rl_overlong_a), +- cmocka_unit_test(rl_match_b), ++ cmocka_unit_test_teardown(rl_empty, teardown_bindings), ++ cmocka_unit_test_teardown(rl_match_a, teardown_bindings), ++ cmocka_unit_test_teardown(rl_nomatch_a, teardown_bindings), ++ cmocka_unit_test_teardown(rl_malformed_a, teardown_bindings), ++ cmocka_unit_test_teardown(rl_overlong_a, teardown_bindings), ++ cmocka_unit_test_teardown(rl_match_b, teardown_bindings), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); + } + ++void check_bindings_size(int n) ++{ ++ /* avoid -Waddress problem */ ++ Bindings *bindings = &global_bindings; ++ ++ assert_int_equal(VECTOR_SIZE(bindings), n); ++} ++ + static void al_a(void **state) + { + static const char ln[] = "MPATHa WWIDa\n"; + char *alias; + +- will_return(__wrap_lseek, 0); +- expect_value(__wrap_write, count, strlen(ln)); +- expect_string(__wrap_write, buf, ln); +- will_return(__wrap_write, strlen(ln)); ++ expect_value(__wrap_write, count, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); ++ will_return(__wrap_write, ln); ++ will_return(__wrap_write, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); ++ will_return(__wrap_rename, 0); ++ expect_condlog(1, "updated bindings file foo"); + expect_condlog(3, NEW_STR("MPATHa", "WWIDa")); + +- alias = allocate_binding(0, "WWIDa", 1, "MPATH"); ++ alias = allocate_binding("foo", "WWIDa", 1, "MPATH"); + assert_ptr_not_equal(alias, NULL); + assert_string_equal(alias, "MPATHa"); ++ check_bindings_size(1); + free(alias); + } + +@@ -1108,15 +1318,17 @@ static void al_zz(void **state) + static const char ln[] = "MPATHzz WWIDzz\n"; + char *alias; + +- will_return(__wrap_lseek, 0); +- expect_value(__wrap_write, count, strlen(ln)); +- expect_string(__wrap_write, buf, ln); +- will_return(__wrap_write, strlen(ln)); ++ expect_value(__wrap_write, count, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); ++ will_return(__wrap_write, ln); ++ will_return(__wrap_write, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); ++ will_return(__wrap_rename, 0); ++ expect_condlog(1, "updated bindings file foo"); + expect_condlog(3, NEW_STR("MPATHzz", "WWIDzz")); + +- alias = allocate_binding(0, "WWIDzz", 26*26 + 26, "MPATH"); ++ alias = allocate_binding("foo", "WWIDzz", 26*26 + 26, "MPATH"); + assert_ptr_not_equal(alias, NULL); + assert_string_equal(alias, "MPATHzz"); ++ check_bindings_size(1); + free(alias); + } + +@@ -1127,6 +1339,7 @@ static void al_0(void **state) + expect_condlog(0, "allocate_binding: cannot allocate new binding for id 0\n"); + alias = allocate_binding(0, "WWIDa", 0, "MPATH"); + assert_ptr_equal(alias, NULL); ++ check_bindings_size(0); + } + + static void al_m2(void **state) +@@ -1136,67 +1349,133 @@ static void al_m2(void **state) + expect_condlog(0, "allocate_binding: cannot allocate new binding for id -2\n"); + alias = allocate_binding(0, "WWIDa", -2, "MPATH"); + assert_ptr_equal(alias, NULL); ++ check_bindings_size(0); ++} ++ ++static void al_write_partial(void **state) ++{ ++ static const char ln[] = "MPATHa WWIDa\n"; ++ char *alias; ++ ++ expect_value(__wrap_write, count, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); ++ will_return(__wrap_write, ln); ++ will_return(__wrap_write, strlen(BINDINGS_FILE_HEADER) + strlen(ln) - 1); ++ expect_value(__wrap_write, count, 1); ++ will_return(__wrap_write, ln + sizeof(ln) - 2); ++ will_return(__wrap_write, 1); ++ will_return(__wrap_rename, 0); ++ expect_condlog(1, "updated bindings file foo"); ++ expect_condlog(3, "Created new binding [MPATHa] for WWID [WWIDa]\n"); ++ ++ alias = allocate_binding("foo", "WWIDa", 1, "MPATH"); ++ assert_ptr_not_equal(alias, NULL); ++ assert_string_equal(alias, "MPATHa"); ++ check_bindings_size(1); ++ free(alias); + } + +-static void al_lseek_err(void **state) ++static void al_write_short(void **state) + { ++ static const char ln[] = "MPATHa WWIDa\n"; + char *alias; + +- will_return(__wrap_lseek, -ENODEV); +- expect_condlog(0, "Cannot seek to end of bindings file : No such device\n"); +- alias = allocate_binding(0, "WWIDa", 1, "MPATH"); ++ expect_value(__wrap_write, count, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); ++ will_return(__wrap_write, ln); ++ will_return(__wrap_write, strlen(BINDINGS_FILE_HEADER) + strlen(ln) - 1); ++ expect_value(__wrap_write, count, 1); ++ will_return(__wrap_write, ln + sizeof(ln) - 2); ++ will_return(__wrap_write, 0); ++ expect_condlog(2, "write_bindings_file: short write"); ++ expect_condlog(1, "failed to write new bindings file"); ++ expect_condlog(1, "allocate_binding: deleting binding MPATHa for WWIDa"); ++ ++ alias = allocate_binding("foo", "WWIDa", 1, "MPATH"); + assert_ptr_equal(alias, NULL); ++ check_bindings_size(0); + } + + static void al_write_err(void **state) + { + static const char ln[] = "MPATHa WWIDa\n"; +- const int offset = 20; + char *alias; + +- will_return(__wrap_lseek, offset); +- expect_value(__wrap_write, count, strlen(ln)); +- expect_string(__wrap_write, buf, ln); +- will_return(__wrap_write, strlen(ln) - 1); +- expect_value(__wrap_ftruncate, length, offset); +- will_return(__wrap_ftruncate, 0); +- expect_condlog(0, "Cannot write binding to bindings file :"); ++ expect_value(__wrap_write, count, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); ++ will_return(__wrap_write, ln); ++ will_return(__wrap_write, -EPERM); ++ expect_condlog(1, "failed to write new bindings file"); ++ expect_condlog(1, "allocate_binding: deleting binding MPATHa for WWIDa"); + +- alias = allocate_binding(0, "WWIDa", 1, "MPATH"); ++ alias = allocate_binding("foo", "WWIDa", 1, "MPATH"); + assert_ptr_equal(alias, NULL); ++ check_bindings_size(0); ++} ++ ++static void al_rename_err(void **state) ++{ ++ static const char ln[] = "MPATHa WWIDa\n"; ++ char *alias; ++ ++ expect_value(__wrap_write, count, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); ++ will_return(__wrap_write, ln); ++ will_return(__wrap_write, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); ++ will_return(__wrap_rename, -EROFS); ++ ++ expect_condlog(0, "update_bindings_file: rename: Read-only file system"); ++ expect_condlog(1, "allocate_binding: deleting binding MPATHa for WWIDa"); ++ alias = allocate_binding("foo", "WWIDa", 1, "MPATH"); ++ assert_ptr_equal(alias, NULL); ++ check_bindings_size(0); + } + + static int test_allocate_binding(void) + { + const struct CMUnitTest tests[] = { +- cmocka_unit_test(al_a), +- cmocka_unit_test(al_zz), +- cmocka_unit_test(al_0), +- cmocka_unit_test(al_m2), +- cmocka_unit_test(al_lseek_err), +- cmocka_unit_test(al_write_err), ++ cmocka_unit_test_teardown(al_a, teardown_bindings), ++ cmocka_unit_test_teardown(al_zz, teardown_bindings), ++ cmocka_unit_test_teardown(al_0, teardown_bindings), ++ cmocka_unit_test_teardown(al_m2, teardown_bindings), ++ cmocka_unit_test_teardown(al_write_partial, teardown_bindings), ++ cmocka_unit_test_teardown(al_write_short, teardown_bindings), ++ cmocka_unit_test_teardown(al_write_err, teardown_bindings), ++ cmocka_unit_test_teardown(al_rename_err, teardown_bindings), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); + } + +-#define mock_allocate_binding(alias, wwid) \ ++#define mock_allocate_binding_err_len(alias, wwid, len, err, msg) \ + do { \ + static const char ln[] = BINDING_STR(alias, wwid); \ + \ +- will_return(__wrap_lseek, 0); \ +- expect_value(__wrap_write, count, strlen(ln)); \ +- expect_string(__wrap_write, buf, ln); \ +- will_return(__wrap_write, strlen(ln)); \ +- expect_condlog(3, NEW_STR(alias, wwid)); \ ++ expect_value(__wrap_write, count, \ ++ strlen(BINDINGS_FILE_HEADER) + (len) + strlen(ln)); \ ++ will_return(__wrap_write, ln); \ ++ will_return(__wrap_write, \ ++ strlen(BINDINGS_FILE_HEADER) + (len) + strlen(ln)); \ ++ will_return(__wrap_rename, err); \ ++ if (err == 0) { \ ++ expect_condlog(1, "updated bindings file x\n"); \ ++ expect_condlog(3, NEW_STR(alias, wwid)); \ ++ } else { \ ++ expect_condlog(0, "update_bindings_file: rename: " msg "\n"); \ ++ expect_condlog(1, "allocate_binding: deleting binding " \ ++ alias " for " wwid "\n"); \ ++ } \ + } while (0) + ++#define mock_allocate_binding_err(alias, wwid, err, msg) \ ++ mock_allocate_binding_err_len(alias, wwid, 0, err, msg) ++ ++#define mock_allocate_binding(alias, wwid) \ ++ mock_allocate_binding_err(alias, wwid, 0, "") ++ ++#define mock_allocate_binding_len(alias, wwid, len) \ ++ mock_allocate_binding_err_len(alias, wwid, len, 0, "") ++ + static void gufa_empty_new_rw(void **state) { + char *alias; + +- will_return(__wrap_open_file, true); +- +- mock_bindings_file("", -1); ++ mock_bindings_file(""); + mock_unused_alias("MPATHa"); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + +@@ -1208,10 +1487,11 @@ static void gufa_empty_new_rw(void **state) { + + static void gufa_empty_new_ro_1(void **state) { + char *alias; +- will_return(__wrap_open_file, false); +- mock_bindings_file("", -1); ++ ++ mock_bindings_file(""); + mock_unused_alias("MPATHa"); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); ++ mock_allocate_binding_err("MPATHa", "WWID0", -EROFS, "Read-only file system"); + + alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false); + assert_ptr_equal(alias, NULL); +@@ -1220,11 +1500,9 @@ static void gufa_empty_new_ro_1(void **state) { + static void gufa_empty_new_ro_2(void **state) { + char *alias; + +- will_return(__wrap_open_file, true); +- +- mock_bindings_file("", -1); +- mock_unused_alias("MPATHa"); ++ mock_bindings_file(""); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); ++ mock_unused_alias("MPATHa"); + + alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); + assert_ptr_equal(alias, NULL); +@@ -1233,11 +1511,10 @@ static void gufa_empty_new_ro_2(void **state) { + static void gufa_match_a_unused(void **state) { + char *alias; + +- will_return(__wrap_open_file, true); +- +- mock_bindings_file("MPATHa WWID0", 0); ++ mock_bindings_file("MPATHa WWID0"); + expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); + mock_unused_alias("MPATHa"); ++ expect_condlog(3, EXISTING_STR("MPATHa", "WWID0")); + + alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); + assert_string_equal(alias, "MPATHa"); +@@ -1247,11 +1524,10 @@ static void gufa_match_a_unused(void **state) { + static void gufa_match_a_self(void **state) { + char *alias; + +- will_return(__wrap_open_file, true); +- +- mock_bindings_file("MPATHa WWID0", 0); ++ mock_bindings_file("MPATHa WWID0"); + expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); + mock_self_alias("MPATHa", "WWID0"); ++ expect_condlog(3, EXISTING_STR("MPATHa", "WWID0")); + + alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); + assert_string_equal(alias, "MPATHa"); +@@ -1261,9 +1537,8 @@ static void gufa_match_a_self(void **state) { + static void gufa_match_a_used(void **state) { + char *alias; + +- will_return(__wrap_open_file, true); + +- mock_bindings_file("MPATHa WWID0", 0); ++ mock_bindings_file("MPATHa WWID0"); + expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); + mock_used_alias("MPATHa", "WWID0"); + +@@ -1273,15 +1548,14 @@ static void gufa_match_a_used(void **state) { + + static void gufa_nomatch_a_c(void **state) { + char *alias; +- will_return(__wrap_open_file, true); ++ static const char bindings[] = ("MPATHa WWID0\n" ++ "MPATHc WWID2\n"); + +- mock_bindings_file("MPATHa WWID0\n" +- "MPATHc WWID2", +- -1); ++ mock_bindings_file(bindings); + mock_unused_alias("MPATHb"); + expect_condlog(3, NOMATCH_WWID_STR("WWID1")); + +- mock_allocate_binding("MPATHb", "WWID1"); ++ mock_allocate_binding_len("MPATHb", "WWID1", strlen(bindings)); + + alias = get_user_friendly_alias("WWID1", "x", "", "MPATH", false); + assert_string_equal(alias, "MPATHb"); +@@ -1290,15 +1564,14 @@ static void gufa_nomatch_a_c(void **state) { + + static void gufa_nomatch_c_a(void **state) { + char *alias; +- will_return(__wrap_open_file, true); ++ const char bindings[] = ("MPATHc WWID2\n" ++ "MPATHa WWID0\n"); + +- mock_bindings_file("MPATHc WWID2\n" +- "MPATHa WWID0", +- -1); ++ mock_bindings_file(bindings); + mock_unused_alias("MPATHb"); + expect_condlog(3, NOMATCH_WWID_STR("WWID1")); + +- mock_allocate_binding("MPATHb", "WWID1"); ++ mock_allocate_binding_len("MPATHb", "WWID1", sizeof(bindings) - 1); + + alias = get_user_friendly_alias("WWID1", "x", "", "MPATH", false); + assert_string_equal(alias, "MPATHb"); +@@ -1307,15 +1580,14 @@ static void gufa_nomatch_c_a(void **state) { + + static void gufa_nomatch_c_b(void **state) { + char *alias; +- will_return(__wrap_open_file, true); ++ const char bindings[] = ("MPATHc WWID2\n" ++ "MPATHb WWID1\n"); + +- mock_bindings_file("MPATHc WWID2\n" +- "MPATHb WWID1\n", +- -1); +- mock_unused_alias("MPATHa"); ++ mock_bindings_file(bindings); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); ++ mock_unused_alias("MPATHa"); + +- mock_allocate_binding("MPATHa", "WWID0"); ++ mock_allocate_binding_len("MPATHa", "WWID0", sizeof(bindings) - 1); + + alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false); + assert_string_equal(alias, "MPATHa"); +@@ -1324,16 +1596,15 @@ static void gufa_nomatch_c_b(void **state) { + + static void gufa_nomatch_c_b_used(void **state) { + char *alias; +- will_return(__wrap_open_file, true); ++ const char bindings[] = ("MPATHc WWID2\n" ++ "MPATHb WWID1\n"); + +- mock_bindings_file("MPATHc WWID2\n" +- "MPATHb WWID1", +- -1); +- mock_used_alias("MPATHa", "WWID4"); ++ mock_bindings_file(bindings); + expect_condlog(3, NOMATCH_WWID_STR("WWID4")); ++ mock_used_alias("MPATHa", "WWID4"); + mock_unused_alias("MPATHd"); + +- mock_allocate_binding("MPATHd", "WWID4"); ++ mock_allocate_binding_len("MPATHd", "WWID4", sizeof(bindings) - 1); + + alias = get_user_friendly_alias("WWID4", "x", "", "MPATH", false); + assert_string_equal(alias, "MPATHd"); +@@ -1342,32 +1613,59 @@ static void gufa_nomatch_c_b_used(void **state) { + + static void gufa_nomatch_b_f_a(void **state) { + char *alias; +- will_return(__wrap_open_file, true); ++ const char bindings[] = ("MPATHb WWID1\n" ++ "MPATHf WWID6\n" ++ "MPATHa WWID0\n"); + +- mock_bindings_file("MPATHb WWID1\n" +- "MPATHf WWID6\n" +- "MPATHa WWID0\n", +- -1); ++ mock_bindings_file_unsorted(bindings); + expect_condlog(3, NOMATCH_WWID_STR("WWID7")); + mock_unused_alias("MPATHg"); + +- mock_allocate_binding("MPATHg", "WWID7"); ++ mock_allocate_binding_len("MPATHg", "WWID7", sizeof(bindings) - 1); + + alias = get_user_friendly_alias("WWID7", "x", "", "MPATH", false); + assert_string_equal(alias, "MPATHg"); + free(alias); + } + ++static void gufa_nomatch_b_aa_a(void **state) { ++ char *alias; ++ STRBUF_ON_STACK(buf); ++ ++ fill_bindings(&buf, 0, 26); ++ mock_bindings_file(get_strbuf_str(&buf)); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID28")); ++ mock_unused_alias("MPATHab"); ++ mock_allocate_binding_len("MPATHab", "WWID28", get_strbuf_len(&buf)); ++ ++ alias = get_user_friendly_alias("WWID28", "x", "", "MPATH", false); ++ assert_string_equal(alias, "MPATHab"); ++ free(alias); ++} ++ ++static void gufa_nomatch_b_f_a_sorted(void **state) { ++ char *alias; ++ const char bindings[] = ("MPATHb WWID1\n" ++ "MPATHf WWID6\n" ++ "MPATHa WWID0\n"); ++ ++ mock_bindings_file(bindings); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID7")); ++ mock_unused_alias("MPATHc"); ++ ++ mock_allocate_binding_len("MPATHc", "WWID7", sizeof(bindings) - 1); ++ ++ alias = get_user_friendly_alias("WWID7", "x", "", "MPATH", false); ++ assert_string_equal(alias, "MPATHc"); ++ free(alias); ++} ++ + static void gufa_old_empty(void **state) { + char *alias; +- will_return(__wrap_open_file, true); + + /* rlookup_binding for ALIAS */ +- mock_bindings_file("", -1); ++ mock_bindings_file(""); + expect_condlog(3, NOMATCH_STR("MPATHz")); +- +- /* lookup_binding */ +- mock_bindings_file("", -1); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + + mock_allocate_binding("MPATHz", "WWID0"); +@@ -1380,11 +1678,9 @@ static void gufa_old_empty(void **state) { + + static void gufa_old_match(void **state) { + char *alias; +- will_return(__wrap_open_file, true); + + mock_bindings_file("MPATHb WWID1\n" +- "MPATHz WWID0", +- 1); ++ "MPATHz WWID0"); + expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID0")); + + alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); +@@ -1394,19 +1690,15 @@ static void gufa_old_match(void **state) { + + static void gufa_old_match_other(void **state) { + char *alias; +- static const char bindings[] = "MPATHz WWID9"; +- +- will_return(__wrap_open_file, true); ++ static const char bindings[] = "MPATHz WWID9\n"; + +- mock_bindings_file(bindings, 0); ++ mock_bindings_file(bindings); + expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID9")); + expect_condlog(0, REUSE_STR("MPATHz", "WWID9")); +- +- mock_bindings_file(bindings, -1); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + mock_unused_alias("MPATHa"); + +- mock_allocate_binding("MPATHa", "WWID0"); ++ mock_allocate_binding_len("MPATHa", "WWID0", sizeof(bindings) - 1); + + alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); + assert_string_equal(alias, "MPATHa"); +@@ -1415,21 +1707,16 @@ static void gufa_old_match_other(void **state) { + + static void gufa_old_match_other_used(void **state) { + char *alias; +- static const char bindings[] = "MPATHz WWID9"; ++ static const char bindings[] = "MPATHz WWID9\n"; + +- will_return(__wrap_open_file, true); +- +- mock_bindings_file(bindings, 0); ++ mock_bindings_file(bindings); + expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID9")); + expect_condlog(0, REUSE_STR("MPATHz", "WWID9")); +- +- mock_bindings_file(bindings, -1); +- mock_used_alias("MPATHa", "WWID0"); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); ++ mock_used_alias("MPATHa", "WWID0"); + mock_unused_alias("MPATHb"); + +- mock_allocate_binding("MPATHb", "WWID0"); +- ++ mock_allocate_binding_len("MPATHb", "WWID0", sizeof(bindings) - 1); + alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); + assert_string_equal(alias, "MPATHb"); + free(alias); +@@ -1439,15 +1726,13 @@ static void gufa_old_match_other_wwidmatch(void **state) { + char *alias; + static const char bindings[] = ("MPATHz WWID9\n" + "MPATHc WWID2"); +- will_return(__wrap_open_file, true); + +- mock_bindings_file(bindings, 0); ++ mock_bindings_file(bindings); + expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID9")); + expect_condlog(0, REUSE_STR("MPATHz", "WWID9")); +- +- mock_bindings_file(bindings, 1); + expect_condlog(3, FOUND_STR("MPATHc", "WWID2")); + mock_unused_alias("MPATHc"); ++ expect_condlog(3, EXISTING_STR("MPATHc", "WWID2")); + + alias = get_user_friendly_alias("WWID2", "x", "MPATHz", "MPATH", false); + assert_string_equal(alias, "MPATHc"); +@@ -1459,13 +1744,9 @@ static void gufa_old_match_other_wwidmatch_used(void **state) { + static const char bindings[] = ("MPATHz WWID9\n" + "MPATHc WWID2"); + +- will_return(__wrap_open_file, true); +- +- mock_bindings_file(bindings, 0); ++ mock_bindings_file(bindings); + expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID9")); + expect_condlog(0, REUSE_STR("MPATHz", "WWID9")); +- +- mock_bindings_file(bindings, 1); + expect_condlog(3, FOUND_STR("MPATHc", "WWID2")); + mock_used_alias("MPATHc", "WWID2"); + +@@ -1477,12 +1758,8 @@ static void gufa_old_nomatch_wwidmatch(void **state) { + char *alias; + static const char bindings[] = "MPATHa WWID0"; + +- will_return(__wrap_open_file, true); +- +- mock_bindings_file(bindings, -1); ++ mock_bindings_file(bindings); + expect_condlog(3, NOMATCH_STR("MPATHz")); +- +- mock_bindings_file(bindings, 0); + expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); + mock_unused_alias("MPATHa"); + expect_condlog(3, EXISTING_STR("MPATHa", "WWID0")); +@@ -1495,12 +1772,9 @@ static void gufa_old_nomatch_wwidmatch(void **state) { + static void gufa_old_nomatch_wwidmatch_used(void **state) { + char *alias; + static const char bindings[] = "MPATHa WWID0"; +- will_return(__wrap_open_file, true); + +- mock_bindings_file(bindings, -1); ++ mock_bindings_file(bindings); + expect_condlog(3, NOMATCH_STR("MPATHz")); +- +- mock_bindings_file(bindings, 0); + expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); + mock_used_alias("MPATHa", "WWID0"); + +@@ -1510,17 +1784,13 @@ static void gufa_old_nomatch_wwidmatch_used(void **state) { + + static void gufa_old_nomatch_nowwidmatch(void **state) { + char *alias; +- static const char bindings[] = "MPATHb WWID1"; +- +- will_return(__wrap_open_file, true); ++ static const char bindings[] = "MPATHb WWID1\n"; + +- mock_bindings_file(bindings, -1); ++ mock_bindings_file(bindings); + expect_condlog(3, NOMATCH_STR("MPATHz")); +- +- mock_bindings_file(bindings, -1); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + +- mock_allocate_binding("MPATHz", "WWID0"); ++ mock_allocate_binding_len("MPATHz", "WWID0", sizeof(bindings) - 1); + expect_condlog(2, ALLOC_STR("MPATHz", "WWID0")); + + alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); +@@ -1531,26 +1801,28 @@ static void gufa_old_nomatch_nowwidmatch(void **state) { + static int test_get_user_friendly_alias() + { + const struct CMUnitTest tests[] = { +- cmocka_unit_test(gufa_empty_new_rw), +- cmocka_unit_test(gufa_empty_new_ro_1), +- cmocka_unit_test(gufa_empty_new_ro_2), +- cmocka_unit_test(gufa_match_a_unused), +- cmocka_unit_test(gufa_match_a_self), +- cmocka_unit_test(gufa_match_a_used), +- cmocka_unit_test(gufa_nomatch_a_c), +- cmocka_unit_test(gufa_nomatch_c_a), +- cmocka_unit_test(gufa_nomatch_c_b), +- cmocka_unit_test(gufa_nomatch_c_b_used), +- cmocka_unit_test(gufa_nomatch_b_f_a), +- cmocka_unit_test(gufa_old_empty), +- cmocka_unit_test(gufa_old_match), +- cmocka_unit_test(gufa_old_match_other), +- cmocka_unit_test(gufa_old_match_other_used), +- cmocka_unit_test(gufa_old_match_other_wwidmatch), +- cmocka_unit_test(gufa_old_match_other_wwidmatch_used), +- cmocka_unit_test(gufa_old_nomatch_wwidmatch), +- cmocka_unit_test(gufa_old_nomatch_wwidmatch_used), +- cmocka_unit_test(gufa_old_nomatch_nowwidmatch), ++ cmocka_unit_test_teardown(gufa_empty_new_rw, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_empty_new_ro_1, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_empty_new_ro_2, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_match_a_unused, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_match_a_self, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_match_a_used, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_nomatch_a_c, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_nomatch_c_a, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_nomatch_c_b, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_nomatch_c_b_used, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_nomatch_b_f_a, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_nomatch_b_aa_a, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_nomatch_b_f_a_sorted, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_old_empty, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_old_match, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_old_match_other, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_old_match_other_used, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_old_match_other_wwidmatch, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_old_match_other_wwidmatch_used, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_old_nomatch_wwidmatch, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_old_nomatch_wwidmatch_used, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_old_nomatch_nowwidmatch, teardown_bindings), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +@@ -1566,7 +1838,6 @@ int main(void) + ret += test_lookup_binding(); + ret += test_rlookup_binding(); + ret += test_allocate_binding(); +- ret += test_allocate_binding(); + ret += test_get_user_friendly_alias(); + + return ret; diff --git a/0020-libmultipath-dm_get_uuid-return-emtpy-UUID-for-non-e.patch b/0020-libmultipath-dm_get_uuid-return-emtpy-UUID-for-non-e.patch new file mode 100644 index 0000000..c105b01 --- /dev/null +++ b/0020-libmultipath-dm_get_uuid-return-emtpy-UUID-for-non-e.patch @@ -0,0 +1,53 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 25 Aug 2023 20:35:19 +0200 +Subject: [PATCH] libmultipath: dm_get_uuid(): return emtpy UUID for + non-existing maps + +libdevmapper will most probably not return a UUID for non-existing +maps anyway. But it's cheap to double-check here. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/devmapper.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index 248c3734..9be82f4e 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -706,12 +706,16 @@ dm_get_prefixed_uuid(const char *name, char *uuid, int uuid_len) + { + struct dm_task *dmt; + const char *uuidtmp; ++ struct dm_info info; + int r = 1; + + dmt = libmp_dm_task_create(DM_DEVICE_INFO); + if (!dmt) + return 1; + ++ if (uuid_len > 0) ++ uuid[0] = '\0'; ++ + if (!dm_task_set_name (dmt, name)) + goto uuidout; + +@@ -720,11 +724,13 @@ dm_get_prefixed_uuid(const char *name, char *uuid, int uuid_len) + goto uuidout; + } + ++ if (!dm_task_get_info(dmt, &info) || ++ !info.exists) ++ goto uuidout; ++ + uuidtmp = dm_task_get_uuid(dmt); + if (uuidtmp) + strlcpy(uuid, uuidtmp, uuid_len); +- else +- uuid[0] = '\0'; + + r = 0; + uuidout: diff --git a/0021-libmultipath-adapt-to-new-semantics-of-dm_get_uuid.patch b/0021-libmultipath-adapt-to-new-semantics-of-dm_get_uuid.patch new file mode 100644 index 0000000..4d15554 --- /dev/null +++ b/0021-libmultipath-adapt-to-new-semantics-of-dm_get_uuid.patch @@ -0,0 +1,158 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 28 Aug 2023 12:26:37 +0200 +Subject: [PATCH] libmultipath: adapt to new semantics of dm_get_uuid() + +dm_get_uuid() will return 1 for non-existing maps. Thus we don't need +to call dm_map_present() any more in alias_already_taken(). This changes +our semantics: previously we'd avoid using an alias for which dm_get_uuid() +had failed. Now we treat failure in dm_get_uuid() as indication that the +map doesn't exist. This is not dangerous because dm_task_get_uuid() cannot +fail, and thus the modified dm_get_uuid() will fail if and only if +dm_map_present() would return false. + +This makes the "failed alias" test mostly obsolete, as "failed" is now +treated as "unused". + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/alias.c | 25 +++++++++++++------------ + tests/alias.c | 32 +++++++------------------------- + 2 files changed, 20 insertions(+), 37 deletions(-) + +diff --git a/libmultipath/alias.c b/libmultipath/alias.c +index d6563749..58436ec0 100644 +--- a/libmultipath/alias.c ++++ b/libmultipath/alias.c +@@ -295,18 +295,19 @@ scan_devname(const char *alias, const char *prefix) + static bool alias_already_taken(const char *alias, const char *map_wwid) + { + +- if (dm_map_present(alias)) { +- char wwid[WWID_SIZE]; +- +- /* If both the name and the wwid match, then it's fine.*/ +- if (dm_get_uuid(alias, wwid, sizeof(wwid)) == 0 && +- strncmp(map_wwid, wwid, sizeof(wwid)) == 0) +- return false; +- condlog(3, "%s: alias '%s' already taken, reselecting alias", +- map_wwid, alias); +- return true; +- } +- return false; ++ char wwid[WWID_SIZE]; ++ ++ /* If the map doesn't exist, it's fine */ ++ if (dm_get_uuid(alias, wwid, sizeof(wwid)) != 0) ++ return false; ++ ++ /* If both the name and the wwid match, it's fine.*/ ++ if (strncmp(map_wwid, wwid, sizeof(wwid)) == 0) ++ return false; ++ ++ condlog(3, "%s: alias '%s' already taken, reselecting alias", ++ map_wwid, alias); ++ return true; + } + + static bool id_already_taken(int id, const char *prefix, const char *map_wwid) +diff --git a/tests/alias.c b/tests/alias.c +index 50a21ecf..d1cc487b 100644 +--- a/tests/alias.c ++++ b/tests/alias.c +@@ -73,12 +73,6 @@ int __wrap_mkstemp(char *template) + return 10; + } + +-int __wrap_dm_map_present(const char * str) +-{ +- check_expected(str); +- return mock_type(int); +-} +- + int __wrap_dm_get_uuid(const char *name, char *uuid, int uuid_len) + { + int ret; +@@ -398,14 +392,13 @@ static int test_scan_devname(void) + + static void mock_unused_alias(const char *alias) + { +- expect_string(__wrap_dm_map_present, str, alias); +- will_return(__wrap_dm_map_present, 0); ++ expect_string(__wrap_dm_get_uuid, name, alias); ++ expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); ++ will_return(__wrap_dm_get_uuid, 1); + } + + static void mock_self_alias(const char *alias, const char *wwid) + { +- expect_string(__wrap_dm_map_present, str, alias); +- will_return(__wrap_dm_map_present, 1); + expect_string(__wrap_dm_get_uuid, name, alias); + expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); + will_return(__wrap_dm_get_uuid, 0); +@@ -432,18 +425,13 @@ static void mock_self_alias(const char *alias, const char *wwid) + + #define mock_failed_alias(alias, wwid) \ + do { \ +- expect_string(__wrap_dm_map_present, str, alias); \ +- will_return(__wrap_dm_map_present, 1); \ + expect_string(__wrap_dm_get_uuid, name, alias); \ + expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); \ + will_return(__wrap_dm_get_uuid, 1); \ +- expect_condlog(3, USED_STR(alias, wwid)); \ + } while (0) + + #define mock_used_alias(alias, wwid) \ + do { \ +- expect_string(__wrap_dm_map_present, str, alias); \ +- will_return(__wrap_dm_map_present, 1); \ + expect_string(__wrap_dm_get_uuid, name, alias); \ + expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); \ + will_return(__wrap_dm_get_uuid, 0); \ +@@ -566,9 +554,8 @@ static void lb_empty_failed(void **state) + mock_bindings_file(""); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + mock_failed_alias("MPATHa", "WWID0"); +- mock_unused_alias("MPATHb"); + rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); +- assert_int_equal(rc, 2); ++ assert_int_equal(rc, 1); + assert_ptr_equal(alias, NULL); + free(alias); + } +@@ -666,9 +653,8 @@ static void lb_nomatch_a_3_used_failed_self(void **state) + mock_used_alias("MPATHc", "WWID1"); + mock_used_alias("MPATHd", "WWID1"); + mock_failed_alias("MPATHe", "WWID1"); +- mock_self_alias("MPATHf", "WWID1"); + rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1); +- assert_int_equal(rc, 6); ++ assert_int_equal(rc, 5); + assert_ptr_equal(alias, NULL); + } + +@@ -940,7 +926,7 @@ static void lb_nomatch_b_a_aa(void **state) + + static void lb_nomatch_b_a_aa_zz(void **state) + { +- int rc, i; ++ int rc; + char *alias; + STRBUF_ON_STACK(buf); + +@@ -949,11 +935,7 @@ static void lb_nomatch_b_a_aa_zz(void **state) + * lookup_binding finds MPATHaaa as next free entry, because MPATHaa is + * found before MPATHb, and MPATHzz was in the bindings, too. + */ +- for (i = 0; i <= 26; i++) { +- print_strbuf(&buf, "MPATH"); +- format_devname(&buf, i + 1); +- print_strbuf(&buf, " WWID%d\n", i); +- } ++ fill_bindings(&buf, 0, 26); + print_strbuf(&buf, "MPATHzz WWID676\n"); + mock_bindings_file(get_strbuf_str(&buf)); + expect_condlog(3, NOMATCH_WWID_STR("WWID703")); diff --git a/0022-libmultipath-sort-aliases-by-length-and-strcmp.patch b/0022-libmultipath-sort-aliases-by-length-and-strcmp.patch new file mode 100644 index 0000000..1504bec --- /dev/null +++ b/0022-libmultipath-sort-aliases-by-length-and-strcmp.patch @@ -0,0 +1,98 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 8 Sep 2023 15:19:54 +0200 +Subject: [PATCH] libmultipath: sort aliases by length and strcmp + +The current sort order of aliases is alphabetical, which is does not match +the actual order of aliases, where "mpathaa" > "mpathz". Change the ordering as +follows: first sort by string length, then alphabetically. This will make +sure that for aliases with the same prefix, alias order is correct ("mpathaaa" +will be sorted after "mpathzz", etc). Even for mixed prefixes, the alias +order will be correct for every individual prefix, even though aliases with +different prefixes may alternate in the file. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/alias.c | 45 +++++++++++++++++++++++++++++++++----------- + 1 file changed, 34 insertions(+), 11 deletions(-) + +diff --git a/libmultipath/alias.c b/libmultipath/alias.c +index 58436ec0..af6565b1 100644 +--- a/libmultipath/alias.c ++++ b/libmultipath/alias.c +@@ -117,6 +117,35 @@ static const struct binding *get_binding_for_wwid(const Bindings *bindings, + return NULL; + } + ++/* ++ * Sort order for aliases. ++ * ++ * The "numeric" ordering of aliases for a given prefix P is ++ * Pa, ..., Pz, Paa, ..., Paz, Pba, ... , Pzz, Paaa, ..., Pzzz, Paaaa, ... ++ * We use the fact that for equal prefix, longer strings are always ++ * higher than shorter ones. Strings of equal length are sorted alphabetically. ++ * This is achieved by sorting be length first, then using strcmp(). ++ * If multiple prefixes are in use, the aliases with a given prefix will ++ * not necessarily be in a contiguous range of the vector, but they will ++ * be ordered such that for a given prefix, numercally higher aliases will ++ * always be sorted after lower ones. ++ */ ++static int alias_compar(const void *p1, const void *p2) ++{ ++ const char *alias1 = *((char * const *)p1); ++ const char *alias2 = *((char * const *)p2); ++ ++ if (alias1 && alias2) { ++ ssize_t ldif = strlen(alias1) - strlen(alias2); ++ ++ if (ldif) ++ return ldif; ++ return strcmp(alias1, alias2); ++ } else ++ /* Move NULL alias to the end */ ++ return alias1 ? -1 : alias2 ? 1 : 0; ++} ++ + static int add_binding(Bindings *bindings, const char *alias, const char *wwid) + { + struct binding *bdg; +@@ -128,7 +157,7 @@ static int add_binding(Bindings *bindings, const char *alias, const char *wwid) + * sorted already. + */ + vector_foreach_slot_backwards(bindings, bdg, i) { +- if ((cmp = strcmp(bdg->alias, alias)) <= 0) ++ if ((cmp = alias_compar(&bdg->alias, &alias)) <= 0) + break; + } + +@@ -657,16 +686,10 @@ static int _check_bindings_file(const struct config *conf, FILE *file, + return rc; + } + +-static int alias_compar(const void *p1, const void *p2) ++static int mp_alias_compar(const void *p1, const void *p2) + { +- const char *alias1 = (*(struct mpentry * const *)p1)->alias; +- const char *alias2 = (*(struct mpentry * const *)p2)->alias; +- +- if (alias1 && alias2) +- return strcmp(alias1, alias2); +- else +- /* Move NULL alias to the end */ +- return alias1 ? -1 : alias2 ? 1 : 0; ++ return alias_compar(&((*(struct mpentry * const *)p1)->alias), ++ &((*(struct mpentry * const *)p2)->alias)); + } + + /* +@@ -700,7 +723,7 @@ int check_alias_settings(const struct config *conf) + pthread_cleanup_push_cast(free_bindings, &bindings); + pthread_cleanup_push(cleanup_vector_free, mptable); + +- vector_sort(mptable, alias_compar); ++ vector_sort(mptable, mp_alias_compar); + vector_foreach_slot(mptable, mpe, i) { + if (!mpe->alias) + /* diff --git a/0023-multipath-tools-tests-fix-alias-test-after-sort-orde.patch b/0023-multipath-tools-tests-fix-alias-test-after-sort-orde.patch new file mode 100644 index 0000000..dd0f29d --- /dev/null +++ b/0023-multipath-tools-tests-fix-alias-test-after-sort-orde.patch @@ -0,0 +1,90 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 8 Sep 2023 15:46:02 +0200 +Subject: [PATCH] multipath-tools tests: fix alias test after sort order change + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + tests/alias.c | 30 ++++++++++++------------------ + 1 file changed, 12 insertions(+), 18 deletions(-) + +diff --git a/tests/alias.c b/tests/alias.c +index d1cc487b..8ed95d7a 100644 +--- a/tests/alias.c ++++ b/tests/alias.c +@@ -932,16 +932,15 @@ static void lb_nomatch_b_a_aa_zz(void **state) + + /* + * add_bindings() sorts alphabetically. ("a", "aa", "ab", "b", "c", ...) +- * lookup_binding finds MPATHaaa as next free entry, because MPATHaa is +- * found before MPATHb, and MPATHzz was in the bindings, too. ++ * lookup_binding finds MPATHab as next free entry. + */ + fill_bindings(&buf, 0, 26); + print_strbuf(&buf, "MPATHzz WWID676\n"); + mock_bindings_file(get_strbuf_str(&buf)); + expect_condlog(3, NOMATCH_WWID_STR("WWID703")); +- mock_unused_alias("MPATHaaa"); ++ mock_unused_alias("MPATHab"); + rc = lookup_binding(NULL, "WWID703", &alias, "MPATH", 1); +- assert_int_equal(rc, 703); ++ assert_int_equal(rc, 28); + assert_ptr_equal(alias, NULL); + } + +@@ -998,13 +997,8 @@ static void lb_nomatch_b_a_3_used(void **state) + + #ifdef MPATH_ID_INT_MAX + /* +- * The bindings will be sorted by alias, alphabetically, which is not +- * the same as the "numeric" sort order for user-friendly aliases. +- * get_free_id() selects the highest used ID + 1 if an unsorted entry +- * is encountered in the bindings table and it's id is equal to the +- * next "expected" id. This happens if all IDs from "a" to "aa" are +- * in the table. If the INT_MAX entry is in the table, too, it will +- * overflow. ++ * The bindings will be sorted by alias. Therefore we have no chance to ++ * simulate a "full" table. + */ + static void lb_nomatch_int_max(void **state) + { +@@ -1016,9 +1010,9 @@ static void lb_nomatch_int_max(void **state) + print_strbuf(&buf, "MPATH%s WWIDMAX\n", MPATH_ID_INT_MAX); + mock_bindings_file(get_strbuf_str(&buf)); + expect_condlog(3, NOMATCH_WWID_STR("WWIDNOMORE")); +- expect_condlog(0, NOMORE_STR); ++ mock_unused_alias("MPATHab"); + rc = lookup_binding(NULL, "WWIDNOMORE", &alias, "MPATH", 1); +- assert_int_equal(rc, -1); ++ assert_int_equal(rc, 28); + assert_ptr_equal(alias, NULL); + } + +@@ -1049,9 +1043,9 @@ static void lb_nomatch_int_max_m1(void **state) + print_strbuf(&buf, "MPATH%s WWIDMAXM1\n", MPATH_ID_INT_MAX_m1); + mock_bindings_file(get_strbuf_str(&buf)); + expect_condlog(3, NOMATCH_WWID_STR("WWIDMAX")); +- mock_unused_alias("MPATH" MPATH_ID_INT_MAX); ++ mock_unused_alias("MPATHab"); + rc = lookup_binding(NULL, "WWIDMAX", &alias, "MPATH", 1); +- assert_int_equal(rc, INT_MAX); ++ assert_int_equal(rc, 28); + assert_ptr_equal(alias, NULL); + } + +@@ -1065,10 +1059,10 @@ static void lb_nomatch_int_max_m1_used(void **state) + print_strbuf(&buf, "MPATH%s WWIDMAXM1\n", MPATH_ID_INT_MAX_m1); + mock_bindings_file(get_strbuf_str(&buf)); + expect_condlog(3, NOMATCH_WWID_STR("WWIDMAX")); +- mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWIDMAX"); +- expect_condlog(0, NOMORE_STR); ++ mock_used_alias("MPATHab", "WWIDMAX"); ++ mock_unused_alias("MPATHac"); + rc = lookup_binding(NULL, "WWIDMAX", &alias, "MPATH", 1); +- assert_int_equal(rc, -1); ++ assert_int_equal(rc, 29); + assert_ptr_equal(alias, NULL); + } + diff --git a/0024-libmultipath-simplify-get_free_id-assuming-total-ord.patch b/0024-libmultipath-simplify-get_free_id-assuming-total-ord.patch new file mode 100644 index 0000000..b16b3da --- /dev/null +++ b/0024-libmultipath-simplify-get_free_id-assuming-total-ord.patch @@ -0,0 +1,122 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 8 Sep 2023 19:50:51 +0200 +Subject: [PATCH] libmultipath: simplify get_free_id() assuming total ordering + +If we can assume that the bindings array is totally ordered for every +prefix, which the previous patch guarantees, the search for a free ID can be +simplified. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/alias.c | 85 ++++++++++---------------------------------- + 1 file changed, 18 insertions(+), 67 deletions(-) + +diff --git a/libmultipath/alias.c b/libmultipath/alias.c +index af6565b1..66e34e31 100644 +--- a/libmultipath/alias.c ++++ b/libmultipath/alias.c +@@ -356,83 +356,34 @@ int get_free_id(const Bindings *bindings, const char *prefix, const char *map_ww + { + const struct binding *bdg; + int i, id = 1; +- int biggest_id = 1; +- int smallest_bigger_id = INT_MAX; + + vector_foreach_slot(bindings, bdg, i) { + int curr_id = scan_devname(bdg->alias, prefix); + +- /* +- * Find an unused index - explanation of the algorithm +- * +- * ID: 1 = mpatha, 2 = mpathb, ... +- * +- * We assume the bindings are unsorted. The only constraint +- * is that no ID occurs more than once. IDs that occur in the +- * bindings are called "used". +- * +- * We call the list 1,2,3,..., exactly in this order, the list +- * of "expected" IDs. The variable "id" always holds the next +- * "expected" ID, IOW the last "expected" ID encountered plus 1. +- * Thus all IDs below "id" are known to be used. However, at the +- * end of the loop, the value of "id" isn't necessarily unused. +- * +- * "smallest_bigger_id" is the smallest used ID that was +- * encountered while it was larger than the next "expected" ID +- * at that iteration. Let X be some used ID. If all IDs below X +- * are used and encountered in the right sequence before X, "id" +- * will be > X when the loop ends. Otherwise, X was encountered +- * "out of order", the condition (X > id) holds when X is +- * encountered, and "smallest_bigger_id" will be set to X; i.e. +- * it will be less or equal than X when the loop ends. +- * +- * At the end of the loop, (id < smallest_bigger_id) means that +- * the value of "id" had been encountered neither in order nor +- * out of order, and is thus unused. (id >= smallest_bigger_id) +- * means that "id"'s value is in use. In this case, we play safe +- * and use "biggest_id + 1" as the next value to try. +- * +- * biggest_id is always > smallest_bigger_id, except in the +- * "perfectly ordered" case. +- */ +- if (curr_id == id) { +- if (id < INT_MAX) +- id++; +- else { +- id = -1; +- break; +- } ++ if (curr_id == -1) ++ continue; ++ if (id > curr_id) { ++ condlog(0, "%s: ERROR: bindings are not sorted", __func__); ++ return -1; + } +- if (curr_id > biggest_id) +- biggest_id = curr_id; +- +- if (curr_id > id && curr_id < smallest_bigger_id) +- smallest_bigger_id = curr_id; ++ while (id < curr_id && id_already_taken(id, prefix, map_wwid)) ++ id++; ++ if (id < curr_id) ++ return id; ++ id++; ++ if (id <= 0) ++ break; + } + +- if (id >= smallest_bigger_id) +- id = biggest_id < INT_MAX ? biggest_id + 1 : -1; +- +- if (id > 0) { +- while(id_already_taken(id, prefix, map_wwid)) { +- if (id == INT_MAX) { +- id = -1; +- break; +- } +- id++; +- if (id == smallest_bigger_id) { +- if (biggest_id == INT_MAX) { +- id = -1; +- break; +- } +- if (biggest_id >= smallest_bigger_id) +- id = biggest_id + 1; +- } +- } ++ for (; id > 0; id++) { ++ if (!id_already_taken(id, prefix, map_wwid)) ++ break; + } + +- if (id < 0) ++ if (id <= 0) { ++ id = -1; + condlog(0, "no more available user_friendly_names"); ++ } + return id; + } + diff --git a/0025-multipath-tools-tests-adapt-alias-tests-for-total-or.patch b/0025-multipath-tools-tests-adapt-alias-tests-for-total-or.patch new file mode 100644 index 0000000..b1d6b15 --- /dev/null +++ b/0025-multipath-tools-tests-adapt-alias-tests-for-total-or.patch @@ -0,0 +1,203 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 8 Sep 2023 19:58:03 +0200 +Subject: [PATCH] multipath-tools tests: adapt alias tests for total ordering + +The "unsorted" test fail now, and are removed. The algorithm is now +better at finding "gaps". + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + tests/alias.c | 88 ++++++++------------------------------------------- + 1 file changed, 14 insertions(+), 74 deletions(-) + +diff --git a/tests/alias.c b/tests/alias.c +index 8ed95d7a..dff5f93b 100644 +--- a/tests/alias.c ++++ b/tests/alias.c +@@ -439,27 +439,7 @@ static void mock_self_alias(const char *alias, const char *wwid) + expect_condlog(3, USED_STR(alias, wwid)); \ + } while(0) + +-static int add_binding_unsorted(Bindings *bindings, +- const char *alias, const char *wwid) +-{ +- struct binding *bdg = calloc(1, sizeof(*bdg)); +- +- if (!bdg) +- return -1; +- bdg->wwid = strdup(wwid); +- bdg->alias = strdup(alias); +- if (!bdg->wwid || !bdg->alias || !vector_alloc_slot(bindings)) { +- free(bdg->alias); +- free(bdg->wwid); +- free(bdg); +- return BINDING_ERROR; +- } +- vector_set_slot(bindings, bdg); +- return BINDING_ADDED; +-} +- +-static void __mock_bindings_file(const char *content, +- int (*add)(Bindings *, const char *, const char *)) ++static void __mock_bindings_file(const char *content) + { + char *cnt __attribute__((cleanup(cleanup_charp))) = NULL; + char *token, *savep = NULL; +@@ -478,17 +458,13 @@ static void __mock_bindings_file(const char *content, + == READ_BINDING_SKIP) + continue; + +- rc = add(&global_bindings, alias, wwid); ++ rc = add_binding(&global_bindings, alias, wwid); + assert_int_equal(rc, BINDING_ADDED); + } + } + + static void mock_bindings_file(const char *content) { +- return __mock_bindings_file(content, add_binding); +-} +- +-static void mock_bindings_file_unsorted(const char *content) { +- return __mock_bindings_file(content, add_binding_unsorted); ++ return __mock_bindings_file(content); + } + + static int teardown_bindings(void **state) +@@ -861,10 +837,6 @@ static void lb_nomatch_b_z_a(void **state) + int rc; + char *alias; + +- /* +- * add_bindings() sorts alphabetically. Therefore get_free_id() +- * finds MPATHc as a free entry. +- */ + mock_bindings_file("MPATHb WWID1\n" + "MPATHz WWID26\n" + "MPATHa WWID0\n"); +@@ -880,10 +852,6 @@ static void lb_nomatch_b_aa_a(void **state) + int rc; + char *alias; + +- /* +- * add_bindings() sorts alphabetically. ("a", "aa", b"). +- * The get_free_id() algorithm finds the "hole" after "b". +- */ + mock_bindings_file("MPATHb WWID1\n" + "MPATHz WWID26\n" + "MPATHa WWID0\n"); +@@ -911,10 +879,6 @@ static void lb_nomatch_b_a_aa(void **state) + char *alias; + STRBUF_ON_STACK(buf); + +- /* +- * add_bindings() sorts alphabetically. ("a", "aa", "ab", "b", "c", ...) +- * lookup_binding finds MPATHac as next free entry. +- */ + fill_bindings(&buf, 0, 26); + mock_bindings_file(get_strbuf_str(&buf)); + expect_condlog(3, NOMATCH_WWID_STR("WWID28")); +@@ -930,10 +894,6 @@ static void lb_nomatch_b_a_aa_zz(void **state) + char *alias; + STRBUF_ON_STACK(buf); + +- /* +- * add_bindings() sorts alphabetically. ("a", "aa", "ab", "b", "c", ...) +- * lookup_binding finds MPATHab as next free entry. +- */ + fill_bindings(&buf, 0, 26); + print_strbuf(&buf, "MPATHzz WWID676\n"); + mock_bindings_file(get_strbuf_str(&buf)); +@@ -944,25 +904,6 @@ static void lb_nomatch_b_a_aa_zz(void **state) + assert_ptr_equal(alias, NULL); + } + +-static void lb_nomatch_b_z_a_unsorted(void **state) +-{ +- int rc; +- char *alias; +- +- /* +- * With unsorted bindings (shouldn't happen normally), get_free_id() +- * plays safe and returns MPATHaa as first free entry. +- */ +- mock_bindings_file_unsorted("MPATHb WWID1\n" +- "MPATHz WWID26\n" +- "MPATHa WWID0\n"); +- expect_condlog(3, NOMATCH_WWID_STR("WWID2")); +- mock_unused_alias("MPATHaa"); +- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); +- assert_int_equal(rc, 27); +- assert_ptr_equal(alias, NULL); +-} +- + static void lb_nomatch_b_a(void **state) + { + int rc; +@@ -1027,9 +968,9 @@ static void lb_nomatch_int_max_used(void **state) + mock_bindings_file(get_strbuf_str(&buf)); + expect_condlog(3, NOMATCH_WWID_STR("WWIDNOMORE")); + mock_used_alias("MPATHa", "WWIDNOMORE"); +- expect_condlog(0, NOMORE_STR); ++ mock_unused_alias("MPATHab"); + rc = lookup_binding(NULL, "WWIDNOMORE", &alias, "MPATH", 1); +- assert_int_equal(rc, -1); ++ assert_int_equal(rc, 28); + assert_ptr_equal(alias, NULL); + } + +@@ -1077,9 +1018,9 @@ static void lb_nomatch_int_max_m1_1_used(void **state) + mock_bindings_file(get_strbuf_str(&buf)); + expect_condlog(3, NOMATCH_WWID_STR("WWIDMAX")); + mock_used_alias("MPATHa", "WWIDMAX"); +- mock_unused_alias("MPATH" MPATH_ID_INT_MAX); ++ mock_unused_alias("MPATHab"); + rc = lookup_binding(NULL, "WWIDMAX", &alias, "MPATH", 1); +- assert_int_equal(rc, INT_MAX); ++ assert_int_equal(rc, 28); + assert_ptr_equal(alias, NULL); + } + +@@ -1095,10 +1036,10 @@ static void lb_nomatch_int_max_m1_2_used(void **state) + + expect_condlog(3, NOMATCH_WWID_STR("WWIDMAX")); + mock_used_alias("MPATHa", "WWIDMAX"); +- mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWIDMAX"); +- expect_condlog(0, NOMORE_STR); ++ mock_used_alias("MPATHab", "WWIDMAX"); ++ mock_unused_alias("MPATHac"); + rc = lookup_binding(NULL, "WWIDMAX", &alias, "MPATH", 1); +- assert_int_equal(rc, -1); ++ assert_int_equal(rc, 29); + assert_ptr_equal(alias, NULL); + } + #endif +@@ -1133,7 +1074,6 @@ static int test_lookup_binding(void) + cmocka_unit_test_teardown(lb_nomatch_b_aa_a, teardown_bindings), + cmocka_unit_test_teardown(lb_nomatch_b_a_aa, teardown_bindings), + cmocka_unit_test_teardown(lb_nomatch_b_a_aa_zz, teardown_bindings), +- cmocka_unit_test_teardown(lb_nomatch_b_z_a_unsorted, teardown_bindings), + cmocka_unit_test_teardown(lb_nomatch_b_a, teardown_bindings), + cmocka_unit_test_teardown(lb_nomatch_b_a_3_used, teardown_bindings), + #ifdef MPATH_ID_INT_MAX +@@ -1593,14 +1533,14 @@ static void gufa_nomatch_b_f_a(void **state) { + "MPATHf WWID6\n" + "MPATHa WWID0\n"); + +- mock_bindings_file_unsorted(bindings); ++ mock_bindings_file(bindings); + expect_condlog(3, NOMATCH_WWID_STR("WWID7")); +- mock_unused_alias("MPATHg"); ++ mock_unused_alias("MPATHc"); + +- mock_allocate_binding_len("MPATHg", "WWID7", sizeof(bindings) - 1); ++ mock_allocate_binding_len("MPATHc", "WWID7", sizeof(bindings) - 1); + + alias = get_user_friendly_alias("WWID7", "x", "", "MPATH", false); +- assert_string_equal(alias, "MPATHg"); ++ assert_string_equal(alias, "MPATHc"); + free(alias); + } + diff --git a/0026-multipath-tools-tests-add-test-for-ordering-of-bindi.patch b/0026-multipath-tools-tests-add-test-for-ordering-of-bindi.patch new file mode 100644 index 0000000..5317ef9 --- /dev/null +++ b/0026-multipath-tools-tests-add-test-for-ordering-of-bindi.patch @@ -0,0 +1,275 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 8 Sep 2023 21:39:44 +0200 +Subject: [PATCH] multipath-tools tests: add test for ordering of bindings + +As the assignment of free aliases now relies on the bindings being +properly sorted, add some unit tests to make sure the sorting algorithm +works. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + tests/alias.c | 212 +++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 209 insertions(+), 3 deletions(-) + +diff --git a/tests/alias.c b/tests/alias.c +index dff5f93b..7f3ff38a 100644 +--- a/tests/alias.c ++++ b/tests/alias.c +@@ -13,6 +13,9 @@ + #include "globals.c" + #include "../libmultipath/alias.c" + ++/* For verbose printing of all aliases in the ordering tests */ ++#define ALIAS_DEBUG 0 ++ + #if INT_MAX == 0x7fffffff + /* user_friendly_name for map #INT_MAX */ + #define MPATH_ID_INT_MAX "fxshrxw" +@@ -439,11 +442,12 @@ static void mock_self_alias(const char *alias, const char *wwid) + expect_condlog(3, USED_STR(alias, wwid)); \ + } while(0) + +-static void __mock_bindings_file(const char *content) ++static void __mock_bindings_file(const char *content, bool conflict_ok) + { + char *cnt __attribute__((cleanup(cleanup_charp))) = NULL; + char *token, *savep = NULL; + int i; ++ uintmax_t values[] = { BINDING_ADDED, BINDING_CONFLICT }; + + cnt = strdup(content); + assert_ptr_not_equal(cnt, NULL); +@@ -459,12 +463,12 @@ static void __mock_bindings_file(const char *content) + continue; + + rc = add_binding(&global_bindings, alias, wwid); +- assert_int_equal(rc, BINDING_ADDED); ++ assert_in_set(rc, values, conflict_ok ? 2 : 1); + } + } + + static void mock_bindings_file(const char *content) { +- return __mock_bindings_file(content); ++ return __mock_bindings_file(content, false); + } + + static int teardown_bindings(void **state) +@@ -1744,6 +1748,207 @@ static int test_get_user_friendly_alias() + return cmocka_run_group_tests(tests, NULL, NULL); + } + ++/* Numbers 1-1000, randomly shuffled */ ++static const int random_numbers[1000] = { ++ 694, 977, 224, 178, 841, 818, 914, 549, 831, 942, 263, 834, 919, 800, ++ 111, 517, 719, 297, 988, 98, 332, 516, 754, 772, 495, 488, 331, 529, ++ 142, 747, 848, 618, 375, 624, 74, 753, 782, 944, 623, 468, 862, 997, ++ 417, 258, 298, 774, 673, 904, 883, 766, 867, 400, 11, 950, 14, 784, ++ 655, 155, 396, 9, 743, 93, 651, 245, 968, 306, 785, 581, 880, 486, ++ 168, 631, 203, 4, 663, 294, 702, 762, 619, 684, 48, 181, 21, 443, 643, ++ 863, 1000, 327, 26, 126, 382, 765, 586, 76, 49, 925, 319, 865, 797, ++ 876, 693, 334, 433, 243, 419, 901, 854, 326, 985, 347, 874, 527, 282, ++ 290, 380, 167, 95, 3, 257, 936, 60, 426, 227, 345, 577, 492, 467, 580, ++ 967, 422, 823, 718, 610, 64, 700, 412, 163, 288, 506, 828, 432, 51, ++ 356, 348, 539, 478, 17, 945, 602, 123, 450, 660, 429, 113, 310, 358, ++ 512, 758, 508, 19, 542, 304, 286, 446, 918, 723, 333, 603, 731, 978, ++ 230, 697, 109, 872, 175, 853, 947, 965, 121, 222, 101, 811, 117, 601, ++ 191, 752, 384, 415, 938, 278, 915, 715, 240, 552, 912, 838, 150, 840, ++ 627, 29, 636, 464, 861, 481, 992, 249, 934, 82, 368, 724, 807, 593, ++ 157, 147, 199, 637, 41, 62, 902, 505, 621, 342, 174, 260, 729, 961, ++ 219, 311, 629, 789, 81, 739, 860, 712, 223, 165, 741, 981, 485, 363, ++ 346, 709, 125, 369, 279, 634, 399, 162, 193, 769, 149, 314, 868, 612, ++ 524, 675, 341, 343, 476, 606, 388, 613, 850, 264, 903, 451, 908, 779, ++ 453, 148, 497, 46, 132, 43, 885, 955, 269, 395, 72, 128, 767, 989, ++ 929, 423, 742, 55, 13, 79, 924, 182, 295, 563, 668, 169, 974, 154, ++ 970, 54, 674, 52, 437, 570, 550, 531, 554, 793, 678, 218, 367, 105, ++ 197, 315, 958, 892, 86, 47, 284, 37, 561, 522, 198, 689, 817, 573, ++ 877, 201, 803, 501, 881, 546, 530, 523, 780, 579, 953, 135, 23, 620, ++ 84, 698, 303, 656, 357, 323, 494, 58, 131, 913, 995, 120, 70, 1, 195, ++ 365, 210, 25, 898, 173, 307, 239, 77, 418, 952, 963, 92, 455, 425, 12, ++ 536, 161, 328, 933, 401, 251, 735, 725, 362, 322, 557, 681, 302, 53, ++ 786, 801, 391, 946, 748, 133, 717, 851, 7, 372, 993, 387, 906, 373, ++ 667, 33, 670, 389, 209, 611, 896, 652, 69, 999, 344, 845, 633, 36, ++ 487, 192, 180, 45, 640, 427, 707, 805, 188, 152, 905, 217, 30, 252, ++ 386, 665, 299, 541, 410, 787, 5, 857, 751, 392, 44, 595, 146, 745, ++ 641, 957, 866, 773, 806, 815, 659, 102, 704, 430, 106, 296, 129, 847, ++ 130, 990, 669, 236, 225, 680, 159, 213, 438, 189, 447, 600, 232, 594, ++ 32, 56, 390, 647, 855, 428, 330, 714, 738, 706, 666, 461, 469, 482, ++ 558, 814, 559, 177, 575, 538, 309, 383, 261, 156, 420, 761, 630, 893, ++ 10, 116, 940, 844, 71, 377, 662, 312, 520, 244, 143, 759, 119, 186, ++ 592, 909, 864, 376, 768, 254, 265, 394, 511, 760, 574, 6, 436, 514, ++ 59, 226, 644, 956, 578, 825, 548, 145, 736, 597, 378, 821, 987, 897, ++ 354, 144, 722, 895, 589, 503, 826, 498, 543, 617, 763, 231, 808, 528, ++ 89, 479, 607, 737, 170, 404, 371, 65, 103, 340, 283, 141, 313, 858, ++ 289, 124, 971, 687, 954, 732, 39, 926, 176, 100, 267, 519, 890, 535, ++ 276, 448, 27, 457, 899, 385, 184, 275, 770, 544, 614, 449, 160, 658, ++ 259, 973, 108, 604, 24, 207, 562, 757, 744, 324, 444, 962, 591, 480, ++ 398, 409, 998, 253, 325, 445, 979, 8, 35, 118, 73, 683, 208, 85, 190, ++ 791, 408, 871, 657, 179, 18, 556, 496, 475, 20, 894, 484, 775, 889, ++ 463, 241, 730, 57, 907, 551, 859, 943, 185, 416, 870, 590, 435, 471, ++ 932, 268, 381, 626, 502, 565, 273, 534, 672, 778, 292, 473, 566, 104, ++ 172, 285, 832, 411, 329, 628, 397, 472, 271, 910, 711, 690, 969, 585, ++ 809, 941, 923, 555, 228, 685, 242, 94, 96, 211, 140, 61, 922, 795, ++ 869, 34, 255, 38, 984, 676, 15, 560, 632, 434, 921, 355, 582, 351, ++ 212, 200, 819, 960, 649, 852, 75, 771, 361, 996, 238, 316, 720, 671, ++ 462, 112, 569, 171, 664, 625, 588, 405, 553, 270, 533, 353, 842, 114, ++ 972, 83, 937, 63, 194, 237, 537, 980, 802, 916, 959, 688, 839, 350, ++ 917, 650, 545, 615, 151, 352, 686, 726, 266, 509, 439, 491, 935, 608, ++ 518, 653, 339, 609, 277, 635, 836, 88, 407, 440, 642, 927, 229, 727, ++ 360, 477, 846, 413, 454, 616, 28, 598, 567, 540, 790, 424, 247, 317, ++ 746, 911, 798, 321, 547, 248, 734, 829, 220, 138, 756, 500, 691, 196, ++ 740, 930, 843, 733, 221, 827, 50, 813, 949, 525, 349, 474, 134, 875, ++ 695, 513, 414, 515, 638, 99, 366, 490, 975, 246, 465, 206, 281, 583, ++ 256, 587, 749, 2, 951, 679, 215, 364, 458, 402, 646, 991, 335, 982, ++ 835, 300, 900, 703, 994, 983, 234, 888, 532, 804, 584, 305, 792, 442, ++ 291, 964, 158, 370, 452, 250, 521, 166, 948, 812, 794, 272, 699, 205, ++ 183, 507, 301, 920, 781, 233, 824, 137, 489, 833, 887, 966, 856, 78, ++ 830, 153, 359, 696, 526, 216, 66, 701, 403, 891, 849, 571, 308, 483, ++ 164, 293, 928, 677, 320, 837, 441, 639, 564, 510, 648, 274, 336, 661, ++ 878, 777, 816, 976, 493, 810, 67, 87, 91, 187, 882, 986, 80, 22, 499, ++ 90, 705, 139, 136, 122, 708, 716, 886, 572, 127, 40, 721, 764, 16, ++ 379, 692, 645, 456, 710, 460, 783, 97, 776, 713, 884, 115, 466, 596, ++ 374, 406, 110, 568, 68, 214, 622, 470, 107, 504, 682, 31, 421, 576, ++ 654, 605, 788, 799, 280, 338, 931, 873, 204, 287, 459, 755, 939, 599, ++ 431, 796, 235, 42, 750, 262, 318, 393, 202, 822, 879, 820, 728, 337, ++}; ++ ++static void fill_bindings_random(struct strbuf *buf, int start, int end, ++ const char *prefix) ++{ ++ int i; ++ ++ for (i = start; i < end; i++) { ++ print_strbuf(buf, "%s", prefix); ++ format_devname(buf, random_numbers[i]); ++ print_strbuf(buf, " WWID%d\n", random_numbers[i]); ++ } ++} ++ ++struct random_aliases { ++ int start; ++ int end; ++ const char *prefix; ++}; ++ ++static void order_test(int n, const struct random_aliases ra[], bool conflict_ok) ++{ ++ STRBUF_ON_STACK(buf); ++ int i, j, prev, curr, tmp; ++ struct binding *bdg; ++ Bindings *bindings = &global_bindings; ++ ++ for (j = 0; j < n; j++) ++ fill_bindings_random(&buf, ra[j].start, ra[j].end, ra[j].prefix); ++ __mock_bindings_file(get_strbuf_str(&buf), conflict_ok); ++ ++ for (j = 0; j < n; j++) { ++ bdg = VECTOR_SLOT(bindings, 0); ++ if (ALIAS_DEBUG && j == 0) ++ printf("%d: %s\n", 0, bdg->alias); ++ prev = scan_devname(bdg->alias, ra[j].prefix); ++ i = 1; ++ vector_foreach_slot_after(bindings, bdg, i) { ++ if (ALIAS_DEBUG && j == 0) ++ printf("%d: %s\n", i, bdg->alias); ++ tmp = scan_devname(bdg->alias, ra[j].prefix); ++ if (tmp == -1) ++ continue; ++ curr = tmp; ++ if (prev > 0) { ++ if (curr <= prev) ++ printf("ERROR: %d (%s) %d >= %d\n", ++ i, bdg->alias, prev, curr); ++ assert_true(curr > prev); ++ } ++ prev = curr; ++ } ++ } ++} ++ ++static void order_01(void **state) ++{ ++ const struct random_aliases ra[] = { ++ { 0, 1000, "MPATH" }, ++ }; ++ ++ order_test(ARRAY_SIZE(ra), ra, false); ++} ++ ++static void order_02(void **state) ++{ ++ const struct random_aliases ra[] = { ++ { 0, 500, "MPATH" }, ++ { 200, 700, "mpath" }, ++ }; ++ order_test(ARRAY_SIZE(ra), ra, false); ++} ++ ++static void order_03(void **state) ++{ ++ const struct random_aliases ra[] = { ++ { 500, 1000, "MPTH" }, ++ { 0, 500, "MPATH" }, ++ }; ++ order_test(ARRAY_SIZE(ra), ra, false); ++} ++ ++static void order_04(void **state) ++{ ++ const struct random_aliases ra[] = { ++ { 0, 500, "mpa" }, ++ { 250, 750, "mp" }, ++ }; ++ order_test(ARRAY_SIZE(ra), ra, true); ++} ++ ++static void order_05(void **state) ++{ ++ const struct random_aliases ra[] = { ++ { 0, 100, "A" }, ++ { 0, 100, "B" }, ++ { 0, 100, "C" }, ++ { 0, 100, "D" }, ++ }; ++ order_test(ARRAY_SIZE(ra), ra, false); ++} ++ ++static void order_06(void **state) ++{ ++ const struct random_aliases ra[] = { ++ { 0, 100, "" }, ++ { 0, 100, "a" }, ++ { 0, 100, "aa" }, ++ { 0, 100, "ab" }, ++ { 0, 100, "aaa" }, ++ }; ++ order_test(ARRAY_SIZE(ra), ra, true); ++} ++ ++static int test_bindings_order() ++{ ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test_teardown(order_01, teardown_bindings), ++ cmocka_unit_test_teardown(order_02, teardown_bindings), ++ cmocka_unit_test_teardown(order_03, teardown_bindings), ++ cmocka_unit_test_teardown(order_04, teardown_bindings), ++ cmocka_unit_test_teardown(order_05, teardown_bindings), ++ cmocka_unit_test_teardown(order_06, teardown_bindings), ++ }; ++ ++ return cmocka_run_group_tests(tests, NULL, NULL); ++} ++ + int main(void) + { + int ret = 0; +@@ -1755,6 +1960,7 @@ int main(void) + ret += test_rlookup_binding(); + ret += test_allocate_binding(); + ret += test_get_user_friendly_alias(); ++ ret += test_bindings_order(); + + return ret; + } diff --git a/0027-multipathd-watch-bindings-file-with-inotify-timestam.patch b/0027-multipathd-watch-bindings-file-with-inotify-timestam.patch new file mode 100644 index 0000000..af21b74 --- /dev/null +++ b/0027-multipathd-watch-bindings-file-with-inotify-timestam.patch @@ -0,0 +1,597 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 7 Sep 2023 22:22:43 +0200 +Subject: [PATCH] multipathd: watch bindings file with inotify + timestamp + +Since "libmultipath: keep bindings in memory", we don't re-read the +bindings file after every modification. Add a notification mechanism +that makes multipathd aware of changes to the bindings file. Because +multipathd itself will change the bindings file, it must compare +timestamps in order to avoid reading the file repeatedly. + +Because select_alias() can be called from multiple thread contexts (uxlsnr, +uevent handler), we need to add locking for the bindings file. The +timestamp must also be protected by a lock, because it can't be read +or written atomically. + +Note: The notification mechanism expects the bindings file to be +atomically replaced by rename(2). Changes must be made in a temporary file and +applied using rename(2), as in update_bindings_file(). The inotify +mechanism deliberately does not listen to close-after-write events +that would be generated by editing the bindings file directly. This + +Note also: new bindings will only be read from add_map_with_path(), +i.e. either during reconfigure(), or when a new map is created during +runtime. Existing maps will not be renamed if the binding file changes, +unless the user runs "multipathd reconfigure". This is not a change +wrt the previous code, but it should be mentioned anyway. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/alias.c | 256 +++++++++++++++++++++++++----- + libmultipath/alias.h | 3 +- + libmultipath/libmultipath.version | 5 + + multipathd/uxlsnr.c | 36 ++++- + tests/alias.c | 3 + + 5 files changed, 256 insertions(+), 47 deletions(-) + +diff --git a/libmultipath/alias.c b/libmultipath/alias.c +index 66e34e31..964b8a7b 100644 +--- a/libmultipath/alias.c ++++ b/libmultipath/alias.c +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + + #include "debug.h" + #include "util.h" +@@ -22,6 +23,7 @@ + #include "config.h" + #include "devmapper.h" + #include "strbuf.h" ++#include "time-util.h" + + /* + * significant parts of this file were taken from iscsi-bindings.c of the +@@ -50,6 +52,12 @@ + "# alias wwid\n" \ + "#\n" + ++/* uatomic access only */ ++static int bindings_file_changed = 1; ++ ++static pthread_mutex_t timestamp_mutex = PTHREAD_MUTEX_INITIALIZER; ++static struct timespec bindings_last_updated; ++ + struct binding { + char *alias; + char *wwid; +@@ -60,6 +68,9 @@ struct binding { + * an abstract type. + */ + typedef struct _vector Bindings; ++ ++/* Protect global_bindings */ ++static pthread_mutex_t bindings_mutex = PTHREAD_MUTEX_INITIALIZER; + static Bindings global_bindings = { .allocated = 0 }; + + enum { +@@ -78,6 +89,27 @@ static void _free_binding(struct binding *bdg) + free(bdg); + } + ++static void free_bindings(Bindings *bindings) ++{ ++ struct binding *bdg; ++ int i; ++ ++ vector_foreach_slot(bindings, bdg, i) ++ _free_binding(bdg); ++ vector_reset(bindings); ++} ++ ++static void set_global_bindings(Bindings *bindings) ++{ ++ Bindings old_bindings; ++ ++ pthread_mutex_lock(&bindings_mutex); ++ old_bindings = global_bindings; ++ global_bindings = *bindings; ++ pthread_mutex_unlock(&bindings_mutex); ++ free_bindings(&old_bindings); ++} ++ + static const struct binding *get_binding_for_alias(const Bindings *bindings, + const char *alias) + { +@@ -199,7 +231,8 @@ static int delete_binding(Bindings *bindings, const char *wwid) + return BINDING_DELETED; + } + +-static int write_bindings_file(const Bindings *bindings, int fd) ++static int write_bindings_file(const Bindings *bindings, int fd, ++ struct timespec *ts) + { + struct binding *bnd; + STRBUF_ON_STACK(content); +@@ -227,9 +260,56 @@ static int write_bindings_file(const Bindings *bindings, int fd) + } + len -= n; + } ++ fsync(fd); ++ if (ts) { ++ struct stat st; ++ ++ if (fstat(fd, &st) == 0) ++ *ts = st.st_mtim; ++ else ++ clock_gettime(CLOCK_REALTIME_COARSE, ts); ++ } + return 0; + } + ++void handle_bindings_file_inotify(const struct inotify_event *event) ++{ ++ struct config *conf; ++ const char *base; ++ bool changed = false; ++ struct stat st; ++ struct timespec ts = { 0, 0 }; ++ int ret; ++ ++ if (!(event->mask & IN_MOVED_TO)) ++ return; ++ ++ conf = get_multipath_config(); ++ base = strrchr(conf->bindings_file, '/'); ++ changed = base && base > conf->bindings_file && ++ !strcmp(base + 1, event->name); ++ ret = stat(conf->bindings_file, &st); ++ put_multipath_config(conf); ++ ++ if (!changed) ++ return; ++ ++ pthread_mutex_lock(×tamp_mutex); ++ if (ret == 0) { ++ ts = st.st_mtim; ++ changed = timespeccmp(&ts, &bindings_last_updated) > 0; ++ } ++ pthread_mutex_unlock(×tamp_mutex); ++ ++ if (changed) { ++ uatomic_xchg(&bindings_file_changed, 1); ++ condlog(3, "%s: bindings file must be re-read, new timestamp: %ld.%06ld", ++ __func__, (long)ts.tv_sec, (long)ts.tv_nsec / 1000); ++ } else ++ condlog(3, "%s: bindings file is up-to-date, timestamp: %ld.%06ld", ++ __func__, (long)ts.tv_sec, (long)ts.tv_nsec / 1000); ++} ++ + static int update_bindings_file(const Bindings *bindings, + const char *bindings_file) + { +@@ -237,6 +317,7 @@ static int update_bindings_file(const Bindings *bindings, + int fd = -1; + char tempname[PATH_MAX]; + mode_t old_umask; ++ struct timespec ts; + + if (safe_sprintf(tempname, "%s.XXXXXX", bindings_file)) + return -1; +@@ -248,7 +329,7 @@ static int update_bindings_file(const Bindings *bindings, + } + umask(old_umask); + pthread_cleanup_push(cleanup_fd_ptr, &fd); +- rc = write_bindings_file(bindings, fd); ++ rc = write_bindings_file(bindings, fd, &ts); + pthread_cleanup_pop(1); + if (rc == -1) { + condlog(1, "failed to write new bindings file"); +@@ -257,8 +338,12 @@ static int update_bindings_file(const Bindings *bindings, + } + if ((rc = rename(tempname, bindings_file)) == -1) + condlog(0, "%s: rename: %m", __func__); +- else ++ else { ++ pthread_mutex_lock(×tamp_mutex); ++ bindings_last_updated = ts; ++ pthread_mutex_unlock(×tamp_mutex); + condlog(1, "updated bindings file %s", bindings_file); ++ } + return rc; + } + +@@ -387,6 +472,7 @@ int get_free_id(const Bindings *bindings, const char *prefix, const char *map_ww + return id; + } + ++/* Called with binding_mutex held */ + static char * + allocate_binding(const char *filename, const char *wwid, int id, const char *prefix) + { +@@ -423,6 +509,30 @@ allocate_binding(const char *filename, const char *wwid, int id, const char *pre + return alias; + } + ++enum { ++ BINDINGS_FILE_UP2DATE, ++ BINDINGS_FILE_READ, ++ BINDINGS_FILE_ERROR, ++ BINDINGS_FILE_BAD, ++}; ++ ++static int _read_bindings_file(const struct config *conf, Bindings *bindings, ++ bool force); ++ ++static void read_bindings_file(void) ++{ ++ struct config *conf; ++ Bindings bindings = {.allocated = 0, }; ++ int rc; ++ ++ conf = get_multipath_config(); ++ pthread_cleanup_push(put_multipath_config, conf); ++ rc = _read_bindings_file(conf, &bindings, false); ++ pthread_cleanup_pop(1); ++ if (rc == BINDINGS_FILE_READ) ++ set_global_bindings(&bindings); ++} ++ + /* + * get_user_friendly_alias() action table + * +@@ -463,6 +573,11 @@ char *get_user_friendly_alias(const char *wwid, const char *file, const char *al + bool new_binding = false; + const struct binding *bdg; + ++ read_bindings_file(); ++ ++ pthread_mutex_lock(&bindings_mutex); ++ pthread_cleanup_push(cleanup_mutex, &bindings_mutex); ++ + if (!*alias_old) + goto new_alias; + +@@ -514,40 +629,40 @@ new_alias: + alias, wwid); + + out: ++ /* unlock bindings_mutex */ ++ pthread_cleanup_pop(1); + return alias; + } + + int get_user_friendly_wwid(const char *alias, char *buff) + { + const struct binding *bdg; ++ int rc = -1; + + if (!alias || *alias == '\0') { + condlog(3, "Cannot find binding for empty alias"); + return -1; + } + ++ read_bindings_file(); ++ ++ pthread_mutex_lock(&bindings_mutex); ++ pthread_cleanup_push(cleanup_mutex, &bindings_mutex); + bdg = get_binding_for_alias(&global_bindings, alias); +- if (!bdg) { ++ if (bdg) { ++ strlcpy(buff, bdg->wwid, WWID_SIZE); ++ rc = 0; ++ } else + *buff = '\0'; +- return -1; +- } +- strlcpy(buff, bdg->wwid, WWID_SIZE); +- return 0; +-} +- +-static void free_bindings(Bindings *bindings) +-{ +- struct binding *bdg; +- int i; +- +- vector_foreach_slot(bindings, bdg, i) +- _free_binding(bdg); +- vector_reset(bindings); ++ pthread_cleanup_pop(1); ++ return rc; + } + + void cleanup_bindings(void) + { ++ pthread_mutex_lock(&bindings_mutex); + free_bindings(&global_bindings); ++ pthread_mutex_unlock(&bindings_mutex); + } + + enum { +@@ -595,7 +710,20 @@ static int _check_bindings_file(const struct config *conf, FILE *file, + char *line = NULL; + size_t line_len = 0; + ssize_t n; +- ++ char header[sizeof(BINDINGS_FILE_HEADER)]; ++ ++ header[sizeof(BINDINGS_FILE_HEADER) - 1] = '\0'; ++ if (fread(header, sizeof(BINDINGS_FILE_HEADER) - 1, 1, file) < 1) { ++ condlog(2, "%s: failed to read header from %s", __func__, ++ conf->bindings_file); ++ fseek(file, 0, SEEK_SET); ++ rc = -1; ++ } else if (strcmp(header, BINDINGS_FILE_HEADER)) { ++ condlog(2, "%s: invalid header in %s", __func__, ++ conf->bindings_file); ++ fseek(file, 0, SEEK_SET); ++ rc = -1; ++ } + pthread_cleanup_push(cleanup_free_ptr, &line); + while ((n = getline(&line, &line_len, file)) >= 0) { + char *alias, *wwid; +@@ -643,6 +771,68 @@ static int mp_alias_compar(const void *p1, const void *p2) + &((*(struct mpentry * const *)p2)->alias)); + } + ++static int _read_bindings_file(const struct config *conf, Bindings *bindings, ++ bool force) ++{ ++ int can_write; ++ int rc = 0, ret, fd; ++ FILE *file; ++ struct stat st; ++ int has_changed = uatomic_xchg(&bindings_file_changed, 0); ++ ++ if (!force) { ++ if (!has_changed) { ++ condlog(4, "%s: bindings are unchanged", __func__); ++ return BINDINGS_FILE_UP2DATE; ++ } ++ } ++ ++ fd = open_file(conf->bindings_file, &can_write, BINDINGS_FILE_HEADER); ++ if (fd == -1) ++ return BINDINGS_FILE_ERROR; ++ ++ file = fdopen(fd, "r"); ++ if (file != NULL) { ++ condlog(3, "%s: reading %s", __func__, conf->bindings_file); ++ ++ pthread_cleanup_push(cleanup_fclose, file); ++ ret = _check_bindings_file(conf, file, bindings); ++ if (ret == 0) { ++ struct timespec ts; ++ ++ rc = BINDINGS_FILE_READ; ++ ret = fstat(fd, &st); ++ if (ret == 0) ++ ts = st.st_mtim; ++ else { ++ condlog(1, "%s: fstat failed (%m), using current time", __func__); ++ clock_gettime(CLOCK_REALTIME_COARSE, &ts); ++ } ++ pthread_mutex_lock(×tamp_mutex); ++ bindings_last_updated = ts; ++ pthread_mutex_unlock(×tamp_mutex); ++ } else if (ret == -1 && can_write && !conf->bindings_read_only) { ++ ret = update_bindings_file(bindings, conf->bindings_file); ++ if (ret == 0) ++ rc = BINDINGS_FILE_READ; ++ else ++ rc = BINDINGS_FILE_BAD; ++ } else { ++ condlog(0, "ERROR: bad settings in read-only bindings file %s", ++ conf->bindings_file); ++ rc = BINDINGS_FILE_BAD; ++ } ++ pthread_cleanup_pop(1); ++ } else { ++ condlog(1, "failed to fdopen %s: %m", ++ conf->bindings_file); ++ close(fd); ++ rc = BINDINGS_FILE_ERROR; ++ } ++ ++ return rc; ++} ++ + /* + * check_alias_settings(): test for inconsistent alias configuration + * +@@ -661,8 +851,7 @@ static int mp_alias_compar(const void *p1, const void *p2) + */ + int check_alias_settings(const struct config *conf) + { +- int can_write; +- int rc = 0, i, fd; ++ int i, rc; + Bindings bindings = {.allocated = 0, }; + vector mptable = NULL; + struct mpentry *mpe; +@@ -695,27 +884,12 @@ int check_alias_settings(const struct config *conf) + pthread_cleanup_pop(1); + pthread_cleanup_pop(1); + +- fd = open_file(conf->bindings_file, &can_write, BINDINGS_FILE_HEADER); +- if (fd != -1) { +- FILE *file = fdopen(fd, "r"); +- +- if (file != NULL) { +- pthread_cleanup_push(cleanup_fclose, file); +- rc = _check_bindings_file(conf, file, &bindings); +- pthread_cleanup_pop(1); +- if (rc == -1 && can_write && !conf->bindings_read_only) +- rc = update_bindings_file(&bindings, conf->bindings_file); +- else if (rc == -1) +- condlog(0, "ERROR: bad settings in read-only bindings file %s", +- conf->bindings_file); +- } else { +- condlog(1, "failed to fdopen %s: %m", +- conf->bindings_file); +- close(fd); +- } ++ rc = _read_bindings_file(conf, &bindings, true); ++ ++ if (rc == BINDINGS_FILE_READ) { ++ set_global_bindings(&bindings); ++ rc = 0; + } + +- cleanup_bindings(); +- global_bindings = bindings; + return rc; + } +diff --git a/libmultipath/alias.h b/libmultipath/alias.h +index 5ef6720b..ca8911f4 100644 +--- a/libmultipath/alias.h ++++ b/libmultipath/alias.h +@@ -10,5 +10,6 @@ char *get_user_friendly_alias(const char *wwid, const char *file, + struct config; + int check_alias_settings(const struct config *); + void cleanup_bindings(void); +- ++struct inotify_event; ++void handle_bindings_file_inotify(const struct inotify_event *event); + #endif /* _ALIAS_H */ +diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version +index ddd302f5..57e50c12 100644 +--- a/libmultipath/libmultipath.version ++++ b/libmultipath/libmultipath.version +@@ -238,3 +238,8 @@ global: + local: + *; + }; ++ ++LIBMULTIPATH_20.1.0 { ++global: ++ handle_bindings_file_inotify; ++}; +diff --git a/multipathd/uxlsnr.c b/multipathd/uxlsnr.c +index 02e89fb4..d1f8f234 100644 +--- a/multipathd/uxlsnr.c ++++ b/multipathd/uxlsnr.c +@@ -41,6 +41,7 @@ + #include "cli.h" + #include "uxlsnr.h" + #include "strbuf.h" ++#include "alias.h" + + /* state of client connection */ + enum { +@@ -190,6 +191,7 @@ void wakeup_cleanup(void *arg) + struct watch_descriptors { + int conf_wd; + int dir_wd; ++ int mp_wd; /* /etc/multipath; for bindings file */ + }; + + /* failing to set the watch descriptor is o.k. we just miss a warning +@@ -200,6 +202,8 @@ static void reset_watch(int notify_fd, struct watch_descriptors *wds, + struct config *conf; + int dir_reset = 0; + int conf_reset = 0; ++ int mp_reset = 0; ++ char *bindings_file __attribute__((cleanup(cleanup_charp))) = NULL; + + if (notify_fd == -1) + return; +@@ -214,7 +218,10 @@ static void reset_watch(int notify_fd, struct watch_descriptors *wds, + conf_reset = 1; + if (wds->dir_wd == -1) + dir_reset = 1; ++ if (wds->mp_wd == -1) ++ mp_reset = 1; + } ++ bindings_file = strdup(conf->bindings_file); + put_multipath_config(conf); + + if (dir_reset) { +@@ -235,7 +242,18 @@ static void reset_watch(int notify_fd, struct watch_descriptors *wds, + if (wds->conf_wd == -1) + condlog(3, "didn't set up notifications on /etc/multipath.conf: %m"); + } +- return; ++ if (mp_reset && bindings_file) { ++ char *slash = strrchr(bindings_file, '/'); ++ ++ if (slash && slash > bindings_file) { ++ *slash = '\0'; ++ wds->mp_wd = inotify_add_watch(notify_fd, bindings_file, ++ IN_MOVED_TO|IN_ONLYDIR); ++ if (wds->mp_wd == -1) ++ condlog(3, "didn't set up notifications on %s: %m", ++ bindings_file); ++ } ++ } + } + + static void handle_inotify(int fd, struct watch_descriptors *wds) +@@ -256,12 +274,13 @@ static void handle_inotify(int fd, struct watch_descriptors *wds) + inotify_rm_watch(fd, wds->conf_wd); + if (wds->dir_wd != -1) + inotify_rm_watch(fd, wds->dir_wd); +- wds->conf_wd = wds->dir_wd = -1; ++ if (wds->mp_wd != -1) ++ inotify_rm_watch(fd, wds->mp_wd); ++ wds->conf_wd = wds->dir_wd = wds->mp_wd = -1; + } + break; + } + +- got_notify = 1; + for (ptr = buff; ptr < buff + len; + ptr += sizeof(struct inotify_event) + event->len) { + event = (const struct inotify_event *) ptr; +@@ -273,7 +292,13 @@ static void handle_inotify(int fd, struct watch_descriptors *wds) + wds->conf_wd = inotify_add_watch(notify_fd, DEFAULT_CONFIGFILE, IN_CLOSE_WRITE); + else if (wds->dir_wd == event->wd) + wds->dir_wd = -1; ++ else if (wds->mp_wd == event->wd) ++ wds->mp_wd = -1; + } ++ if (wds->mp_wd != -1 && wds->mp_wd == event->wd) ++ handle_bindings_file_inotify(event); ++ else ++ got_notify = 1; + } + } + if (got_notify) +@@ -599,7 +624,7 @@ void *uxsock_listen(long ux_sock, void *trigger_data) + int max_pfds = MIN_POLLS + POLLFDS_BASE; + /* conf->sequence_nr will be 1 when uxsock_listen is first called */ + unsigned int sequence_nr = 0; +- struct watch_descriptors wds = { .conf_wd = -1, .dir_wd = -1 }; ++ struct watch_descriptors wds = { .conf_wd = -1, .dir_wd = -1, .mp_wd = -1, }; + struct vectors *vecs = trigger_data; + + condlog(3, "uxsock: startup listener"); +@@ -666,7 +691,8 @@ void *uxsock_listen(long ux_sock, void *trigger_data) + + reset_watch(notify_fd, &wds, &sequence_nr); + polls[POLLFD_NOTIFY].fd = notify_fd; +- if (notify_fd == -1 || (wds.conf_wd == -1 && wds.dir_wd == -1)) ++ if (notify_fd == -1 || (wds.conf_wd == -1 && wds.dir_wd == -1 ++ && wds.mp_wd == -1)) + polls[POLLFD_NOTIFY].events = 0; + else + polls[POLLFD_NOTIFY].events = POLLIN; +diff --git a/tests/alias.c b/tests/alias.c +index 7f3ff38a..9ae27567 100644 +--- a/tests/alias.c ++++ b/tests/alias.c +@@ -1954,6 +1954,9 @@ int main(void) + int ret = 0; + init_test_verbosity(3); + ++ /* avoid open_file() call in _read_bindings_file */ ++ bindings_file_changed = 0; ++ + ret += test_format_devname(); + ret += test_scan_devname(); + ret += test_lookup_binding(); diff --git a/0028-multipath-tools-tests-mock-pthread_mutex_-lock-unloc.patch b/0028-multipath-tools-tests-mock-pthread_mutex_-lock-unloc.patch new file mode 100644 index 0000000..bba92f3 --- /dev/null +++ b/0028-multipath-tools-tests-mock-pthread_mutex_-lock-unloc.patch @@ -0,0 +1,102 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 8 Sep 2023 19:54:07 +0200 +Subject: [PATCH] multipath-tools tests: mock pthread_mutex_{lock,unlock} + +If some test fails with a lock held, cmocka doesn't deal well with +pthread_cleanup_pop(). Such tests can cause deadlock with the locking +primitives in the alias code, because locks don't get properly unlocked. Just +mock the lock/unlock functions and generate an error if they weren't paired at +the end of the test. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + tests/Makefile | 1 + + tests/alias.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 47 insertions(+) + +diff --git a/tests/Makefile b/tests/Makefile +index c777d07a..7dac8a8f 100644 +--- a/tests/Makefile ++++ b/tests/Makefile +@@ -52,6 +52,7 @@ blacklist-test_LIBDEPS := -ludev + vpd-test_OBJDEPS := $(multipathdir)/discovery.o + vpd-test_LIBDEPS := -ludev -lpthread -ldl + alias-test_TESTDEPS := test-log.o ++alias-test_OBJDEPS := $(mpathutildir)/util.o + alias-test_LIBDEPS := -lpthread -ldl + valid-test_OBJDEPS := $(multipathdir)/valid.o $(multipathdir)/discovery.o + valid-test_LIBDEPS := -lmount -ludev -lpthread -ldl +diff --git a/tests/alias.c b/tests/alias.c +index 9ae27567..94df36d8 100644 +--- a/tests/alias.c ++++ b/tests/alias.c +@@ -89,6 +89,47 @@ int __wrap_dm_get_uuid(const char *name, char *uuid, int uuid_len) + return ret; + } + ++static int lock_errors; ++static int bindings_locked; ++static int timestamp_locked; ++int __wrap_pthread_mutex_lock(pthread_mutex_t *mutex) ++{ ++ if (mutex == &bindings_mutex) { ++ if (bindings_locked) { ++ fprintf(stderr, "%s: bindings_mutex LOCKED\n", __func__); ++ lock_errors++; ++ } ++ bindings_locked = 1; ++ } else if (mutex == ×tamp_mutex) { ++ if (timestamp_locked) { ++ fprintf(stderr, "%s: timestamp_mutex LOCKED\n", __func__); ++ lock_errors++; ++ } ++ timestamp_locked = 1; ++ } else ++ fprintf(stderr, "%s called for unknown mutex %p\n", __func__, mutex); ++ return 0; ++} ++ ++int __wrap_pthread_mutex_unlock(pthread_mutex_t *mutex) ++{ ++ if (mutex == &bindings_mutex) { ++ if (!bindings_locked) { ++ fprintf(stderr, "%s: bindings_mutex UNLOCKED\n", __func__); ++ lock_errors++; ++ } ++ bindings_locked = 0; ++ } else if (mutex == ×tamp_mutex) { ++ if (!timestamp_locked) { ++ fprintf(stderr, "%s: timestamp_mutex UNLOCKED\n", __func__); ++ lock_errors++; ++ } ++ timestamp_locked = 0; ++ } else ++ fprintf(stderr, "%s called for unknown mutex %p\n", __func__, mutex); ++ return 0; ++} ++ + #define TEST_FDNO 1234 + #define TEST_FPTR ((FILE *) 0xaffe) + +@@ -1718,6 +1759,10 @@ static void gufa_old_nomatch_nowwidmatch(void **state) { + free(alias); + } + ++static void gufa_check_locking(void **state) { ++ assert_int_equal(lock_errors, 0); ++} ++ + static int test_get_user_friendly_alias() + { + const struct CMUnitTest tests[] = { +@@ -1743,6 +1788,7 @@ static int test_get_user_friendly_alias() + cmocka_unit_test_teardown(gufa_old_nomatch_wwidmatch, teardown_bindings), + cmocka_unit_test_teardown(gufa_old_nomatch_wwidmatch_used, teardown_bindings), + cmocka_unit_test_teardown(gufa_old_nomatch_nowwidmatch, teardown_bindings), ++ cmocka_unit_test(gufa_check_locking), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); diff --git a/0029-multipath-tools-Makefile-sanitize-paths-for-configur.patch b/0029-multipath-tools-Makefile-sanitize-paths-for-configur.patch new file mode 100644 index 0000000..26b79a8 --- /dev/null +++ b/0029-multipath-tools-Makefile-sanitize-paths-for-configur.patch @@ -0,0 +1,73 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 8 Sep 2023 22:13:51 +0200 +Subject: [PATCH] multipath-tools Makefile: sanitize paths for configuration + files + +Make the path to multipath.conf configurable, and use the same prefix +by default for multipath.conf and multipath/conf.d. For "usr-merged" +distributions with immutable /usr, we'll want to have the configuration +under a different prefix. This can be achieved by using e.g. + + make prefix=/usr etc_prefix="" + +Note that with prefix=/usr, before this patch the code would use +/usr/etc/multipath/conf.d, but /etc/multipath.conf. If this (rather +inconsistent) behavior is desired, use the following command line: + + make prefix=/usr configfile=/etc/multipath.conf + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 9 ++++++--- + libmultipath/defaults.h | 1 - + 2 files changed, 6 insertions(+), 4 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 502cd0f1..39972d93 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -37,6 +37,8 @@ prefix := + exec_prefix := $(prefix) + # Prefix for non-essential libraries (libdmmp) + usr_prefix := $(prefix) ++# Prefix for configfuration files (multipath.conf) ++etc_prefix := $(prefix) + # Where to install systemd-related files. systemd is usually installed under /usr + # Note: some systemd installations use separate "prefix" and "rootprefix". + # In this case, override only unitdir to use systemd's "rootprefix" instead of $(systemd_prefix) +@@ -54,7 +56,8 @@ usrlibdir := $(usr_prefix)/$(LIB) + includedir := $(usr_prefix)/include + pkgconfdir := $(usrlibdir)/pkgconfig + plugindir := $(prefix)/$(LIB)/multipath +-configdir := $(prefix)/etc/multipath/conf.d ++configdir := $(etc_prefix)/etc/multipath/conf.d ++configfile := $(etc_prefix)/etc/multipath.conf + runtimedir := $(if $(shell test -L /var/run -o ! -d /var/run && echo 1),/run,/var/run) + devmapper_incdir := $(or $(shell $(PKG_CONFIG) --variable=includedir devmapper),/usr/include) + libudev_incdir := $(or $(shell $(PKG_CONFIG) --variable=includedir libudev),/usr/include) +@@ -84,8 +87,8 @@ WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implici + $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) $(W_URCU_TYPE_LIMITS) + CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) \ + -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \ +- -DRUNTIME_DIR=\"$(runtimedir)\" \ +- -DCONFIG_DIR=\"$(configdir)\" -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP ++ -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(configdir)\" \ ++ -DDEFAULT_CONFIGFILE=\"$(configfile)\" -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP + CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe + BIN_CFLAGS := -fPIE -DPIE + LIB_CFLAGS := -fPIC +diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h +index b3f11d4c..bc2d6388 100644 +--- a/libmultipath/defaults.h ++++ b/libmultipath/defaults.h +@@ -66,7 +66,6 @@ + #define MAX_DEV_LOSS_TMO UINT_MAX + #define DEFAULT_PIDFILE RUNTIME_DIR "/multipathd.pid" + #define DEFAULT_SOCKET "/org/kernel/linux/storage/multipathd" +-#define DEFAULT_CONFIGFILE "/etc/multipath.conf" + #define DEFAULT_BINDINGS_FILE "/etc/multipath/bindings" + #define DEFAULT_WWIDS_FILE "/etc/multipath/wwids" + #define DEFAULT_PRKEYS_FILE "/etc/multipath/prkeys" diff --git a/0030-multipath-tools-add-compile-time-configuration-for-e.patch b/0030-multipath-tools-add-compile-time-configuration-for-e.patch new file mode 100644 index 0000000..afdf833 --- /dev/null +++ b/0030-multipath-tools-add-compile-time-configuration-for-e.patch @@ -0,0 +1,58 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 8 Sep 2023 22:26:22 +0200 +Subject: [PATCH] multipath-tools: add compile time configuration for + "/etc/multipath" + +Instead of hard-conding "/etc/multipath" as the path for the state +files "bindings", "prkeys", and "wwids", make this path configurable +via the "statedir" compile-time option. The default is currently still +/etc, it might change to /var/lib or similar in the future. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 4 +++- + libmultipath/defaults.h | 6 +++--- + 2 files changed, 6 insertions(+), 4 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 39972d93..96206b2f 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -58,6 +58,7 @@ pkgconfdir := $(usrlibdir)/pkgconfig + plugindir := $(prefix)/$(LIB)/multipath + configdir := $(etc_prefix)/etc/multipath/conf.d + configfile := $(etc_prefix)/etc/multipath.conf ++statedir := $(etc_prefix)/etc/multipath + runtimedir := $(if $(shell test -L /var/run -o ! -d /var/run && echo 1),/run,/var/run) + devmapper_incdir := $(or $(shell $(PKG_CONFIG) --variable=includedir devmapper),/usr/include) + libudev_incdir := $(or $(shell $(PKG_CONFIG) --variable=includedir libudev),/usr/include) +@@ -88,7 +89,8 @@ WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implici + CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) \ + -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \ + -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(configdir)\" \ +- -DDEFAULT_CONFIGFILE=\"$(configfile)\" -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP ++ -DDEFAULT_CONFIGFILE=\"$(configfile)\" -DSTATE_DIR=\"$(statedir)\" \ ++ -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP + CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe + BIN_CFLAGS := -fPIE -DPIE + LIB_CFLAGS := -fPIC +diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h +index bc2d6388..d01f9712 100644 +--- a/libmultipath/defaults.h ++++ b/libmultipath/defaults.h +@@ -66,9 +66,9 @@ + #define MAX_DEV_LOSS_TMO UINT_MAX + #define DEFAULT_PIDFILE RUNTIME_DIR "/multipathd.pid" + #define DEFAULT_SOCKET "/org/kernel/linux/storage/multipathd" +-#define DEFAULT_BINDINGS_FILE "/etc/multipath/bindings" +-#define DEFAULT_WWIDS_FILE "/etc/multipath/wwids" +-#define DEFAULT_PRKEYS_FILE "/etc/multipath/prkeys" ++#define DEFAULT_BINDINGS_FILE STATE_DIR "/bindings" ++#define DEFAULT_WWIDS_FILE STATE_DIR "/wwids" ++#define DEFAULT_PRKEYS_FILE STATE_DIR "/prkeys" + #define MULTIPATH_SHM_BASE RUNTIME_DIR "/multipath/" + + diff --git a/0031-multipath-tools-man-pages-generate-with-correct-path.patch b/0031-multipath-tools-man-pages-generate-with-correct-path.patch new file mode 100644 index 0000000..65fc077 --- /dev/null +++ b/0031-multipath-tools-man-pages-generate-with-correct-path.patch @@ -0,0 +1,366 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 8 Sep 2023 22:48:16 +0200 +Subject: [PATCH] multipath-tools man pages: generate with correct paths + +Generate the man pages using the compile-time settings for paths +to multipath.conf etc. + +Add a paragraph about the CONFIGDIR (/etc/multipath/conf.d) +and the drop-in configuration files in the multipath.conf man page. + +Also, make sure all generated man pages and other files are correctly +removed by "make clean". + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + .gitignore | 4 +++ + Makefile.inc | 3 +++ + mpathpersist/Makefile | 5 ++-- + .../{mpathpersist.8 => mpathpersist.8.in} | 2 +- + multipath/Makefile | 13 +++++---- + multipath/{multipath.8 => multipath.8.in} | 10 +++---- + .../{multipath.conf.5 => multipath.conf.5.in} | 27 ++++++++++++------- + multipathd/Makefile | 9 ++++--- + multipathd/{multipathd.8 => multipathd.8.in} | 8 +++--- + 9 files changed, 49 insertions(+), 32 deletions(-) + rename mpathpersist/{mpathpersist.8 => mpathpersist.8.in} (99%) + rename multipath/{multipath.8 => multipath.8.in} (97%) + rename multipath/{multipath.conf.5 => multipath.conf.5.in} (98%) + rename multipathd/{multipathd.8 => multipathd.8.in} (97%) + +diff --git a/.gitignore b/.gitignore +index 535353e5..2986578f 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -13,11 +13,15 @@ cscope.files + cscope.out + kpartx/kpartx + multipath/multipath ++multipath/multipath.8 ++multipath/multipath.conf.5 + multipath/multipath.rules + multipath/tmpfiles.conf + multipathd/multipathd ++multipathd/multipathd.8 + multipathd/multipathc + mpathpersist/mpathpersist ++mpathpersist/mpathpersist.8 + abi.tar.gz + abi + abi-test +diff --git a/Makefile.inc b/Makefile.inc +index 96206b2f..79e521e1 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -133,3 +133,6 @@ NV_VERSION_SCRIPT = $(DEVLIB:%.so=%-nv.version) + @grep -P '^[ \t]+[a-zA-Z_][a-zA-Z0-9_]*;' $< >>$@ + @printf 'local:\n\t*;\n};\n' >>$@ + ++%: %.in ++ @echo creating $@ ++ $(Q)sed 's:@CONFIGFILE@:'$(configfile)':g;s:@CONFIGDIR@:'$(configdir)':g;s:@STATE_DIR@:'$(statedir)':g;s:@RUNTIME_DIR@:'$(runtimedir)':g' $< >$@ +diff --git a/mpathpersist/Makefile b/mpathpersist/Makefile +index f57c105c..f3749467 100644 +--- a/mpathpersist/Makefile ++++ b/mpathpersist/Makefile +@@ -8,10 +8,11 @@ LIBDEPS += -L$(mpathpersistdir) -lmpathpersist -L$(multipathdir) -lmultipath \ + -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd -lpthread -ldevmapper -ludev + + EXEC = mpathpersist ++MANPAGES := mpathpersist.8 + + OBJS = main.o + +-all: $(EXEC) ++all: $(EXEC) $(MANPAGES) + + $(EXEC): $(OBJS) + $(Q)$(CC) $(OBJS) -o $(EXEC) $(LDFLAGS) $(CFLAGS) $(LIBDEPS) +@@ -23,7 +24,7 @@ install: + $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 + + clean: dep_clean +- $(Q)$(RM) core *.o $(EXEC) ++ $(Q)$(RM) core *.o $(EXEC) $(MANPAGES) + + include $(wildcard $(OBJS:.o=.d)) + +diff --git a/mpathpersist/mpathpersist.8 b/mpathpersist/mpathpersist.8.in +similarity index 99% +rename from mpathpersist/mpathpersist.8 +rename to mpathpersist/mpathpersist.8.in +index 8d26b37c..fecef0d6 100644 +--- a/mpathpersist/mpathpersist.8 ++++ b/mpathpersist/mpathpersist.8.in +@@ -31,7 +31,7 @@ mpathpersist \- Manages SCSI persistent reservations on dm multipath devices. + . + This utility is used to manage SCSI persistent reservations on Device Mapper + Multipath devices. To be able to use this functionality, the \fIreservation_key\fR +-attribute must be defined in the \fI/etc/multipath.conf\fR file. Otherwise the ++attribute must be defined in the \fI@CONFIGFILE@\fR file. Otherwise the + \fBmultipathd\fR daemon will not check for persistent reservation for newly + discovered paths or reinstated paths. + . +diff --git a/multipath/Makefile b/multipath/Makefile +index 73db991a..68cb5ce7 100644 +--- a/multipath/Makefile ++++ b/multipath/Makefile +@@ -3,7 +3,9 @@ + # + include ../Makefile.inc + +-EXEC := multipath ++EXEC := multipath ++MANPAGES := multipath.8 multipath.conf.5 ++GENERATED := $(MANPAGES) multipath.rules tmpfiles.conf + + CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathcmddir) + CFLAGS += $(BIN_CFLAGS) +@@ -13,7 +15,7 @@ LIBDEPS += -L$(multipathdir) -lmultipath -L$(mpathutildir) -lmpathutil \ + + OBJS := main.o + +-all: $(EXEC) multipath.rules tmpfiles.conf ++all: $(EXEC) $(GENERATED) + + $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so + @echo building $@ because of $? +@@ -47,15 +49,12 @@ uninstall: + $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules + $(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 + $(Q)$(RM) $(DESTDIR)$(mandir)/man5/$(EXEC).conf.5 ++ $(Q)$(RM) $(DESTDIR)$(tmpfilesdir)/multipath.conf + + clean: dep_clean +- $(Q)$(RM) core *.o $(EXEC) multipath.rules tmpfiles.conf ++ $(Q)$(RM) core *.o $(EXEC) $(GENERATED) + + include $(wildcard $(OBJS:.o=.d)) + + dep_clean: + $(Q)$(RM) $(OBJS:.o=.d) +- +-%: %.in +- @echo creating $@ +- $(Q)sed 's,@RUNTIME_DIR@,$(runtimedir),' $< >$@ +diff --git a/multipath/multipath.8 b/multipath/multipath.8.in +similarity index 97% +rename from multipath/multipath.8 +rename to multipath/multipath.8.in +index 5fed6df7..348eb220 100644 +--- a/multipath/multipath.8 ++++ b/multipath/multipath.8.in +@@ -185,7 +185,7 @@ Display the currently used multipathd configuration. + .B \-T + Display the currently used multipathd configuration, limiting the output to + those devices actually present in the system. This can be used a template for +-creating \fImultipath.conf\fR. ++creating \fI@CONFIGFILE@\fR. + . + .\" ---------------------------------------------------------------------------- + .SH OPTIONS +@@ -233,11 +233,11 @@ option from \fBmultipath.conf(5)\fR. + .B \-i + Ignore WWIDs file when processing devices. If + \fIfind_multipaths strict\fR or \fIfind_multipaths no\fR is set in +-\fImultipath.conf\fR, multipath only considers devices that are ++\fI@CONFIGFILE@\fR, multipath only considers devices that are + listed in the WWIDs file. This option overrides that behavior. For other values + of \fIfind_multipaths\fR, this option has no effect. See the description of + \fIfind_multipaths\fR in +-.BR multipath.conf (5). ++.BR @CONFIGFILE@ (5). + This option should only be used in rare circumstances. + . + .TP +@@ -246,8 +246,8 @@ Treat the bindings file as read only. + . + .TP + .BI \-b " file" +-Set \fIuser_friendly_names\fR bindings file location. The default is +-\fI/etc/multipath/bindings\fR. ++(\fBdeprecated, do not use\fR) Set \fIuser_friendly_names\fR bindings file location. The default is ++\fI@STATE_DIR@/bindings\fR. + . + .TP + .B \-q +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5.in +similarity index 98% +rename from multipath/multipath.conf.5 +rename to multipath/multipath.conf.5.in +index 93af17db..20df2232 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5.in +@@ -13,14 +13,14 @@ + .SH NAME + .\" ---------------------------------------------------------------------------- + . +-multipath.conf \- multipath daemon configuration file. ++@CONFIGFILE@, @CONFIGDIR@/*.conf \- multipath daemon configuration file. + . + . + .\" ---------------------------------------------------------------------------- + .SH DESCRIPTION + .\" ---------------------------------------------------------------------------- + . +-.B "/etc/multipath.conf" ++.B "@CONFIGFILE@" + is the configuration file for the multipath daemon. It is used to + overwrite the built-in configuration table of \fBmultipathd\fP. + Any line whose first non-white-space character is a '#' is considered +@@ -29,6 +29,15 @@ a comment line. Empty lines are ignored. + Currently used multipathd configuration can be displayed with the \fBmultipath -t\fR + or \fBmultipathd show config\fR command. + . ++.PP ++Additional configuration can be made in drop-in files under ++.B @CONFIGDIR@. ++Files ending in \fI.conf\fR in this directory are read ++in alphabetical order, after reading \fI@CONFIGFILE@\fR. ++They use the same syntax as \fI@CONFIGFILE@\fR itself, ++and support all sections and keywords. If a keyword occurs in the same section ++in multiple files, the last occurence will take precedence over all others. ++. + . + .\" ---------------------------------------------------------------------------- + .SH SYNTAX +@@ -85,7 +94,7 @@ not mandatory. + . + .LP + .B Note on regular expressions: +-The \fImultipath.conf\fR syntax allows many attribute values to be specified as POSIX ++The \fI@CONFIGFILE@\fR syntax allows many attribute values to be specified as POSIX + Extended Regular Expressions (see \fBregex\fR(7)). These regular expressions + are \fBcase sensitive\fR and \fBnot anchored\fR, thus the expression "bar" matches "barbie", + "rhabarber", and "wunderbar", but not "Barbie". To avoid unwanted substring +@@ -711,7 +720,7 @@ The default is: \fBno\fR + .B user_friendly_names + If set to + .I yes +-, using the bindings file \fI/etc/multipath/bindings\fR to assign a persistent ++, using the bindings file \fI@STATE_DIR@/bindings\fR to assign a persistent + and unique alias to the multipath, in the form of mpath. If set to + .I no + use the WWID as the alias. In either case this be will +@@ -790,7 +799,7 @@ The full pathname of the binding file to be used when the user_friendly_names + option is set. + .RS + .TP +-The default is: \fB/etc/multipath/bindings\fR ++The default is: \fB@STATE_DIR@/bindings\fR + .RE + . + . +@@ -801,7 +810,7 @@ The full pathname of the WWIDs file, which is used by multipath to keep track + of the WWIDs for LUNs it has created multipath devices on in the past. + .RS + .TP +-The default is: \fB/etc/multipath/wwids\fR ++The default is: \fB@STATE_DIR@/wwids\fR + .RE + . + . +@@ -813,7 +822,7 @@ track of the persistent reservation key used for a specific WWID, when + \fIreservation_key\fR is set to \fBfile\fR. + .RS + .TP +-The default is: \fB/etc/multipath/prkeys\fR ++The default is: \fB@STATE_DIR@/prkeys\fR + .RE + . + . +@@ -872,7 +881,7 @@ The default is: \fBno\fR + .I yes + and the SCSI layer has already attached a hardware_handler to the device, + multipath will not force the device to use the hardware_handler specified by +-multipath.conf. If the SCSI layer has not attached a hardware handler, ++@CONFIGFILE@. If the SCSI layer has not attached a hardware handler, + multipath will continue to use its configured hardware handler. + .RS + .PP +@@ -1559,7 +1568,7 @@ given device, the attributes of all matching entries are applied to it. + If an attribute is specified in several matching device subsections, + later entries take precedence. Thus, entries in files under \fIconfig_dir\fR (in + reverse alphabetical order) have the highest precedence, followed by entries +-in \fImultipath.conf\fR; the built-in hardware table has the lowest ++in \fI@CONFIGFILE@\fR; the built-in hardware table has the lowest + precedence. Inside a configuration file, later entries have higher precedence + than earlier ones. + .LP +diff --git a/multipathd/Makefile b/multipathd/Makefile +index 0d0146c5..cdba3db1 100644 +--- a/multipathd/Makefile ++++ b/multipathd/Makefile +@@ -1,7 +1,8 @@ + include ../Makefile.inc + +-EXEC := multipathd +-CLI := multipathc ++EXEC := multipathd ++CLI := multipathc ++MANPAGES := multipathd.8 + + CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathpersistdir) -I$(mpathcmddir) -I$(thirdpartydir) \ + $(shell $(PKG_CONFIG) --modversion liburcu 2>/dev/null | \ +@@ -42,7 +43,7 @@ ifeq ($(FPIN_SUPPORT),1) + OBJS += fpin_handlers.o + endif + +-all : $(EXEC) $(CLI) ++all : $(EXEC) $(CLI) $(MANPAGES) + + $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so + @echo building $@ because of $? +@@ -79,7 +80,7 @@ uninstall: + $(Q)$(RM) $(DESTDIR)$(unitdir)/$(EXEC).socket + + clean: dep_clean +- $(Q)$(RM) core *.o $(EXEC) $(CLI) ++ $(Q)$(RM) core *.o $(EXEC) $(CLI) $(MANPAGES) + + include $(wildcard $(OBJS:.o=.d) $(CLI_OBJS:.o=.d)) + +diff --git a/multipathd/multipathd.8 b/multipathd/multipathd.8.in +similarity index 97% +rename from multipathd/multipathd.8 +rename to multipathd/multipathd.8.in +index cc72b775..e98c27fd 100644 +--- a/multipathd/multipathd.8 ++++ b/multipathd/multipathd.8.in +@@ -155,7 +155,7 @@ Show the format wildcards used in interactive commands taking $format. + .TP + .B list|show config + Show the currently used configuration, derived from default values and values +-specified within the configuration file \fI/etc/multipath.conf\fR. ++specified within the configuration file \fI@CONFIGFILE@\fR. + . + .TP + .B list|show config local +@@ -165,7 +165,7 @@ the devices section to those devices that are actually present in the system. + .TP + .B list|show blacklist + Show the currently used blacklist rules, derived from default values and values +-specified within the configuration file \fI/etc/multipath.conf\fR. ++specified within the configuration file \fI@CONFIGFILE@\fR. + . + .TP + .B list|show devices +@@ -290,13 +290,13 @@ Get the current persistent reservation key associated with $map. + .B map|multipath $map setprkey key $key + Set the persistent reservation key associated with $map to $key in the + \fIprkeys_file\fR. This key will only be used by multipathd if +-\fIreservation_key\fR is set to \fBfile\fR in \fI/etc/multipath.conf\fR. ++\fIreservation_key\fR is set to \fBfile\fR in \fI@CONFIGFILE@\fR. + . + .TP + .B map|multipath $map unsetprkey + Remove the persistent reservation key associated with $map from the + \fIprkeys_file\fR. This will only unset the key used by multipathd if +-\fIreservation_key\fR is set to \fBfile\fR in \fI/etc/multipath.conf\fR. ++\fIreservation_key\fR is set to \fBfile\fR in \fI@CONFIGFILE@\fR. + . + .TP + .B path $path setmarginal diff --git a/0032-libdmmp-Makefile-fix-bug-in-install-section.patch b/0032-libdmmp-Makefile-fix-bug-in-install-section.patch new file mode 100644 index 0000000..a3f2470 --- /dev/null +++ b/0032-libdmmp-Makefile-fix-bug-in-install-section.patch @@ -0,0 +1,25 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 11 Sep 2023 09:30:13 +0200 +Subject: [PATCH] libdmmp/Makefile: fix bug in install section + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libdmmp/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libdmmp/Makefile b/libdmmp/Makefile +index 078eca8f..172ba045 100644 +--- a/libdmmp/Makefile ++++ b/libdmmp/Makefile +@@ -44,7 +44,7 @@ install: + $(DESTDIR)$(pkgconfdir)/$(PKGFILE) + $(Q)sed -i 's|__INCLUDEDIR__|$(includedir)|g' \ + $(DESTDIR)$(pkgconfdir)/$(PKGFILE) +- $(Q)$(INSTALL_PROGRAM) -d 755 $(DESTDIR)$(mandir)/man3 ++ $(Q)$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(mandir)/man3 + $(Q)$(INSTALL_PROGRAM) -m 644 -t $(DESTDIR)$(mandir)/man3 docs/man/*.3 + + uninstall: diff --git a/0033-multipath-tools-README.md-improve-documentation-for-.patch b/0033-multipath-tools-README.md-improve-documentation-for-.patch new file mode 100644 index 0000000..3c7edd0 --- /dev/null +++ b/0033-multipath-tools-README.md-improve-documentation-for-.patch @@ -0,0 +1,75 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 11 Sep 2023 10:22:13 +0200 +Subject: [PATCH] multipath-tools: README.md: improve documentation for + compile-time options + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + README.md | 38 ++++++++++++++++++++++++++------------ + 1 file changed, 26 insertions(+), 12 deletions(-) + +diff --git a/README.md b/README.md +index a7f994ae..679e55bf 100644 +--- a/README.md ++++ b/README.md +@@ -89,9 +89,17 @@ The following variables can be passed to the `make` command line: + * `plugindir="/some/path"`: directory where libmultipath plugins (path + checkers, prioritizers, and foreign multipath support) will be looked up. + This used to be the run-time option `multipath_dir` in earlier versions. +- * `configdir="/some/path"` : directory to search for configuration files. ++ The default is `$(prefix)/$(LIB)/multipath`, where `$(LIB)` is `lib64` on ++ systems that have `/lib64`, and `lib` otherwise. ++ * `configfile="/some/path`": The path to the main configuration file. ++ The defalt is `$(etc_prefix)/etc/multipath.conf`. ++ * `configdir="/some/path"` : directory to search for additional configuration files. + This used to be the run-time option `config_dir` in earlier versions. +- The default is `/etc/multipath/conf.d`. ++ The default is `$(etc_prefix)/etc/multipath/conf.d`. ++ * `statedir="/some/path"`: The path of the directory where multipath-tools ++ stores run-time settings that need persist between reboots, such as known ++ WWIDs, user-friendly names, and persistent reservation keys. ++ The default is `$(etc_prefix)/etc/multipath`. + * `READLINE=libedit` or `READLINE=libreadline`: enable command line history + and TAB completion in the interactive mode *(which is entered with `multipathd -k` or `multipathc`)*. + The respective development package will be required for building. +@@ -119,21 +127,27 @@ The following variables can be passed to the `make` command line: + ### Installation Paths + + * `prefix`: The directory prefix for (almost) all files to be installed. +- Distributions may want to set this to `/usr`. +- **Note**: for multipath-tools, unlike many other packages, `prefix` +- defaults to the empty string, which resolves to the root directory (`/`). ++ "Usr-merged" distributions[^systemd] may want to set this to `/usr`. The ++ default is empty (`""`). + * `usr_prefix`: where to install those parts of the code that aren't necessary +- for booting. You may want to set this to `/usr` if `prefix` is empty. +- * `systemd_prefix`: Prefix for systemd-related files. It defaults to `/usr`. +- Some systemd installations use separate `prefix` and `rootprefix`. On such +- a distribution, set `prefix`, and override `unitdir` to use systemd's +- `rootprefix`. ++ for booting. Non-usr-merged distributions[^systemd] may want to set this to ++ `/usr`. The default is `$(prefix)`. ++ * `systemd_prefix`: Prefix for systemd-related files[^systemd]. The default is `/usr`. ++ * `etc_prefix`: The prefix for configuration files. "Usr-merged" ++ distributions with immutable `/usr`[^systemd] may want to set this to ++ `/etc`. The default is `$(prefix)`. + * `LIB`: the subdirectory under `prefix` where shared libraries will be + installed. By default, the makefile uses `/lib64` if this directory is + found on the build system, and `/lib` otherwise. + +-See also `configdir` and `plugindir` above. See `Makefile.inc` for more +-fine-grained control. ++The options `configdir`, `plugindir`, `configfile`, and `statedir` above can ++be used for setting indvidual paths where the `prefix` variables don't provide ++sufficient control. See `Makefile.inc` for even more fine-grained control. ++ ++[^systemd]: Some systemd installations use separate `prefix` and `rootprefix`. ++ On such a distribution, set `prefix`, and override `unitdir` to use systemd's ++ `rootprefix`. Recent systemd releases generally require everything to be ++ installed under `/usr` (so-called "usr-merged" distribution). On "usr- + + ### Compiler Options + diff --git a/0034-libmultipath-print-built-in-values-for-deprecated-op.patch b/0034-libmultipath-print-built-in-values-for-deprecated-op.patch new file mode 100644 index 0000000..45e7874 --- /dev/null +++ b/0034-libmultipath-print-built-in-values-for-deprecated-op.patch @@ -0,0 +1,55 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 11 Sep 2023 11:36:25 +0200 +Subject: [PATCH] libmultipath: print built-in values for deprecated options + +In the error messages we print when a deprecated option is encountered, +print the compile-time value of the option. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/dict.c | 16 +++++++++------- + 1 file changed, 9 insertions(+), 7 deletions(-) + +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index f81c84aa..dace343d 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -314,14 +314,16 @@ def_ ## option ## _handler (struct config *conf, vector strvec, \ + static int deprecated_handler(struct config *conf, vector strvec, const char *file, + int line_nr); + +-#define declare_deprecated_handler(option) \ ++#define declare_deprecated_handler(option, default) \ + static int \ + deprecated_ ## option ## _handler (struct config *conf, vector strvec, \ + const char *file, int line_nr) \ + { \ + static bool warned; \ + if (!warned) { \ +- condlog(1, "%s line %d: ignoring deprecated option \"" #option "\"", file, line_nr); \ ++ condlog(1, "%s line %d: ignoring deprecated option \"" \ ++ #option "\", using built-in value: \"%s\"", \ ++ file, line_nr, default); \ + warned = true; \ + } \ + return deprecated_handler(conf, strvec, file, line_nr); \ +@@ -2057,11 +2059,11 @@ snprint_deprecated (struct config *conf, struct strbuf *buff, const void * data) + } + + // Deprecated keywords +-declare_deprecated_handler(config_dir) +-declare_deprecated_handler(disable_changed_wwids) +-declare_deprecated_handler(getuid_callout) +-declare_deprecated_handler(multipath_dir) +-declare_deprecated_handler(pg_timeout) ++declare_deprecated_handler(config_dir, CONFIG_DIR) ++declare_deprecated_handler(disable_changed_wwids, "yes") ++declare_deprecated_handler(getuid_callout, "(not set)") ++declare_deprecated_handler(multipath_dir, MULTIPATH_DIR) ++declare_deprecated_handler(pg_timeout, "(not set)") + + /* + * If you add or remove a keyword also update multipath/multipath.conf.5 diff --git a/0035-multipath-add-a-missing-newline.patch b/0035-multipath-add-a-missing-newline.patch new file mode 100644 index 0000000..706b7d3 --- /dev/null +++ b/0035-multipath-add-a-missing-newline.patch @@ -0,0 +1,25 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 11 Sep 2023 11:37:37 +0200 +Subject: [PATCH] multipath: add a missing newline + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/multipath/main.c b/multipath/main.c +index 45e9745f..b91289e8 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -1025,7 +1025,7 @@ main (int argc, char *argv[]) + } + + if (check_alias_settings(conf)) { +- fprintf(stderr, "fatal configuration error, aborting"); ++ fprintf(stderr, "fatal configuration error, aborting\n"); + exit(RTVL_FAIL); + } + diff --git a/0036-multipath-tools-allow-prefixes-with-and-w-o-trailing.patch b/0036-multipath-tools-allow-prefixes-with-and-w-o-trailing.patch new file mode 100644 index 0000000..c48240b --- /dev/null +++ b/0036-multipath-tools-allow-prefixes-with-and-w-o-trailing.patch @@ -0,0 +1,66 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 11 Sep 2023 16:03:34 +0200 +Subject: [PATCH] multipath-tools: allow prefixes with and w/o trailing slash + +Add some logic to Makefile.inc that leads to the same result +for "prefix=" and "prefix=/", or "prefix=/usr" and "prefix=/usr/". +The logic does not work for multiple trailing slashes. It applies +to all XYZ_prefix variables in Makefile.inc. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 35 ++++++++++++++++++++++------------- + 1 file changed, 22 insertions(+), 13 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 79e521e1..6e384e68 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -43,22 +43,31 @@ etc_prefix := $(prefix) + # Note: some systemd installations use separate "prefix" and "rootprefix". + # In this case, override only unitdir to use systemd's "rootprefix" instead of $(systemd_prefix) + systemd_prefix := /usr +-unitdir := $(systemd_prefix)/lib/systemd/system +-tmpfilesdir := $(systemd_prefix)/lib/tmpfiles.d +-modulesloaddir := $(systemd_prefix)/lib/modules-load.d +-libudevdir := $(systemd_prefix)/lib/udev ++ ++# Make sure all prefix variables end in "/" ++append-slash = $(1)$(if $(filter %/,$(1)),,/) ++override prefix := $(call append-slash,$(prefix)) ++override exec_prefix := $(call append-slash,$(exec_prefix)) ++override usr_prefix := $(call append-slash,$(usr_prefix)) ++override etc_prefix := $(call append-slash,$(etc_prefix)) ++override systemd_prefix := $(call append-slash,$(systemd_prefix)) ++ ++unitdir := $(systemd_prefix)lib/systemd/system ++tmpfilesdir := $(systemd_prefix)lib/tmpfiles.d ++modulesloaddir := $(systemd_prefix)lib/modules-load.d ++libudevdir := $(systemd_prefix)lib/udev + udevrulesdir := $(libudevdir)/rules.d +-bindir := $(exec_prefix)/sbin +-mandir := $(usr_prefix)/share/man ++bindir := $(exec_prefix)sbin ++mandir := $(usr_prefix)share/man + LIB := $(if $(shell test -d /lib64 && echo 1),lib64,lib) +-syslibdir := $(prefix)/$(LIB) +-usrlibdir := $(usr_prefix)/$(LIB) +-includedir := $(usr_prefix)/include ++syslibdir := $(prefix)$(LIB) ++usrlibdir := $(usr_prefix)$(LIB) ++includedir := $(usr_prefix)include + pkgconfdir := $(usrlibdir)/pkgconfig +-plugindir := $(prefix)/$(LIB)/multipath +-configdir := $(etc_prefix)/etc/multipath/conf.d +-configfile := $(etc_prefix)/etc/multipath.conf +-statedir := $(etc_prefix)/etc/multipath ++plugindir := $(prefix)$(LIB)/multipath ++configdir := $(etc_prefix)etc/multipath/conf.d ++configfile := $(etc_prefix)etc/multipath.conf ++statedir := $(etc_prefix)etc/multipath + runtimedir := $(if $(shell test -L /var/run -o ! -d /var/run && echo 1),/run,/var/run) + devmapper_incdir := $(or $(shell $(PKG_CONFIG) --variable=includedir devmapper),/usr/include) + libudev_incdir := $(or $(shell $(PKG_CONFIG) --variable=includedir libudev),/usr/include) diff --git a/0037-libmultipath-deprecate-bindings_file-wwids_file-prke.patch b/0037-libmultipath-deprecate-bindings_file-wwids_file-prke.patch new file mode 100644 index 0000000..6e066ee --- /dev/null +++ b/0037-libmultipath-deprecate-bindings_file-wwids_file-prke.patch @@ -0,0 +1,897 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 11 Sep 2023 17:58:13 +0200 +Subject: [PATCH] libmultipath: deprecate bindings_file, wwids_file, + prkeys_file + +The options bindings_file, wwids_file, and prkeys_file have been +deprecated since cb4d6db ("libmultipath: deprecate file and directory config +options") (multipath-tools 0.8.8). Deprecate and ignore them now. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/alias.c | 43 +++++++++---------- + libmultipath/alias.h | 3 +- + libmultipath/config.c | 18 -------- + libmultipath/config.h | 3 -- + libmultipath/dict.c | 39 +++--------------- + libmultipath/libmultipath.version | 8 +--- + libmultipath/prkey.c | 7 ++-- + libmultipath/prkey.h | 7 ++-- + libmultipath/propsel.c | 5 +-- + libmultipath/wwids.c | 18 ++------ + multipath/main.c | 2 +- + multipath/multipath.conf.5.in | 23 +++++------ + multipathd/uxlsnr.c | 17 +++----- + tests/alias.c | 68 +++++++++++++++---------------- + 14 files changed, 90 insertions(+), 171 deletions(-) + +diff --git a/libmultipath/alias.c b/libmultipath/alias.c +index 964b8a7b..e5d3f151 100644 +--- a/libmultipath/alias.c ++++ b/libmultipath/alias.c +@@ -55,6 +55,8 @@ + /* uatomic access only */ + static int bindings_file_changed = 1; + ++static const char bindings_file_path[] = DEFAULT_BINDINGS_FILE; ++ + static pthread_mutex_t timestamp_mutex = PTHREAD_MUTEX_INITIALIZER; + static struct timespec bindings_last_updated; + +@@ -274,7 +276,6 @@ static int write_bindings_file(const Bindings *bindings, int fd, + + void handle_bindings_file_inotify(const struct inotify_event *event) + { +- struct config *conf; + const char *base; + bool changed = false; + struct stat st; +@@ -284,12 +285,9 @@ void handle_bindings_file_inotify(const struct inotify_event *event) + if (!(event->mask & IN_MOVED_TO)) + return; + +- conf = get_multipath_config(); +- base = strrchr(conf->bindings_file, '/'); +- changed = base && base > conf->bindings_file && +- !strcmp(base + 1, event->name); +- ret = stat(conf->bindings_file, &st); +- put_multipath_config(conf); ++ base = strrchr(bindings_file_path, '/'); ++ changed = base && !strcmp(base + 1, event->name); ++ ret = stat(bindings_file_path, &st); + + if (!changed) + return; +@@ -310,8 +308,7 @@ void handle_bindings_file_inotify(const struct inotify_event *event) + __func__, (long)ts.tv_sec, (long)ts.tv_nsec / 1000); + } + +-static int update_bindings_file(const Bindings *bindings, +- const char *bindings_file) ++static int update_bindings_file(const Bindings *bindings) + { + int rc; + int fd = -1; +@@ -319,7 +316,7 @@ static int update_bindings_file(const Bindings *bindings, + mode_t old_umask; + struct timespec ts; + +- if (safe_sprintf(tempname, "%s.XXXXXX", bindings_file)) ++ if (safe_sprintf(tempname, "%s.XXXXXX", bindings_file_path)) + return -1; + /* coverity: SECURE_TEMP */ + old_umask = umask(0077); +@@ -336,13 +333,13 @@ static int update_bindings_file(const Bindings *bindings, + unlink(tempname); + return rc; + } +- if ((rc = rename(tempname, bindings_file)) == -1) ++ if ((rc = rename(tempname, bindings_file_path)) == -1) + condlog(0, "%s: rename: %m", __func__); + else { + pthread_mutex_lock(×tamp_mutex); + bindings_last_updated = ts; + pthread_mutex_unlock(×tamp_mutex); +- condlog(1, "updated bindings file %s", bindings_file); ++ condlog(1, "updated bindings file %s", bindings_file_path); + } + return rc; + } +@@ -474,7 +471,7 @@ int get_free_id(const Bindings *bindings, const char *prefix, const char *map_ww + + /* Called with binding_mutex held */ + static char * +-allocate_binding(const char *filename, const char *wwid, int id, const char *prefix) ++allocate_binding(const char *wwid, int id, const char *prefix) + { + STRBUF_ON_STACK(buf); + char *alias; +@@ -498,7 +495,7 @@ allocate_binding(const char *filename, const char *wwid, int id, const char *pre + return NULL; + } + +- if (update_bindings_file(&global_bindings, filename) == -1) { ++ if (update_bindings_file(&global_bindings) == -1) { + condlog(1, "%s: deleting binding %s for %s", __func__, alias, wwid); + delete_binding(&global_bindings, wwid); + free(alias); +@@ -565,7 +562,7 @@ static void read_bindings_file(void) + * that the mpvec corrcectly represents kernel state. + */ + +-char *get_user_friendly_alias(const char *wwid, const char *file, const char *alias_old, ++char *get_user_friendly_alias(const char *wwid, const char *alias_old, + const char *prefix, bool bindings_read_only) + { + char *alias = NULL; +@@ -622,7 +619,7 @@ new_alias: + } + + if (!bindings_read_only && id > 0) +- alias = allocate_binding(file, wwid, id, prefix); ++ alias = allocate_binding(wwid, id, prefix); + + if (alias && !new_binding) + condlog(2, "Allocated existing binding [%s] for WWID [%s]", +@@ -715,12 +712,12 @@ static int _check_bindings_file(const struct config *conf, FILE *file, + header[sizeof(BINDINGS_FILE_HEADER) - 1] = '\0'; + if (fread(header, sizeof(BINDINGS_FILE_HEADER) - 1, 1, file) < 1) { + condlog(2, "%s: failed to read header from %s", __func__, +- conf->bindings_file); ++ bindings_file_path); + fseek(file, 0, SEEK_SET); + rc = -1; + } else if (strcmp(header, BINDINGS_FILE_HEADER)) { + condlog(2, "%s: invalid header in %s", __func__, +- conf->bindings_file); ++ bindings_file_path); + fseek(file, 0, SEEK_SET); + rc = -1; + } +@@ -787,13 +784,13 @@ static int _read_bindings_file(const struct config *conf, Bindings *bindings, + } + } + +- fd = open_file(conf->bindings_file, &can_write, BINDINGS_FILE_HEADER); ++ fd = open_file(bindings_file_path, &can_write, BINDINGS_FILE_HEADER); + if (fd == -1) + return BINDINGS_FILE_ERROR; + + file = fdopen(fd, "r"); + if (file != NULL) { +- condlog(3, "%s: reading %s", __func__, conf->bindings_file); ++ condlog(3, "%s: reading %s", __func__, bindings_file_path); + + pthread_cleanup_push(cleanup_fclose, file); + ret = _check_bindings_file(conf, file, bindings); +@@ -812,20 +809,20 @@ static int _read_bindings_file(const struct config *conf, Bindings *bindings, + bindings_last_updated = ts; + pthread_mutex_unlock(×tamp_mutex); + } else if (ret == -1 && can_write && !conf->bindings_read_only) { +- ret = update_bindings_file(bindings, conf->bindings_file); ++ ret = update_bindings_file(bindings); + if (ret == 0) + rc = BINDINGS_FILE_READ; + else + rc = BINDINGS_FILE_BAD; + } else { + condlog(0, "ERROR: bad settings in read-only bindings file %s", +- conf->bindings_file); ++ bindings_file_path); + rc = BINDINGS_FILE_BAD; + } + pthread_cleanup_pop(1); + } else { + condlog(1, "failed to fdopen %s: %m", +- conf->bindings_file); ++ bindings_file_path); + close(fd); + rc = BINDINGS_FILE_ERROR; + } +diff --git a/libmultipath/alias.h b/libmultipath/alias.h +index ca8911f4..629e8d56 100644 +--- a/libmultipath/alias.h ++++ b/libmultipath/alias.h +@@ -3,8 +3,7 @@ + + int valid_alias(const char *alias); + int get_user_friendly_wwid(const char *alias, char *buff); +-char *get_user_friendly_alias(const char *wwid, const char *file, +- const char *alias_old, ++char *get_user_friendly_alias(const char *wwid, const char *alias_old, + const char *prefix, bool bindings_read_only); + + struct config; +diff --git a/libmultipath/config.c b/libmultipath/config.c +index 7b207590..b7dbc6f5 100644 +--- a/libmultipath/config.c ++++ b/libmultipath/config.c +@@ -752,15 +752,6 @@ static void _uninit_config(struct config *conf) + if (conf->hwhandler) + free(conf->hwhandler); + +- if (conf->bindings_file) +- free(conf->bindings_file); +- +- if (conf->wwids_file) +- free(conf->wwids_file); +- +- if (conf->prkeys_file) +- free(conf->prkeys_file); +- + if (conf->prio_name) + free(conf->prio_name); + +@@ -922,9 +913,6 @@ int _init_config (const char *file, struct config *conf) + * internal defaults + */ + get_sys_max_fds(&conf->max_fds); +- conf->bindings_file = set_default(DEFAULT_BINDINGS_FILE); +- conf->wwids_file = set_default(DEFAULT_WWIDS_FILE); +- conf->prkeys_file = set_default(DEFAULT_PRKEYS_FILE); + conf->attribute_flags = 0; + conf->reassign_maps = DEFAULT_REASSIGN_MAPS; + conf->checkint = CHECKINT_UNDEF; +@@ -1078,12 +1066,6 @@ int _init_config (const char *file, struct config *conf) + merge_blacklist(conf->elist_wwid); + merge_blacklist_device(conf->elist_device); + +- if (conf->bindings_file == NULL) +- conf->bindings_file = set_default(DEFAULT_BINDINGS_FILE); +- +- if (!conf->bindings_file || !conf->wwids_file || !conf->prkeys_file) +- goto out; +- + libmp_verbosity = conf->verbosity; + return 0; + out: +diff --git a/libmultipath/config.h b/libmultipath/config.h +index 0a2c297b..8c22ce75 100644 +--- a/libmultipath/config.h ++++ b/libmultipath/config.h +@@ -207,9 +207,6 @@ struct config { + char * uid_attribute; + char * features; + char * hwhandler; +- char * bindings_file; +- char * wwids_file; +- char * prkeys_file; + char * prio_name; + char * prio_args; + char * checker_name; +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index dace343d..044067af 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -168,27 +168,6 @@ fail: + return 0; + } + +-static int +-set_path(vector strvec, void *ptr, const char *file, int line_nr) +-{ +- char **str_ptr = (char **)ptr; +- char *old_str = *str_ptr; +- +- *str_ptr = set_value(strvec); +- if (!*str_ptr) { +- free(old_str); +- return 1; +- } +- if ((*str_ptr)[0] != '/'){ +- condlog(1, "%s line %d, %s is not an absolute path. Ignoring", +- file, line_nr, *str_ptr); +- free(*str_ptr); +- *str_ptr = old_str; +- } else +- free(old_str); +- return 0; +-} +- + static int + set_str_noslash(vector strvec, void *ptr, const char *file, int line_nr) + { +@@ -831,15 +810,6 @@ declare_hw_snprint(user_friendly_names, print_yes_no_undef) + declare_mp_handler(user_friendly_names, set_yes_no_undef) + declare_mp_snprint(user_friendly_names, print_yes_no_undef) + +-declare_def_warn_handler(bindings_file, set_path) +-declare_def_snprint(bindings_file, print_str) +- +-declare_def_warn_handler(wwids_file, set_path) +-declare_def_snprint(wwids_file, print_str) +- +-declare_def_warn_handler(prkeys_file, set_path) +-declare_def_snprint(prkeys_file, print_str) +- + declare_def_handler(retain_hwhandler, set_yes_no_undef) + declare_def_snprint_defint(retain_hwhandler, print_yes_no_undef, + DEFAULT_RETAIN_HWHANDLER) +@@ -2064,6 +2034,9 @@ declare_deprecated_handler(disable_changed_wwids, "yes") + declare_deprecated_handler(getuid_callout, "(not set)") + declare_deprecated_handler(multipath_dir, MULTIPATH_DIR) + declare_deprecated_handler(pg_timeout, "(not set)") ++declare_deprecated_handler(bindings_file, DEFAULT_BINDINGS_FILE) ++declare_deprecated_handler(wwids_file, DEFAULT_WWIDS_FILE) ++declare_deprecated_handler(prkeys_file, DEFAULT_PRKEYS_FILE) + + /* + * If you add or remove a keyword also update multipath/multipath.conf.5 +@@ -2106,9 +2079,9 @@ init_keywords(vector keywords) + install_keyword("fast_io_fail_tmo", &def_fast_io_fail_handler, &snprint_def_fast_io_fail); + install_keyword("dev_loss_tmo", &def_dev_loss_handler, &snprint_def_dev_loss); + install_keyword("eh_deadline", &def_eh_deadline_handler, &snprint_def_eh_deadline); +- install_keyword("bindings_file", &def_bindings_file_handler, &snprint_def_bindings_file); +- install_keyword("wwids_file", &def_wwids_file_handler, &snprint_def_wwids_file); +- install_keyword("prkeys_file", &def_prkeys_file_handler, &snprint_def_prkeys_file); ++ install_keyword("bindings_file", &deprecated_bindings_file_handler, &snprint_deprecated); ++ install_keyword("wwids_file", &deprecated_wwids_file_handler, &snprint_deprecated); ++ install_keyword("prkeys_file", &deprecated_prkeys_file_handler, &snprint_deprecated); + 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); +diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version +index 57e50c12..8368ef7a 100644 +--- a/libmultipath/libmultipath.version ++++ b/libmultipath/libmultipath.version +@@ -43,7 +43,7 @@ LIBMPATHCOMMON_1.0.0 { + put_multipath_config; + }; + +-LIBMULTIPATH_20.0.0 { ++LIBMULTIPATH_21.0.0 { + global: + /* symbols referenced by multipath and multipathd */ + add_foreign; +@@ -121,6 +121,7 @@ global: + get_used_hwes; + get_vpd_sgio; + group_by_prio; ++ handle_bindings_file_inotify; + has_dm_info; + init_checkers; + init_config; +@@ -238,8 +239,3 @@ global: + local: + *; + }; +- +-LIBMULTIPATH_20.1.0 { +-global: +- handle_bindings_file_inotify; +-}; +diff --git a/libmultipath/prkey.c b/libmultipath/prkey.c +index a215499d..c66d293b 100644 +--- a/libmultipath/prkey.c ++++ b/libmultipath/prkey.c +@@ -157,8 +157,7 @@ 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, +- uint8_t *sa_flags) ++int get_prkey(struct multipath *mpp, uint64_t *prkey, uint8_t *sa_flags) + { + int fd; + int unused; +@@ -168,7 +167,7 @@ int get_prkey(struct config *conf, struct multipath *mpp, uint64_t *prkey, + if (!strlen(mpp->wwid)) + goto out; + +- fd = open_file(conf->prkeys_file, &unused, PRKEYS_FILE_HEADER); ++ fd = open_file(DEFAULT_PRKEYS_FILE, &unused, PRKEYS_FILE_HEADER); + if (fd < 0) + goto out; + ret = do_prkey(fd, mpp->wwid, keystr, PRKEY_READ); +@@ -201,7 +200,7 @@ int set_prkey(struct config *conf, struct multipath *mpp, uint64_t prkey, + sa_flags &= MPATH_F_APTPL_MASK; + } + +- fd = open_file(conf->prkeys_file, &can_write, PRKEYS_FILE_HEADER); ++ fd = open_file(DEFAULT_PRKEYS_FILE, &can_write, PRKEYS_FILE_HEADER); + if (fd < 0) + goto out; + if (!can_write) { +diff --git a/libmultipath/prkey.h b/libmultipath/prkey.h +index a16de106..43afd5e4 100644 +--- a/libmultipath/prkey.h ++++ b/libmultipath/prkey.h +@@ -16,9 +16,8 @@ + int print_reservation_key(struct strbuf *buff, + struct be64 key, uint8_t flags, int source); + int parse_prkey_flags(const char *ptr, uint64_t *prkey, uint8_t *flags); +-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); ++int set_prkey(struct config *conf, struct multipath *mpp, ++ uint64_t prkey, uint8_t sa_flags); ++int get_prkey(struct multipath *mpp, uint64_t *prkey, uint8_t *sa_flags); + + #endif /* _PRKEY_H */ +diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c +index 354e883f..44241e2a 100644 +--- a/libmultipath/propsel.c ++++ b/libmultipath/propsel.c +@@ -401,8 +401,7 @@ int select_alias(struct config *conf, struct multipath * mp) + + select_alias_prefix(conf, mp); + +- mp->alias = get_user_friendly_alias(mp->wwid, conf->bindings_file, +- mp->alias_old, mp->alias_prefix, ++ mp->alias = get_user_friendly_alias(mp->wwid, mp->alias_old, mp->alias_prefix, + conf->bindings_read_only); + + if (mp->alias && !strncmp(mp->alias, mp->alias_old, WWID_SIZE)) +@@ -992,7 +991,7 @@ int select_reservation_key(struct config *conf, struct multipath *mp) + out: + if (mp->prkey_source == PRKEY_SOURCE_FILE) { + from_file = " (from prkeys file)"; +- if (get_prkey(conf, mp, &prkey, &mp->sa_flags) != 0) ++ if (get_prkey(mp, &prkey, &mp->sa_flags) != 0) + put_be64(mp->reservation_key, 0); + else + put_be64(mp->reservation_key, prkey); +diff --git a/libmultipath/wwids.c b/libmultipath/wwids.c +index 89bb60ca..591cd09b 100644 +--- a/libmultipath/wwids.c ++++ b/libmultipath/wwids.c +@@ -94,12 +94,8 @@ replace_wwids(vector mp) + struct multipath * mpp; + size_t len; + int ret = -1; +- struct config *conf; + +- conf = get_multipath_config(); +- pthread_cleanup_push(put_multipath_config, conf); +- fd = open_file(conf->wwids_file, &can_write, WWIDS_FILE_HEADER); +- pthread_cleanup_pop(1); ++ fd = open_file(DEFAULT_WWIDS_FILE, &can_write, WWIDS_FILE_HEADER); + if (fd < 0) + goto out; + +@@ -200,7 +196,6 @@ remove_wwid(char *wwid) { + int len, can_write; + char *str; + int ret = -1; +- struct config *conf; + + len = strlen(wwid) + 4; /* two slashes the newline and a zero byte */ + str = malloc(len); +@@ -216,10 +211,7 @@ remove_wwid(char *wwid) { + goto out; + } + condlog(3, "removing line '%s' from wwids file", str); +- conf = get_multipath_config(); +- pthread_cleanup_push(put_multipath_config, conf); +- fd = open_file(conf->wwids_file, &can_write, WWIDS_FILE_HEADER); +- pthread_cleanup_pop(1); ++ fd = open_file(DEFAULT_WWIDS_FILE, &can_write, WWIDS_FILE_HEADER); + + if (fd < 0) { + ret = -1; +@@ -244,12 +236,8 @@ check_wwids_file(char *wwid, int write_wwid) + { + int fd, can_write, found, ret; + FILE *f; +- struct config *conf; + +- conf = get_multipath_config(); +- pthread_cleanup_push(put_multipath_config, conf); +- fd = open_file(conf->wwids_file, &can_write, WWIDS_FILE_HEADER); +- pthread_cleanup_pop(1); ++ fd = open_file(DEFAULT_WWIDS_FILE, &can_write, WWIDS_FILE_HEADER); + if (fd < 0) + return -1; + +diff --git a/multipath/main.c b/multipath/main.c +index b91289e8..9e1c5052 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -856,7 +856,7 @@ main (int argc, char *argv[]) + libmp_verbosity = atoi(optarg); + break; + case 'b': +- conf->bindings_file = strdup(optarg); ++ condlog(1, "option -b ignored"); + break; + case 'B': + conf->bindings_read_only = 1; +diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in +index 20df2232..d320a88f 100644 +--- a/multipath/multipath.conf.5.in ++++ b/multipath/multipath.conf.5.in +@@ -794,35 +794,28 @@ The default is: \fB\fR + . + .TP + .B bindings_file +-(Deprecated) This option is deprecated, and will be removed in a future release. +-The full pathname of the binding file to be used when the user_friendly_names +-option is set. ++(Deprecated) This option is not supported any more, and will be ignored. + .RS + .TP +-The default is: \fB@STATE_DIR@/bindings\fR ++The compiled-in value is: \fB@STATE_DIR@/bindings\fR + .RE + . + . + .TP + .B wwids_file +-(Deprecated) This option is deprecated, and will be removed in a future release. +-The full pathname of the WWIDs file, which is used by multipath to keep track +-of the WWIDs for LUNs it has created multipath devices on in the past. ++(Deprecated) This option is not supported any more, and will be ignored. + .RS + .TP +-The default is: \fB@STATE_DIR@/wwids\fR ++The compiled-in value is: \fB@STATE_DIR@/wwids\fR + .RE + . + . + .TP + .B prkeys_file +-(Deprecated) This option is deprecated, and will be removed in a future release. +-The full pathname of the prkeys file, which is used by multipathd to keep +-track of the persistent reservation key used for a specific WWID, when +-\fIreservation_key\fR is set to \fBfile\fR. ++(Deprecated) This option is not supported any more, and will be ignored. + .RS + .TP +-The default is: \fB@STATE_DIR@/prkeys\fR ++The compiled-in value is: \fB@STATE_DIR@/prkeys\fR + .RE + . + . +@@ -989,6 +982,10 @@ The default is: \fB\fR + .TP + .B config_dir + (Deprecated) This option is not supported any more, and the value is ignored. ++.RS ++.TP ++The compiled-in value is: \fB@CONFIGDIR@\fR ++.RE + . + . + .TP +diff --git a/multipathd/uxlsnr.c b/multipathd/uxlsnr.c +index d1f8f234..4d6f258c 100644 +--- a/multipathd/uxlsnr.c ++++ b/multipathd/uxlsnr.c +@@ -203,7 +203,6 @@ static void reset_watch(int notify_fd, struct watch_descriptors *wds, + int dir_reset = 0; + int conf_reset = 0; + int mp_reset = 0; +- char *bindings_file __attribute__((cleanup(cleanup_charp))) = NULL; + + if (notify_fd == -1) + return; +@@ -221,7 +220,6 @@ static void reset_watch(int notify_fd, struct watch_descriptors *wds, + if (wds->mp_wd == -1) + mp_reset = 1; + } +- bindings_file = strdup(conf->bindings_file); + put_multipath_config(conf); + + if (dir_reset) { +@@ -242,17 +240,12 @@ static void reset_watch(int notify_fd, struct watch_descriptors *wds, + if (wds->conf_wd == -1) + condlog(3, "didn't set up notifications on /etc/multipath.conf: %m"); + } +- if (mp_reset && bindings_file) { +- char *slash = strrchr(bindings_file, '/'); +- +- if (slash && slash > bindings_file) { +- *slash = '\0'; +- wds->mp_wd = inotify_add_watch(notify_fd, bindings_file, +- IN_MOVED_TO|IN_ONLYDIR); +- if (wds->mp_wd == -1) ++ if (mp_reset) { ++ wds->mp_wd = inotify_add_watch(notify_fd, STATE_DIR, ++ IN_MOVED_TO|IN_ONLYDIR); ++ if (wds->mp_wd == -1) + condlog(3, "didn't set up notifications on %s: %m", +- bindings_file); +- } ++ STATE_DIR); + } + } + +diff --git a/tests/alias.c b/tests/alias.c +index 94df36d8..f893d174 100644 +--- a/tests/alias.c ++++ b/tests/alias.c +@@ -1264,10 +1264,10 @@ static void al_a(void **state) + will_return(__wrap_write, ln); + will_return(__wrap_write, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); + will_return(__wrap_rename, 0); +- expect_condlog(1, "updated bindings file foo"); ++ expect_condlog(1, "updated bindings file " DEFAULT_BINDINGS_FILE); + expect_condlog(3, NEW_STR("MPATHa", "WWIDa")); + +- alias = allocate_binding("foo", "WWIDa", 1, "MPATH"); ++ alias = allocate_binding("WWIDa", 1, "MPATH"); + assert_ptr_not_equal(alias, NULL); + assert_string_equal(alias, "MPATHa"); + check_bindings_size(1); +@@ -1283,10 +1283,10 @@ static void al_zz(void **state) + will_return(__wrap_write, ln); + will_return(__wrap_write, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); + will_return(__wrap_rename, 0); +- expect_condlog(1, "updated bindings file foo"); ++ expect_condlog(1, "updated bindings file " DEFAULT_BINDINGS_FILE); + expect_condlog(3, NEW_STR("MPATHzz", "WWIDzz")); + +- alias = allocate_binding("foo", "WWIDzz", 26*26 + 26, "MPATH"); ++ alias = allocate_binding("WWIDzz", 26*26 + 26, "MPATH"); + assert_ptr_not_equal(alias, NULL); + assert_string_equal(alias, "MPATHzz"); + check_bindings_size(1); +@@ -1298,7 +1298,7 @@ static void al_0(void **state) + char *alias; + + expect_condlog(0, "allocate_binding: cannot allocate new binding for id 0\n"); +- alias = allocate_binding(0, "WWIDa", 0, "MPATH"); ++ alias = allocate_binding("WWIDa", 0, "MPATH"); + assert_ptr_equal(alias, NULL); + check_bindings_size(0); + } +@@ -1308,7 +1308,7 @@ static void al_m2(void **state) + char *alias; + + expect_condlog(0, "allocate_binding: cannot allocate new binding for id -2\n"); +- alias = allocate_binding(0, "WWIDa", -2, "MPATH"); ++ alias = allocate_binding("WWIDa", -2, "MPATH"); + assert_ptr_equal(alias, NULL); + check_bindings_size(0); + } +@@ -1325,10 +1325,10 @@ static void al_write_partial(void **state) + will_return(__wrap_write, ln + sizeof(ln) - 2); + will_return(__wrap_write, 1); + will_return(__wrap_rename, 0); +- expect_condlog(1, "updated bindings file foo"); ++ expect_condlog(1, "updated bindings file " DEFAULT_BINDINGS_FILE); + expect_condlog(3, "Created new binding [MPATHa] for WWID [WWIDa]\n"); + +- alias = allocate_binding("foo", "WWIDa", 1, "MPATH"); ++ alias = allocate_binding("WWIDa", 1, "MPATH"); + assert_ptr_not_equal(alias, NULL); + assert_string_equal(alias, "MPATHa"); + check_bindings_size(1); +@@ -1350,7 +1350,7 @@ static void al_write_short(void **state) + expect_condlog(1, "failed to write new bindings file"); + expect_condlog(1, "allocate_binding: deleting binding MPATHa for WWIDa"); + +- alias = allocate_binding("foo", "WWIDa", 1, "MPATH"); ++ alias = allocate_binding("WWIDa", 1, "MPATH"); + assert_ptr_equal(alias, NULL); + check_bindings_size(0); + } +@@ -1366,7 +1366,7 @@ static void al_write_err(void **state) + expect_condlog(1, "failed to write new bindings file"); + expect_condlog(1, "allocate_binding: deleting binding MPATHa for WWIDa"); + +- alias = allocate_binding("foo", "WWIDa", 1, "MPATH"); ++ alias = allocate_binding("WWIDa", 1, "MPATH"); + assert_ptr_equal(alias, NULL); + check_bindings_size(0); + } +@@ -1383,7 +1383,7 @@ static void al_rename_err(void **state) + + expect_condlog(0, "update_bindings_file: rename: Read-only file system"); + expect_condlog(1, "allocate_binding: deleting binding MPATHa for WWIDa"); +- alias = allocate_binding("foo", "WWIDa", 1, "MPATH"); ++ alias = allocate_binding("WWIDa", 1, "MPATH"); + assert_ptr_equal(alias, NULL); + check_bindings_size(0); + } +@@ -1415,7 +1415,7 @@ static int test_allocate_binding(void) + strlen(BINDINGS_FILE_HEADER) + (len) + strlen(ln)); \ + will_return(__wrap_rename, err); \ + if (err == 0) { \ +- expect_condlog(1, "updated bindings file x\n"); \ ++ expect_condlog(1, "updated bindings file " DEFAULT_BINDINGS_FILE); \ + expect_condlog(3, NEW_STR(alias, wwid)); \ + } else { \ + expect_condlog(0, "update_bindings_file: rename: " msg "\n"); \ +@@ -1441,7 +1441,7 @@ static void gufa_empty_new_rw(void **state) { + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + + mock_allocate_binding("MPATHa", "WWID0"); +- alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false); ++ alias = get_user_friendly_alias("WWID0", "", "MPATH", false); + assert_string_equal(alias, "MPATHa"); + free(alias); + } +@@ -1454,7 +1454,7 @@ static void gufa_empty_new_ro_1(void **state) { + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + mock_allocate_binding_err("MPATHa", "WWID0", -EROFS, "Read-only file system"); + +- alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false); ++ alias = get_user_friendly_alias("WWID0", "", "MPATH", false); + assert_ptr_equal(alias, NULL); + } + +@@ -1465,7 +1465,7 @@ static void gufa_empty_new_ro_2(void **state) { + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + mock_unused_alias("MPATHa"); + +- alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); ++ alias = get_user_friendly_alias("WWID0", "", "MPATH", true); + assert_ptr_equal(alias, NULL); + } + +@@ -1477,7 +1477,7 @@ static void gufa_match_a_unused(void **state) { + mock_unused_alias("MPATHa"); + expect_condlog(3, EXISTING_STR("MPATHa", "WWID0")); + +- alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); ++ alias = get_user_friendly_alias("WWID0", "", "MPATH", true); + assert_string_equal(alias, "MPATHa"); + free(alias); + } +@@ -1490,7 +1490,7 @@ static void gufa_match_a_self(void **state) { + mock_self_alias("MPATHa", "WWID0"); + expect_condlog(3, EXISTING_STR("MPATHa", "WWID0")); + +- alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); ++ alias = get_user_friendly_alias("WWID0", "", "MPATH", true); + assert_string_equal(alias, "MPATHa"); + free(alias); + } +@@ -1503,7 +1503,7 @@ static void gufa_match_a_used(void **state) { + expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); + mock_used_alias("MPATHa", "WWID0"); + +- alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); ++ alias = get_user_friendly_alias("WWID0", "", "MPATH", true); + assert_ptr_equal(alias, NULL); + } + +@@ -1518,7 +1518,7 @@ static void gufa_nomatch_a_c(void **state) { + + mock_allocate_binding_len("MPATHb", "WWID1", strlen(bindings)); + +- alias = get_user_friendly_alias("WWID1", "x", "", "MPATH", false); ++ alias = get_user_friendly_alias("WWID1", "", "MPATH", false); + assert_string_equal(alias, "MPATHb"); + free(alias); + } +@@ -1534,7 +1534,7 @@ static void gufa_nomatch_c_a(void **state) { + + mock_allocate_binding_len("MPATHb", "WWID1", sizeof(bindings) - 1); + +- alias = get_user_friendly_alias("WWID1", "x", "", "MPATH", false); ++ alias = get_user_friendly_alias("WWID1", "", "MPATH", false); + assert_string_equal(alias, "MPATHb"); + free(alias); + } +@@ -1550,7 +1550,7 @@ static void gufa_nomatch_c_b(void **state) { + + mock_allocate_binding_len("MPATHa", "WWID0", sizeof(bindings) - 1); + +- alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false); ++ alias = get_user_friendly_alias("WWID0", "", "MPATH", false); + assert_string_equal(alias, "MPATHa"); + free(alias); + } +@@ -1567,7 +1567,7 @@ static void gufa_nomatch_c_b_used(void **state) { + + mock_allocate_binding_len("MPATHd", "WWID4", sizeof(bindings) - 1); + +- alias = get_user_friendly_alias("WWID4", "x", "", "MPATH", false); ++ alias = get_user_friendly_alias("WWID4", "", "MPATH", false); + assert_string_equal(alias, "MPATHd"); + free(alias); + } +@@ -1584,7 +1584,7 @@ static void gufa_nomatch_b_f_a(void **state) { + + mock_allocate_binding_len("MPATHc", "WWID7", sizeof(bindings) - 1); + +- alias = get_user_friendly_alias("WWID7", "x", "", "MPATH", false); ++ alias = get_user_friendly_alias("WWID7", "", "MPATH", false); + assert_string_equal(alias, "MPATHc"); + free(alias); + } +@@ -1599,7 +1599,7 @@ static void gufa_nomatch_b_aa_a(void **state) { + mock_unused_alias("MPATHab"); + mock_allocate_binding_len("MPATHab", "WWID28", get_strbuf_len(&buf)); + +- alias = get_user_friendly_alias("WWID28", "x", "", "MPATH", false); ++ alias = get_user_friendly_alias("WWID28", "", "MPATH", false); + assert_string_equal(alias, "MPATHab"); + free(alias); + } +@@ -1616,7 +1616,7 @@ static void gufa_nomatch_b_f_a_sorted(void **state) { + + mock_allocate_binding_len("MPATHc", "WWID7", sizeof(bindings) - 1); + +- alias = get_user_friendly_alias("WWID7", "x", "", "MPATH", false); ++ alias = get_user_friendly_alias("WWID7", "", "MPATH", false); + assert_string_equal(alias, "MPATHc"); + free(alias); + } +@@ -1632,7 +1632,7 @@ static void gufa_old_empty(void **state) { + mock_allocate_binding("MPATHz", "WWID0"); + expect_condlog(2, ALLOC_STR("MPATHz", "WWID0")); + +- alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); ++ alias = get_user_friendly_alias("WWID0", "MPATHz", "MPATH", false); + assert_string_equal(alias, "MPATHz"); + free(alias); + } +@@ -1644,7 +1644,7 @@ static void gufa_old_match(void **state) { + "MPATHz WWID0"); + expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID0")); + +- alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); ++ alias = get_user_friendly_alias("WWID0", "MPATHz", "MPATH", false); + assert_string_equal(alias, "MPATHz"); + free(alias); + } +@@ -1661,7 +1661,7 @@ static void gufa_old_match_other(void **state) { + + mock_allocate_binding_len("MPATHa", "WWID0", sizeof(bindings) - 1); + +- alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); ++ alias = get_user_friendly_alias("WWID0", "MPATHz", "MPATH", false); + assert_string_equal(alias, "MPATHa"); + free(alias); + } +@@ -1678,7 +1678,7 @@ static void gufa_old_match_other_used(void **state) { + mock_unused_alias("MPATHb"); + + mock_allocate_binding_len("MPATHb", "WWID0", sizeof(bindings) - 1); +- alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); ++ alias = get_user_friendly_alias("WWID0", "MPATHz", "MPATH", false); + assert_string_equal(alias, "MPATHb"); + free(alias); + } +@@ -1695,7 +1695,7 @@ static void gufa_old_match_other_wwidmatch(void **state) { + mock_unused_alias("MPATHc"); + expect_condlog(3, EXISTING_STR("MPATHc", "WWID2")); + +- alias = get_user_friendly_alias("WWID2", "x", "MPATHz", "MPATH", false); ++ alias = get_user_friendly_alias("WWID2", "MPATHz", "MPATH", false); + assert_string_equal(alias, "MPATHc"); + free(alias); + } +@@ -1711,7 +1711,7 @@ static void gufa_old_match_other_wwidmatch_used(void **state) { + expect_condlog(3, FOUND_STR("MPATHc", "WWID2")); + mock_used_alias("MPATHc", "WWID2"); + +- alias = get_user_friendly_alias("WWID2", "x", "MPATHz", "MPATH", false); ++ alias = get_user_friendly_alias("WWID2", "MPATHz", "MPATH", false); + assert_ptr_equal(alias, NULL); + } + +@@ -1725,7 +1725,7 @@ static void gufa_old_nomatch_wwidmatch(void **state) { + mock_unused_alias("MPATHa"); + expect_condlog(3, EXISTING_STR("MPATHa", "WWID0")); + +- alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); ++ alias = get_user_friendly_alias("WWID0", "MPATHz", "MPATH", false); + assert_string_equal(alias, "MPATHa"); + free(alias); + } +@@ -1739,7 +1739,7 @@ static void gufa_old_nomatch_wwidmatch_used(void **state) { + expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); + mock_used_alias("MPATHa", "WWID0"); + +- alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); ++ alias = get_user_friendly_alias("WWID0", "MPATHz", "MPATH", false); + assert_ptr_equal(alias, NULL); + } + +@@ -1754,7 +1754,7 @@ static void gufa_old_nomatch_nowwidmatch(void **state) { + mock_allocate_binding_len("MPATHz", "WWID0", sizeof(bindings) - 1); + expect_condlog(2, ALLOC_STR("MPATHz", "WWID0")); + +- alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); ++ alias = get_user_friendly_alias("WWID0", "MPATHz", "MPATH", false); + assert_string_equal(alias, "MPATHz"); + free(alias); + } diff --git a/0038-libmultipath-avoid-Warray-bounds-error-in-uatomic-op.patch b/0038-libmultipath-avoid-Warray-bounds-error-in-uatomic-op.patch new file mode 100644 index 0000000..269efcf --- /dev/null +++ b/0038-libmultipath-avoid-Warray-bounds-error-in-uatomic-op.patch @@ -0,0 +1,158 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 12 Sep 2023 11:54:47 +0200 +Subject: [PATCH] libmultipath: avoid -Warray-bounds error in uatomic + operations + +The use of uatomic_xchg() in alias.c causes a -Warray-bounds error +on distributions using gcc 12, such as Fedora 37. This is a similar +error to 2534c4f ("libmultipath: avoid -Warray-bounds error with gcc +12 and musl libc"). This happens only with liburcu 0.13 and earlier, +and only with certain gcc versions. See liburcu commit 835b9ab +("Fix: x86 and s390 uatomic: __hp() macro warning with gcc 11"). + +Enhance the fix for 2534c4f by a adding a workaround for uatomic_xchg(), +and introduce the macro URCU_VERSION (originally only used for multipathd) +globally. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 2 +- + create-config.mk | 5 +++++ + libmultipath/alias.c | 5 +++-- + libmultipath/lock.h | 21 +++++++++++++-------- + multipathd/Makefile | 2 -- + 5 files changed, 22 insertions(+), 13 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 6e384e68..04bfa56e 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -95,7 +95,7 @@ OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 + WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int \ + -Werror=implicit-function-declaration -Werror=format-security \ + $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) $(W_URCU_TYPE_LIMITS) +-CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) \ ++CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) $(D_URCU_VERSION) \ + -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \ + -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(configdir)\" \ + -DDEFAULT_CONFIGFILE=\"$(configfile)\" -DSTATE_DIR=\"$(statedir)\" \ +diff --git a/create-config.mk b/create-config.mk +index d1255971..4d318b96 100644 +--- a/create-config.mk ++++ b/create-config.mk +@@ -73,6 +73,10 @@ TEST_URCU_TYPE_LIMITS = $(shell \ + $(CC) -c -Werror=type-limits -o /dev/null -xc - 2>/dev/null \ + || echo -Wno-type-limits ) + ++URCU_VERSION = $(shell \ ++ $(PKG_CONFIG) --modversion liburcu 2>/dev/null | \ ++ awk -F. '{ printf("-DURCU_VERSION=0x%06x", 256 * ( 256 * $$1 + $$2) + $$3); }') ++ + DEFINES := + + ifneq ($(call check_func,dm_task_no_flush,$(devmapper_incdir)/libdevmapper.h),0) +@@ -168,6 +172,7 @@ $(TOPDIR)/config.mk: $(multipathdir)/autoconfig.h + @echo creating $@ + @echo "FPIN_SUPPORT := $(FPIN_SUPPORT)" >$@ + @echo "FORTIFY_OPT := $(FORTIFY_OPT)" >>$@ ++ @echo "D_URCU_VERSION := $(call URCU_VERSION)" >>$@ + @echo "SYSTEMD := $(SYSTEMD)" >>$@ + @echo "ANA_SUPPORT := $(ANA_SUPPORT)" >>$@ + @echo "STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector)" >>$@ +diff --git a/libmultipath/alias.c b/libmultipath/alias.c +index e5d3f151..74431f3f 100644 +--- a/libmultipath/alias.c ++++ b/libmultipath/alias.c +@@ -24,6 +24,7 @@ + #include "devmapper.h" + #include "strbuf.h" + #include "time-util.h" ++#include "lock.h" + + /* + * significant parts of this file were taken from iscsi-bindings.c of the +@@ -300,7 +301,7 @@ void handle_bindings_file_inotify(const struct inotify_event *event) + pthread_mutex_unlock(×tamp_mutex); + + if (changed) { +- uatomic_xchg(&bindings_file_changed, 1); ++ uatomic_xchg_int(&bindings_file_changed, 1); + condlog(3, "%s: bindings file must be re-read, new timestamp: %ld.%06ld", + __func__, (long)ts.tv_sec, (long)ts.tv_nsec / 1000); + } else +@@ -775,7 +776,7 @@ static int _read_bindings_file(const struct config *conf, Bindings *bindings, + int rc = 0, ret, fd; + FILE *file; + struct stat st; +- int has_changed = uatomic_xchg(&bindings_file_changed, 0); ++ int has_changed = uatomic_xchg_int(&bindings_file_changed, 0); + + if (!force) { + if (!has_changed) { +diff --git a/libmultipath/lock.h b/libmultipath/lock.h +index 9814be76..ac80d1d8 100644 +--- a/libmultipath/lock.h ++++ b/libmultipath/lock.h +@@ -13,15 +13,20 @@ struct mutex_lock { + int waiters; /* uatomic access only */ + }; + +-#if !defined(__GLIBC__) && defined(__GNUC__) && __GNUC__ == 12 ++static inline void init_lock(struct mutex_lock *a) ++{ ++ pthread_mutex_init(&a->mutex, NULL); ++ uatomic_set(&a->waiters, 0); ++} ++ ++#if defined(__GNUC__) && __GNUC__ == 12 && URCU_VERSION < 0xe00 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Warray-bounds" + #endif + +-static inline void init_lock(struct mutex_lock *a) ++static inline int uatomic_xchg_int(int *ptr, int val) + { +- pthread_mutex_init(&a->mutex, NULL); +- uatomic_set(&a->waiters, 0); ++ return uatomic_xchg(ptr, val); + } + + static inline void lock(struct mutex_lock *a) +@@ -31,6 +36,10 @@ static inline void lock(struct mutex_lock *a) + uatomic_dec(&a->waiters); + } + ++#if defined(__GNUC__) && __GNUC__ == 12 && URCU_VERSION < 0xe00 ++#pragma GCC diagnostic pop ++#endif ++ + static inline int trylock(struct mutex_lock *a) + { + return pthread_mutex_trylock(&a->mutex); +@@ -51,10 +60,6 @@ static inline bool lock_has_waiters(struct mutex_lock *a) + return (uatomic_read(&a->waiters) > 0); + } + +-#if !defined(__GLIBC__) && defined(__GNUC__) && __GNUC__ == 12 +-#pragma GCC diagnostic pop +-#endif +- + #define lock_cleanup_pop(a) pthread_cleanup_pop(1) + + void cleanup_lock (void * data); +diff --git a/multipathd/Makefile b/multipathd/Makefile +index cdba3db1..0ba6ecb7 100644 +--- a/multipathd/Makefile ++++ b/multipathd/Makefile +@@ -5,8 +5,6 @@ CLI := multipathc + MANPAGES := multipathd.8 + + CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathpersistdir) -I$(mpathcmddir) -I$(thirdpartydir) \ +- $(shell $(PKG_CONFIG) --modversion liburcu 2>/dev/null | \ +- awk -F. '{ printf("-DURCU_VERSION=0x%06x", 256 * ( 256 * $$1 + $$2) + $$3); }') \ + -DBINDIR='"$(bindir)"' $(SYSTEMD_CPPFLAGS) + + # diff --git a/0039-multipath-tools-fix-spelling.patch b/0039-multipath-tools-fix-spelling.patch new file mode 100644 index 0000000..c0c86f9 --- /dev/null +++ b/0039-multipath-tools-fix-spelling.patch @@ -0,0 +1,52 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Fri, 15 Sep 2023 22:22:06 +0200 +Subject: [PATCH] multipath-tools: fix spelling + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + README.md | 4 ++-- + multipath/multipath.conf.5.in | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/README.md b/README.md +index 679e55bf..524c9fb1 100644 +--- a/README.md ++++ b/README.md +@@ -92,7 +92,7 @@ The following variables can be passed to the `make` command line: + The default is `$(prefix)/$(LIB)/multipath`, where `$(LIB)` is `lib64` on + systems that have `/lib64`, and `lib` otherwise. + * `configfile="/some/path`": The path to the main configuration file. +- The defalt is `$(etc_prefix)/etc/multipath.conf`. ++ The default is `$(etc_prefix)/etc/multipath.conf`. + * `configdir="/some/path"` : directory to search for additional configuration files. + This used to be the run-time option `config_dir` in earlier versions. + The default is `$(etc_prefix)/etc/multipath/conf.d`. +@@ -141,7 +141,7 @@ The following variables can be passed to the `make` command line: + found on the build system, and `/lib` otherwise. + + The options `configdir`, `plugindir`, `configfile`, and `statedir` above can +-be used for setting indvidual paths where the `prefix` variables don't provide ++be used for setting individual paths where the `prefix` variables don't provide + sufficient control. See `Makefile.inc` for even more fine-grained control. + + [^systemd]: Some systemd installations use separate `prefix` and `rootprefix`. +diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in +index d320a88f..226d0019 100644 +--- a/multipath/multipath.conf.5.in ++++ b/multipath/multipath.conf.5.in +@@ -36,7 +36,7 @@ Files ending in \fI.conf\fR in this directory are read + in alphabetical order, after reading \fI@CONFIGFILE@\fR. + They use the same syntax as \fI@CONFIGFILE@\fR itself, + and support all sections and keywords. If a keyword occurs in the same section +-in multiple files, the last occurence will take precedence over all others. ++in multiple files, the last occurrence will take precedence over all others. + . + . + .\" ---------------------------------------------------------------------------- diff --git a/0040-multipathd-Added-support-to-handle-FPIN-Li-events-fo.patch b/0040-multipathd-Added-support-to-handle-FPIN-Li-events-fo.patch new file mode 100644 index 0000000..7ed50a3 --- /dev/null +++ b/0040-multipathd-Added-support-to-handle-FPIN-Li-events-fo.patch @@ -0,0 +1,300 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Muneendra +Date: Wed, 20 Sep 2023 20:41:15 -0700 +Subject: [PATCH] multipathd: Added support to handle FPIN-Li events for + FC-NVMe + + This patch adds the support to handle FPIN-Li for FC-NVMe. + On receiving the FPIN-Li events this patch moves the devices paths + which are affected due to link integrity to marginal path groups. + The paths which are set to marginal path group will be unset + on receiving the RSCN events + +(mwilck: minor compile fix for 32-bit architectures) + +Signed-off-by: Muneendra +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + multipathd/fpin_handlers.c | 206 +++++++++++++++++++++++++++---------- + 1 file changed, 151 insertions(+), 55 deletions(-) + +diff --git a/multipathd/fpin_handlers.c b/multipathd/fpin_handlers.c +index aa0f63c9..be087ca0 100644 +--- a/multipathd/fpin_handlers.c ++++ b/multipathd/fpin_handlers.c +@@ -60,18 +60,15 @@ static void _udev_device_unref(void *p) + + + /*set/unset the path state to marginal*/ +-static int fpin_set_pathstate(struct path *pp, bool set) ++static void fpin_set_pathstate(struct path *pp, bool set) + { + const char *action = set ? "set" : "unset"; + +- if (!pp || !pp->mpp || !pp->mpp->alias) +- return -1; +- +- condlog(3, "\n%s: %s marginal path %s (fpin)", +- action, pp->mpp->alias, pp->dev_t); ++ condlog(3, "%s: %s marginal path %s (fpin)", ++ pp->mpp ? pp->mpp->alias : "orphan", action, pp->dev_t); + pp->marginal = set; +- pp->mpp->fpin_must_reload = true; +- return 0; ++ if (pp->mpp) ++ pp->mpp->fpin_must_reload = true; + } + + /* This will unset marginal state of a device*/ +@@ -82,14 +79,14 @@ static void fpin_path_unsetmarginal(char *devname, struct vectors *vecs) + pp = find_path_by_dev(vecs->pathvec, devname); + if (!pp) + pp = find_path_by_devt(vecs->pathvec, devname); +- +- fpin_set_pathstate(pp, false); ++ if (pp) ++ fpin_set_pathstate(pp, false); + } + + /*This will set the marginal state of a device*/ +-static int fpin_path_setmarginal(struct path *pp) ++static void fpin_path_setmarginal(struct path *pp) + { +- return fpin_set_pathstate(pp, true); ++ fpin_set_pathstate(pp, true); + } + + /* Unsets all the devices in the list from marginal state */ +@@ -183,8 +180,8 @@ static void fpin_set_rport_marginal(struct udev_device *rport_dev) + udev_device_get_syspath(rport_dev)); + } + +-/*Add the marginal devices info into the list*/ +-static void ++/*Add the marginal devices info into the list and return 0 on success*/ ++static int + fpin_add_marginal_dev_info(uint32_t host_num, char *devname) + { + struct marginal_dev_list *newdev = NULL; +@@ -199,65 +196,160 @@ fpin_add_marginal_dev_info(uint32_t host_num, char *devname) + list_add_tail(&(newdev->node), + &fpin_li_marginal_dev_list_head); + pthread_mutex_unlock(&fpin_li_marginal_dev_mutex); +- } ++ } else ++ return -ENOMEM; ++ return 0; + } + + /* +- * This function goes through the vecs->pathvec, and for +- * each path, check that the host number, +- * the target WWPN associated with the path matches +- * with the els wwpn and sets the path and port state to ++ * This function compares Transport Address Controller Port pn, ++ * Host Transport Address Controller Port pn with the els wwpn ,attached_wwpn ++ * and return 1 (match) or 0 (no match) or a negative error code ++ */ ++static int extract_nvme_addresses_chk_path_pwwn(const char *address, ++ uint64_t els_wwpn, uint64_t els_attached_wwpn) ++ ++{ ++ uint64_t traddr; ++ uint64_t host_traddr; ++ ++ /* ++ * Find the position of "traddr=" and "host_traddr=" ++ * and the address will be in the below format ++ * "traddr=nn-0x200400110dff9400:pn-0x200400110dff9400, ++ * host_traddr=nn-0x200400110dff9400:pn-0x200400110dff9400" ++ */ ++ const char *traddr_start = strstr(address, "traddr="); ++ const char *host_traddr_start = strstr(address, "host_traddr="); ++ ++ if (!traddr_start || !host_traddr_start) ++ return -EINVAL; ++ ++ /* Extract traddr pn */ ++ if (sscanf(traddr_start, "traddr=nn-%*[^:]:pn-%" SCNx64, &traddr) != 1) ++ return -EINVAL; ++ ++ /* Extract host_traddr pn*/ ++ if (sscanf(host_traddr_start, "host_traddr=nn-%*[^:]:pn-%" SCNx64, ++ &host_traddr) != 1) ++ return -EINVAL; ++ condlog(4, "traddr 0x%" PRIx64 " hosttraddr 0x%" PRIx64 " els_wwpn 0x%" ++ PRIx64" els_host_traddr 0x%" PRIx64, ++ traddr, host_traddr, ++ els_wwpn, els_attached_wwpn); ++ if ((host_traddr == els_attached_wwpn) && (traddr == els_wwpn)) ++ return 1; ++ return 0; ++} ++ ++/* ++ * This function check that the Transport Address Controller Port pn, ++ * Host Transport Address Controller Port pn associated with the path matches ++ * with the els wwpn ,attached_wwpn and sets the path state to + * Marginal + */ +-static int fpin_chk_wwn_setpath_marginal(uint16_t host_num, struct vectors *vecs, ++static void fpin_check_set_nvme_path_marginal(uint16_t host_num, struct path *pp, ++ uint64_t els_wwpn, uint64_t attached_wwpn) ++{ ++ struct udev_device *ctl = NULL; ++ const char *address = NULL; ++ int ret = 0; ++ ++ ctl = udev_device_get_parent_with_subsystem_devtype(pp->udev, "nvme", NULL); ++ if (ctl == NULL) { ++ condlog(2, "%s: No parent device for ", pp->dev); ++ return; ++ } ++ address = udev_device_get_sysattr_value(ctl, "address"); ++ if (!address) { ++ condlog(2, "%s: unable to get the address ", pp->dev); ++ return; ++ } ++ condlog(4, "\n address %s: dev :%s\n", address, pp->dev); ++ ret = extract_nvme_addresses_chk_path_pwwn(address, els_wwpn, attached_wwpn); ++ if (ret <= 0) ++ return; ++ ret = fpin_add_marginal_dev_info(host_num, pp->dev); ++ if (ret < 0) ++ return; ++ fpin_path_setmarginal(pp); ++} ++ ++/* ++ * This function check the host number, the target WWPN ++ * associated with the path matches with the els wwpn and ++ * sets the path and port state to Marginal ++ */ ++static void fpin_check_set_scsi_path_marginal(uint16_t host_num, struct path *pp, + uint64_t els_wwpn) + { +- struct path *pp; +- struct multipath *mpp; +- int i, k; + char rport_id[42]; + const char *value = NULL; + struct udev_device *rport_dev = NULL; + uint64_t wwpn; + int ret = 0; ++ sprintf(rport_id, "rport-%d:%d-%d", ++ pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.transport_id); ++ rport_dev = udev_device_new_from_subsystem_sysname(udev, ++ "fc_remote_ports", rport_id); ++ if (!rport_dev) { ++ condlog(2, "%s: No fc_remote_port device for '%s'", pp->dev, ++ rport_id); ++ return; ++ } ++ pthread_cleanup_push(_udev_device_unref, rport_dev); ++ value = udev_device_get_sysattr_value(rport_dev, "port_name"); ++ if (!value) ++ goto unref; ++ ++ wwpn = strtol(value, NULL, 16); ++ /* ++ * If the port wwpn matches sets the path and port state ++ * to marginal ++ */ ++ if (wwpn == els_wwpn) { ++ ret = fpin_add_marginal_dev_info(host_num, pp->dev); ++ if (ret < 0) ++ goto unref; ++ fpin_path_setmarginal(pp); ++ fpin_set_rport_marginal(rport_dev); ++ } ++unref: ++ pthread_cleanup_pop(1); ++ return; ++ ++} ++ ++/* ++ * This function goes through the vecs->pathvec, and for ++ * each path, it checks and sets the path state to marginal ++ * if the path's associated port wwpn ,hostnum matches with ++ * els wwnpn ,attached_wwpn ++ */ ++static int fpin_chk_wwn_setpath_marginal(uint16_t host_num, struct vectors *vecs, ++ uint64_t els_wwpn, uint64_t attached_wwpn) ++{ ++ struct path *pp; ++ struct multipath *mpp; ++ int i, k; ++ int ret = 0; + + pthread_cleanup_push(cleanup_lock, &vecs->lock); + lock(&vecs->lock); + pthread_testcancel(); + + vector_foreach_slot(vecs->pathvec, pp, k) { +- /* Checks the host number and also for the SCSI FCP */ +- if (pp->bus != SYSFS_BUS_SCSI || pp->sg_id.proto_id != SCSI_PROTOCOL_FCP || host_num != pp->sg_id.host_no) ++ if (!pp->mpp) + continue; +- sprintf(rport_id, "rport-%d:%d-%d", +- pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.transport_id); +- rport_dev = udev_device_new_from_subsystem_sysname(udev, +- "fc_remote_ports", rport_id); +- if (!rport_dev) { +- condlog(2, "%s: No fc_remote_port device for '%s'", pp->dev, +- rport_id); +- continue; +- } +- pthread_cleanup_push(_udev_device_unref, rport_dev); +- value = udev_device_get_sysattr_value(rport_dev, "port_name"); +- if (!value) +- goto unref; +- +- if (value) +- wwpn = strtol(value, NULL, 16); +- /* +- * If the port wwpn matches sets the path and port state +- * to marginal +- */ +- if (wwpn == els_wwpn) { +- ret = fpin_path_setmarginal(pp); +- if (ret < 0) +- goto unref; +- fpin_set_rport_marginal(rport_dev); +- fpin_add_marginal_dev_info(host_num, pp->dev); ++ /*checks if the bus type is nvme and the protocol is FC-NVMe*/ ++ if ((pp->bus == SYSFS_BUS_NVME) && (pp->sg_id.proto_id == NVME_PROTOCOL_FC)) { ++ fpin_check_set_nvme_path_marginal(host_num, pp, els_wwpn, attached_wwpn); ++ } else if ((pp->bus == SYSFS_BUS_SCSI) && ++ (pp->sg_id.proto_id == SCSI_PROTOCOL_FCP) && ++ (host_num == pp->sg_id.host_no)) { ++ /* Checks the host number and also for the SCSI FCP */ ++ fpin_check_set_scsi_path_marginal(host_num, pp, els_wwpn); + } +-unref: +- pthread_cleanup_pop(1); + } + /* walk backwards because reload_and_sync_map() can remove mpp */ + vector_foreach_slot_backwards(vecs->mpvec, mpp, i) { +@@ -286,14 +378,18 @@ fpin_parse_li_els_setpath_marginal(uint16_t host_num, struct fc_tlv_desc *tlv, + struct fc_fn_li_desc *li_desc = (struct fc_fn_li_desc *)tlv; + int count = 0; + int ret = 0; ++ uint64_t attached_wwpn; + + /* Update the wwn to list */ + wwn_count = be32_to_cpu(li_desc->pname_count); +- condlog(4, "Got wwn count as %d\n", wwn_count); ++ attached_wwpn = be64_to_cpu(li_desc->attached_wwpn); ++ condlog(4, "Got wwn count as %d detecting wwn 0x%" PRIx64 ++ " attached_wwpn 0x%" PRIx64 "\n", ++ wwn_count, be64_to_cpu(li_desc->detecting_wwpn), attached_wwpn); + + for (iter = 0; iter < wwn_count; iter++) { + wwpn = be64_to_cpu(li_desc->pname_list[iter]); +- ret = fpin_chk_wwn_setpath_marginal(host_num, vecs, wwpn); ++ ret = fpin_chk_wwn_setpath_marginal(host_num, vecs, wwpn, attached_wwpn); + if (ret < 0) + condlog(2, "failed to set the path marginal associated with wwpn: 0x%" PRIx64 "\n", wwpn); + diff --git a/0001-RH-fixup-udev-rules-for-redhat.patch b/0041-RH-fixup-udev-rules-for-redhat.patch similarity index 89% rename from 0001-RH-fixup-udev-rules-for-redhat.patch rename to 0041-RH-fixup-udev-rules-for-redhat.patch index 618603c..e96c1e7 100644 --- a/0001-RH-fixup-udev-rules-for-redhat.patch +++ b/0041-RH-fixup-udev-rules-for-redhat.patch @@ -15,7 +15,7 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 2e25d2ea..540e1dfc 100644 +index 04bfa56e..62d3d5cc 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -34,9 +34,9 @@ endif @@ -27,9 +27,9 @@ index 2e25d2ea..540e1dfc 100644 # Prefix for non-essential libraries (libdmmp) -usr_prefix := $(prefix) +usr_prefix := $(prefix)/usr + # Prefix for configfuration files (multipath.conf) + etc_prefix := $(prefix) # Where to install systemd-related files. systemd is usually installed under /usr - # Note: some systemd installations use separate "prefix" and "rootprefix". - # In this case, override only unitdir to use systemd's "rootprefix" instead of $(systemd_prefix) diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules index 1969dee0..d2b28233 100644 --- a/kpartx/kpartx.rules @@ -43,10 +43,10 @@ index 1969dee0..d2b28233 100644 LABEL="kpartx_end" diff --git a/multipath/Makefile b/multipath/Makefile -index 73db991a..b3c2cc81 100644 +index 68cb5ce7..f70e64ec 100644 --- a/multipath/Makefile +++ b/multipath/Makefile -@@ -24,7 +24,7 @@ install: +@@ -26,7 +26,7 @@ install: $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) $(Q)$(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) @@ -55,7 +55,7 @@ index 73db991a..b3c2cc81 100644 $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(modulesloaddir) $(Q)$(INSTALL_PROGRAM) -m 644 modules-load.conf $(DESTDIR)$(modulesloaddir)/multipath.conf $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(tmpfilesdir) -@@ -44,7 +44,7 @@ uninstall: +@@ -46,7 +46,7 @@ uninstall: $(Q)$(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf @@ -63,4 +63,4 @@ index 73db991a..b3c2cc81 100644 + $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules $(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 $(Q)$(RM) $(DESTDIR)$(mandir)/man5/$(EXEC).conf.5 - + $(Q)$(RM) $(DESTDIR)$(tmpfilesdir)/multipath.conf diff --git a/0002-RH-Remove-the-property-blacklist-exception-builtin.patch b/0042-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 79% rename from 0002-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0042-RH-Remove-the-property-blacklist-exception-builtin.patch index cbd2480..61e8943 100644 --- a/0002-RH-Remove-the-property-blacklist-exception-builtin.patch +++ b/0042-RH-Remove-the-property-blacklist-exception-builtin.patch @@ -13,26 +13,25 @@ it. Signed-off-by: Benjamin Marzinski --- - libmultipath/blacklist.c | 6 ++---- - multipath/multipath.conf.5 | 11 ++++++----- - tests/blacklist.c | 7 ++----- - 3 files changed, 10 insertions(+), 14 deletions(-) + libmultipath/blacklist.c | 5 ++--- + multipath/multipath.conf.5.in | 11 ++++++----- + tests/blacklist.c | 7 ++----- + 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c -index 8d15d2ea..eff690fd 100644 +index 75100b20..0b212078 100644 --- a/libmultipath/blacklist.c +++ b/libmultipath/blacklist.c -@@ -201,9 +201,6 @@ setup_default_blist (struct config * conf) - if (store_ble(conf->blist_devnode, "!^(sd[a-z]|dasd[a-z]|nvme[0-9])", ORIGIN_DEFAULT)) - return 1; - +@@ -230,8 +230,6 @@ setup_default_blist (struct config * conf) + ORIGIN_DEFAULT)) + return 1; + } - if (store_ble(conf->elist_property, "(SCSI_IDENT_|ID_WWN)", ORIGIN_DEFAULT)) - return 1; -- + vector_foreach_slot (conf->hwtable, hwe, i) { if (hwe->bl_product) { - if (find_blacklist_device(conf->blist_device, -@@ -409,7 +406,8 @@ filter_property(const struct config *conf, struct udev_device *udev, +@@ -438,7 +436,8 @@ filter_property(const struct config *conf, struct udev_device *udev, *uid_attribute != '\0'; bool uid_attr_seen = false; @@ -42,11 +41,11 @@ index 8d15d2ea..eff690fd 100644 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 b4dccd1b..284282c6 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -1367,9 +1367,14 @@ keywords. Both are regular expressions. For a full description of these keywords +diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in +index 226d0019..bae4168f 100644 +--- a/multipath/multipath.conf.5.in ++++ b/multipath/multipath.conf.5.in +@@ -1402,9 +1402,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, @@ -62,7 +61,7 @@ index b4dccd1b..284282c6 100644 . .RS .PP -@@ -1380,10 +1385,6 @@ Blacklisting by missing properties is only applied to devices which do have the +@@ -1415,10 +1420,6 @@ Blacklisting by missing properties is only applied to devices which do have the property specified by \fIuid_attribute\fR (e.g. \fIID_SERIAL\fR) set. Previously, it was applied to every device, possibly causing devices to be blacklisted because of temporary I/O error conditions. @@ -74,10 +73,10 @@ index b4dccd1b..284282c6 100644 .TP .B protocol diff --git a/tests/blacklist.c b/tests/blacklist.c -index 882aa3a1..6a22b660 100644 +index ba8dfd07..693db3fa 100644 --- a/tests/blacklist.c +++ b/tests/blacklist.c -@@ -375,9 +375,8 @@ static void test_property_missing(void **state) +@@ -384,9 +384,8 @@ static void test_property_missing(void **state) { static struct udev_device udev = { "sdb", { "ID_FOO", "ID_BAZ", "ID_BAR", "ID_SERIAL", NULL } }; conf.blist_property = blist_property_wwn; @@ -88,7 +87,7 @@ index 882aa3a1..6a22b660 100644 assert_int_equal(filter_property(&conf, &udev, 3, "ID_BLAH"), MATCH_NOTHING); assert_int_equal(filter_property(&conf, &udev, 3, ""), -@@ -469,9 +468,7 @@ static void test_filter_path_missing1(void **state) +@@ -478,9 +477,7 @@ static void test_filter_path_missing1(void **state) conf.blist_device = blist_device_foo_bar; conf.blist_protocol = blist_protocol_fcp; conf.blist_wwid = blist_wwid_xyzzy; diff --git a/0003-RH-don-t-start-without-a-config-file.patch b/0043-RH-don-t-start-without-a-config-file.patch similarity index 71% rename from 0003-RH-don-t-start-without-a-config-file.patch rename to 0043-RH-don-t-start-without-a-config-file.patch index e6e03b4..ef9415d 100644 --- a/0003-RH-don-t-start-without-a-config-file.patch +++ b/0043-RH-don-t-start-without-a-config-file.patch @@ -14,17 +14,18 @@ Signed-off-by: Benjamin Marzinski --- libmultipath/config.c | 13 +++++++++++++ libmultipath/config.h | 1 + + multipath/main.c | 6 ++++++ multipath/multipath.rules.in | 1 + - multipathd/multipathd.8 | 2 ++ + multipathd/multipathd.8.in | 2 ++ multipathd/multipathd.service | 1 + multipathd/multipathd.socket | 1 + - 6 files changed, 19 insertions(+) + 7 files changed, 25 insertions(+) diff --git a/libmultipath/config.c b/libmultipath/config.c -index 5c5c0726..183b319d 100644 +index b7dbc6f5..3a374b3d 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c -@@ -966,6 +966,19 @@ int _init_config (const char *file, struct config *conf) +@@ -958,6 +958,19 @@ int _init_config (const char *file, struct config *conf) } factorize_hwtable(conf->hwtable, builtin_hwtable_size, file); validate_pctable(conf->overrides, 0, file); @@ -45,7 +46,7 @@ index 5c5c0726..183b319d 100644 conf->processed_main_config = 1; diff --git a/libmultipath/config.h b/libmultipath/config.h -index 87947469..0dc89c16 100644 +index 8c22ce75..92f3a0df 100644 --- a/libmultipath/config.h +++ b/libmultipath/config.h @@ -10,6 +10,7 @@ @@ -56,6 +57,35 @@ index 87947469..0dc89c16 100644 enum devtypes { DEV_NONE, +diff --git a/multipath/main.c b/multipath/main.c +index 9e1c5052..46944589 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -829,11 +829,14 @@ main (int argc, char *argv[]) + struct config *conf; + int retries = -1; + bool enable_foreign = false; ++ bool have_config; ++ struct stat buf; + + libmultipath_init(); + if (atexit(dm_lib_exit) || atexit(libmultipath_exit)) + condlog(1, "failed to register cleanup handler for libmultipath: %m"); + logsink = LOGSINK_STDERR_WITH_TIME; ++ have_config = (stat(DEFAULT_CONFIGFILE, &buf) == 0); + if (init_config(DEFAULT_CONFIGFILE)) + exit(RTVL_FAIL); + if (atexit(uninit_config)) +@@ -1081,6 +1084,9 @@ main (int argc, char *argv[]) + while ((r = configure(conf, cmd, dev_type, dev)) == RTVL_RETRY) + condlog(3, "restart multipath configuration process"); + ++ if (!have_config && r == RTVL_OK && ++ (cmd == CMD_LIST_SHORT || cmd == CMD_LIST_LONG)) ++ r = RTVL_FAIL; + out: + put_multipath_config(conf); + if (dev) diff --git a/multipath/multipath.rules.in b/multipath/multipath.rules.in index 6f123760..70b69a06 100644 --- a/multipath/multipath.rules.in @@ -68,11 +98,11 @@ index 6f123760..70b69a06 100644 ENV{DEVTYPE}!="partition", GOTO="test_dev" IMPORT{parent}="DM_MULTIPATH_DEVICE_PATH" -diff --git a/multipathd/multipathd.8 b/multipathd/multipathd.8 -index bdf102eb..a16a0bd5 100644 ---- a/multipathd/multipathd.8 -+++ b/multipathd/multipathd.8 -@@ -48,6 +48,8 @@ map regains its maximum performance and redundancy. +diff --git a/multipathd/multipathd.8.in b/multipathd/multipathd.8.in +index e98c27fd..fd2061e5 100644 +--- a/multipathd/multipathd.8.in ++++ b/multipathd/multipathd.8.in +@@ -49,6 +49,8 @@ map regains its maximum performance and redundancy. With the \fB-k\fR option, \fBmultipathd\fR acts as a client utility that sends commands to a running instance of the multipathd daemon (see \fBCOMMANDS\fR below). diff --git a/0004-RH-Fix-nvme-function-missing-argument.patch b/0044-RH-Fix-nvme-function-missing-argument.patch similarity index 100% rename from 0004-RH-Fix-nvme-function-missing-argument.patch rename to 0044-RH-Fix-nvme-function-missing-argument.patch diff --git a/0005-RH-use-rpm-optflags-if-present.patch b/0045-RH-use-rpm-optflags-if-present.patch similarity index 83% rename from 0005-RH-use-rpm-optflags-if-present.patch rename to 0045-RH-use-rpm-optflags-if-present.patch index 6a7fdea..1ad6b40 100644 --- a/0005-RH-use-rpm-optflags-if-present.patch +++ b/0045-RH-use-rpm-optflags-if-present.patch @@ -13,10 +13,10 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 540e1dfc..748911e2 100644 +index 62d3d5cc..72fd8d57 100644 --- a/Makefile.inc +++ b/Makefile.inc -@@ -78,11 +78,23 @@ ORIG_LDFLAGS := $(LDFLAGS) +@@ -91,11 +91,23 @@ ORIG_LDFLAGS := $(LDFLAGS) SYSTEMD_CPPFLAGS := $(if $(SYSTEMD),-DUSE_SYSTEMD=$(SYSTEMD)) SYSTEMD_LIBDEPS := $(if $(SYSTEMD),$(if $(shell test $(SYSTEMD) -gt 209 && echo 1),-lsystemd,-lsystemd-daemon)) @@ -38,13 +38,13 @@ index 540e1dfc..748911e2 100644 +WARNFLAGS := -Werror -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int \ -Werror=implicit-function-declaration -Werror=format-security \ - $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) $(W_URCU_TYPE_LIMITS) --CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) \ +-CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) $(D_URCU_VERSION) \ + $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) $(W_URCU_TYPE_LIMITS) -Wstrict-prototypes -+CPPFLAGS := $(CPPFLAGS) \ ++CPPFLAGS := $(CPPFLAGS) $(D_URCU_VERSION) \ -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \ - -DRUNTIME_DIR=\"$(runtimedir)\" \ - -DCONFIG_DIR=\"$(configdir)\" -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP -@@ -90,7 +102,7 @@ CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe + -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(configdir)\" \ + -DDEFAULT_CONFIGFILE=\"$(configfile)\" -DSTATE_DIR=\"$(statedir)\" \ +@@ -104,7 +116,7 @@ CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe BIN_CFLAGS := -fPIE -DPIE LIB_CFLAGS := -fPIC SHARED_FLAGS := -shared diff --git a/0006-RH-add-mpathconf.patch b/0046-RH-add-mpathconf.patch similarity index 98% rename from 0006-RH-add-mpathconf.patch rename to 0046-RH-add-mpathconf.patch index e279822..01bc8d2 100644 --- a/0006-RH-add-mpathconf.patch +++ b/0046-RH-add-mpathconf.patch @@ -21,10 +21,10 @@ Signed-off-by: Benjamin Marzinski create mode 100644 multipath/mpathconf.8 diff --git a/libmultipath/config.c b/libmultipath/config.c -index 183b319d..01f36a4f 100644 +index 3a374b3d..4544f484 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c -@@ -968,6 +968,8 @@ int _init_config (const char *file, struct config *conf) +@@ -960,6 +960,8 @@ int _init_config (const char *file, struct config *conf) validate_pctable(conf->overrides, 0, file); } else { condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices."); @@ -34,10 +34,10 @@ index 183b319d..01f36a4f 100644 conf->blist_devnode = vector_alloc(); if (!conf->blist_devnode) { diff --git a/multipath/Makefile b/multipath/Makefile -index b3c2cc81..413294ef 100644 +index f70e64ec..9942d1a9 100644 --- a/multipath/Makefile +++ b/multipath/Makefile -@@ -22,6 +22,7 @@ $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so +@@ -24,6 +24,7 @@ $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so install: $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ @@ -45,7 +45,7 @@ index b3c2cc81..413294ef 100644 $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) $(Q)$(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) $(Q)$(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)$(udevrulesdir)/62-multipath.rules -@@ -31,6 +32,7 @@ install: +@@ -33,6 +34,7 @@ install: $(Q)$(INSTALL_PROGRAM) -m 644 tmpfiles.conf $(DESTDIR)$(tmpfilesdir)/multipath.conf $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 @@ -53,7 +53,7 @@ index b3c2cc81..413294ef 100644 $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man5 $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5 $(DESTDIR)$(mandir)/man5 ifneq ($(SCSI_DH_MODULES_PRELOAD),) -@@ -41,11 +43,13 @@ endif +@@ -43,11 +45,13 @@ endif uninstall: $(Q)$(RM) $(DESTDIR)$(bindir)/$(EXEC) @@ -65,8 +65,8 @@ index b3c2cc81..413294ef 100644 $(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 + $(Q)$(RM) $(DESTDIR)$(mandir)/man8/mpathconf.8 $(Q)$(RM) $(DESTDIR)$(mandir)/man5/$(EXEC).conf.5 + $(Q)$(RM) $(DESTDIR)$(tmpfilesdir)/multipath.conf - clean: dep_clean diff --git a/multipath/mpathconf b/multipath/mpathconf new file mode 100644 index 00000000..319664b1 diff --git a/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0047-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 87% rename from 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0047-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch index 714a1bb..7714825 100644 --- a/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +++ b/0047-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch @@ -15,12 +15,12 @@ multipathd.service Signed-off-by: Benjamin Marzinski --- multipath/main.c | 54 +++++++++++++++++++++++++++++++++-- - multipath/multipath.8 | 7 ++++- + multipath/multipath.8.in | 7 ++++- multipathd/multipathd.service | 1 + 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/multipath/main.c b/multipath/main.c -index 90f940f1..3549740a 100644 +index 46944589..47f89a0a 100644 --- a/multipath/main.c +++ b/multipath/main.c @@ -120,7 +120,7 @@ usage (char * progname) @@ -41,7 +41,7 @@ index 90f940f1..3549740a 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" -@@ -447,6 +449,50 @@ static void cleanup_vecs(void) +@@ -448,6 +450,50 @@ static void cleanup_vecs(void) free_pathvec(vecs.pathvec, FREE_PATHS); } @@ -92,16 +92,16 @@ index 90f940f1..3549740a 100644 static int configure (struct config *conf, enum mpath_cmds cmd, enum devtypes dev_type, char *devpath) -@@ -842,7 +888,7 @@ main (int argc, char *argv[]) - conf->force_sync = 1; - if (atexit(cleanup_vecs)) +@@ -848,7 +894,7 @@ main (int argc, char *argv[]) condlog(1, "failed to register cleanup handler for vecs: %m"); + if (atexit(cleanup_bindings)) + condlog(1, "failed to register cleanup handler for bindings: %m"); - while ((arg = getopt(argc, argv, ":adDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { + while ((arg = getopt(argc, argv, ":aAdDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { switch(arg) { case 'v': if (!isdigit(optarg[0])) { -@@ -913,6 +959,10 @@ main (int argc, char *argv[]) +@@ -919,6 +965,10 @@ main (int argc, char *argv[]) case 'T': cmd = CMD_DUMP_CONFIG; break; @@ -112,11 +112,11 @@ index 90f940f1..3549740a 100644 case 'h': usage(argv[0]); exit(RTVL_OK); -diff --git a/multipath/multipath.8 b/multipath/multipath.8 -index 88149d53..072a03ee 100644 ---- a/multipath/multipath.8 -+++ b/multipath/multipath.8 -@@ -63,7 +63,7 @@ multipath \- Device mapper target autoconfig. +diff --git a/multipath/multipath.8.in b/multipath/multipath.8.in +index 348eb220..82a7e68e 100644 +--- a/multipath/multipath.8.in ++++ b/multipath/multipath.8.in +@@ -64,7 +64,7 @@ multipath \- Device mapper target autoconfig. .B multipath .RB [\| \-v\ \c .IR level \|] @@ -125,7 +125,7 @@ index 88149d53..072a03ee 100644 . .LP .B multipath -@@ -145,6 +145,11 @@ device mapper, path checkers ...). +@@ -146,6 +146,11 @@ device mapper, path checkers ...). Add the WWID for the specified device to the WWIDs file. . .TP diff --git a/0008-RH-reset-default-find_mutipaths-value-to-off.patch b/0048-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 96% rename from 0008-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0048-RH-reset-default-find_mutipaths-value-to-off.patch index ea12464..432b070 100644 --- a/0008-RH-reset-default-find_mutipaths-value-to-off.patch +++ b/0048-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 a5e9ea0c..514fd880 100644 +index d01f9712..ee2e13a9 100644 --- a/libmultipath/defaults.h +++ b/libmultipath/defaults.h @@ -23,7 +23,7 @@ diff --git a/0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0049-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 95% rename from 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0049-RH-attempt-to-get-ANA-info-via-sysfs-first.patch index 06233ff..1f94eb3 100644 --- a/0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +++ b/0049-RH-attempt-to-get-ANA-info-via-sysfs-first.patch @@ -13,7 +13,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/libmultipath/prioritizers/ana.c b/libmultipath/prioritizers/ana.c -index b5c7873d..e139360c 100644 +index e9827dca..80a32aa3 100644 --- a/libmultipath/prioritizers/ana.c +++ b/libmultipath/prioritizers/ana.c @@ -24,6 +24,7 @@ @@ -68,7 +68,7 @@ index b5c7873d..e139360c 100644 static int get_ana_info(struct path * pp) { int rc; -@@ -210,8 +234,11 @@ int getprio(struct path *pp, __attribute__((unused)) char *args, +@@ -209,8 +233,11 @@ int getprio(struct path *pp, __attribute__((unused)) char *args) if (pp->fd < 0) rc = -ANA_ERR_NO_INFORMATION; diff --git a/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch b/0050-RH-make-parse_vpd_pg83-match-scsi_id-output.patch similarity index 98% rename from 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch rename to 0050-RH-make-parse_vpd_pg83-match-scsi_id-output.patch index 4e0b116..1906258 100644 --- a/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +++ b/0050-RH-make-parse_vpd_pg83-match-scsi_id-output.patch @@ -14,7 +14,7 @@ Signed-off-by: Benjamin Marzinski 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 6865cd92..72825829 100644 +index 84ce5fe7..104fdd5a 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c @@ -1177,13 +1177,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, diff --git a/0011-RH-add-scsi-device-handlers-to-modules-load.d.patch b/0051-RH-add-scsi-device-handlers-to-modules-load.d.patch similarity index 96% rename from 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch rename to 0051-RH-add-scsi-device-handlers-to-modules-load.d.patch index 26b0d06..407b621 100644 --- a/0011-RH-add-scsi-device-handlers-to-modules-load.d.patch +++ b/0051-RH-add-scsi-device-handlers-to-modules-load.d.patch @@ -11,7 +11,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc -index 748911e2..c07bcb0c 100644 +index 72fd8d57..a49e9f5a 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -16,7 +16,7 @@ READLINE := diff --git a/0012-RH-compile-with-libreadline-support.patch b/0052-RH-compile-with-libreadline-support.patch similarity index 96% rename from 0012-RH-compile-with-libreadline-support.patch rename to 0052-RH-compile-with-libreadline-support.patch index df99295..c78d5c0 100644 --- a/0012-RH-compile-with-libreadline-support.patch +++ b/0052-RH-compile-with-libreadline-support.patch @@ -12,7 +12,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc -index c07bcb0c..e59313c6 100644 +index a49e9f5a..51b55196 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -12,7 +12,7 @@ diff --git a/0053-RH-Add-mpathcleanup.patch b/0053-RH-Add-mpathcleanup.patch new file mode 100644 index 0000000..9278829 --- /dev/null +++ b/0053-RH-Add-mpathcleanup.patch @@ -0,0 +1,186 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Fri, 7 Jul 2023 15:25:59 -0500 +Subject: [PATCH] RH: Add mpathcleanup + +mpathcleanup is a program that will remove a multipath device as well as +all of the scsi path devices that make it up. + +Signed-off-by: Benjamin Marzinski +--- + multipath/Makefile | 2 + + multipath/mpathcleanup | 145 +++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 147 insertions(+) + create mode 100755 multipath/mpathcleanup + +diff --git a/multipath/Makefile b/multipath/Makefile +index 9942d1a9..d281b501 100644 +--- a/multipath/Makefile ++++ b/multipath/Makefile +@@ -25,6 +25,7 @@ install: + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) + $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ + $(Q)$(INSTALL_PROGRAM) -m 755 mpathconf $(DESTDIR)$(bindir)/ ++ $(Q)$(INSTALL_PROGRAM) -m 755 mpathcleanup $(DESTDIR)$(bindir)/ + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) + $(Q)$(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) + $(Q)$(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)$(udevrulesdir)/62-multipath.rules +@@ -46,6 +47,7 @@ endif + uninstall: + $(Q)$(RM) $(DESTDIR)$(bindir)/$(EXEC) + $(Q)$(RM) $(DESTDIR)$(bindir)/mpathconf ++ $(Q)$(RM) $(DESTDIR)$(bindir)/mpathcleanup + $(Q)$(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules + $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf + $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf +diff --git a/multipath/mpathcleanup b/multipath/mpathcleanup +new file mode 100755 +index 00000000..6fd921e4 +--- /dev/null ++++ b/multipath/mpathcleanup +@@ -0,0 +1,145 @@ ++#!/bin/bash ++# ++# Copyright (C) 2023 Red Hat, Inc. All rights reserved. ++# ++# This file is part of the device-mapper-multipath package. ++# ++# This copyrighted material is made available to anyone wishing to use, ++# modify, copy, or redistribute it subject to the terms and conditions ++# of the GNU General Public License v.2. ++# ++# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ ++unset PROGRAM FLUSH DEVICE DEVNAME MAJOR MINOR PATHDEVS PATHDEV HAVE_MULTIPATHD QUEUEING ++ ++function usage ++{ ++ echo "usage: $PROGRAM [-h] [--flush] " ++ echo "" ++ echo "remove a multipath device and its scsi path devices" ++ echo "" ++ echo "options:" ++ echo " -h, --help show this help message and exit" ++ echo " --flush disable queuing on the multipath device and" ++ echo " flush the path devices before removing" ++} ++ ++function parse_args ++{ ++ while [ -n "$1" ]; do ++ case $1 in ++ --flush) ++ FLUSH=1 ++ shift ++ ;; ++ --help | -h) ++ usage ++ exit 1 ++ ;; ++ *) ++ if [ -n "$DEVICE" ]; then ++ usage ++ exit 1 ++ fi ++ DEVICE=$1 ++ shift ++ ;; ++ esac ++ done ++} ++ ++function validate_device ++{ ++ if [ -z "$DEVICE" ]; then ++ usage ++ exit 1 ++ fi ++ if [[ "$DEVICE" =~ ^[[:digit:]]+:[[:digit:]]+$ ]]; then ++ MAJOR=${DEVICE%%:*} ++ MINOR=${DEVICE##*:} ++ DEVNAME=`dmsetup ls --target multipath | grep "($MAJOR, $MINOR)$" | awk '{print $1}'` ++ else ++ DEVNAME=`dmsetup ls --target multipath | awk '{print $1}' | grep "^$DEVICE$"` ++ fi ++ if [ -z "$DEVNAME" ]; then ++ DEVNAME=`multipath -v 1 -l $DEVICE 2>/dev/null` ++ if [ -z "$DEVNAME" ]; then ++ echo "$DEVICE is not a multipath device" ++ exit 1 ++ fi ++ # verify that this is not a native nvme multipath device ++ dmsetup ls --target multipath | awk '{print $1}' | grep -q "^$DEVNAME$" ++ if test $? -eq 1; then ++ echo "$DEVICE is not a device-mapper multipath device" ++ exit 1 ++ fi ++ fi ++ if [ -z "$MINOR" ]; then ++ MINOR=`dmsetup info -c --noheadings -o minor $DEVNAME` ++ fi ++} ++ ++function get_paths ++{ ++ PATHDEVS=`ls /sys/block/dm-$MINOR/slaves` ++ for PATHDEV in $PATHDEVS; do ++ if [[ ! "$PATHDEV" =~ ^sd[a-z]+$ ]]; then ++ echo "$PATHDEV is not a scsi device. $PROGRAM only works with scsi devices" ++ exit 1 ++ fi ++ done ++} ++ ++function remove_devs ++{ ++ pidof multipathd > /dev/null ++ HAVE_MULTIPATHD=$? ++ multipath -v2 -l "$DEVNAME" | grep features | grep -q queue_if_no_path ++ QUEUEING=$? ++ if [ -n "$FLUSH" ] && [ "$QUEUEING" -eq 0 ]; then ++ if test $HAVE_MULTIPATHD -eq 0; then ++ multipathd disablequeueing map "$DEVNAME" > /dev/null ++ else ++ dmsetup message "$DEVNAME" 0 fail_if_no_path ++ fi ++ sleep 1 ++ fi ++ if test $HAVE_MULTIPATHD -eq 0; then ++ multipath -f "$DEVNAME" ++ else ++ multipathd -Df "$DEVNAME" ++ fi ++ if test $? -eq 1; then ++ echo "$DEVICE cannot be removed" ++ exit 1 ++ fi ++ for PATHDEV in $PATHDEVS; do ++ if [ -n "$FLUSH" ]; then ++ blockdev --flushbufs /dev/"$PATHDEV" ++ fi ++ echo 1 > /sys/block/"$PATHDEV"/device/delete ++ done ++} ++ ++function verify_removal ++{ ++ multipath -v 1 -d $DEVNAME | grep -q "^$DEVNAME$" ++ if test $? -eq 0; then ++ echo "$DEVICE removed but path devices still exist" ++ exit 1 ++ fi ++ multipath -v 1 -l $DEVNAME | grep -q "^$DEVNAME$" ++ if test $? -eq 0; then ++ echo "$DEVICE removal succeeded, but device still exists" ++ exit 1 ++ fi ++} ++ ++PROGRAM="$0" ++parse_args "$@" ++validate_device ++get_paths ++remove_devs ++verify_removal diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 268e4b9..30c0bbf 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,27 +1,68 @@ Name: device-mapper-multipath -Version: 0.9.5 -Release: 2%{?dist} +Version: 0.9.6 +Release: 1%{?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 -L https://github.com/opensvc/multipath-tools/archive/0.9.5.tar.gz -o multipath-tools-0.9.5.tgz -Source0: multipath-tools-0.9.5.tgz +# curl -L https://github.com/opensvc/multipath-tools/archive/0.9.6.tar.gz -o multipath-tools-0.9.6.tgz +Source0: multipath-tools-0.9.6.tgz Source1: multipath.conf -Patch0001: 0001-RH-fixup-udev-rules-for-redhat.patch -Patch0002: 0002-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0003: 0003-RH-don-t-start-without-a-config-file.patch -Patch0004: 0004-RH-Fix-nvme-function-missing-argument.patch -Patch0005: 0005-RH-use-rpm-optflags-if-present.patch -Patch0006: 0006-RH-add-mpathconf.patch -Patch0007: 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0008: 0008-RH-reset-default-find_mutipaths-value-to-off.patch -Patch0009: 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch -Patch0010: 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch -Patch0011: 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch -Patch0012: 0012-RH-compile-with-libreadline-support.patch +Patch0001: 0001-libmultipath-sysfs_set_scsi_tmo-do-nothing-for-ACT_D.patch +Patch0002: 0002-libmultipath-add-alias_already_taken.patch +Patch0003: 0003-libmultipath-unify-use_existing_alias-and-get_user_f.patch +Patch0004: 0004-libmultipath-never-allocate-an-alias-that-s-already-.patch +Patch0005: 0005-libmultipath-lookup_binding-add-comment-about-the-al.patch +Patch0006: 0006-multipath-tools-test-simplify-debugging-for-condlog-.patch +Patch0007: 0007-multipath-tools-tests-add-tests-for-get_user_friendl.patch +Patch0008: 0008-multipath-tools-test-consistent-use-of-macros-in-ali.patch +Patch0009: 0009-multipath-tools-tests-convert-mock_-failed-used-_ali.patch +Patch0010: 0010-multipath-tools-test-use-mock_bindings_file-consiste.patch +Patch0011: 0011-libmultipath-add-global-variable-for-current-binding.patch +Patch0012: 0012-libmultipath-rename-fix_bindings_file-to-update_bind.patch +Patch0013: 0013-libmultipath-alias.c-move-bindings-related-code-up.patch +Patch0014: 0014-libmultipath-update_bindings_file-take-filename-argu.patch +Patch0015: 0015-libmultipath-update_bindings_file-use-a-single-write.patch +Patch0016: 0016-libmultipath-update_bindings_file-don-t-log-temp-fil.patch +Patch0017: 0017-libmultipath-alias.c-factor-out-read_binding.patch +Patch0018: 0018-libmultipath-keep-bindings-in-memory.patch +Patch0019: 0019-multipath-tools-tests-fix-alias-tests.patch +Patch0020: 0020-libmultipath-dm_get_uuid-return-emtpy-UUID-for-non-e.patch +Patch0021: 0021-libmultipath-adapt-to-new-semantics-of-dm_get_uuid.patch +Patch0022: 0022-libmultipath-sort-aliases-by-length-and-strcmp.patch +Patch0023: 0023-multipath-tools-tests-fix-alias-test-after-sort-orde.patch +Patch0024: 0024-libmultipath-simplify-get_free_id-assuming-total-ord.patch +Patch0025: 0025-multipath-tools-tests-adapt-alias-tests-for-total-or.patch +Patch0026: 0026-multipath-tools-tests-add-test-for-ordering-of-bindi.patch +Patch0027: 0027-multipathd-watch-bindings-file-with-inotify-timestam.patch +Patch0028: 0028-multipath-tools-tests-mock-pthread_mutex_-lock-unloc.patch +Patch0029: 0029-multipath-tools-Makefile-sanitize-paths-for-configur.patch +Patch0030: 0030-multipath-tools-add-compile-time-configuration-for-e.patch +Patch0031: 0031-multipath-tools-man-pages-generate-with-correct-path.patch +Patch0032: 0032-libdmmp-Makefile-fix-bug-in-install-section.patch +Patch0033: 0033-multipath-tools-README.md-improve-documentation-for-.patch +Patch0034: 0034-libmultipath-print-built-in-values-for-deprecated-op.patch +Patch0035: 0035-multipath-add-a-missing-newline.patch +Patch0036: 0036-multipath-tools-allow-prefixes-with-and-w-o-trailing.patch +Patch0037: 0037-libmultipath-deprecate-bindings_file-wwids_file-prke.patch +Patch0038: 0038-libmultipath-avoid-Warray-bounds-error-in-uatomic-op.patch +Patch0039: 0039-multipath-tools-fix-spelling.patch +Patch0040: 0040-multipathd-Added-support-to-handle-FPIN-Li-events-fo.patch +Patch0041: 0041-RH-fixup-udev-rules-for-redhat.patch +Patch0042: 0042-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0043: 0043-RH-don-t-start-without-a-config-file.patch +Patch0044: 0044-RH-Fix-nvme-function-missing-argument.patch +Patch0045: 0045-RH-use-rpm-optflags-if-present.patch +Patch0046: 0046-RH-add-mpathconf.patch +Patch0047: 0047-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0048: 0048-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0049: 0049-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0050: 0050-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +Patch0051: 0051-RH-add-scsi-device-handlers-to-modules-load.d.patch +Patch0052: 0052-RH-compile-with-libreadline-support.patch +Patch0053: 0053-RH-Add-mpathcleanup.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -108,7 +149,7 @@ This package contains the files needed to develop applications that use device-mapper-multipath's libdmmp C API library %prep -%autosetup -n multipath-tools-0.9.5 -p1 +%autosetup -n multipath-tools-0.9.6 -p1 cp %{SOURCE1} . %build @@ -158,6 +199,7 @@ fi %{_sbindir}/multipathd %{_sbindir}/multipathc %{_sbindir}/mpathconf +%{_sbindir}/mpathcleanup %{_sbindir}/mpathpersist %{_unitdir}/multipathd.service %{_unitdir}/multipathd.socket @@ -230,6 +272,13 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Fri Sep 22 2023 Benjamin Marzinski - 0.9.6-1 +- Update to the head of the upstream staging branch +- Rename redhat patches + * Previous patches 0001-0012 are now patches 0041-0052 +- Add 0053-RH-Add-mpathcleanup.patch + * add mpathcleanup program + * Wed Jul 19 2023 Fedora Release Engineering - 0.9.5-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild diff --git a/sources b/sources index ece6ffe..5d41f65 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (multipath-tools-0.9.5.tgz) = 39c2e5d45542c6076eb3b17b9994629b4c1f74347aa43e0119001fa2d07d3a606fd5e617962906a11b313afb37a115bd8eec2ef24447e980e61b5900625f9146 +SHA512 (multipath-tools-0.9.6.tgz) = 17d2b46ead9df6826b3266035bc077a2f4d4bea01e2cd59e32d3917cda40c320f11bc8572da7ba66251e312b46d9be317737069193d481d202d49f9aa5fd71b9 SHA512 (multipath.conf) = 71953dce5a68adcf60a942305f5a66023e6f4c4baf53b1bfdb4edf65ed5b8e03db804363c36d1dcfd85591f4766f52b515269904c53b84d7b076da0b80b09942 From 748e0a08b6e2efb771d80e644047f0ad856e8b0d Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Tue, 21 Nov 2023 16:11:29 -0500 Subject: [PATCH 42/67] device-mapper-mulitpath-0.9.7-1 Update source to upstream version 0.9.7 * Previous patches 0001-0040 are included in the source tarball Rename redhat patches * Previous patches 0041-0053 are now patches 0001-0013 Remove /usr/lib/modules-load.d/multipath.conf * has been replaced with modprobe@dm_multipath.service unit Wants. --- .gitignore | 1 + ... 0001-RH-fixup-udev-rules-for-redhat.patch | 21 +- ...fs_set_scsi_tmo-do-nothing-for-ACT_D.patch | 51 - ...property-blacklist-exception-builtin.patch | 6 +- ...libmultipath-add-alias_already_taken.patch | 75 - ...RH-don-t-start-without-a-config-file.patch | 28 +- ...fy-use_existing_alias-and-get_user_f.patch | 207 -- ...H-Fix-nvme-function-missing-argument.patch | 0 ...er-allocate-an-alias-that-s-already-.patch | 101 - ... 0005-RH-use-rpm-optflags-if-present.patch | 10 +- ...kup_binding-add-comment-about-the-al.patch | 61 - ...hconf.patch => 0006-RH-add-mpathconf.patch | 8 +- ...test-simplify-debugging-for-condlog-.patch | 35 - ...om-kernel-cmdline-mpath.wwids-with-A.patch | 14 +- ...tests-add-tests-for-get_user_friendl.patch | 493 ----- ...-default-find_mutipaths-value-to-off.patch | 2 +- ...test-consistent-use-of-macros-in-ali.patch | 365 ---- ...empt-to-get-ANA-info-via-sysfs-first.patch | 0 ...tests-convert-mock_-failed-used-_ali.patch | 246 --- ...-parse_vpd_pg83-match-scsi_id-output.patch | 6 +- ...test-use-mock_bindings_file-consiste.patch | 500 ----- ...si-device-handlers-to-modules-load.d.patch | 2 +- ...-global-variable-for-current-binding.patch | 109 -- ...-RH-compile-with-libreadline-support.patch | 2 +- ...ame-fix_bindings_file-to-update_bind.patch | 40 - ...up.patch => 0013-RH-Add-mpathcleanup.patch | 4 +- ...lias.c-move-bindings-related-code-up.patch | 285 --- ...ate_bindings_file-take-filename-argu.patch | 61 - ...ate_bindings_file-use-a-single-write.patch | 59 - ...ate_bindings_file-don-t-log-temp-fil.patch | 29 - ...path-alias.c-factor-out-read_binding.patch | 94 - ...libmultipath-keep-bindings-in-memory.patch | 545 ------ ...ultipath-tools-tests-fix-alias-tests.patch | 1698 ----------------- ...get_uuid-return-emtpy-UUID-for-non-e.patch | 53 - ...dapt-to-new-semantics-of-dm_get_uuid.patch | 158 -- ...th-sort-aliases-by-length-and-strcmp.patch | 98 - ...tests-fix-alias-test-after-sort-orde.patch | 90 - ...plify-get_free_id-assuming-total-ord.patch | 122 -- ...tests-adapt-alias-tests-for-total-or.patch | 203 -- ...tests-add-test-for-ordering-of-bindi.patch | 275 --- ...-bindings-file-with-inotify-timestam.patch | 597 ------ ...tests-mock-pthread_mutex_-lock-unloc.patch | 102 - ...Makefile-sanitize-paths-for-configur.patch | 73 - ...add-compile-time-configuration-for-e.patch | 58 - ...man-pages-generate-with-correct-path.patch | 366 ---- ...-Makefile-fix-bug-in-install-section.patch | 25 - ...README.md-improve-documentation-for-.patch | 75 - ...nt-built-in-values-for-deprecated-op.patch | 55 - 0035-multipath-add-a-missing-newline.patch | 25 - ...allow-prefixes-with-and-w-o-trailing.patch | 66 - ...recate-bindings_file-wwids_file-prke.patch | 897 --------- ...id-Warray-bounds-error-in-uatomic-op.patch | 158 -- 0039-multipath-tools-fix-spelling.patch | 52 - ...-support-to-handle-FPIN-Li-events-fo.patch | 300 --- device-mapper-multipath.spec | 83 +- sources | 2 +- 56 files changed, 77 insertions(+), 9014 deletions(-) rename 0041-RH-fixup-udev-rules-for-redhat.patch => 0001-RH-fixup-udev-rules-for-redhat.patch (81%) delete mode 100644 0001-libmultipath-sysfs_set_scsi_tmo-do-nothing-for-ACT_D.patch rename 0042-RH-Remove-the-property-blacklist-exception-builtin.patch => 0002-RH-Remove-the-property-blacklist-exception-builtin.patch (96%) delete mode 100644 0002-libmultipath-add-alias_already_taken.patch rename 0043-RH-don-t-start-without-a-config-file.patch => 0003-RH-don-t-start-without-a-config-file.patch (87%) delete mode 100644 0003-libmultipath-unify-use_existing_alias-and-get_user_f.patch rename 0044-RH-Fix-nvme-function-missing-argument.patch => 0004-RH-Fix-nvme-function-missing-argument.patch (100%) delete mode 100644 0004-libmultipath-never-allocate-an-alias-that-s-already-.patch rename 0045-RH-use-rpm-optflags-if-present.patch => 0005-RH-use-rpm-optflags-if-present.patch (87%) delete mode 100644 0005-libmultipath-lookup_binding-add-comment-about-the-al.patch rename 0046-RH-add-mpathconf.patch => 0006-RH-add-mpathconf.patch (99%) delete mode 100644 0006-multipath-tools-test-simplify-debugging-for-condlog-.patch rename 0047-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch => 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch (93%) delete mode 100644 0007-multipath-tools-tests-add-tests-for-get_user_friendl.patch rename 0048-RH-reset-default-find_mutipaths-value-to-off.patch => 0008-RH-reset-default-find_mutipaths-value-to-off.patch (96%) delete mode 100644 0008-multipath-tools-test-consistent-use-of-macros-in-ali.patch rename 0049-RH-attempt-to-get-ANA-info-via-sysfs-first.patch => 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch (100%) delete mode 100644 0009-multipath-tools-tests-convert-mock_-failed-used-_ali.patch rename 0050-RH-make-parse_vpd_pg83-match-scsi_id-output.patch => 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch (94%) delete mode 100644 0010-multipath-tools-test-use-mock_bindings_file-consiste.patch rename 0051-RH-add-scsi-device-handlers-to-modules-load.d.patch => 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch (96%) delete mode 100644 0011-libmultipath-add-global-variable-for-current-binding.patch rename 0052-RH-compile-with-libreadline-support.patch => 0012-RH-compile-with-libreadline-support.patch (96%) delete mode 100644 0012-libmultipath-rename-fix_bindings_file-to-update_bind.patch rename 0053-RH-Add-mpathcleanup.patch => 0013-RH-Add-mpathcleanup.patch (98%) delete mode 100644 0013-libmultipath-alias.c-move-bindings-related-code-up.patch delete mode 100644 0014-libmultipath-update_bindings_file-take-filename-argu.patch delete mode 100644 0015-libmultipath-update_bindings_file-use-a-single-write.patch delete mode 100644 0016-libmultipath-update_bindings_file-don-t-log-temp-fil.patch delete mode 100644 0017-libmultipath-alias.c-factor-out-read_binding.patch delete mode 100644 0018-libmultipath-keep-bindings-in-memory.patch delete mode 100644 0019-multipath-tools-tests-fix-alias-tests.patch delete mode 100644 0020-libmultipath-dm_get_uuid-return-emtpy-UUID-for-non-e.patch delete mode 100644 0021-libmultipath-adapt-to-new-semantics-of-dm_get_uuid.patch delete mode 100644 0022-libmultipath-sort-aliases-by-length-and-strcmp.patch delete mode 100644 0023-multipath-tools-tests-fix-alias-test-after-sort-orde.patch delete mode 100644 0024-libmultipath-simplify-get_free_id-assuming-total-ord.patch delete mode 100644 0025-multipath-tools-tests-adapt-alias-tests-for-total-or.patch delete mode 100644 0026-multipath-tools-tests-add-test-for-ordering-of-bindi.patch delete mode 100644 0027-multipathd-watch-bindings-file-with-inotify-timestam.patch delete mode 100644 0028-multipath-tools-tests-mock-pthread_mutex_-lock-unloc.patch delete mode 100644 0029-multipath-tools-Makefile-sanitize-paths-for-configur.patch delete mode 100644 0030-multipath-tools-add-compile-time-configuration-for-e.patch delete mode 100644 0031-multipath-tools-man-pages-generate-with-correct-path.patch delete mode 100644 0032-libdmmp-Makefile-fix-bug-in-install-section.patch delete mode 100644 0033-multipath-tools-README.md-improve-documentation-for-.patch delete mode 100644 0034-libmultipath-print-built-in-values-for-deprecated-op.patch delete mode 100644 0035-multipath-add-a-missing-newline.patch delete mode 100644 0036-multipath-tools-allow-prefixes-with-and-w-o-trailing.patch delete mode 100644 0037-libmultipath-deprecate-bindings_file-wwids_file-prke.patch delete mode 100644 0038-libmultipath-avoid-Warray-bounds-error-in-uatomic-op.patch delete mode 100644 0039-multipath-tools-fix-spelling.patch delete mode 100644 0040-multipathd-Added-support-to-handle-FPIN-Li-events-fo.patch diff --git a/.gitignore b/.gitignore index 75c4abc..f698d08 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,4 @@ multipath-tools-091027.tar.gz /multipath-tools-0.9.4.tgz /multipath-tools-0.9.5.tgz /multipath-tools-0.9.6.tgz +/multipath-tools-0.9.7.tgz diff --git a/0041-RH-fixup-udev-rules-for-redhat.patch b/0001-RH-fixup-udev-rules-for-redhat.patch similarity index 81% rename from 0041-RH-fixup-udev-rules-for-redhat.patch rename to 0001-RH-fixup-udev-rules-for-redhat.patch index e96c1e7..02efadd 100644 --- a/0041-RH-fixup-udev-rules-for-redhat.patch +++ b/0001-RH-fixup-udev-rules-for-redhat.patch @@ -9,27 +9,24 @@ different naming scheme for partitions than SuSE. Signed-off-by: Benjamin Marzinski --- - Makefile.inc | 4 ++-- + Makefile.inc | 2 +- kpartx/kpartx.rules | 2 +- multipath/Makefile | 4 ++-- - 3 files changed, 5 insertions(+), 5 deletions(-) + 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 04bfa56e..62d3d5cc 100644 +index 6b454303..0b0e3ad2 100644 --- a/Makefile.inc +++ b/Makefile.inc -@@ -34,9 +34,9 @@ endif +@@ -34,7 +34,7 @@ endif # Paths. All these can be overridden on the "make" command line. prefix := # Prefix for binaries -exec_prefix := $(prefix) +exec_prefix := $(prefix)/usr # Prefix for non-essential libraries (libdmmp) --usr_prefix := $(prefix) -+usr_prefix := $(prefix)/usr + usr_prefix := $(if $(prefix),$(prefix),/usr) # Prefix for configfuration files (multipath.conf) - etc_prefix := $(prefix) - # Where to install systemd-related files. systemd is usually installed under /usr diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules index 1969dee0..d2b28233 100644 --- a/kpartx/kpartx.rules @@ -43,7 +40,7 @@ index 1969dee0..d2b28233 100644 LABEL="kpartx_end" diff --git a/multipath/Makefile b/multipath/Makefile -index 68cb5ce7..f70e64ec 100644 +index 0efb9b26..504d6892 100644 --- a/multipath/Makefile +++ b/multipath/Makefile @@ -26,7 +26,7 @@ install: @@ -52,10 +49,10 @@ index 68cb5ce7..f70e64ec 100644 $(Q)$(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) - $(Q)$(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)$(udevrulesdir)/56-multipath.rules + $(Q)$(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)$(udevrulesdir)/62-multipath.rules - $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(modulesloaddir) - $(Q)$(INSTALL_PROGRAM) -m 644 modules-load.conf $(DESTDIR)$(modulesloaddir)/multipath.conf $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(tmpfilesdir) -@@ -46,7 +46,7 @@ uninstall: + $(Q)$(INSTALL_PROGRAM) -m 644 tmpfiles.conf $(DESTDIR)$(tmpfilesdir)/multipath.conf + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 +@@ -48,7 +48,7 @@ uninstall: $(Q)$(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf diff --git a/0001-libmultipath-sysfs_set_scsi_tmo-do-nothing-for-ACT_D.patch b/0001-libmultipath-sysfs_set_scsi_tmo-do-nothing-for-ACT_D.patch deleted file mode 100644 index 9b8a486..0000000 --- a/0001-libmultipath-sysfs_set_scsi_tmo-do-nothing-for-ACT_D.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 22 Aug 2023 16:21:43 +0200 -Subject: [PATCH] libmultipath: sysfs_set_scsi_tmo: do nothing for ACT_DRY_RUN - -"multipath -d" might change sysfs timeouts of SCSI devices. -Make sure it doesn't. - -Signed-off-by: Martin Wilck -Cc: Jehan Singh -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 4 ++-- - libmultipath/discovery.c | 3 +++ - 2 files changed, 5 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 9513baae..029fbbd2 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -1193,13 +1193,13 @@ int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid, - - if (cmpp) - mpp->queue_mode = cmpp->queue_mode; -+ if (cmd == CMD_DRY_RUN && mpp->action == ACT_UNDEF) -+ mpp->action = ACT_DRY_RUN; - if (setup_map(mpp, ¶ms, vecs)) { - remove_map(mpp, vecs->pathvec, NULL); - continue; - } - -- if (cmd == CMD_DRY_RUN) -- mpp->action = ACT_DRY_RUN; - if (mpp->action == ACT_UNDEF) - select_action(mpp, curmp, - force_reload == FORCE_RELOAD_YES ? 1 : 0); -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index e4de48e7..84ce5fe7 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -857,6 +857,9 @@ sysfs_set_scsi_tmo (struct config *conf, struct multipath *mpp) - bool warn_dev_loss = false; - bool warn_fast_io_fail = false; - -+ if (mpp->action == ACT_DRY_RUN || mpp->action == ACT_REJECT) -+ return 0; -+ - if (mpp->no_path_retry > 0) { - uint64_t no_path_retry_tmo = - (uint64_t)mpp->no_path_retry * conf->checkint; diff --git a/0042-RH-Remove-the-property-blacklist-exception-builtin.patch b/0002-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 96% rename from 0042-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0002-RH-Remove-the-property-blacklist-exception-builtin.patch index 61e8943..bc259d4 100644 --- a/0042-RH-Remove-the-property-blacklist-exception-builtin.patch +++ b/0002-RH-Remove-the-property-blacklist-exception-builtin.patch @@ -42,10 +42,10 @@ index 75100b20..0b212078 100644 udev_device_get_properties_list_entry(udev)) { diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in -index 226d0019..bae4168f 100644 +index 683bdb72..87b3b2a5 100644 --- a/multipath/multipath.conf.5.in +++ b/multipath/multipath.conf.5.in -@@ -1402,9 +1402,14 @@ keywords. Both are regular expressions. For a full description of these keywords +@@ -1431,9 +1431,14 @@ keywords. Both are regular expressions. For a full description of these keywords Regular expression for an udev property. All devices that have matching udev properties will be excluded/included. The handling of the \fIproperty\fR keyword is special, @@ -61,7 +61,7 @@ index 226d0019..bae4168f 100644 . .RS .PP -@@ -1415,10 +1420,6 @@ Blacklisting by missing properties is only applied to devices which do have the +@@ -1444,10 +1449,6 @@ Blacklisting by missing properties is only applied to devices which do have the property specified by \fIuid_attribute\fR (e.g. \fIID_SERIAL\fR) set. Previously, it was applied to every device, possibly causing devices to be blacklisted because of temporary I/O error conditions. diff --git a/0002-libmultipath-add-alias_already_taken.patch b/0002-libmultipath-add-alias_already_taken.patch deleted file mode 100644 index 8ed3c7b..0000000 --- a/0002-libmultipath-add-alias_already_taken.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 22 Aug 2023 21:36:11 +0200 -Subject: [PATCH] libmultipath: add alias_already_taken() - -Factor out a trivial helper function. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/alias.c | 32 +++++++++++++++++++------------- - 1 file changed, 19 insertions(+), 13 deletions(-) - -diff --git a/libmultipath/alias.c b/libmultipath/alias.c -index c0139a2e..83ded886 100644 ---- a/libmultipath/alias.c -+++ b/libmultipath/alias.c -@@ -8,6 +8,7 @@ - #include - #include - #include -+#include - - #include "debug.h" - #include "util.h" -@@ -109,30 +110,35 @@ scan_devname(const char *alias, const char *prefix) - return n; - } - --static int --id_already_taken(int id, const char *prefix, const char *map_wwid) -+static bool alias_already_taken(const char *alias, const char *map_wwid) - { -- STRBUF_ON_STACK(buf); -- const char *alias; -- -- if (append_strbuf_str(&buf, prefix) < 0 || -- format_devname(&buf, id) < 0) -- return 0; - -- alias = get_strbuf_str(&buf); - if (dm_map_present(alias)) { - char wwid[WWID_SIZE]; - - /* If both the name and the wwid match, then it's fine.*/ - if (dm_get_uuid(alias, wwid, sizeof(wwid)) == 0 && - strncmp(map_wwid, wwid, sizeof(wwid)) == 0) -- return 0; -- condlog(3, "%s: alias '%s' already taken, but not in bindings file. reselecting alias", map_wwid, alias); -- return 1; -+ return false; -+ condlog(3, "%s: alias '%s' already taken, but not in bindings file. reselecting alias", -+ map_wwid, alias); -+ return true; - } -- return 0; -+ return false; - } - -+static bool id_already_taken(int id, const char *prefix, const char *map_wwid) -+{ -+ STRBUF_ON_STACK(buf); -+ const char *alias; -+ -+ if (append_strbuf_str(&buf, prefix) < 0 || -+ format_devname(&buf, id) < 0) -+ return false; -+ -+ alias = get_strbuf_str(&buf); -+ return alias_already_taken(alias, map_wwid); -+} - - /* - * Returns: 0 if matching entry in WWIDs file found diff --git a/0043-RH-don-t-start-without-a-config-file.patch b/0003-RH-don-t-start-without-a-config-file.patch similarity index 87% rename from 0043-RH-don-t-start-without-a-config-file.patch rename to 0003-RH-don-t-start-without-a-config-file.patch index ef9415d..fa304dc 100644 --- a/0043-RH-don-t-start-without-a-config-file.patch +++ b/0003-RH-don-t-start-without-a-config-file.patch @@ -12,13 +12,13 @@ simple way to disable multipath. Simply removing or renaming Signed-off-by: Benjamin Marzinski --- - libmultipath/config.c | 13 +++++++++++++ - libmultipath/config.h | 1 + - multipath/main.c | 6 ++++++ - multipath/multipath.rules.in | 1 + - multipathd/multipathd.8.in | 2 ++ - multipathd/multipathd.service | 1 + - multipathd/multipathd.socket | 1 + + libmultipath/config.c | 13 +++++++++++++ + libmultipath/config.h | 1 + + multipath/main.c | 6 ++++++ + multipath/multipath.rules.in | 1 + + multipathd/multipathd.8.in | 2 ++ + multipathd/multipathd.service.in | 1 + + multipathd/multipathd.socket | 1 + 7 files changed, 25 insertions(+) diff --git a/libmultipath/config.c b/libmultipath/config.c @@ -46,7 +46,7 @@ index b7dbc6f5..3a374b3d 100644 conf->processed_main_config = 1; diff --git a/libmultipath/config.h b/libmultipath/config.h -index 8c22ce75..92f3a0df 100644 +index 384193ab..158cebf0 100644 --- a/libmultipath/config.h +++ b/libmultipath/config.h @@ -10,6 +10,7 @@ @@ -111,12 +111,12 @@ index e98c27fd..fd2061e5 100644 . . .\" ---------------------------------------------------------------------------- -diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service -index 5a9cde12..311f49c7 100644 ---- a/multipathd/multipathd.service -+++ b/multipathd/multipathd.service -@@ -6,6 +6,7 @@ Wants=systemd-udevd-kernel.socket - After=systemd-udevd-kernel.socket +diff --git a/multipathd/multipathd.service.in b/multipathd/multipathd.service.in +index 6d03ff71..0965d6f9 100644 +--- a/multipathd/multipathd.service.in ++++ b/multipathd/multipathd.service.in +@@ -6,6 +6,7 @@ Wants=systemd-udevd-kernel.socket @MODPROBE_UNIT@ + After=systemd-udevd-kernel.socket @MODPROBE_UNIT@ After=multipathd.socket systemd-remount-fs.service Before=initrd-cleanup.service +ConditionPathExists=/etc/multipath.conf diff --git a/0003-libmultipath-unify-use_existing_alias-and-get_user_f.patch b/0003-libmultipath-unify-use_existing_alias-and-get_user_f.patch deleted file mode 100644 index 5beb1fe..0000000 --- a/0003-libmultipath-unify-use_existing_alias-and-get_user_f.patch +++ /dev/null @@ -1,207 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 22 Aug 2023 22:00:58 +0200 -Subject: [PATCH] libmultipath: unify use_existing_alias() and - get_user_friendly_alias() - -These functions are only called from select_alias(). The logic -is more obvious when unified in a single function. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/alias.c | 82 ++++++++++++------------------------------ - libmultipath/alias.h | 9 ++--- - libmultipath/propsel.c | 19 +++++----- - 3 files changed, 34 insertions(+), 76 deletions(-) - -diff --git a/libmultipath/alias.c b/libmultipath/alias.c -index 83ded886..68f5d848 100644 ---- a/libmultipath/alias.c -+++ b/libmultipath/alias.c -@@ -329,13 +329,13 @@ allocate_binding(int fd, const char *wwid, int id, const char *prefix) - return alias; - } - --char * --use_existing_alias (const char *wwid, const char *file, const char *alias_old, -- const char *prefix, int bindings_read_only) -+char *get_user_friendly_alias(const char *wwid, const char *file, const char *alias_old, -+ const char *prefix, bool bindings_read_only) - { - char *alias = NULL; - int id = 0; - int fd, can_write; -+ bool new_binding = false; - char buff[WWID_SIZE]; - FILE *f; - -@@ -349,6 +349,10 @@ use_existing_alias (const char *wwid, const char *file, const char *alias_old, - close(fd); - return NULL; - } -+ -+ if (!strlen(alias_old)) -+ goto new_alias; -+ - /* lookup the binding. if it exists, the wwid will be in buff - * either way, id contains the id for the alias - */ -@@ -358,14 +362,14 @@ use_existing_alias (const char *wwid, const char *file, const char *alias_old, - /* if buff is our wwid, it's already - * allocated correctly - */ -- if (strcmp(buff, wwid) == 0) -+ if (strcmp(buff, wwid) == 0) { - alias = strdup(alias_old); -- else { -- alias = NULL; -+ goto out; -+ } else { - condlog(0, "alias %s already bound to wwid %s, cannot reuse", - alias_old, buff); -+ goto new_alias; - } -- goto out; - } - - id = lookup_binding(f, wwid, &alias, NULL, 0); -@@ -377,8 +381,15 @@ use_existing_alias (const char *wwid, const char *file, const char *alias_old, - - /* allocate the existing alias in the bindings file */ - id = scan_devname(alias_old, prefix); -- if (id <= 0) -- goto out; -+ -+new_alias: -+ if (id <= 0) { -+ id = lookup_binding(f, wwid, &alias, prefix, 1); -+ if (id <= 0) -+ goto out; -+ else -+ new_binding = true; -+ } - - if (fflush(f) != 0) { - condlog(0, "cannot fflush bindings file stream : %s", -@@ -388,8 +399,9 @@ use_existing_alias (const char *wwid, const char *file, const char *alias_old, - - if (can_write && !bindings_read_only) { - alias = allocate_binding(fd, wwid, id, prefix); -- condlog(0, "Allocated existing binding [%s] for WWID [%s]", -- alias, wwid); -+ if (alias && !new_binding) -+ condlog(2, "Allocated existing binding [%s] for WWID [%s]", -+ alias, wwid); - } - - out: -@@ -399,54 +411,6 @@ out: - return alias; - } - --char * --get_user_friendly_alias(const char *wwid, const char *file, const char *prefix, -- int bindings_read_only) --{ -- char *alias; -- int fd, id; -- FILE *f; -- int can_write; -- -- if (!wwid || *wwid == '\0') { -- condlog(3, "Cannot find binding for empty WWID"); -- return NULL; -- } -- -- fd = open_file(file, &can_write, bindings_file_header); -- if (fd < 0) -- return NULL; -- -- f = fdopen(fd, "r"); -- if (!f) { -- condlog(0, "cannot fdopen on bindings file descriptor : %s", -- strerror(errno)); -- close(fd); -- return NULL; -- } -- -- id = lookup_binding(f, wwid, &alias, prefix, 1); -- if (id < 0) { -- fclose(f); -- return NULL; -- } -- -- pthread_cleanup_push(free, alias); -- -- if (fflush(f) != 0) { -- condlog(0, "cannot fflush bindings file stream : %s", -- strerror(errno)); -- free(alias); -- alias = NULL; -- } else if (can_write && !bindings_read_only && !alias) -- alias = allocate_binding(fd, wwid, id, prefix); -- -- fclose(f); -- -- pthread_cleanup_pop(0); -- return alias; --} -- - int - get_user_friendly_wwid(const char *alias, char *buff, const char *file) - { -diff --git a/libmultipath/alias.h b/libmultipath/alias.h -index dbc950c4..fa332233 100644 ---- a/libmultipath/alias.h -+++ b/libmultipath/alias.h -@@ -2,13 +2,10 @@ - #define _ALIAS_H - - int valid_alias(const char *alias); --char *get_user_friendly_alias(const char *wwid, const char *file, -- const char *prefix, -- int bindings_readonly); - int get_user_friendly_wwid(const char *alias, char *buff, const char *file); --char *use_existing_alias (const char *wwid, const char *file, -- const char *alias_old, -- const char *prefix, int bindings_read_only); -+char *get_user_friendly_alias(const char *wwid, const char *file, -+ const char *alias_old, -+ const char *prefix, bool bindings_read_only); - - struct config; - int check_alias_settings(const struct config *); -diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c -index d6bce129..354e883f 100644 ---- a/libmultipath/propsel.c -+++ b/libmultipath/propsel.c -@@ -401,19 +401,16 @@ int select_alias(struct config *conf, struct multipath * mp) - - select_alias_prefix(conf, mp); - -- if (strlen(mp->alias_old) > 0) { -- mp->alias = use_existing_alias(mp->wwid, conf->bindings_file, -- mp->alias_old, mp->alias_prefix, -- conf->bindings_read_only); -- memset (mp->alias_old, 0, WWID_SIZE); -- origin = "(setting: using existing alias)"; -- } -+ mp->alias = get_user_friendly_alias(mp->wwid, conf->bindings_file, -+ mp->alias_old, mp->alias_prefix, -+ conf->bindings_read_only); - -- if (mp->alias == NULL) { -- mp->alias = get_user_friendly_alias(mp->wwid, -- conf->bindings_file, mp->alias_prefix, conf->bindings_read_only); -+ if (mp->alias && !strncmp(mp->alias, mp->alias_old, WWID_SIZE)) -+ origin = "(setting: using existing alias)"; -+ else if (mp->alias) - origin = "(setting: user_friendly_name)"; -- } -+ memset (mp->alias_old, 0, WWID_SIZE); -+ - out: - if (mp->alias == NULL) { - mp->alias = strdup(mp->wwid); diff --git a/0044-RH-Fix-nvme-function-missing-argument.patch b/0004-RH-Fix-nvme-function-missing-argument.patch similarity index 100% rename from 0044-RH-Fix-nvme-function-missing-argument.patch rename to 0004-RH-Fix-nvme-function-missing-argument.patch diff --git a/0004-libmultipath-never-allocate-an-alias-that-s-already-.patch b/0004-libmultipath-never-allocate-an-alias-that-s-already-.patch deleted file mode 100644 index 3d05b85..0000000 --- a/0004-libmultipath-never-allocate-an-alias-that-s-already-.patch +++ /dev/null @@ -1,101 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 22 Aug 2023 22:23:29 +0200 -Subject: [PATCH] libmultipath: never allocate an alias that's already taken - -If the bindings file is changed in a way that multipathd can't handle -(e.g. by swapping the aliases of two maps), multipathd must not try -to re-use an alias that is already used by another map. Creating -or renaming a map with such an alias will fail. We already avoid -this for some cases, but not for all. Fix it. - -Signed-off-by: Martin Wilck -Cc: David Bond -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/alias.c | 31 +++++++++++++++++++++++-------- - tests/alias.c | 2 +- - 2 files changed, 24 insertions(+), 9 deletions(-) - -diff --git a/libmultipath/alias.c b/libmultipath/alias.c -index 68f5d848..3e3dfe98 100644 ---- a/libmultipath/alias.c -+++ b/libmultipath/alias.c -@@ -120,7 +120,7 @@ static bool alias_already_taken(const char *alias, const char *map_wwid) - if (dm_get_uuid(alias, wwid, sizeof(wwid)) == 0 && - strncmp(map_wwid, wwid, sizeof(wwid)) == 0) - return false; -- condlog(3, "%s: alias '%s' already taken, but not in bindings file. reselecting alias", -+ condlog(3, "%s: alias '%s' already taken, reselecting alias", - map_wwid, alias); - return true; - } -@@ -359,12 +359,11 @@ char *get_user_friendly_alias(const char *wwid, const char *file, const char *al - rlookup_binding(f, buff, alias_old); - - if (strlen(buff) > 0) { -- /* if buff is our wwid, it's already -- * allocated correctly -- */ -+ /* If buff is our wwid, it's already allocated correctly. */ - if (strcmp(buff, wwid) == 0) { - alias = strdup(alias_old); - goto out; -+ - } else { - condlog(0, "alias %s already bound to wwid %s, cannot reuse", - alias_old, buff); -@@ -372,19 +371,35 @@ char *get_user_friendly_alias(const char *wwid, const char *file, const char *al - } - } - -- id = lookup_binding(f, wwid, &alias, NULL, 0); -+ /* -+ * Look for an existing alias in the bindings file. -+ * Pass prefix = NULL, so lookup_binding() won't try to allocate a new id. -+ */ -+ lookup_binding(f, wwid, &alias, NULL, 0); - if (alias) { -- condlog(3, "Use existing binding [%s] for WWID [%s]", -- alias, wwid); -+ if (alias_already_taken(alias, wwid)) { -+ free(alias); -+ alias = NULL; -+ } else -+ condlog(3, "Use existing binding [%s] for WWID [%s]", -+ alias, wwid); - goto out; - } - -- /* allocate the existing alias in the bindings file */ -+ /* alias_old is already taken by our WWID, update bindings file. */ - id = scan_devname(alias_old, prefix); - - new_alias: - if (id <= 0) { -+ /* -+ * no existing alias was provided, or allocating it -+ * failed. Try a new one. -+ */ - id = lookup_binding(f, wwid, &alias, prefix, 1); -+ if (id == 0 && alias_already_taken(alias, wwid)) { -+ free(alias); -+ alias = NULL; -+ } - if (id <= 0) - goto out; - else -diff --git a/tests/alias.c b/tests/alias.c -index 3ca6c28b..11f209e0 100644 ---- a/tests/alias.c -+++ b/tests/alias.c -@@ -398,7 +398,7 @@ static void mock_self_alias(const char *alias, const char *wwid) - will_return(__wrap_dm_get_uuid, wwid); - } - --#define USED_STR(alias_str, wwid_str) wwid_str ": alias '" alias_str "' already taken, but not in bindings file. reselecting alias\n" -+#define USED_STR(alias_str, wwid_str) wwid_str ": alias '" alias_str "' already taken, reselecting alias\n" - - static void mock_failed_alias(const char *alias, char *msg) - { diff --git a/0045-RH-use-rpm-optflags-if-present.patch b/0005-RH-use-rpm-optflags-if-present.patch similarity index 87% rename from 0045-RH-use-rpm-optflags-if-present.patch rename to 0005-RH-use-rpm-optflags-if-present.patch index 1ad6b40..6352c23 100644 --- a/0045-RH-use-rpm-optflags-if-present.patch +++ b/0005-RH-use-rpm-optflags-if-present.patch @@ -13,12 +13,12 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 62d3d5cc..72fd8d57 100644 +index 0b0e3ad2..3d80d224 100644 --- a/Makefile.inc +++ b/Makefile.inc -@@ -91,11 +91,23 @@ ORIG_LDFLAGS := $(LDFLAGS) - SYSTEMD_CPPFLAGS := $(if $(SYSTEMD),-DUSE_SYSTEMD=$(SYSTEMD)) - SYSTEMD_LIBDEPS := $(if $(SYSTEMD),$(if $(shell test $(SYSTEMD) -gt 209 && echo 1),-lsystemd,-lsystemd-daemon)) +@@ -95,11 +95,23 @@ SYSTEMD_LIBDEPS := $(if $(SYSTEMD),$(if $(shell test $(SYSTEMD) -gt 209 && echo + MODPROBE_UNIT := $(shell test "0$(SYSTEMD)" -lt 245 2>/dev/null || \ + echo "modprobe@dm_multipath.service") -OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 -WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int \ @@ -44,7 +44,7 @@ index 62d3d5cc..72fd8d57 100644 -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \ -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(configdir)\" \ -DDEFAULT_CONFIGFILE=\"$(configfile)\" -DSTATE_DIR=\"$(statedir)\" \ -@@ -104,7 +116,7 @@ CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe +@@ -108,7 +120,7 @@ CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe BIN_CFLAGS := -fPIE -DPIE LIB_CFLAGS := -fPIC SHARED_FLAGS := -shared diff --git a/0005-libmultipath-lookup_binding-add-comment-about-the-al.patch b/0005-libmultipath-lookup_binding-add-comment-about-the-al.patch deleted file mode 100644 index 71d077a..0000000 --- a/0005-libmultipath-lookup_binding-add-comment-about-the-al.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 22 Aug 2023 22:30:16 +0200 -Subject: [PATCH] libmultipath: lookup_binding: add comment about the algorithm - -When I read this code, I always get confused. Adding comments to -explain the algorithm. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/alias.c | 35 +++++++++++++++++++++++++++++++++++ - 1 file changed, 35 insertions(+) - -diff --git a/libmultipath/alias.c b/libmultipath/alias.c -index 3e3dfe98..9e9ac563 100644 ---- a/libmultipath/alias.c -+++ b/libmultipath/alias.c -@@ -172,6 +172,41 @@ lookup_binding(FILE *f, const char *map_wwid, char **map_alias, - alias = strtok_r(buf, " \t", &saveptr); - if (!alias) /* blank line */ - continue; -+ -+ /* -+ * Find an unused index - explanation of the algorithm -+ * -+ * ID: 1 = mpatha, 2 = mpathb, ... -+ * -+ * We assume the bindings are unsorted. The only constraint -+ * is that no ID occurs more than once. IDs that occur in the -+ * bindings are called "used". -+ * -+ * We call the list 1,2,3,..., exactly in this order, the list -+ * of "expected" IDs. The variable "id" always holds the next -+ * "expected" ID, IOW the last "expected" ID encountered plus 1. -+ * Thus all IDs below "id" are known to be used. However, at the -+ * end of the loop, the value of "id" isn't necessarily unused. -+ * -+ * "smallest_bigger_id" is the smallest used ID that was -+ * encountered while it was larger than the next "expected" ID -+ * at that iteration. Let X be some used ID. If all IDs below X -+ * are used and encountered in the right sequence before X, "id" -+ * will be > X when the loop ends. Otherwise, X was encountered -+ * "out of order", the condition (X > id) holds when X is -+ * encountered, and "smallest_bigger_id" will be set to X; i.e. -+ * it will be less or equal than X when the loop ends. -+ * -+ * At the end of the loop, (id < smallest_bigger_id) means that -+ * the value of "id" had been encountered neither in order nor -+ * out of order, and is thus unused. (id >= smallest_bigger_id) -+ * means that "id"'s value is in use. In this case, we play safe -+ * and use "biggest_id + 1" as the next value to try. -+ * -+ * biggest_id is always > smallest_bigger_id, except in the -+ * "perfectly ordered" case. -+ */ -+ - curr_id = scan_devname(alias, prefix); - if (curr_id == id) { - if (id < INT_MAX) diff --git a/0046-RH-add-mpathconf.patch b/0006-RH-add-mpathconf.patch similarity index 99% rename from 0046-RH-add-mpathconf.patch rename to 0006-RH-add-mpathconf.patch index 01bc8d2..7782f65 100644 --- a/0046-RH-add-mpathconf.patch +++ b/0006-RH-add-mpathconf.patch @@ -34,7 +34,7 @@ index 3a374b3d..4544f484 100644 conf->blist_devnode = vector_alloc(); if (!conf->blist_devnode) { diff --git a/multipath/Makefile b/multipath/Makefile -index f70e64ec..9942d1a9 100644 +index 504d6892..9f14036c 100644 --- a/multipath/Makefile +++ b/multipath/Makefile @@ -24,6 +24,7 @@ $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so @@ -45,15 +45,15 @@ index f70e64ec..9942d1a9 100644 $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) $(Q)$(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) $(Q)$(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)$(udevrulesdir)/62-multipath.rules -@@ -33,6 +34,7 @@ install: +@@ -31,6 +32,7 @@ install: $(Q)$(INSTALL_PROGRAM) -m 644 tmpfiles.conf $(DESTDIR)$(tmpfilesdir)/multipath.conf $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 + $(Q)$(INSTALL_PROGRAM) -m 644 mpathconf.8 $(DESTDIR)$(mandir)/man8 $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man5 $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5 $(DESTDIR)$(mandir)/man5 - ifneq ($(SCSI_DH_MODULES_PRELOAD),) -@@ -43,11 +45,13 @@ endif + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(modulesloaddir) +@@ -45,11 +47,13 @@ endif uninstall: $(Q)$(RM) $(DESTDIR)$(bindir)/$(EXEC) diff --git a/0006-multipath-tools-test-simplify-debugging-for-condlog-.patch b/0006-multipath-tools-test-simplify-debugging-for-condlog-.patch deleted file mode 100644 index a206358..0000000 --- a/0006-multipath-tools-test-simplify-debugging-for-condlog-.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 23 Aug 2023 22:56:41 +0200 -Subject: [PATCH] multipath-tools test: simplify debugging for condlog mismatch - -If there's a mismatch between expected and actual log message, -print both messages. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - tests/test-log.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/tests/test-log.c b/tests/test-log.c -index c1745872..63516999 100644 ---- a/tests/test-log.c -+++ b/tests/test-log.c -@@ -16,12 +16,14 @@ void __wrap_dlog (int prio, const char * fmt, ...) - va_list ap; - char *expected; - -- check_expected(prio); - va_start(ap, fmt); - vsnprintf(buff, MAX_MSG_SIZE, fmt, ap); - va_end(ap); - fprintf(stderr, "%s(%d): %s", __func__, prio, buff); - expected = mock_ptr_type(char *); -+ if (memcmp(expected, buff, strlen(expected))) -+ fprintf(stderr, "%s(expected): %s", __func__, expected); -+ check_expected(prio); - assert_memory_equal(buff, expected, strlen(expected)); - } - diff --git a/0047-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 93% rename from 0047-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch index 7714825..a3c4e9d 100644 --- a/0047-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +++ b/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch @@ -14,9 +14,9 @@ multipathd.service Signed-off-by: Benjamin Marzinski --- - multipath/main.c | 54 +++++++++++++++++++++++++++++++++-- - multipath/multipath.8.in | 7 ++++- - multipathd/multipathd.service | 1 + + multipath/main.c | 54 ++++++++++++++++++++++++++++++-- + multipath/multipath.8.in | 7 ++++- + multipathd/multipathd.service.in | 1 + 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/multipath/main.c b/multipath/main.c @@ -137,10 +137,10 @@ index 348eb220..82a7e68e 100644 .B \-w Remove the WWID for the specified device from the WWIDs file. . -diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service -index 311f49c7..5324f4bc 100644 ---- a/multipathd/multipathd.service -+++ b/multipathd/multipathd.service +diff --git a/multipathd/multipathd.service.in b/multipathd/multipathd.service.in +index 0965d6f9..c964eb1b 100644 +--- a/multipathd/multipathd.service.in ++++ b/multipathd/multipathd.service.in @@ -17,6 +17,7 @@ ConditionVirtualization=!container [Service] Type=notify diff --git a/0007-multipath-tools-tests-add-tests-for-get_user_friendl.patch b/0007-multipath-tools-tests-add-tests-for-get_user_friendl.patch deleted file mode 100644 index f829db4..0000000 --- a/0007-multipath-tools-tests-add-tests-for-get_user_friendl.patch +++ /dev/null @@ -1,493 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 23 Aug 2023 22:57:29 +0200 -Subject: [PATCH] multipath-tools tests: add tests for - get_user_friendly_alias() - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - tests/alias.c | 441 ++++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 441 insertions(+) - -diff --git a/tests/alias.c b/tests/alias.c -index 11f209e0..7e443b06 100644 ---- a/tests/alias.c -+++ b/tests/alias.c -@@ -81,6 +81,35 @@ int __wrap_dm_get_uuid(const char *name, char *uuid, int uuid_len) - return ret; - } - -+#define TEST_FDNO 1234 -+#define TEST_FPTR ((FILE *) 0xaffe) -+ -+int __wrap_open_file(const char *file, int *can_write, const char *header) -+{ -+ int cw = mock_type(int); -+ -+ *can_write = cw; -+ return TEST_FDNO; -+} -+ -+FILE *__wrap_fdopen(int fd, const char *mode) -+{ -+ assert_int_equal(fd, TEST_FDNO); -+ return TEST_FPTR; -+} -+ -+int __wrap_fflush(FILE *f) -+{ -+ assert_ptr_equal(f, TEST_FPTR); -+ return 0; -+} -+ -+int __wrap_fclose(FILE *f) -+{ -+ assert_ptr_equal(f, TEST_FPTR); -+ return 0; -+} -+ - /* strbuf wrapper for the old format_devname() */ - static int __format_devname(char *name, int id, size_t len, const char *prefix) - { -@@ -399,6 +428,22 @@ static void mock_self_alias(const char *alias, const char *wwid) - } - - #define USED_STR(alias_str, wwid_str) wwid_str ": alias '" alias_str "' already taken, reselecting alias\n" -+#define NOMATCH_STR(alias_str) ("No matching alias [" alias_str "] in bindings file.\n") -+#define FOUND_STR(alias_str, wwid_str) \ -+ "Found matching wwid [" wwid_str "] in bindings file." \ -+ " Setting alias to " alias_str "\n" -+#define FOUND_ALIAS_STR(alias_str, wwid_str) \ -+ "Found matching alias [" alias_str "] in bindings file." \ -+ " Setting wwid to " wwid_str "\n" -+#define NOMATCH_WWID_STR(wwid_str) ("No matching wwid [" wwid_str "] in bindings file.\n") -+#define NEW_STR(alias_str, wwid_str) ("Created new binding [" alias_str "] for WWID [" wwid_str "]\n") -+#define EXISTING_STR(alias_str, wwid_str) ("Use existing binding [" alias_str "] for WWID [" wwid_str "]\n") -+#define ALLOC_STR(alias_str, wwid_str) ("Allocated existing binding [" alias_str "] for WWID [" wwid_str "]\n") -+#define BINDING_STR(alias_str, wwid_str) (alias_str " " wwid_str "\n") -+#define BOUND_STR(alias_str, wwid_str) ("alias "alias_str " already bound to wwid " wwid_str ", cannot reuse") -+#define ERR_STR(alias_str, wwid_str) ("ERROR: old alias [" alias_str "] for wwid [" wwid_str "] is used by other map\n") -+#define REUSE_STR(alias_str, wwid_str) ("alias " alias_str " already bound to wwid " wwid_str ", cannot reuse\n") -+#define NOMORE_STR "no more available user_friendly_names\n" - - static void mock_failed_alias(const char *alias, char *msg) - { -@@ -421,6 +466,24 @@ static void mock_used_alias(const char *alias, char *msg) - expect_condlog(3, msg); - } - -+static void mock_bindings_file(const char *content, int match_line) -+{ -+ static char cnt[1024]; -+ char *token; -+ int i; -+ -+ assert_in_range(strlcpy(cnt, content, sizeof(cnt)), 0, sizeof(cnt) - 1); -+ -+ for (token = strtok(cnt, "\n"), i = 0; -+ token && *token; -+ token = strtok(NULL, "\n"), i++) { -+ will_return(__wrap_fgets, token); -+ if (match_line == i) -+ return; -+ } -+ will_return(__wrap_fgets, NULL); -+} -+ - static void lb_empty(void **state) - { - int rc; -@@ -1147,6 +1210,382 @@ static int test_allocate_binding(void) - return cmocka_run_group_tests(tests, NULL, NULL); - } - -+#define mock_allocate_binding(alias, wwid) \ -+ do { \ -+ static const char ln[] = BINDING_STR(alias, wwid); \ -+ \ -+ will_return(__wrap_lseek, 0); \ -+ expect_value(__wrap_write, count, strlen(ln)); \ -+ expect_string(__wrap_write, buf, ln); \ -+ will_return(__wrap_write, strlen(ln)); \ -+ expect_condlog(3, NEW_STR(alias, wwid)); \ -+ } while (0) -+ -+static void gufa_empty_new_rw(void **state) { -+ char *alias; -+ -+ will_return(__wrap_open_file, true); -+ -+ will_return(__wrap_fgets, NULL); -+ mock_unused_alias("MPATHa"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); -+ -+ mock_allocate_binding("MPATHa", "WWID0"); -+ alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false); -+ assert_string_equal(alias, "MPATHa"); -+ free(alias); -+} -+ -+static void gufa_empty_new_ro_1(void **state) { -+ char *alias; -+ will_return(__wrap_open_file, false); -+ will_return(__wrap_fgets, NULL); -+ mock_unused_alias("MPATHa"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); -+ -+ alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false); -+ assert_ptr_equal(alias, NULL); -+} -+ -+static void gufa_empty_new_ro_2(void **state) { -+ char *alias; -+ -+ will_return(__wrap_open_file, true); -+ -+ will_return(__wrap_fgets, NULL); -+ mock_unused_alias("MPATHa"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); -+ -+ alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); -+ assert_ptr_equal(alias, NULL); -+} -+ -+static void gufa_match_a_unused(void **state) { -+ char *alias; -+ -+ will_return(__wrap_open_file, true); -+ -+ will_return(__wrap_fgets, BINDING_STR("MPATHa", "WWID0")); -+ expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); -+ mock_unused_alias("MPATHa"); -+ -+ alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); -+ assert_string_equal(alias, "MPATHa"); -+ free(alias); -+} -+ -+static void gufa_match_a_self(void **state) { -+ char *alias; -+ -+ will_return(__wrap_open_file, true); -+ -+ will_return(__wrap_fgets, BINDING_STR("MPATHa", "WWID0")); -+ expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); -+ mock_self_alias("MPATHa", "WWID0"); -+ -+ alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); -+ assert_string_equal(alias, "MPATHa"); -+ free(alias); -+} -+ -+static void gufa_match_a_used(void **state) { -+ char *alias; -+ -+ will_return(__wrap_open_file, true); -+ -+ will_return(__wrap_fgets, BINDING_STR("MPATHa", "WWID0")); -+ expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); -+ mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); -+ -+ alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); -+ assert_ptr_equal(alias, NULL); -+} -+ -+static void gufa_nomatch_a_c(void **state) { -+ char *alias; -+ will_return(__wrap_open_file, true); -+ -+ mock_bindings_file("MPATHa WWID0\n" -+ "MPATHc WWID2", -+ -1); -+ mock_unused_alias("MPATHb"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID1")); -+ -+ mock_allocate_binding("MPATHb", "WWID1"); -+ -+ alias = get_user_friendly_alias("WWID1", "x", "", "MPATH", false); -+ assert_string_equal(alias, "MPATHb"); -+ free(alias); -+} -+ -+static void gufa_nomatch_c_a(void **state) { -+ char *alias; -+ will_return(__wrap_open_file, true); -+ -+ mock_bindings_file("MPATHc WWID2\n" -+ "MPATHa WWID0", -+ -1); -+ mock_unused_alias("MPATHb"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID1")); -+ -+ mock_allocate_binding("MPATHb", "WWID1"); -+ -+ alias = get_user_friendly_alias("WWID1", "x", "", "MPATH", false); -+ assert_string_equal(alias, "MPATHb"); -+ free(alias); -+} -+ -+static void gufa_nomatch_c_b(void **state) { -+ char *alias; -+ will_return(__wrap_open_file, true); -+ -+ mock_bindings_file("MPATHc WWID2\n" -+ "MPATHb WWID1\n", -+ -1); -+ mock_unused_alias("MPATHa"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); -+ -+ mock_allocate_binding("MPATHa", "WWID0"); -+ -+ alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false); -+ assert_string_equal(alias, "MPATHa"); -+ free(alias); -+} -+ -+static void gufa_nomatch_c_b_used(void **state) { -+ char *alias; -+ will_return(__wrap_open_file, true); -+ -+ mock_bindings_file("MPATHc WWID2\n" -+ "MPATHb WWID1", -+ -1); -+ mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID4")); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID4")); -+ mock_unused_alias("MPATHd"); -+ -+ mock_allocate_binding("MPATHd", "WWID4"); -+ -+ alias = get_user_friendly_alias("WWID4", "x", "", "MPATH", false); -+ assert_string_equal(alias, "MPATHd"); -+ free(alias); -+} -+ -+static void gufa_nomatch_b_f_a(void **state) { -+ char *alias; -+ will_return(__wrap_open_file, true); -+ -+ mock_bindings_file("MPATHb WWID1\n" -+ "MPATHf WWID6\n" -+ "MPATHa WWID0\n", -+ -1); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID7")); -+ mock_unused_alias("MPATHg"); -+ -+ mock_allocate_binding("MPATHg", "WWID7"); -+ -+ alias = get_user_friendly_alias("WWID7", "x", "", "MPATH", false); -+ assert_string_equal(alias, "MPATHg"); -+ free(alias); -+} -+ -+static void gufa_old_empty(void **state) { -+ char *alias; -+ will_return(__wrap_open_file, true); -+ -+ /* rlookup_binding for ALIAS */ -+ will_return(__wrap_fgets, NULL); -+ expect_condlog(3, NOMATCH_STR("MPATHz")); -+ -+ /* lookup_binding */ -+ will_return(__wrap_fgets, NULL); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); -+ -+ mock_allocate_binding("MPATHz", "WWID0"); -+ expect_condlog(2, ALLOC_STR("MPATHz", "WWID0")); -+ -+ alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); -+ assert_string_equal(alias, "MPATHz"); -+ free(alias); -+} -+ -+static void gufa_old_match(void **state) { -+ char *alias; -+ will_return(__wrap_open_file, true); -+ -+ mock_bindings_file("MPATHb WWID1\n" -+ "MPATHz WWID0", -+ 1); -+ expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID0")); -+ -+ alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); -+ assert_string_equal(alias, "MPATHz"); -+ free(alias); -+} -+ -+static void gufa_old_match_other(void **state) { -+ char *alias; -+ static const char bindings[] = "MPATHz WWID9"; -+ -+ will_return(__wrap_open_file, true); -+ -+ mock_bindings_file(bindings, 0); -+ expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID9")); -+ expect_condlog(0, REUSE_STR("MPATHz", "WWID9")); -+ -+ mock_bindings_file(bindings, -1); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); -+ mock_unused_alias("MPATHa"); -+ -+ mock_allocate_binding("MPATHa", "WWID0"); -+ -+ alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); -+ assert_string_equal(alias, "MPATHa"); -+ free(alias); -+} -+ -+static void gufa_old_match_other_used(void **state) { -+ char *alias; -+ static const char bindings[] = "MPATHz WWID9"; -+ -+ will_return(__wrap_open_file, true); -+ -+ mock_bindings_file(bindings, 0); -+ expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID9")); -+ expect_condlog(0, REUSE_STR("MPATHz", "WWID9")); -+ -+ mock_bindings_file(bindings, -1); -+ mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); -+ mock_unused_alias("MPATHb"); -+ -+ mock_allocate_binding("MPATHb", "WWID0"); -+ -+ alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); -+ assert_string_equal(alias, "MPATHb"); -+ free(alias); -+} -+ -+static void gufa_old_match_other_wwidmatch(void **state) { -+ char *alias; -+ static const char bindings[] = ("MPATHz WWID9\n" -+ "MPATHc WWID2"); -+ will_return(__wrap_open_file, true); -+ -+ mock_bindings_file(bindings, 0); -+ expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID9")); -+ expect_condlog(0, REUSE_STR("MPATHz", "WWID9")); -+ -+ mock_bindings_file(bindings, 1); -+ expect_condlog(3, FOUND_STR("MPATHc", "WWID2")); -+ mock_unused_alias("MPATHc"); -+ -+ alias = get_user_friendly_alias("WWID2", "x", "MPATHz", "MPATH", false); -+ assert_string_equal(alias, "MPATHc"); -+ free(alias); -+} -+ -+static void gufa_old_match_other_wwidmatch_used(void **state) { -+ char *alias; -+ static const char bindings[] = ("MPATHz WWID9\n" -+ "MPATHc WWID2"); -+ -+ will_return(__wrap_open_file, true); -+ -+ mock_bindings_file(bindings, 0); -+ expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID9")); -+ expect_condlog(0, REUSE_STR("MPATHz", "WWID9")); -+ -+ mock_bindings_file(bindings, 1); -+ expect_condlog(3, FOUND_STR("MPATHc", "WWID2")); -+ mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID2")); -+ -+ alias = get_user_friendly_alias("WWID2", "x", "MPATHz", "MPATH", false); -+ assert_ptr_equal(alias, NULL); -+} -+ -+static void gufa_old_nomatch_wwidmatch(void **state) { -+ char *alias; -+ static const char bindings[] = "MPATHa WWID0"; -+ -+ will_return(__wrap_open_file, true); -+ -+ mock_bindings_file(bindings, -1); -+ expect_condlog(3, NOMATCH_STR("MPATHz")); -+ -+ mock_bindings_file(bindings, 0); -+ expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); -+ mock_unused_alias("MPATHa"); -+ expect_condlog(3, EXISTING_STR("MPATHa", "WWID0")); -+ -+ alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); -+ assert_string_equal(alias, "MPATHa"); -+ free(alias); -+} -+ -+static void gufa_old_nomatch_wwidmatch_used(void **state) { -+ char *alias; -+ static const char bindings[] = "MPATHa WWID0"; -+ will_return(__wrap_open_file, true); -+ -+ mock_bindings_file(bindings, -1); -+ expect_condlog(3, NOMATCH_STR("MPATHz")); -+ -+ mock_bindings_file(bindings, 0); -+ expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); -+ mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); -+ -+ alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); -+ assert_ptr_equal(alias, NULL); -+} -+ -+static void gufa_old_nomatch_nowwidmatch(void **state) { -+ char *alias; -+ static const char bindings[] = "MPATHb WWID1"; -+ -+ will_return(__wrap_open_file, true); -+ -+ mock_bindings_file(bindings, -1); -+ expect_condlog(3, NOMATCH_STR("MPATHz")); -+ -+ mock_bindings_file(bindings, -1); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); -+ -+ mock_allocate_binding("MPATHz", "WWID0"); -+ expect_condlog(2, ALLOC_STR("MPATHz", "WWID0")); -+ -+ alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); -+ assert_string_equal(alias, "MPATHz"); -+ free(alias); -+} -+ -+static int test_get_user_friendly_alias() -+{ -+ const struct CMUnitTest tests[] = { -+ cmocka_unit_test(gufa_empty_new_rw), -+ cmocka_unit_test(gufa_empty_new_ro_1), -+ cmocka_unit_test(gufa_empty_new_ro_2), -+ cmocka_unit_test(gufa_match_a_unused), -+ cmocka_unit_test(gufa_match_a_self), -+ cmocka_unit_test(gufa_match_a_used), -+ cmocka_unit_test(gufa_nomatch_a_c), -+ cmocka_unit_test(gufa_nomatch_c_a), -+ cmocka_unit_test(gufa_nomatch_c_b), -+ cmocka_unit_test(gufa_nomatch_c_b_used), -+ cmocka_unit_test(gufa_nomatch_b_f_a), -+ cmocka_unit_test(gufa_old_empty), -+ cmocka_unit_test(gufa_old_match), -+ cmocka_unit_test(gufa_old_match_other), -+ cmocka_unit_test(gufa_old_match_other_used), -+ cmocka_unit_test(gufa_old_match_other_wwidmatch), -+ cmocka_unit_test(gufa_old_match_other_wwidmatch_used), -+ cmocka_unit_test(gufa_old_nomatch_wwidmatch), -+ cmocka_unit_test(gufa_old_nomatch_wwidmatch_used), -+ cmocka_unit_test(gufa_old_nomatch_nowwidmatch), -+ }; -+ -+ return cmocka_run_group_tests(tests, NULL, NULL); -+} -+ - int main(void) - { - int ret = 0; -@@ -1157,6 +1596,8 @@ int main(void) - ret += test_lookup_binding(); - ret += test_rlookup_binding(); - ret += test_allocate_binding(); -+ ret += test_allocate_binding(); -+ ret += test_get_user_friendly_alias(); - - return ret; - } diff --git a/0048-RH-reset-default-find_mutipaths-value-to-off.patch b/0008-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 96% rename from 0048-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0008-RH-reset-default-find_mutipaths-value-to-off.patch index 432b070..4e1253c 100644 --- a/0048-RH-reset-default-find_mutipaths-value-to-off.patch +++ b/0008-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 d01f9712..ee2e13a9 100644 +index 64b633f2..5bda9f93 100644 --- a/libmultipath/defaults.h +++ b/libmultipath/defaults.h @@ -23,7 +23,7 @@ diff --git a/0008-multipath-tools-test-consistent-use-of-macros-in-ali.patch b/0008-multipath-tools-test-consistent-use-of-macros-in-ali.patch deleted file mode 100644 index 430ceaf..0000000 --- a/0008-multipath-tools-test-consistent-use-of-macros-in-ali.patch +++ /dev/null @@ -1,365 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 24 Aug 2023 10:40:32 +0200 -Subject: [PATCH] multipath-tools test: consistent use of macros in alias test - -Use the macros introduced with the tests for get_user_friendly_alias() -also in the previously existing tests. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - tests/alias.c | 80 ++++++++++++++++++++++++--------------------------- - 1 file changed, 38 insertions(+), 42 deletions(-) - -diff --git a/tests/alias.c b/tests/alias.c -index 7e443b06..427b2814 100644 ---- a/tests/alias.c -+++ b/tests/alias.c -@@ -490,7 +490,7 @@ static void lb_empty(void **state) - char *alias; - - will_return(__wrap_fgets, NULL); -- expect_condlog(3, "No matching wwid [WWID0] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - rc = lookup_binding(NULL, "WWID0", &alias, NULL, 0); - assert_int_equal(rc, 1); - assert_ptr_equal(alias, NULL); -@@ -503,7 +503,7 @@ static void lb_empty_unused(void **state) - - will_return(__wrap_fgets, NULL); - mock_unused_alias("MPATHa"); -- expect_condlog(3, "No matching wwid [WWID0] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); - assert_int_equal(rc, 1); - assert_ptr_equal(alias, NULL); -@@ -518,7 +518,7 @@ static void lb_empty_failed(void **state) - will_return(__wrap_fgets, NULL); - mock_failed_alias("MPATHa", USED_STR("MPATHa", "WWID0")); - mock_unused_alias("MPATHb"); -- expect_condlog(3, "No matching wwid [WWID0] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); - assert_int_equal(rc, 2); - assert_ptr_equal(alias, NULL); -@@ -533,7 +533,7 @@ static void lb_empty_1_used(void **state) - will_return(__wrap_fgets, NULL); - mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); - mock_unused_alias("MPATHb"); -- expect_condlog(3, "No matching wwid [WWID0] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); - assert_int_equal(rc, 2); - assert_ptr_equal(alias, NULL); -@@ -548,7 +548,7 @@ static void lb_empty_1_used_self(void **state) - will_return(__wrap_fgets, NULL); - mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); - mock_self_alias("MPATHb", "WWID0"); -- expect_condlog(3, "No matching wwid [WWID0] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); - assert_int_equal(rc, 2); - assert_ptr_equal(alias, NULL); -@@ -561,8 +561,7 @@ static void lb_match_a(void **state) - char *alias; - - will_return(__wrap_fgets, "MPATHa WWID0\n"); -- expect_condlog(3, "Found matching wwid [WWID0] in bindings file." -- " Setting alias to MPATHa\n"); -+ expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); - rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 0); - assert_int_equal(rc, 0); - assert_ptr_not_equal(alias, NULL); -@@ -577,7 +576,7 @@ static void lb_nomatch_a(void **state) - - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, NULL); -- expect_condlog(3, "No matching wwid [WWID1] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID1")); - rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 0); - assert_int_equal(rc, 2); - assert_ptr_equal(alias, NULL); -@@ -590,7 +589,7 @@ static void lb_nomatch_a_bad_check(void **state) - - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, NULL); -- expect_condlog(0, "no more available user_friendly_names\n"); -+ expect_condlog(0, NOMORE_STR); - rc = lookup_binding(NULL, "WWID1", &alias, NULL, 1); - assert_int_equal(rc, -1); - assert_ptr_equal(alias, NULL); -@@ -604,7 +603,7 @@ static void lb_nomatch_a_unused(void **state) - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, NULL); - mock_unused_alias("MPATHb"); -- expect_condlog(3, "No matching wwid [WWID1] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID1")); - rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1); - assert_int_equal(rc, 2); - assert_ptr_equal(alias, NULL); -@@ -622,7 +621,7 @@ static void lb_nomatch_a_3_used_failed_self(void **state) - mock_used_alias("MPATHd", USED_STR("MPATHd", "WWID1")); - mock_failed_alias("MPATHe", USED_STR("MPATHe", "WWID1")); - mock_self_alias("MPATHf", "WWID1"); -- expect_condlog(3, "No matching wwid [WWID1] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID1")); - rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1); - assert_int_equal(rc, 6); - assert_ptr_equal(alias, NULL); -@@ -635,8 +634,7 @@ static void do_lb_match_c(void **state, int check_if_taken) - - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, "MPATHc WWID1\n"); -- expect_condlog(3, "Found matching wwid [WWID1] in bindings file." -- " Setting alias to MPATHc\n"); -+ expect_condlog(3, FOUND_STR("MPATHc", "WWID1")); - rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", check_if_taken); - assert_int_equal(rc, 0); - assert_ptr_not_equal(alias, NULL); -@@ -662,7 +660,7 @@ static void lb_nomatch_a_c(void **state) - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, "MPATHc WWID1\n"); - will_return(__wrap_fgets, NULL); -- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); - assert_int_equal(rc, 2); - assert_ptr_equal(alias, NULL); -@@ -677,7 +675,7 @@ static void lb_nomatch_a_d_unused(void **state) - will_return(__wrap_fgets, "MPATHd WWID1\n"); - will_return(__wrap_fgets, NULL); - mock_unused_alias("MPATHb"); -- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, 2); - assert_ptr_equal(alias, NULL); -@@ -693,7 +691,7 @@ static void lb_nomatch_a_d_1_used(void **state) - will_return(__wrap_fgets, NULL); - mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2")); - mock_unused_alias("MPATHc"); -- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, 3); - assert_ptr_equal(alias, NULL); -@@ -710,7 +708,7 @@ static void lb_nomatch_a_d_2_used(void **state) - mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2")); - mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID2")); - mock_unused_alias("MPATHe"); -- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, 5); - assert_ptr_equal(alias, NULL); -@@ -728,7 +726,7 @@ static void lb_nomatch_a_d_3_used(void **state) - mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID2")); - mock_used_alias("MPATHe", USED_STR("MPATHe", "WWID2")); - mock_unused_alias("MPATHf"); -- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, 6); - assert_ptr_equal(alias, NULL); -@@ -742,7 +740,7 @@ static void lb_nomatch_c_a(void **state) - will_return(__wrap_fgets, "MPATHc WWID1\n"); - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, NULL); -- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); - assert_int_equal(rc, 2); - assert_ptr_equal(alias, NULL); -@@ -758,7 +756,7 @@ static void lb_nomatch_d_a_unused(void **state) - will_return(__wrap_fgets, "MPATHd WWID0\n"); - will_return(__wrap_fgets, NULL); - mock_unused_alias("MPATHb"); -- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, 2); - assert_ptr_equal(alias, NULL); -@@ -775,7 +773,7 @@ static void lb_nomatch_d_a_1_used(void **state) - will_return(__wrap_fgets, NULL); - mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2")); - mock_unused_alias("MPATHe"); -- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, 5); - assert_ptr_equal(alias, NULL); -@@ -790,7 +788,7 @@ static void lb_nomatch_a_b(void **state) - will_return(__wrap_fgets, "MPATHz WWID26\n"); - will_return(__wrap_fgets, "MPATHb WWID1\n"); - will_return(__wrap_fgets, NULL); -- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); - assert_int_equal(rc, 3); - assert_ptr_equal(alias, NULL); -@@ -806,7 +804,7 @@ static void lb_nomatch_a_b_bad(void **state) - will_return(__wrap_fgets, "MPATHb\n"); - will_return(__wrap_fgets, NULL); - expect_condlog(3, "Ignoring malformed line 3 in bindings file\n"); -- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); - assert_int_equal(rc, 3); - assert_ptr_equal(alias, NULL); -@@ -823,7 +821,7 @@ static void lb_nomatch_a_b_bad_self(void **state) - will_return(__wrap_fgets, NULL); - expect_condlog(3, "Ignoring malformed line 3 in bindings file\n"); - mock_self_alias("MPATHc", "WWID2"); -- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, 3); - assert_ptr_equal(alias, NULL); -@@ -838,7 +836,7 @@ static void lb_nomatch_b_a(void **state) - will_return(__wrap_fgets, "MPATHz WWID26\n"); - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, NULL); -- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); - assert_int_equal(rc, 27); - assert_ptr_equal(alias, NULL); -@@ -857,7 +855,7 @@ static void lb_nomatch_b_a_3_used(void **state) - mock_used_alias("MPATHab", USED_STR("MPATHab", "WWID2")); - mock_used_alias("MPATHac", USED_STR("MPATHac", "WWID2")); - mock_unused_alias("MPATHad"); -- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, 30); - assert_ptr_equal(alias, NULL); -@@ -873,7 +871,7 @@ static void do_lb_nomatch_int_max(void **state, int check_if_taken) - will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n"); - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, NULL); -- expect_condlog(0, "no more available user_friendly_names\n"); -+ expect_condlog(0, NOMORE_STR); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", check_if_taken); - assert_int_equal(rc, -1); - assert_ptr_equal(alias, NULL); -@@ -898,7 +896,7 @@ static void lb_nomatch_int_max_used(void **state) - will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n"); - will_return(__wrap_fgets, NULL); - mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID2")); -- expect_condlog(0, "no more available user_friendly_names\n"); -+ expect_condlog(0, NOMORE_STR); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, -1); - assert_ptr_equal(alias, NULL); -@@ -913,7 +911,7 @@ static void lb_nomatch_int_max_m1(void **state) - will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"); - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, NULL); -- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); - assert_int_equal(rc, INT_MAX); - assert_ptr_equal(alias, NULL); -@@ -929,7 +927,7 @@ static void lb_nomatch_int_max_m1_used(void **state) - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, NULL); - mock_used_alias("MPATH" MPATH_ID_INT_MAX, USED_STR("MPATH" MPATH_ID_INT_MAX, "WWID2")); -- expect_condlog(0, "no more available user_friendly_names\n"); -+ expect_condlog(0, NOMORE_STR); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, -1); - assert_ptr_equal(alias, NULL); -@@ -945,7 +943,7 @@ static void lb_nomatch_int_max_m1_1_used(void **state) - will_return(__wrap_fgets, NULL); - mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID2")); - mock_unused_alias("MPATH" MPATH_ID_INT_MAX); -- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, INT_MAX); - assert_ptr_equal(alias, NULL); -@@ -961,7 +959,7 @@ static void lb_nomatch_int_max_m1_2_used(void **state) - will_return(__wrap_fgets, NULL); - mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID2")); - mock_used_alias("MPATH" MPATH_ID_INT_MAX, USED_STR("MPATH" MPATH_ID_INT_MAX, "WWID2")); -- expect_condlog(0, "no more available user_friendly_names\n"); -+ expect_condlog(0, NOMORE_STR); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, -1); - assert_ptr_equal(alias, NULL); -@@ -1017,7 +1015,7 @@ static void rl_empty(void **state) - - buf[0] = '\0'; - will_return(__wrap_fgets, NULL); -- expect_condlog(3, "No matching alias [MPATHa] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_STR("MPATHa")); - rc = rlookup_binding(NULL, buf, "MPATHa"); - assert_int_equal(rc, -1); - assert_string_equal(buf, ""); -@@ -1030,8 +1028,7 @@ static void rl_match_a(void **state) - - buf[0] = '\0'; - will_return(__wrap_fgets, "MPATHa WWID0\n"); -- expect_condlog(3, "Found matching alias [MPATHa] in bindings file. " -- "Setting wwid to WWID0\n"); -+ expect_condlog(3, FOUND_ALIAS_STR("MPATHa", "WWID0")); - rc = rlookup_binding(NULL, buf, "MPATHa"); - assert_int_equal(rc, 0); - assert_string_equal(buf, "WWID0"); -@@ -1045,7 +1042,7 @@ static void rl_nomatch_a(void **state) - buf[0] = '\0'; - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, NULL); -- expect_condlog(3, "No matching alias [MPATHb] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_STR("MPATHb")); - rc = rlookup_binding(NULL, buf, "MPATHb"); - assert_int_equal(rc, -1); - assert_string_equal(buf, ""); -@@ -1060,7 +1057,7 @@ static void rl_malformed_a(void **state) - will_return(__wrap_fgets, "MPATHa \n"); - will_return(__wrap_fgets, NULL); - expect_condlog(3, "Ignoring malformed line 1 in bindings file\n"); -- expect_condlog(3, "No matching alias [MPATHa] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_STR("MPATHa")); - rc = rlookup_binding(NULL, buf, "MPATHa"); - assert_int_equal(rc, -1); - assert_string_equal(buf, ""); -@@ -1080,7 +1077,7 @@ static void rl_overlong_a(void **state) - will_return(__wrap_fgets, line); - will_return(__wrap_fgets, NULL); - expect_condlog(3, "Ignoring too large wwid at 1 in bindings file\n"); -- expect_condlog(3, "No matching alias [MPATHa] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_STR("MPATHa")); - rc = rlookup_binding(NULL, buf, "MPATHa"); - assert_int_equal(rc, -1); - assert_string_equal(buf, ""); -@@ -1095,8 +1092,7 @@ static void rl_match_b(void **state) - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, "MPATHz WWID26\n"); - will_return(__wrap_fgets, "MPATHb WWID2\n"); -- expect_condlog(3, "Found matching alias [MPATHb] in bindings file. " -- "Setting wwid to WWID2\n"); -+ expect_condlog(3, FOUND_ALIAS_STR("MPATHb", "WWID2")); - rc = rlookup_binding(NULL, buf, "MPATHb"); - assert_int_equal(rc, 0); - assert_string_equal(buf, "WWID2"); -@@ -1125,7 +1121,7 @@ static void al_a(void **state) - expect_value(__wrap_write, count, strlen(ln)); - expect_string(__wrap_write, buf, ln); - will_return(__wrap_write, strlen(ln)); -- expect_condlog(3, "Created new binding [MPATHa] for WWID [WWIDa]\n"); -+ expect_condlog(3, NEW_STR("MPATHa", "WWIDa")); - - alias = allocate_binding(0, "WWIDa", 1, "MPATH"); - assert_ptr_not_equal(alias, NULL); -@@ -1142,7 +1138,7 @@ static void al_zz(void **state) - expect_value(__wrap_write, count, strlen(ln)); - expect_string(__wrap_write, buf, ln); - will_return(__wrap_write, strlen(ln)); -- expect_condlog(3, "Created new binding [MPATHzz] for WWID [WWIDzz]\n"); -+ expect_condlog(3, NEW_STR("MPATHzz", "WWIDzz")); - - alias = allocate_binding(0, "WWIDzz", 26*26 + 26, "MPATH"); - assert_ptr_not_equal(alias, NULL); diff --git a/0049-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 100% rename from 0049-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch diff --git a/0009-multipath-tools-tests-convert-mock_-failed-used-_ali.patch b/0009-multipath-tools-tests-convert-mock_-failed-used-_ali.patch deleted file mode 100644 index 9d71adf..0000000 --- a/0009-multipath-tools-tests-convert-mock_-failed-used-_ali.patch +++ /dev/null @@ -1,246 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 24 Aug 2023 10:49:32 +0200 -Subject: [PATCH] multipath-tools tests: convert mock_{failed,used}_alias to - macros - -This way we can further improve readability of the individual test -cases. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - tests/alias.c | 92 +++++++++++++++++++++++++-------------------------- - 1 file changed, 46 insertions(+), 46 deletions(-) - -diff --git a/tests/alias.c b/tests/alias.c -index 427b2814..a32b43e8 100644 ---- a/tests/alias.c -+++ b/tests/alias.c -@@ -445,26 +445,26 @@ static void mock_self_alias(const char *alias, const char *wwid) - #define REUSE_STR(alias_str, wwid_str) ("alias " alias_str " already bound to wwid " wwid_str ", cannot reuse\n") - #define NOMORE_STR "no more available user_friendly_names\n" - --static void mock_failed_alias(const char *alias, char *msg) --{ -- expect_string(__wrap_dm_map_present, str, alias); -- will_return(__wrap_dm_map_present, 1); -- expect_string(__wrap_dm_get_uuid, name, alias); -- expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); -- will_return(__wrap_dm_get_uuid, 1); -- expect_condlog(3, msg); --} -+#define mock_failed_alias(alias, wwid) \ -+ do { \ -+ expect_string(__wrap_dm_map_present, str, alias); \ -+ will_return(__wrap_dm_map_present, 1); \ -+ expect_string(__wrap_dm_get_uuid, name, alias); \ -+ expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); \ -+ will_return(__wrap_dm_get_uuid, 1); \ -+ expect_condlog(3, USED_STR(alias, wwid)); \ -+ } while (0) - --static void mock_used_alias(const char *alias, char *msg) --{ -- expect_string(__wrap_dm_map_present, str, alias); -- will_return(__wrap_dm_map_present, 1); -- expect_string(__wrap_dm_get_uuid, name, alias); -- expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); -- will_return(__wrap_dm_get_uuid, 0); -- will_return(__wrap_dm_get_uuid, "WWID_USED"); -- expect_condlog(3, msg); --} -+#define mock_used_alias(alias, wwid) \ -+ do { \ -+ expect_string(__wrap_dm_map_present, str, alias); \ -+ will_return(__wrap_dm_map_present, 1); \ -+ expect_string(__wrap_dm_get_uuid, name, alias); \ -+ expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); \ -+ will_return(__wrap_dm_get_uuid, 0); \ -+ will_return(__wrap_dm_get_uuid, "WWID_USED"); \ -+ expect_condlog(3, USED_STR(alias, wwid)); \ -+ } while(0) - - static void mock_bindings_file(const char *content, int match_line) - { -@@ -516,7 +516,7 @@ static void lb_empty_failed(void **state) - char *alias; - - will_return(__wrap_fgets, NULL); -- mock_failed_alias("MPATHa", USED_STR("MPATHa", "WWID0")); -+ mock_failed_alias("MPATHa", "WWID0"); - mock_unused_alias("MPATHb"); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); -@@ -531,7 +531,7 @@ static void lb_empty_1_used(void **state) - char *alias; - - will_return(__wrap_fgets, NULL); -- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); -+ mock_used_alias("MPATHa", "WWID0"); - mock_unused_alias("MPATHb"); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); -@@ -546,7 +546,7 @@ static void lb_empty_1_used_self(void **state) - char *alias; - - will_return(__wrap_fgets, NULL); -- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); -+ mock_used_alias("MPATHa", "WWID0"); - mock_self_alias("MPATHb", "WWID0"); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); -@@ -616,10 +616,10 @@ static void lb_nomatch_a_3_used_failed_self(void **state) - - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, NULL); -- mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID1")); -- mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID1")); -- mock_used_alias("MPATHd", USED_STR("MPATHd", "WWID1")); -- mock_failed_alias("MPATHe", USED_STR("MPATHe", "WWID1")); -+ mock_used_alias("MPATHb", "WWID1"); -+ mock_used_alias("MPATHc", "WWID1"); -+ mock_used_alias("MPATHd", "WWID1"); -+ mock_failed_alias("MPATHe", "WWID1"); - mock_self_alias("MPATHf", "WWID1"); - expect_condlog(3, NOMATCH_WWID_STR("WWID1")); - rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1); -@@ -689,7 +689,7 @@ static void lb_nomatch_a_d_1_used(void **state) - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, "MPATHd WWID1\n"); - will_return(__wrap_fgets, NULL); -- mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2")); -+ mock_used_alias("MPATHb", "WWID2"); - mock_unused_alias("MPATHc"); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -@@ -705,8 +705,8 @@ static void lb_nomatch_a_d_2_used(void **state) - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, "MPATHd WWID1\n"); - will_return(__wrap_fgets, NULL); -- mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2")); -- mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID2")); -+ mock_used_alias("MPATHb", "WWID2"); -+ mock_used_alias("MPATHc", "WWID2"); - mock_unused_alias("MPATHe"); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -@@ -722,9 +722,9 @@ static void lb_nomatch_a_d_3_used(void **state) - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, "MPATHd WWID1\n"); - will_return(__wrap_fgets, NULL); -- mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2")); -- mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID2")); -- mock_used_alias("MPATHe", USED_STR("MPATHe", "WWID2")); -+ mock_used_alias("MPATHb", "WWID2"); -+ mock_used_alias("MPATHc", "WWID2"); -+ mock_used_alias("MPATHe", "WWID2"); - mock_unused_alias("MPATHf"); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -@@ -771,7 +771,7 @@ static void lb_nomatch_d_a_1_used(void **state) - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, "MPATHd WWID0\n"); - will_return(__wrap_fgets, NULL); -- mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2")); -+ mock_used_alias("MPATHb", "WWID2"); - mock_unused_alias("MPATHe"); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -@@ -851,9 +851,9 @@ static void lb_nomatch_b_a_3_used(void **state) - will_return(__wrap_fgets, "MPATHz WWID26\n"); - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, NULL); -- mock_used_alias("MPATHaa", USED_STR("MPATHaa", "WWID2")); -- mock_used_alias("MPATHab", USED_STR("MPATHab", "WWID2")); -- mock_used_alias("MPATHac", USED_STR("MPATHac", "WWID2")); -+ mock_used_alias("MPATHaa", "WWID2"); -+ mock_used_alias("MPATHab", "WWID2"); -+ mock_used_alias("MPATHac", "WWID2"); - mock_unused_alias("MPATHad"); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -@@ -895,7 +895,7 @@ static void lb_nomatch_int_max_used(void **state) - will_return(__wrap_fgets, "MPATHb WWID1\n"); - will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n"); - will_return(__wrap_fgets, NULL); -- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID2")); -+ mock_used_alias("MPATHa", "WWID2"); - expect_condlog(0, NOMORE_STR); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, -1); -@@ -926,7 +926,7 @@ static void lb_nomatch_int_max_m1_used(void **state) - will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"); - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, NULL); -- mock_used_alias("MPATH" MPATH_ID_INT_MAX, USED_STR("MPATH" MPATH_ID_INT_MAX, "WWID2")); -+ mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWID2"); - expect_condlog(0, NOMORE_STR); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, -1); -@@ -941,7 +941,7 @@ static void lb_nomatch_int_max_m1_1_used(void **state) - will_return(__wrap_fgets, "MPATHb WWID1\n"); - will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"); - will_return(__wrap_fgets, NULL); -- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID2")); -+ mock_used_alias("MPATHa", "WWID2"); - mock_unused_alias("MPATH" MPATH_ID_INT_MAX); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -@@ -957,8 +957,8 @@ static void lb_nomatch_int_max_m1_2_used(void **state) - will_return(__wrap_fgets, "MPATHb WWID1\n"); - will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"); - will_return(__wrap_fgets, NULL); -- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID2")); -- mock_used_alias("MPATH" MPATH_ID_INT_MAX, USED_STR("MPATH" MPATH_ID_INT_MAX, "WWID2")); -+ mock_used_alias("MPATHa", "WWID2"); -+ mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWID2"); - expect_condlog(0, NOMORE_STR); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, -1); -@@ -1291,7 +1291,7 @@ static void gufa_match_a_used(void **state) { - - will_return(__wrap_fgets, BINDING_STR("MPATHa", "WWID0")); - expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); -- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); -+ mock_used_alias("MPATHa", "WWID0"); - - alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); - assert_ptr_equal(alias, NULL); -@@ -1355,7 +1355,7 @@ static void gufa_nomatch_c_b_used(void **state) { - mock_bindings_file("MPATHc WWID2\n" - "MPATHb WWID1", - -1); -- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID4")); -+ mock_used_alias("MPATHa", "WWID4"); - expect_condlog(3, NOMATCH_WWID_STR("WWID4")); - mock_unused_alias("MPATHd"); - -@@ -1450,7 +1450,7 @@ static void gufa_old_match_other_used(void **state) { - expect_condlog(0, REUSE_STR("MPATHz", "WWID9")); - - mock_bindings_file(bindings, -1); -- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); -+ mock_used_alias("MPATHa", "WWID0"); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - mock_unused_alias("MPATHb"); - -@@ -1493,7 +1493,7 @@ static void gufa_old_match_other_wwidmatch_used(void **state) { - - mock_bindings_file(bindings, 1); - expect_condlog(3, FOUND_STR("MPATHc", "WWID2")); -- mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID2")); -+ mock_used_alias("MPATHc", "WWID2"); - - alias = get_user_friendly_alias("WWID2", "x", "MPATHz", "MPATH", false); - assert_ptr_equal(alias, NULL); -@@ -1528,7 +1528,7 @@ static void gufa_old_nomatch_wwidmatch_used(void **state) { - - mock_bindings_file(bindings, 0); - expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); -- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); -+ mock_used_alias("MPATHa", "WWID0"); - - alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); - assert_ptr_equal(alias, NULL); diff --git a/0050-RH-make-parse_vpd_pg83-match-scsi_id-output.patch b/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch similarity index 94% rename from 0050-RH-make-parse_vpd_pg83-match-scsi_id-output.patch rename to 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch index 1906258..aa49d69 100644 --- a/0050-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +++ b/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch @@ -14,10 +14,10 @@ Signed-off-by: Benjamin Marzinski 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 84ce5fe7..104fdd5a 100644 +index 6fd4dabb..19692b1e 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c -@@ -1177,13 +1177,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, +@@ -1216,13 +1216,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, good_len = 8; break; case 2: @@ -33,7 +33,7 @@ index 84ce5fe7..104fdd5a 100644 good_len = 8; break; default: -@@ -1201,10 +1197,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, +@@ -1240,10 +1236,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, break; case 0x8: /* SCSI Name: Prio 3 */ diff --git a/0010-multipath-tools-test-use-mock_bindings_file-consiste.patch b/0010-multipath-tools-test-use-mock_bindings_file-consiste.patch deleted file mode 100644 index 2105f5a..0000000 --- a/0010-multipath-tools-test-use-mock_bindings_file-consiste.patch +++ /dev/null @@ -1,500 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 24 Aug 2023 11:13:44 +0200 -Subject: [PATCH] multipath-tools test: use mock_bindings_file() consistently - -Further improve test readablity. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - tests/alias.c | 178 +++++++++++++++++++++----------------------------- - 1 file changed, 76 insertions(+), 102 deletions(-) - -diff --git a/tests/alias.c b/tests/alias.c -index a32b43e8..f334f928 100644 ---- a/tests/alias.c -+++ b/tests/alias.c -@@ -489,7 +489,7 @@ static void lb_empty(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("", -1); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - rc = lookup_binding(NULL, "WWID0", &alias, NULL, 0); - assert_int_equal(rc, 1); -@@ -501,7 +501,7 @@ static void lb_empty_unused(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("", -1); - mock_unused_alias("MPATHa"); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); -@@ -515,7 +515,7 @@ static void lb_empty_failed(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("", -1); - mock_failed_alias("MPATHa", "WWID0"); - mock_unused_alias("MPATHb"); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); -@@ -530,7 +530,7 @@ static void lb_empty_1_used(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("", -1); - mock_used_alias("MPATHa", "WWID0"); - mock_unused_alias("MPATHb"); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); -@@ -545,7 +545,7 @@ static void lb_empty_1_used_self(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("", -1); - mock_used_alias("MPATHa", "WWID0"); - mock_self_alias("MPATHb", "WWID0"); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); -@@ -560,7 +560,7 @@ static void lb_match_a(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -+ mock_bindings_file("MPATHa WWID0\n", 0); - expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); - rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 0); - assert_int_equal(rc, 0); -@@ -574,8 +574,7 @@ static void lb_nomatch_a(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHa WWID0\n", -1); - expect_condlog(3, NOMATCH_WWID_STR("WWID1")); - rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 0); - assert_int_equal(rc, 2); -@@ -587,8 +586,7 @@ static void lb_nomatch_a_bad_check(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHa WWID0\n", -1); - expect_condlog(0, NOMORE_STR); - rc = lookup_binding(NULL, "WWID1", &alias, NULL, 1); - assert_int_equal(rc, -1); -@@ -600,8 +598,7 @@ static void lb_nomatch_a_unused(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHa WWID0\n", -1); - mock_unused_alias("MPATHb"); - expect_condlog(3, NOMATCH_WWID_STR("WWID1")); - rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1); -@@ -614,8 +611,7 @@ static void lb_nomatch_a_3_used_failed_self(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHa WWID0\n", -1); - mock_used_alias("MPATHb", "WWID1"); - mock_used_alias("MPATHc", "WWID1"); - mock_used_alias("MPATHd", "WWID1"); -@@ -632,8 +628,8 @@ static void do_lb_match_c(void **state, int check_if_taken) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, "MPATHc WWID1\n"); -+ mock_bindings_file("MPATHa WWID0\n" -+ "MPATHc WWID1", 1); - expect_condlog(3, FOUND_STR("MPATHc", "WWID1")); - rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", check_if_taken); - assert_int_equal(rc, 0); -@@ -657,9 +653,8 @@ static void lb_nomatch_a_c(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, "MPATHc WWID1\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHa WWID0\n" -+ "MPATHc WWID1", -1); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); - assert_int_equal(rc, 2); -@@ -671,9 +666,8 @@ static void lb_nomatch_a_d_unused(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, "MPATHd WWID1\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHa WWID0\n" -+ "MPATHd WWID1", -1); - mock_unused_alias("MPATHb"); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -@@ -686,9 +680,8 @@ static void lb_nomatch_a_d_1_used(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, "MPATHd WWID1\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHa WWID0\n" -+ "MPATHd WWID1", -1); - mock_used_alias("MPATHb", "WWID2"); - mock_unused_alias("MPATHc"); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); -@@ -702,9 +695,8 @@ static void lb_nomatch_a_d_2_used(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, "MPATHd WWID1\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHa WWID0\n" -+ "MPATHd WWID1", -1); - mock_used_alias("MPATHb", "WWID2"); - mock_used_alias("MPATHc", "WWID2"); - mock_unused_alias("MPATHe"); -@@ -719,9 +711,8 @@ static void lb_nomatch_a_d_3_used(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, "MPATHd WWID1\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHa WWID0\n" -+ "MPATHd WWID1", -1); - mock_used_alias("MPATHb", "WWID2"); - mock_used_alias("MPATHc", "WWID2"); - mock_used_alias("MPATHe", "WWID2"); -@@ -737,9 +728,8 @@ static void lb_nomatch_c_a(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHc WWID1\n"); -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHc WWID1\n" -+ "MPATHa WWID0\n", -1); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); - assert_int_equal(rc, 2); -@@ -751,10 +741,9 @@ static void lb_nomatch_d_a_unused(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHc WWID1\n"); -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, "MPATHd WWID0\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHc WWID1\n" -+ "MPATHa WWID0\n" -+ "MPATHd WWID0\n", -1); - mock_unused_alias("MPATHb"); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -@@ -767,10 +756,9 @@ static void lb_nomatch_d_a_1_used(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHc WWID1\n"); -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, "MPATHd WWID0\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHc WWID1\n" -+ "MPATHa WWID0\n" -+ "MPATHd WWID0\n", -1); - mock_used_alias("MPATHb", "WWID2"); - mock_unused_alias("MPATHe"); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); -@@ -784,10 +772,9 @@ static void lb_nomatch_a_b(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, "MPATHz WWID26\n"); -- will_return(__wrap_fgets, "MPATHb WWID1\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHa WWID0\n" -+ "MPATHz WWID26\n" -+ "MPATHb WWID1\n", -1); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); - assert_int_equal(rc, 3); -@@ -799,10 +786,9 @@ static void lb_nomatch_a_b_bad(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, "MPATHz WWID26\n"); -- will_return(__wrap_fgets, "MPATHb\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHa WWID0\n" -+ "MPATHz WWID26\n" -+ "MPATHb\n", -1); - expect_condlog(3, "Ignoring malformed line 3 in bindings file\n"); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); -@@ -815,10 +801,9 @@ static void lb_nomatch_a_b_bad_self(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, "MPATHz WWID26\n"); -- will_return(__wrap_fgets, "MPATHb\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHa WWID0\n" -+ "MPATHz WWID26\n" -+ "MPATHb\n", -1); - expect_condlog(3, "Ignoring malformed line 3 in bindings file\n"); - mock_self_alias("MPATHc", "WWID2"); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); -@@ -832,10 +817,9 @@ static void lb_nomatch_b_a(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHb WWID1\n"); -- will_return(__wrap_fgets, "MPATHz WWID26\n"); -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHb WWID1\n" -+ "MPATHz WWID26\n" -+ "MPATHa WWID0\n", -1); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); - assert_int_equal(rc, 27); -@@ -847,10 +831,9 @@ static void lb_nomatch_b_a_3_used(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHb WWID1\n"); -- will_return(__wrap_fgets, "MPATHz WWID26\n"); -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHb WWID1\n" -+ "MPATHz WWID26\n" -+ "MPATHa WWID0\n", -1); - mock_used_alias("MPATHaa", "WWID2"); - mock_used_alias("MPATHab", "WWID2"); - mock_used_alias("MPATHac", "WWID2"); -@@ -867,10 +850,9 @@ static void do_lb_nomatch_int_max(void **state, int check_if_taken) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHb WWID1\n"); -- will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n"); -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHb WWID1\n" -+ "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n" -+ "MPATHa WWID0\n", -1); - expect_condlog(0, NOMORE_STR); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", check_if_taken); - assert_int_equal(rc, -1); -@@ -892,9 +874,8 @@ static void lb_nomatch_int_max_used(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHb WWID1\n"); -- will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHb WWID1\n" -+ "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n", -1); - mock_used_alias("MPATHa", "WWID2"); - expect_condlog(0, NOMORE_STR); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -@@ -907,10 +888,9 @@ static void lb_nomatch_int_max_m1(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHb WWID1\n"); -- will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"); -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHb WWID1\n" -+ "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n" -+ "MPATHa WWID0\n", -1); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); - assert_int_equal(rc, INT_MAX); -@@ -922,10 +902,9 @@ static void lb_nomatch_int_max_m1_used(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHb WWID1\n"); -- will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"); -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHb WWID1\n" -+ "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n" -+ "MPATHa WWID0\n", -1); - mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWID2"); - expect_condlog(0, NOMORE_STR); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -@@ -938,9 +917,8 @@ static void lb_nomatch_int_max_m1_1_used(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHb WWID1\n"); -- will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHb WWID1\n" -+ "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n", -1); - mock_used_alias("MPATHa", "WWID2"); - mock_unused_alias("MPATH" MPATH_ID_INT_MAX); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); -@@ -954,9 +932,8 @@ static void lb_nomatch_int_max_m1_2_used(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHb WWID1\n"); -- will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHb WWID1\n" -+ "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n", -1); - mock_used_alias("MPATHa", "WWID2"); - mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWID2"); - expect_condlog(0, NOMORE_STR); -@@ -1014,7 +991,7 @@ static void rl_empty(void **state) - char buf[WWID_SIZE]; - - buf[0] = '\0'; -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("", -1); - expect_condlog(3, NOMATCH_STR("MPATHa")); - rc = rlookup_binding(NULL, buf, "MPATHa"); - assert_int_equal(rc, -1); -@@ -1027,7 +1004,7 @@ static void rl_match_a(void **state) - char buf[WWID_SIZE]; - - buf[0] = '\0'; -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -+ mock_bindings_file("MPATHa WWID0\n", 0); - expect_condlog(3, FOUND_ALIAS_STR("MPATHa", "WWID0")); - rc = rlookup_binding(NULL, buf, "MPATHa"); - assert_int_equal(rc, 0); -@@ -1040,8 +1017,7 @@ static void rl_nomatch_a(void **state) - char buf[WWID_SIZE]; - - buf[0] = '\0'; -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHa WWID0\n", -1); - expect_condlog(3, NOMATCH_STR("MPATHb")); - rc = rlookup_binding(NULL, buf, "MPATHb"); - assert_int_equal(rc, -1); -@@ -1054,8 +1030,7 @@ static void rl_malformed_a(void **state) - char buf[WWID_SIZE]; - - buf[0] = '\0'; -- will_return(__wrap_fgets, "MPATHa \n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHa \n", -1); - expect_condlog(3, "Ignoring malformed line 1 in bindings file\n"); - expect_condlog(3, NOMATCH_STR("MPATHa")); - rc = rlookup_binding(NULL, buf, "MPATHa"); -@@ -1074,8 +1049,7 @@ static void rl_overlong_a(void **state) - snprintf(line + sizeof(line) - 2, 2, "\n"); - - buf[0] = '\0'; -- will_return(__wrap_fgets, line); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file(line, -1); - expect_condlog(3, "Ignoring too large wwid at 1 in bindings file\n"); - expect_condlog(3, NOMATCH_STR("MPATHa")); - rc = rlookup_binding(NULL, buf, "MPATHa"); -@@ -1089,9 +1063,9 @@ static void rl_match_b(void **state) - char buf[WWID_SIZE]; - - buf[0] = '\0'; -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, "MPATHz WWID26\n"); -- will_return(__wrap_fgets, "MPATHb WWID2\n"); -+ mock_bindings_file("MPATHa WWID0\n" -+ "MPATHz WWID26\n" -+ "MPATHb WWID2\n", 2); - expect_condlog(3, FOUND_ALIAS_STR("MPATHb", "WWID2")); - rc = rlookup_binding(NULL, buf, "MPATHb"); - assert_int_equal(rc, 0); -@@ -1222,7 +1196,7 @@ static void gufa_empty_new_rw(void **state) { - - will_return(__wrap_open_file, true); - -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("", -1); - mock_unused_alias("MPATHa"); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - -@@ -1235,7 +1209,7 @@ static void gufa_empty_new_rw(void **state) { - static void gufa_empty_new_ro_1(void **state) { - char *alias; - will_return(__wrap_open_file, false); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("", -1); - mock_unused_alias("MPATHa"); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - -@@ -1248,7 +1222,7 @@ static void gufa_empty_new_ro_2(void **state) { - - will_return(__wrap_open_file, true); - -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("", -1); - mock_unused_alias("MPATHa"); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - -@@ -1261,7 +1235,7 @@ static void gufa_match_a_unused(void **state) { - - will_return(__wrap_open_file, true); - -- will_return(__wrap_fgets, BINDING_STR("MPATHa", "WWID0")); -+ mock_bindings_file("MPATHa WWID0", 0); - expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); - mock_unused_alias("MPATHa"); - -@@ -1275,7 +1249,7 @@ static void gufa_match_a_self(void **state) { - - will_return(__wrap_open_file, true); - -- will_return(__wrap_fgets, BINDING_STR("MPATHa", "WWID0")); -+ mock_bindings_file("MPATHa WWID0", 0); - expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); - mock_self_alias("MPATHa", "WWID0"); - -@@ -1289,7 +1263,7 @@ static void gufa_match_a_used(void **state) { - - will_return(__wrap_open_file, true); - -- will_return(__wrap_fgets, BINDING_STR("MPATHa", "WWID0")); -+ mock_bindings_file("MPATHa WWID0", 0); - expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); - mock_used_alias("MPATHa", "WWID0"); - -@@ -1389,11 +1363,11 @@ static void gufa_old_empty(void **state) { - will_return(__wrap_open_file, true); - - /* rlookup_binding for ALIAS */ -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("", -1); - expect_condlog(3, NOMATCH_STR("MPATHz")); - - /* lookup_binding */ -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("", -1); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - - mock_allocate_binding("MPATHz", "WWID0"); diff --git a/0051-RH-add-scsi-device-handlers-to-modules-load.d.patch b/0011-RH-add-scsi-device-handlers-to-modules-load.d.patch similarity index 96% rename from 0051-RH-add-scsi-device-handlers-to-modules-load.d.patch rename to 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch index 407b621..0059895 100644 --- a/0051-RH-add-scsi-device-handlers-to-modules-load.d.patch +++ b/0011-RH-add-scsi-device-handlers-to-modules-load.d.patch @@ -11,7 +11,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc -index 72fd8d57..a49e9f5a 100644 +index 3d80d224..15e3bd3a 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -16,7 +16,7 @@ READLINE := diff --git a/0011-libmultipath-add-global-variable-for-current-binding.patch b/0011-libmultipath-add-global-variable-for-current-binding.patch deleted file mode 100644 index c91259d..0000000 --- a/0011-libmultipath-add-global-variable-for-current-binding.patch +++ /dev/null @@ -1,109 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 22 Aug 2023 15:32:17 +0200 -Subject: [PATCH] libmultipath: add global variable for current bindings - -Add a variable global_bindings that holds the currently active vector of -bindings. This variable is freed at program exit. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/alias.c | 11 +++++++++-- - libmultipath/alias.h | 1 + - libmultipath/libmultipath.version | 1 + - multipath/main.c | 2 ++ - multipathd/main.c | 1 + - 5 files changed, 14 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/alias.c b/libmultipath/alias.c -index 9e9ac563..dd363fd8 100644 ---- a/libmultipath/alias.c -+++ b/libmultipath/alias.c -@@ -511,6 +511,7 @@ static void _free_binding(struct binding *bdg) - * an abstract type. - */ - typedef struct _vector Bindings; -+static Bindings global_bindings = { .allocated = 0 }; - - static void free_bindings(Bindings *bindings) - { -@@ -522,6 +523,11 @@ static void free_bindings(Bindings *bindings) - vector_reset(bindings); - } - -+void cleanup_bindings(void) -+{ -+ free_bindings(&global_bindings); -+} -+ - enum { - BINDING_EXISTS, - BINDING_CONFLICT, -@@ -751,7 +757,6 @@ int check_alias_settings(const struct config *conf) - pthread_cleanup_pop(1); - pthread_cleanup_pop(1); - -- pthread_cleanup_push_cast(free_bindings, &bindings); - fd = open_file(conf->bindings_file, &can_write, BINDINGS_FILE_HEADER); - if (fd != -1) { - FILE *file = fdopen(fd, "r"); -@@ -771,6 +776,8 @@ int check_alias_settings(const struct config *conf) - close(fd); - } - } -- pthread_cleanup_pop(1); -+ -+ cleanup_bindings(); -+ global_bindings = bindings; - return rc; - } -diff --git a/libmultipath/alias.h b/libmultipath/alias.h -index fa332233..37b49d9c 100644 ---- a/libmultipath/alias.h -+++ b/libmultipath/alias.h -@@ -9,5 +9,6 @@ char *get_user_friendly_alias(const char *wwid, const char *file, - - struct config; - int check_alias_settings(const struct config *); -+void cleanup_bindings(void); - - #endif /* _ALIAS_H */ -diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version -index a7b8c337..ddd302f5 100644 ---- a/libmultipath/libmultipath.version -+++ b/libmultipath/libmultipath.version -@@ -64,6 +64,7 @@ global: - checker_name; - checker_state_name; - check_foreign; -+ cleanup_bindings; - cleanup_lock; - coalesce_paths; - count_active_paths; -diff --git a/multipath/main.c b/multipath/main.c -index b78f3162..45e9745f 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -843,6 +843,8 @@ main (int argc, char *argv[]) - conf->force_sync = 1; - if (atexit(cleanup_vecs)) - condlog(1, "failed to register cleanup handler for vecs: %m"); -+ if (atexit(cleanup_bindings)) -+ condlog(1, "failed to register cleanup handler for bindings: %m"); - while ((arg = getopt(argc, argv, ":adDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { - switch(arg) { - case 'v': -diff --git a/multipathd/main.c b/multipathd/main.c -index 2e02a548..214ed4ae 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -3325,6 +3325,7 @@ static void cleanup_child(void) - { - cleanup_threads(); - cleanup_vecs(); -+ cleanup_bindings(); - if (poll_dmevents) - cleanup_dmevent_waiter(); - diff --git a/0052-RH-compile-with-libreadline-support.patch b/0012-RH-compile-with-libreadline-support.patch similarity index 96% rename from 0052-RH-compile-with-libreadline-support.patch rename to 0012-RH-compile-with-libreadline-support.patch index c78d5c0..b0c8749 100644 --- a/0052-RH-compile-with-libreadline-support.patch +++ b/0012-RH-compile-with-libreadline-support.patch @@ -12,7 +12,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc -index a49e9f5a..51b55196 100644 +index 15e3bd3a..64384a72 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -12,7 +12,7 @@ diff --git a/0012-libmultipath-rename-fix_bindings_file-to-update_bind.patch b/0012-libmultipath-rename-fix_bindings_file-to-update_bind.patch deleted file mode 100644 index e0f8673..0000000 --- a/0012-libmultipath-rename-fix_bindings_file-to-update_bind.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 22 Aug 2023 15:37:15 +0200 -Subject: [PATCH] libmultipath: rename fix_bindings_file() to - update_bindings_file() - -We will use this function in a more generic way, give it a more -generic name. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/alias.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/libmultipath/alias.c b/libmultipath/alias.c -index dd363fd8..0aac2393 100644 ---- a/libmultipath/alias.c -+++ b/libmultipath/alias.c -@@ -595,8 +595,8 @@ static int write_bindings_file(const Bindings *bindings, int fd) - return 0; - } - --static int fix_bindings_file(const struct config *conf, -- const Bindings *bindings) -+static int update_bindings_file(const struct config *conf, -+ const Bindings *bindings) - { - int rc; - int fd = -1; -@@ -766,7 +766,7 @@ int check_alias_settings(const struct config *conf) - rc = _check_bindings_file(conf, file, &bindings); - pthread_cleanup_pop(1); - if (rc == -1 && can_write && !conf->bindings_read_only) -- rc = fix_bindings_file(conf, &bindings); -+ rc = update_bindings_file(conf, &bindings); - else if (rc == -1) - condlog(0, "ERROR: bad settings in read-only bindings file %s", - conf->bindings_file); diff --git a/0053-RH-Add-mpathcleanup.patch b/0013-RH-Add-mpathcleanup.patch similarity index 98% rename from 0053-RH-Add-mpathcleanup.patch rename to 0013-RH-Add-mpathcleanup.patch index 9278829..c15fb6d 100644 --- a/0053-RH-Add-mpathcleanup.patch +++ b/0013-RH-Add-mpathcleanup.patch @@ -14,7 +14,7 @@ Signed-off-by: Benjamin Marzinski create mode 100755 multipath/mpathcleanup diff --git a/multipath/Makefile b/multipath/Makefile -index 9942d1a9..d281b501 100644 +index 9f14036c..99ad81b0 100644 --- a/multipath/Makefile +++ b/multipath/Makefile @@ -25,6 +25,7 @@ install: @@ -25,7 +25,7 @@ index 9942d1a9..d281b501 100644 $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) $(Q)$(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) $(Q)$(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)$(udevrulesdir)/62-multipath.rules -@@ -46,6 +47,7 @@ endif +@@ -48,6 +49,7 @@ endif uninstall: $(Q)$(RM) $(DESTDIR)$(bindir)/$(EXEC) $(Q)$(RM) $(DESTDIR)$(bindir)/mpathconf diff --git a/0013-libmultipath-alias.c-move-bindings-related-code-up.patch b/0013-libmultipath-alias.c-move-bindings-related-code-up.patch deleted file mode 100644 index 1ad7b9e..0000000 --- a/0013-libmultipath-alias.c-move-bindings-related-code-up.patch +++ /dev/null @@ -1,285 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 22 Aug 2023 16:54:54 +0200 -Subject: [PATCH] libmultipath: alias.c: move bindings related code up - -No code changes, just moving code. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/alias.c | 239 ++++++++++++++++++++++--------------------- - 1 file changed, 120 insertions(+), 119 deletions(-) - -diff --git a/libmultipath/alias.c b/libmultipath/alias.c -index 0aac2393..7af403da 100644 ---- a/libmultipath/alias.c -+++ b/libmultipath/alias.c -@@ -9,6 +9,7 @@ - #include - #include - #include -+#include - - #include "debug.h" - #include "util.h" -@@ -51,6 +52,125 @@ - - static const char bindings_file_header[] = BINDINGS_FILE_HEADER; - -+struct binding { -+ char *alias; -+ char *wwid; -+}; -+ -+/* -+ * Perhaps one day we'll implement this more efficiently, thus use -+ * an abstract type. -+ */ -+typedef struct _vector Bindings; -+static Bindings global_bindings = { .allocated = 0 }; -+ -+enum { -+ BINDING_EXISTS, -+ BINDING_CONFLICT, -+ BINDING_ADDED, -+ BINDING_DELETED, -+ BINDING_NOTFOUND, -+ BINDING_ERROR, -+}; -+ -+static void _free_binding(struct binding *bdg) -+{ -+ free(bdg->wwid); -+ free(bdg->alias); -+ free(bdg); -+} -+ -+static int add_binding(Bindings *bindings, const char *alias, const char *wwid) -+{ -+ struct binding *bdg; -+ int i, cmp = 0; -+ -+ /* -+ * Keep the bindings array sorted by alias. -+ * Optimization: Search backwards, assuming that the bindings file is -+ * sorted already. -+ */ -+ vector_foreach_slot_backwards(bindings, bdg, i) { -+ if ((cmp = strcmp(bdg->alias, alias)) <= 0) -+ break; -+ } -+ -+ /* Check for exact match */ -+ if (i >= 0 && cmp == 0) -+ return strcmp(bdg->wwid, wwid) ? -+ BINDING_CONFLICT : BINDING_EXISTS; -+ -+ i++; -+ bdg = calloc(1, sizeof(*bdg)); -+ if (bdg) { -+ bdg->wwid = strdup(wwid); -+ bdg->alias = strdup(alias); -+ if (bdg->wwid && bdg->alias && -+ vector_insert_slot(bindings, i, bdg)) -+ return BINDING_ADDED; -+ else -+ _free_binding(bdg); -+ } -+ -+ return BINDING_ERROR; -+} -+ -+static int write_bindings_file(const Bindings *bindings, int fd) -+{ -+ struct binding *bnd; -+ STRBUF_ON_STACK(line); -+ int i; -+ -+ if (write(fd, BINDINGS_FILE_HEADER, sizeof(BINDINGS_FILE_HEADER) - 1) -+ != sizeof(BINDINGS_FILE_HEADER) - 1) -+ return -1; -+ -+ vector_foreach_slot(bindings, bnd, i) { -+ int len; -+ -+ if ((len = print_strbuf(&line, "%s %s\n", -+ bnd->alias, bnd->wwid)) < 0) -+ return -1; -+ if (write(fd, get_strbuf_str(&line), len) != len) -+ return -1; -+ truncate_strbuf(&line, 0); -+ } -+ return 0; -+} -+ -+static int update_bindings_file(const struct config *conf, -+ const Bindings *bindings) -+{ -+ int rc; -+ int fd = -1; -+ char tempname[PATH_MAX]; -+ mode_t old_umask; -+ -+ if (safe_sprintf(tempname, "%s.XXXXXX", conf->bindings_file)) -+ return -1; -+ /* coverity: SECURE_TEMP */ -+ old_umask = umask(0077); -+ if ((fd = mkstemp(tempname)) == -1) { -+ condlog(1, "%s: mkstemp: %m", __func__); -+ return -1; -+ } -+ umask(old_umask); -+ pthread_cleanup_push(cleanup_fd_ptr, &fd); -+ rc = write_bindings_file(bindings, fd); -+ pthread_cleanup_pop(1); -+ if (rc == -1) { -+ condlog(1, "failed to write new bindings file %s", -+ tempname); -+ unlink(tempname); -+ return rc; -+ } -+ if ((rc = rename(tempname, conf->bindings_file)) == -1) -+ condlog(0, "%s: rename: %m", __func__); -+ else -+ condlog(1, "updated bindings file %s", conf->bindings_file); -+ return rc; -+} -+ - int - valid_alias(const char *alias) - { -@@ -494,25 +614,6 @@ get_user_friendly_wwid(const char *alias, char *buff, const char *file) - return 0; - } - --struct binding { -- char *alias; -- char *wwid; --}; -- --static void _free_binding(struct binding *bdg) --{ -- free(bdg->wwid); -- free(bdg->alias); -- free(bdg); --} -- --/* -- * Perhaps one day we'll implement this more efficiently, thus use -- * an abstract type. -- */ --typedef struct _vector Bindings; --static Bindings global_bindings = { .allocated = 0 }; -- - static void free_bindings(Bindings *bindings) - { - struct binding *bdg; -@@ -528,106 +629,6 @@ void cleanup_bindings(void) - free_bindings(&global_bindings); - } - --enum { -- BINDING_EXISTS, -- BINDING_CONFLICT, -- BINDING_ADDED, -- BINDING_DELETED, -- BINDING_NOTFOUND, -- BINDING_ERROR, --}; -- --static int add_binding(Bindings *bindings, const char *alias, const char *wwid) --{ -- struct binding *bdg; -- int i, cmp = 0; -- -- /* -- * Keep the bindings array sorted by alias. -- * Optimization: Search backwards, assuming that the bindings file is -- * sorted already. -- */ -- vector_foreach_slot_backwards(bindings, bdg, i) { -- if ((cmp = strcmp(bdg->alias, alias)) <= 0) -- break; -- } -- -- /* Check for exact match */ -- if (i >= 0 && cmp == 0) -- return strcmp(bdg->wwid, wwid) ? -- BINDING_CONFLICT : BINDING_EXISTS; -- -- i++; -- bdg = calloc(1, sizeof(*bdg)); -- if (bdg) { -- bdg->wwid = strdup(wwid); -- bdg->alias = strdup(alias); -- if (bdg->wwid && bdg->alias && -- vector_insert_slot(bindings, i, bdg)) -- return BINDING_ADDED; -- else -- _free_binding(bdg); -- } -- -- return BINDING_ERROR; --} -- --static int write_bindings_file(const Bindings *bindings, int fd) --{ -- struct binding *bnd; -- STRBUF_ON_STACK(line); -- int i; -- -- if (write(fd, BINDINGS_FILE_HEADER, sizeof(BINDINGS_FILE_HEADER) - 1) -- != sizeof(BINDINGS_FILE_HEADER) - 1) -- return -1; -- -- vector_foreach_slot(bindings, bnd, i) { -- int len; -- -- if ((len = print_strbuf(&line, "%s %s\n", -- bnd->alias, bnd->wwid)) < 0) -- return -1; -- if (write(fd, get_strbuf_str(&line), len) != len) -- return -1; -- truncate_strbuf(&line, 0); -- } -- return 0; --} -- --static int update_bindings_file(const struct config *conf, -- const Bindings *bindings) --{ -- int rc; -- int fd = -1; -- char tempname[PATH_MAX]; -- mode_t old_umask; -- -- if (safe_sprintf(tempname, "%s.XXXXXX", conf->bindings_file)) -- return -1; -- /* coverity: SECURE_TEMP */ -- old_umask = umask(0077); -- if ((fd = mkstemp(tempname)) == -1) { -- condlog(1, "%s: mkstemp: %m", __func__); -- return -1; -- } -- umask(old_umask); -- pthread_cleanup_push(cleanup_fd_ptr, &fd); -- rc = write_bindings_file(bindings, fd); -- pthread_cleanup_pop(1); -- if (rc == -1) { -- condlog(1, "failed to write new bindings file %s", -- tempname); -- unlink(tempname); -- return rc; -- } -- if ((rc = rename(tempname, conf->bindings_file)) == -1) -- condlog(0, "%s: rename: %m", __func__); -- else -- condlog(1, "updated bindings file %s", conf->bindings_file); -- return rc; --} -- - static int _check_bindings_file(const struct config *conf, FILE *file, - Bindings *bindings) - { diff --git a/0014-libmultipath-update_bindings_file-take-filename-argu.patch b/0014-libmultipath-update_bindings_file-take-filename-argu.patch deleted file mode 100644 index 6b9d2e8..0000000 --- a/0014-libmultipath-update_bindings_file-take-filename-argu.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 24 Aug 2023 15:53:49 +0200 -Subject: [PATCH] libmultipath: update_bindings_file: take filename argument - -This function just uses the file name, no other configuration -parameters. Also, pass the Bindings argument first to use the -same convention as the other functions in this file. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/alias.c | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - -diff --git a/libmultipath/alias.c b/libmultipath/alias.c -index 7af403da..9bd3875e 100644 ---- a/libmultipath/alias.c -+++ b/libmultipath/alias.c -@@ -138,15 +138,15 @@ static int write_bindings_file(const Bindings *bindings, int fd) - return 0; - } - --static int update_bindings_file(const struct config *conf, -- const Bindings *bindings) -+static int update_bindings_file(const Bindings *bindings, -+ const char *bindings_file) - { - int rc; - int fd = -1; - char tempname[PATH_MAX]; - mode_t old_umask; - -- if (safe_sprintf(tempname, "%s.XXXXXX", conf->bindings_file)) -+ if (safe_sprintf(tempname, "%s.XXXXXX", bindings_file)) - return -1; - /* coverity: SECURE_TEMP */ - old_umask = umask(0077); -@@ -164,10 +164,10 @@ static int update_bindings_file(const struct config *conf, - unlink(tempname); - return rc; - } -- if ((rc = rename(tempname, conf->bindings_file)) == -1) -+ if ((rc = rename(tempname, bindings_file)) == -1) - condlog(0, "%s: rename: %m", __func__); - else -- condlog(1, "updated bindings file %s", conf->bindings_file); -+ condlog(1, "updated bindings file %s", bindings_file); - return rc; - } - -@@ -767,7 +767,7 @@ int check_alias_settings(const struct config *conf) - rc = _check_bindings_file(conf, file, &bindings); - pthread_cleanup_pop(1); - if (rc == -1 && can_write && !conf->bindings_read_only) -- rc = update_bindings_file(conf, &bindings); -+ rc = update_bindings_file(&bindings, conf->bindings_file); - else if (rc == -1) - condlog(0, "ERROR: bad settings in read-only bindings file %s", - conf->bindings_file); diff --git a/0015-libmultipath-update_bindings_file-use-a-single-write.patch b/0015-libmultipath-update_bindings_file-use-a-single-write.patch deleted file mode 100644 index 1e1fd15..0000000 --- a/0015-libmultipath-update_bindings_file-use-a-single-write.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 24 Aug 2023 15:54:45 +0200 -Subject: [PATCH] libmultipath: update_bindings_file: use a single write() - -Save code and syscalls by assembling the content in memory first. -write() may return less bytes written than expected. Deal with it. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/alias.c | 26 +++++++++++++++++--------- - 1 file changed, 17 insertions(+), 9 deletions(-) - -diff --git a/libmultipath/alias.c b/libmultipath/alias.c -index 9bd3875e..92f90f05 100644 ---- a/libmultipath/alias.c -+++ b/libmultipath/alias.c -@@ -118,22 +118,30 @@ static int add_binding(Bindings *bindings, const char *alias, const char *wwid) - static int write_bindings_file(const Bindings *bindings, int fd) - { - struct binding *bnd; -- STRBUF_ON_STACK(line); -+ STRBUF_ON_STACK(content); - int i; -+ size_t len; - -- if (write(fd, BINDINGS_FILE_HEADER, sizeof(BINDINGS_FILE_HEADER) - 1) -- != sizeof(BINDINGS_FILE_HEADER) - 1) -+ if (__append_strbuf_str(&content, BINDINGS_FILE_HEADER, -+ sizeof(BINDINGS_FILE_HEADER) - 1) == -1) - return -1; - - vector_foreach_slot(bindings, bnd, i) { -- int len; -- -- if ((len = print_strbuf(&line, "%s %s\n", -- bnd->alias, bnd->wwid)) < 0) -+ if (print_strbuf(&content, "%s %s\n", -+ bnd->alias, bnd->wwid) < 0) - return -1; -- if (write(fd, get_strbuf_str(&line), len) != len) -+ } -+ len = get_strbuf_len(&content); -+ while (len > 0) { -+ ssize_t n = write(fd, get_strbuf_str(&content), len); -+ -+ if (n < 0) -+ return n; -+ else if (n == 0) { -+ condlog(2, "%s: short write", __func__); - return -1; -- truncate_strbuf(&line, 0); -+ } -+ len -= n; - } - return 0; - } diff --git a/0016-libmultipath-update_bindings_file-don-t-log-temp-fil.patch b/0016-libmultipath-update_bindings_file-don-t-log-temp-fil.patch deleted file mode 100644 index 1126b95..0000000 --- a/0016-libmultipath-update_bindings_file-don-t-log-temp-fil.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 24 Aug 2023 22:33:39 +0200 -Subject: [PATCH] libmultipath: update_bindings_file: don't log temp file name - -The name of the temp file is unlikely to be helpful for users, -and hard to predict in the unit test. Omit it. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/alias.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/libmultipath/alias.c b/libmultipath/alias.c -index 92f90f05..afa5879e 100644 ---- a/libmultipath/alias.c -+++ b/libmultipath/alias.c -@@ -167,8 +167,7 @@ static int update_bindings_file(const Bindings *bindings, - rc = write_bindings_file(bindings, fd); - pthread_cleanup_pop(1); - if (rc == -1) { -- condlog(1, "failed to write new bindings file %s", -- tempname); -+ condlog(1, "failed to write new bindings file"); - unlink(tempname); - return rc; - } diff --git a/0017-libmultipath-alias.c-factor-out-read_binding.patch b/0017-libmultipath-alias.c-factor-out-read_binding.patch deleted file mode 100644 index 8c9cb08..0000000 --- a/0017-libmultipath-alias.c-factor-out-read_binding.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 24 Aug 2023 21:17:25 +0200 -Subject: [PATCH] libmultipath: alias.c: factor out read_binding() - -This way we can test the parsing of input lines from the bindings -file more easily. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/alias.c | 58 ++++++++++++++++++++++++++++++-------------- - 1 file changed, 40 insertions(+), 18 deletions(-) - -diff --git a/libmultipath/alias.c b/libmultipath/alias.c -index afa5879e..ecf4a2ac 100644 ---- a/libmultipath/alias.c -+++ b/libmultipath/alias.c -@@ -636,6 +636,43 @@ void cleanup_bindings(void) - free_bindings(&global_bindings); - } - -+enum { -+ READ_BINDING_OK, -+ READ_BINDING_SKIP, -+}; -+ -+static int read_binding(char *line, unsigned int linenr, char **alias, -+ char **wwid) { -+ char *c, *saveptr; -+ -+ c = strpbrk(line, "#\n\r"); -+ if (c) -+ *c = '\0'; -+ -+ *alias = strtok_r(line, " \t", &saveptr); -+ if (!*alias) /* blank line */ -+ return READ_BINDING_SKIP; -+ -+ *wwid = strtok_r(NULL, " \t", &saveptr); -+ if (!*wwid) { -+ condlog(1, "invalid line %u in bindings file, missing WWID", -+ linenr); -+ return READ_BINDING_SKIP; -+ } -+ if (strlen(*wwid) > WWID_SIZE - 1) { -+ condlog(3, -+ "Ignoring too large wwid at %u in bindings file", -+ linenr); -+ return READ_BINDING_SKIP; -+ } -+ c = strtok_r(NULL, " \t", &saveptr); -+ if (c) -+ /* This is non-fatal */ -+ condlog(1, "invalid line %d in bindings file, extra args \"%s\"", -+ linenr, c); -+ return READ_BINDING_OK; -+} -+ - static int _check_bindings_file(const struct config *conf, FILE *file, - Bindings *bindings) - { -@@ -647,27 +684,12 @@ static int _check_bindings_file(const struct config *conf, FILE *file, - - pthread_cleanup_push(cleanup_free_ptr, &line); - while ((n = getline(&line, &line_len, file)) >= 0) { -- char *c, *alias, *wwid, *saveptr; -+ char *alias, *wwid; - const char *mpe_wwid; - -- linenr++; -- c = strpbrk(line, "#\n\r"); -- if (c) -- *c = '\0'; -- alias = strtok_r(line, " \t", &saveptr); -- if (!alias) /* blank line */ -- continue; -- wwid = strtok_r(NULL, " \t", &saveptr); -- if (!wwid) { -- condlog(1, "invalid line %d in bindings file, missing WWID", -- linenr); -+ if (read_binding(line, ++linenr, &alias, &wwid) -+ == READ_BINDING_SKIP) - continue; -- } -- c = strtok_r(NULL, " \t", &saveptr); -- if (c) -- /* This is non-fatal */ -- condlog(1, "invalid line %d in bindings file, extra args \"%s\"", -- linenr, c); - - mpe_wwid = get_mpe_wwid(conf->mptable, alias); - if (mpe_wwid && strcmp(mpe_wwid, wwid)) { diff --git a/0018-libmultipath-keep-bindings-in-memory.patch b/0018-libmultipath-keep-bindings-in-memory.patch deleted file mode 100644 index bb26ea2..0000000 --- a/0018-libmultipath-keep-bindings-in-memory.patch +++ /dev/null @@ -1,545 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 22 Aug 2023 21:14:51 +0200 -Subject: [PATCH] libmultipath: keep bindings in memory - -Rather than opening the bindings file every time we must retrieve -a binding, keep the contents in memory and write the file only -if additions have been made. This simplifies the code, and should speed up -alias lookups significantly. As a side effect, the aliases will be stored -sorted by alias, which changes the way aliases are allocated if there are -unused "holes" in the sequence of aliases. For example, if the bindings file -contains mpathb, mpathy, and mpatha, in this order, the next new alias used to -be mpathz and is now mpathc. - -Another side effect is that multipathd will not automatically pick up changes -to the bindings file at runtime without a reconfigure operation. It is -questionable whether these on-the-fly changes were a good idea in the first -place, as inconsistent configurations may easily come to pass. It desired, -it would be feasible to implement automatic update of the bindings using the -existing inotify approach. - -The new implementation of get_user_friendly_alias() is slightly different -than before. The logic is summarized in a comment in the code. Unit tests -will be provided that illustrate the changes. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/alias.c | 351 ++++++++++++++++----------------------- - libmultipath/alias.h | 2 +- - libmultipath/configure.c | 3 +- - 3 files changed, 144 insertions(+), 212 deletions(-) - -diff --git a/libmultipath/alias.c b/libmultipath/alias.c -index ecf4a2ac..d6563749 100644 ---- a/libmultipath/alias.c -+++ b/libmultipath/alias.c -@@ -50,8 +50,6 @@ - "# alias wwid\n" \ - "#\n" - --static const char bindings_file_header[] = BINDINGS_FILE_HEADER; -- - struct binding { - char *alias; - char *wwid; -@@ -80,6 +78,45 @@ static void _free_binding(struct binding *bdg) - free(bdg); - } - -+static const struct binding *get_binding_for_alias(const Bindings *bindings, -+ const char *alias) -+{ -+ const struct binding *bdg; -+ int i; -+ -+ if (!alias) -+ return NULL; -+ vector_foreach_slot(bindings, bdg, i) { -+ if (!strncmp(bdg->alias, alias, WWID_SIZE)) { -+ condlog(3, "Found matching alias [%s] in bindings file." -+ " Setting wwid to %s", alias, bdg->wwid); -+ return bdg; -+ } -+ } -+ -+ condlog(3, "No matching alias [%s] in bindings file.", alias); -+ return NULL; -+} -+ -+static const struct binding *get_binding_for_wwid(const Bindings *bindings, -+ const char *wwid) -+{ -+ const struct binding *bdg; -+ int i; -+ -+ if (!wwid) -+ return NULL; -+ vector_foreach_slot(bindings, bdg, i) { -+ if (!strncmp(bdg->wwid, wwid, WWID_SIZE)) { -+ condlog(3, "Found matching wwid [%s] in bindings file." -+ " Setting alias to %s", wwid, bdg->alias); -+ return bdg; -+ } -+ } -+ condlog(3, "No matching wwid [%s] in bindings file.", wwid); -+ return NULL; -+} -+ - static int add_binding(Bindings *bindings, const char *alias, const char *wwid) - { - struct binding *bdg; -@@ -115,6 +152,24 @@ static int add_binding(Bindings *bindings, const char *alias, const char *wwid) - return BINDING_ERROR; - } - -+static int delete_binding(Bindings *bindings, const char *wwid) -+{ -+ struct binding *bdg; -+ int i; -+ -+ vector_foreach_slot(bindings, bdg, i) { -+ if (!strncmp(bdg->wwid, wwid, WWID_SIZE)) { -+ _free_binding(bdg); -+ break; -+ } -+ } -+ if (i >= VECTOR_SIZE(bindings)) -+ return BINDING_NOTFOUND; -+ -+ vector_del_slot(bindings, i); -+ return BINDING_DELETED; -+} -+ - static int write_bindings_file(const Bindings *bindings, int fd) - { - struct binding *bnd; -@@ -267,38 +322,15 @@ static bool id_already_taken(int id, const char *prefix, const char *map_wwid) - return alias_already_taken(alias, map_wwid); - } - --/* -- * Returns: 0 if matching entry in WWIDs file found -- * -1 if an error occurs -- * >0 a free ID that could be used for the WWID at hand -- * *map_alias is set to a freshly allocated string with the matching alias if -- * the function returns 0, or to NULL otherwise. -- */ --static int --lookup_binding(FILE *f, const char *map_wwid, char **map_alias, -- const char *prefix, int check_if_taken) -+int get_free_id(const Bindings *bindings, const char *prefix, const char *map_wwid) - { -- char buf[LINE_MAX]; -- unsigned int line_nr = 0; -- int id = 1; -+ const struct binding *bdg; -+ int i, id = 1; - int biggest_id = 1; - int smallest_bigger_id = INT_MAX; - -- *map_alias = NULL; -- -- rewind(f); -- while (fgets(buf, LINE_MAX, f)) { -- const char *alias, *wwid; -- char *c, *saveptr; -- int curr_id; -- -- line_nr++; -- c = strpbrk(buf, "#\n\r"); -- if (c) -- *c = '\0'; -- alias = strtok_r(buf, " \t", &saveptr); -- if (!alias) /* blank line */ -- continue; -+ vector_foreach_slot(bindings, bdg, i) { -+ int curr_id = scan_devname(bdg->alias, prefix); - - /* - * Find an unused index - explanation of the algorithm -@@ -333,8 +365,6 @@ lookup_binding(FILE *f, const char *map_wwid, char **map_alias, - * biggest_id is always > smallest_bigger_id, except in the - * "perfectly ordered" case. - */ -- -- curr_id = scan_devname(alias, prefix); - if (curr_id == id) { - if (id < INT_MAX) - id++; -@@ -345,36 +375,15 @@ lookup_binding(FILE *f, const char *map_wwid, char **map_alias, - } - if (curr_id > biggest_id) - biggest_id = curr_id; -+ - if (curr_id > id && curr_id < smallest_bigger_id) - smallest_bigger_id = curr_id; -- wwid = strtok_r(NULL, " \t", &saveptr); -- if (!wwid){ -- condlog(3, -- "Ignoring malformed line %u in bindings file", -- line_nr); -- continue; -- } -- if (strcmp(wwid, map_wwid) == 0){ -- condlog(3, "Found matching wwid [%s] in bindings file." -- " Setting alias to %s", wwid, alias); -- *map_alias = strdup(alias); -- if (*map_alias == NULL) { -- condlog(0, "Cannot copy alias from bindings " -- "file: out of memory"); -- return -1; -- } -- return 0; -- } -- } -- if (!prefix && check_if_taken) -- id = -1; -- if (id >= smallest_bigger_id) { -- if (biggest_id < INT_MAX) -- id = biggest_id + 1; -- else -- id = -1; - } -- if (id > 0 && check_if_taken) { -+ -+ if (id >= smallest_bigger_id) -+ id = biggest_id < INT_MAX ? biggest_id + 1 : -1; -+ -+ if (id > 0) { - while(id_already_taken(id, prefix, map_wwid)) { - if (id == INT_MAX) { - id = -1; -@@ -391,64 +400,17 @@ lookup_binding(FILE *f, const char *map_wwid, char **map_alias, - } - } - } -- if (id < 0) { -+ -+ if (id < 0) - condlog(0, "no more available user_friendly_names"); -- return -1; -- } else -- condlog(3, "No matching wwid [%s] in bindings file.", map_wwid); - return id; - } - --static int --rlookup_binding(FILE *f, char *buff, const char *map_alias) --{ -- char line[LINE_MAX]; -- unsigned int line_nr = 0; -- -- buff[0] = '\0'; -- -- while (fgets(line, LINE_MAX, f)) { -- char *c, *saveptr; -- const char *alias, *wwid; -- -- line_nr++; -- c = strpbrk(line, "#\n\r"); -- if (c) -- *c = '\0'; -- alias = strtok_r(line, " \t", &saveptr); -- if (!alias) /* blank line */ -- continue; -- wwid = strtok_r(NULL, " \t", &saveptr); -- if (!wwid){ -- condlog(3, -- "Ignoring malformed line %u in bindings file", -- line_nr); -- continue; -- } -- if (strlen(wwid) > WWID_SIZE - 1) { -- condlog(3, -- "Ignoring too large wwid at %u in bindings file", line_nr); -- continue; -- } -- if (strcmp(alias, map_alias) == 0){ -- condlog(3, "Found matching alias [%s] in bindings file." -- " Setting wwid to %s", alias, wwid); -- strlcpy(buff, wwid, WWID_SIZE); -- return 0; -- } -- } -- condlog(3, "No matching alias [%s] in bindings file.", map_alias); -- -- return -1; --} -- - static char * --allocate_binding(int fd, const char *wwid, int id, const char *prefix) -+allocate_binding(const char *filename, const char *wwid, int id, const char *prefix) - { - STRBUF_ON_STACK(buf); -- off_t offset; -- ssize_t len; -- char *alias, *c; -+ char *alias; - - if (id <= 0) { - condlog(0, "%s: cannot allocate new binding for id %d", -@@ -460,164 +422,135 @@ allocate_binding(int fd, const char *wwid, int id, const char *prefix) - format_devname(&buf, id) == -1) - return NULL; - -- if (print_strbuf(&buf, " %s\n", wwid) < 0) -- return NULL; -+ alias = steal_strbuf_str(&buf); - -- offset = lseek(fd, 0, SEEK_END); -- if (offset < 0){ -- condlog(0, "Cannot seek to end of bindings file : %s", -- strerror(errno)); -+ if (add_binding(&global_bindings, alias, wwid) != BINDING_ADDED) { -+ condlog(0, "%s: cannot allocate new binding %s for %s", -+ __func__, alias, wwid); -+ free(alias); - return NULL; - } - -- len = get_strbuf_len(&buf); -- alias = steal_strbuf_str(&buf); -- -- if (write(fd, alias, len) != len) { -- condlog(0, "Cannot write binding to bindings file : %s", -- strerror(errno)); -- /* clear partial write */ -- if (ftruncate(fd, offset)) -- condlog(0, "Cannot truncate the header : %s", -- strerror(errno)); -+ if (update_bindings_file(&global_bindings, filename) == -1) { -+ condlog(1, "%s: deleting binding %s for %s", __func__, alias, wwid); -+ delete_binding(&global_bindings, wwid); - free(alias); - return NULL; - } -- c = strchr(alias, ' '); -- if (c) -- *c = '\0'; - - condlog(3, "Created new binding [%s] for WWID [%s]", alias, wwid); - return alias; - } - -+/* -+ * get_user_friendly_alias() action table -+ * -+ * The table shows the various cases, the actions taken, and the CI -+ * functions from tests/alias.c that represent them. -+ * -+ * - O: old alias given -+ * - A: old alias in table (y: yes, correct WWID; X: yes, wrong WWID) -+ * - W: wwid in table -+ * -+ * | No | O | A | W | action | function gufa_X | -+ * |----+---+---+---+--------------------------------------------+------------------------------| -+ * | 1 | n | - | n | get new alias | nomatch_Y | -+ * | 2 | n | - | y | use alias from bindings | match_a_Y | -+ * | 3 | y | n | n | add binding for old alias | old_nomatch_nowwidmatch | -+ * | 4 | y | n | y | use alias from bindings (avoid duplicates) | old_nomatch_wwidmatch | -+ * | 5 | y | y | n | [ impossible ] | - | -+ * | 6 | y | y | y | use old alias == alias from bindings | old_match | -+ * | 7 | y | X | n | get new alias | old_match_other | -+ * | 8 | y | X | y | use alias from bindings | old_match_other_wwidmatch | -+ * -+ * Notes: -+ * - "use alias from bindings" means that the alias from the bindings file will -+ * be tried; if it is in use, the alias selection will fail. No other -+ * bindings will be attempted. -+ * - "get new alias" fails if all aliases are used up, or if writing the -+ * bindings file fails. -+ * - if "alias_old" is set, it can't be bound to a different map. alias_old is -+ * initialized in find_existing_alias() by scanning the mpvec. We trust -+ * that the mpvec corrcectly represents kernel state. -+ */ -+ - char *get_user_friendly_alias(const char *wwid, const char *file, const char *alias_old, - const char *prefix, bool bindings_read_only) - { - char *alias = NULL; - int id = 0; -- int fd, can_write; - bool new_binding = false; -- char buff[WWID_SIZE]; -- FILE *f; -- -- fd = open_file(file, &can_write, bindings_file_header); -- if (fd < 0) -- return NULL; -- -- f = fdopen(fd, "r"); -- if (!f) { -- condlog(0, "cannot fdopen on bindings file descriptor"); -- close(fd); -- return NULL; -- } -+ const struct binding *bdg; - -- if (!strlen(alias_old)) -+ if (!*alias_old) - goto new_alias; - -- /* lookup the binding. if it exists, the wwid will be in buff -- * either way, id contains the id for the alias -- */ -- rlookup_binding(f, buff, alias_old); -- -- if (strlen(buff) > 0) { -- /* If buff is our wwid, it's already allocated correctly. */ -- if (strcmp(buff, wwid) == 0) { -+ /* See if there's a binding matching both alias_old and wwid */ -+ bdg = get_binding_for_alias(&global_bindings, alias_old); -+ if (bdg) { -+ if (!strcmp(bdg->wwid, wwid)) { - alias = strdup(alias_old); - goto out; -- - } else { - condlog(0, "alias %s already bound to wwid %s, cannot reuse", -- alias_old, buff); -+ alias_old, bdg->wwid); - goto new_alias; - } - } - -- /* -- * Look for an existing alias in the bindings file. -- * Pass prefix = NULL, so lookup_binding() won't try to allocate a new id. -- */ -- lookup_binding(f, wwid, &alias, NULL, 0); -- if (alias) { -- if (alias_already_taken(alias, wwid)) { -- free(alias); -- alias = NULL; -- } else -+ /* allocate the existing alias in the bindings file */ -+ id = scan_devname(alias_old, prefix); -+ -+new_alias: -+ /* Check for existing binding of WWID */ -+ bdg = get_binding_for_wwid(&global_bindings, wwid); -+ if (bdg) { -+ if (!alias_already_taken(bdg->alias, wwid)) { - condlog(3, "Use existing binding [%s] for WWID [%s]", -- alias, wwid); -+ bdg->alias, wwid); -+ alias = strdup(bdg->alias); -+ } - goto out; - } - -- /* alias_old is already taken by our WWID, update bindings file. */ -- id = scan_devname(alias_old, prefix); -- --new_alias: - if (id <= 0) { - /* - * no existing alias was provided, or allocating it - * failed. Try a new one. - */ -- id = lookup_binding(f, wwid, &alias, prefix, 1); -- if (id == 0 && alias_already_taken(alias, wwid)) { -- free(alias); -- alias = NULL; -- } -+ id = get_free_id(&global_bindings, prefix, wwid); - if (id <= 0) - goto out; - else - new_binding = true; - } - -- if (fflush(f) != 0) { -- condlog(0, "cannot fflush bindings file stream : %s", -- strerror(errno)); -- goto out; -- } -+ if (!bindings_read_only && id > 0) -+ alias = allocate_binding(file, wwid, id, prefix); - -- if (can_write && !bindings_read_only) { -- alias = allocate_binding(fd, wwid, id, prefix); -- if (alias && !new_binding) -- condlog(2, "Allocated existing binding [%s] for WWID [%s]", -- alias, wwid); -- } -+ if (alias && !new_binding) -+ condlog(2, "Allocated existing binding [%s] for WWID [%s]", -+ alias, wwid); - - out: -- pthread_cleanup_push(free, alias); -- fclose(f); -- pthread_cleanup_pop(0); - return alias; - } - --int --get_user_friendly_wwid(const char *alias, char *buff, const char *file) -+int get_user_friendly_wwid(const char *alias, char *buff) - { -- int fd, unused; -- FILE *f; -+ const struct binding *bdg; - - if (!alias || *alias == '\0') { - condlog(3, "Cannot find binding for empty alias"); - return -1; - } - -- fd = open_file(file, &unused, bindings_file_header); -- if (fd < 0) -- return -1; -- -- f = fdopen(fd, "r"); -- if (!f) { -- condlog(0, "cannot fdopen on bindings file descriptor : %s", -- strerror(errno)); -- close(fd); -+ bdg = get_binding_for_alias(&global_bindings, alias); -+ if (!bdg) { -+ *buff = '\0'; - return -1; - } -- -- rlookup_binding(f, buff, alias); -- if (!strlen(buff)) { -- fclose(f); -- return -1; -- } -- -- fclose(f); -+ strlcpy(buff, bdg->wwid, WWID_SIZE); - return 0; - } - -diff --git a/libmultipath/alias.h b/libmultipath/alias.h -index 37b49d9c..5ef6720b 100644 ---- a/libmultipath/alias.h -+++ b/libmultipath/alias.h -@@ -2,7 +2,7 @@ - #define _ALIAS_H - - int valid_alias(const char *alias); --int get_user_friendly_wwid(const char *alias, char *buff, const char *file); -+int get_user_friendly_wwid(const char *alias, char *buff); - char *get_user_friendly_alias(const char *wwid, const char *file, - const char *alias_old, - const char *prefix, bool bindings_read_only); -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 029fbbd2..d8094903 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -1378,8 +1378,7 @@ static int _get_refwwid(enum mpath_cmds cmd, const char *dev, - refwwid = tmpwwid; - - /* or may be a binding */ -- else if (get_user_friendly_wwid(dev, tmpwwid, -- conf->bindings_file) == 0) -+ else if (get_user_friendly_wwid(dev, tmpwwid) == 0) - refwwid = tmpwwid; - - /* or may be an alias */ diff --git a/0019-multipath-tools-tests-fix-alias-tests.patch b/0019-multipath-tools-tests-fix-alias-tests.patch deleted file mode 100644 index da618f6..0000000 --- a/0019-multipath-tools-tests-fix-alias-tests.patch +++ /dev/null @@ -1,1698 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 25 Aug 2023 17:55:55 +0200 -Subject: [PATCH] multipath-tools tests: fix alias tests - -The different implementation of get_user_friendly_alias() and its helpers -necessitates changes in the unit tests. It would be nice if it didn't, but the -unit tests are too closely bound to the implementation to make this possible. - -- The bindings table is held in memory in alphabetically sorted order, which - may change the result of looking for free alias IDs if the entries in the - bindings file were unordered initially. In particular, if only a small - number of bindings exists, "holes" in the file will be detected more easily. - But because the sort order of the aliases differs from simple alphabetic - sorting ("mpathz" precedes "mpathaa"), a bindings file that contains all - bindings from "a" to "aa" (or more) will appear unsorted. - As an extra check, some of the unit tests deliberately use a different - implementation of add_binding() that does not order the bindings - table. - -- Broken lines in the bindings file never make it to the in-memory - representation. An alias that appeard "used" because it occurred in a broken - line will not appear used any more. Warnings about malformed lines will only - be printed while the bindings file is read, not from get_user_friendly_alias(). - -- The match_line argument of mock_bindings_file() is obsolete. - -- lookup_binding() and rlookup_binding() have been removed from - libmultipath. They are now emulated in the unit test code. - -- lookup_binding() didn't check for used alias in all cases previously, but it does now. - -- prefix != NULL and check_if_taken == false is not supported any more - in lookup_binding(). - -- allocate_binding() uses a very different sequence of systems calls now, as - it's implemented using update_bindings_file(). In particular, it's now more - difficult to predict the content of the write() call that creates the - bindings file. See comments for __wrap_write(). - -- some unit tests for get_user_friendly_alias() had to call - mock_bindings_file() twice, because the old implementation would read the - file twice (first rlookup_binding() and then lookup_binding()). This is not - necessary any more. - -- The unit tests need a teardown function to clear the bindings table in memory. - -- Minor changes are necessary because of changed ordering of the log messages. - Previously, lookup_binding() combined check for an existing entry and the - search for a new ID. The new algorithm does this in two separate steps and - tests for used aliases in between, which causes a change in the order in which - log messages are emitted. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - tests/alias.c | 957 ++++++++++++++++++++++++++++++++------------------ - 1 file changed, 614 insertions(+), 343 deletions(-) - -diff --git a/tests/alias.c b/tests/alias.c -index f334f928..50a21ecf 100644 ---- a/tests/alias.c -+++ b/tests/alias.c -@@ -3,10 +3,12 @@ - #include - #include - #include -+#include "strbuf.h" - #include "util.h" - #include "alias.h" - #include "test-log.h" - #include -+#include - - #include "globals.c" - #include "../libmultipath/alias.c" -@@ -20,18 +22,6 @@ - #define MPATH_ID_INT_MAX_p1 "fxshrxx" - #endif - --void __wrap_rewind(FILE *stream) --{} -- --char *__wrap_fgets(char *buf, int n, FILE *stream) --{ -- char *val = mock_ptr_type(char *); -- if (!val) -- return NULL; -- strlcpy(buf, val, n); -- return buf; --} -- - static int __set_errno(int err) - { - if (err >= 0) { -@@ -43,23 +33,44 @@ static int __set_errno(int err) - } - } - --off_t __wrap_lseek(int fd, off_t offset, int whence) -+/* -+ * allocate_binding -> write_bindings_file() writes the entire file, i.e. the -+ * header, any pre-existing bindings, and the new binding. The complete content -+ * depends on history and is different to predict here. Therefore we check only -+ * the newly added binding. Because add_binding() sorts entries, this new -+ * binding isn't necessarily the last one; receive it from will_return() and -+ * search for it with strstr(). -+ * If the string to be written doesn't start with the bindings file -+ * header, it's a test of a partial write. -+ */ -+ssize_t __wrap_write(int fd, const void *buf, size_t count) - { -- return __set_errno(mock_type(int)); -+ const char *binding, *start; - -+#if DEBUG_WRITE -+ fprintf(stderr, "%s: %zx exp %zx\n===\n%s\n===\n", __func__, strlen(buf), -+ count, (const char *)buf); -+#endif -+ if (!strncmp((const char *)buf, BINDINGS_FILE_HEADER, -+ sizeof(BINDINGS_FILE_HEADER) - 1)) -+ start = (const char *)buf + sizeof(BINDINGS_FILE_HEADER) - 1; -+ else -+ start = buf; -+ binding = mock_ptr_type(char *); -+ start = strstr(start, binding); -+ check_expected(count); -+ assert_ptr_not_equal(start, NULL); -+ return __set_errno(mock_type(int)); - } - --ssize_t __wrap_write(int fd, const void *buf, size_t count) -+int __wrap_rename(const char *old, const char *new) - { -- check_expected(count); -- check_expected(buf); - return __set_errno(mock_type(int)); - } - --int __wrap_ftruncate(int fd, off_t length) -+int __wrap_mkstemp(char *template) - { -- check_expected(length); -- return __set_errno(mock_type(int)); -+ return 10; - } - - int __wrap_dm_map_present(const char * str) -@@ -84,32 +95,6 @@ int __wrap_dm_get_uuid(const char *name, char *uuid, int uuid_len) - #define TEST_FDNO 1234 - #define TEST_FPTR ((FILE *) 0xaffe) - --int __wrap_open_file(const char *file, int *can_write, const char *header) --{ -- int cw = mock_type(int); -- -- *can_write = cw; -- return TEST_FDNO; --} -- --FILE *__wrap_fdopen(int fd, const char *mode) --{ -- assert_int_equal(fd, TEST_FDNO); -- return TEST_FPTR; --} -- --int __wrap_fflush(FILE *f) --{ -- assert_ptr_equal(f, TEST_FPTR); -- return 0; --} -- --int __wrap_fclose(FILE *f) --{ -- assert_ptr_equal(f, TEST_FPTR); -- return 0; --} -- - /* strbuf wrapper for the old format_devname() */ - static int __format_devname(char *name, int id, size_t len, const char *prefix) - { -@@ -466,22 +451,85 @@ static void mock_self_alias(const char *alias, const char *wwid) - expect_condlog(3, USED_STR(alias, wwid)); \ - } while(0) - --static void mock_bindings_file(const char *content, int match_line) -+static int add_binding_unsorted(Bindings *bindings, -+ const char *alias, const char *wwid) -+{ -+ struct binding *bdg = calloc(1, sizeof(*bdg)); -+ -+ if (!bdg) -+ return -1; -+ bdg->wwid = strdup(wwid); -+ bdg->alias = strdup(alias); -+ if (!bdg->wwid || !bdg->alias || !vector_alloc_slot(bindings)) { -+ free(bdg->alias); -+ free(bdg->wwid); -+ free(bdg); -+ return BINDING_ERROR; -+ } -+ vector_set_slot(bindings, bdg); -+ return BINDING_ADDED; -+} -+ -+static void __mock_bindings_file(const char *content, -+ int (*add)(Bindings *, const char *, const char *)) - { -- static char cnt[1024]; -- char *token; -+ char *cnt __attribute__((cleanup(cleanup_charp))) = NULL; -+ char *token, *savep = NULL; - int i; - -- assert_in_range(strlcpy(cnt, content, sizeof(cnt)), 0, sizeof(cnt) - 1); -+ cnt = strdup(content); -+ assert_ptr_not_equal(cnt, NULL); - -- for (token = strtok(cnt, "\n"), i = 0; -+ for (token = strtok_r(cnt, "\n", &savep), i = 0; - token && *token; -- token = strtok(NULL, "\n"), i++) { -- will_return(__wrap_fgets, token); -- if (match_line == i) -- return; -+ token = strtok_r(NULL, "\n", &savep), i++) { -+ char *alias, *wwid; -+ int rc; -+ -+ if (read_binding(token, i + 1, &alias, &wwid) -+ == READ_BINDING_SKIP) -+ continue; -+ -+ rc = add(&global_bindings, alias, wwid); -+ assert_int_equal(rc, BINDING_ADDED); - } -- will_return(__wrap_fgets, NULL); -+} -+ -+static void mock_bindings_file(const char *content) { -+ return __mock_bindings_file(content, add_binding); -+} -+ -+static void mock_bindings_file_unsorted(const char *content) { -+ return __mock_bindings_file(content, add_binding_unsorted); -+} -+ -+static int teardown_bindings(void **state) -+{ -+ cleanup_bindings(); -+ return 0; -+} -+ -+static int lookup_binding(FILE *dummy, const char *wwid, char **alias, -+ const char *prefix, int check_if_taken) -+{ -+ const struct binding *bdg; -+ int id; -+ -+ /* -+ * get_free_id() always checks if aliases are taken. -+ * Therefore if prefix is non-null, check_if_taken must be true. -+ */ -+ assert_true(!prefix || check_if_taken); -+ *alias = NULL; -+ bdg = get_binding_for_wwid(&global_bindings, wwid); -+ if (bdg) { -+ *alias = strdup(bdg->alias); -+ return 0; -+ } else if (!prefix && check_if_taken) -+ return -1; -+ -+ id = get_free_id(&global_bindings, prefix, wwid); -+ return id; - } - - static void lb_empty(void **state) -@@ -489,7 +537,7 @@ static void lb_empty(void **state) - int rc; - char *alias; - -- mock_bindings_file("", -1); -+ mock_bindings_file(""); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - rc = lookup_binding(NULL, "WWID0", &alias, NULL, 0); - assert_int_equal(rc, 1); -@@ -501,7 +549,7 @@ static void lb_empty_unused(void **state) - int rc; - char *alias; - -- mock_bindings_file("", -1); -+ mock_bindings_file(""); - mock_unused_alias("MPATHa"); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); -@@ -515,10 +563,10 @@ static void lb_empty_failed(void **state) - int rc; - char *alias; - -- mock_bindings_file("", -1); -+ mock_bindings_file(""); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - mock_failed_alias("MPATHa", "WWID0"); - mock_unused_alias("MPATHb"); -- expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); - assert_int_equal(rc, 2); - assert_ptr_equal(alias, NULL); -@@ -530,10 +578,10 @@ static void lb_empty_1_used(void **state) - int rc; - char *alias; - -- mock_bindings_file("", -1); -+ mock_bindings_file(""); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - mock_used_alias("MPATHa", "WWID0"); - mock_unused_alias("MPATHb"); -- expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); - assert_int_equal(rc, 2); - assert_ptr_equal(alias, NULL); -@@ -545,10 +593,10 @@ static void lb_empty_1_used_self(void **state) - int rc; - char *alias; - -- mock_bindings_file("", -1); -+ mock_bindings_file(""); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - mock_used_alias("MPATHa", "WWID0"); - mock_self_alias("MPATHb", "WWID0"); -- expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); - assert_int_equal(rc, 2); - assert_ptr_equal(alias, NULL); -@@ -560,9 +608,9 @@ static void lb_match_a(void **state) - int rc; - char *alias; - -- mock_bindings_file("MPATHa WWID0\n", 0); -+ mock_bindings_file("MPATHa WWID0\n"); - expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); -- rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 0); -+ rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); - assert_int_equal(rc, 0); - assert_ptr_not_equal(alias, NULL); - assert_string_equal(alias, "MPATHa"); -@@ -574,9 +622,10 @@ static void lb_nomatch_a(void **state) - int rc; - char *alias; - -- mock_bindings_file("MPATHa WWID0\n", -1); -+ mock_bindings_file("MPATHa WWID0\n"); - expect_condlog(3, NOMATCH_WWID_STR("WWID1")); -- rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 0); -+ mock_unused_alias("MPATHb"); -+ rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1); - assert_int_equal(rc, 2); - assert_ptr_equal(alias, NULL); - } -@@ -586,8 +635,8 @@ static void lb_nomatch_a_bad_check(void **state) - int rc; - char *alias; - -- mock_bindings_file("MPATHa WWID0\n", -1); -- expect_condlog(0, NOMORE_STR); -+ mock_bindings_file("MPATHa WWID0\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID1")); - rc = lookup_binding(NULL, "WWID1", &alias, NULL, 1); - assert_int_equal(rc, -1); - assert_ptr_equal(alias, NULL); -@@ -598,7 +647,7 @@ static void lb_nomatch_a_unused(void **state) - int rc; - char *alias; - -- mock_bindings_file("MPATHa WWID0\n", -1); -+ mock_bindings_file("MPATHa WWID0\n"); - mock_unused_alias("MPATHb"); - expect_condlog(3, NOMATCH_WWID_STR("WWID1")); - rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1); -@@ -611,27 +660,27 @@ static void lb_nomatch_a_3_used_failed_self(void **state) - int rc; - char *alias; - -- mock_bindings_file("MPATHa WWID0\n", -1); -+ mock_bindings_file("MPATHa WWID0\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID1")); - mock_used_alias("MPATHb", "WWID1"); - mock_used_alias("MPATHc", "WWID1"); - mock_used_alias("MPATHd", "WWID1"); - mock_failed_alias("MPATHe", "WWID1"); - mock_self_alias("MPATHf", "WWID1"); -- expect_condlog(3, NOMATCH_WWID_STR("WWID1")); - rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1); - assert_int_equal(rc, 6); - assert_ptr_equal(alias, NULL); - } - --static void do_lb_match_c(void **state, int check_if_taken) -+static void do_lb_match_c(void **state) - { - int rc; - char *alias; - - mock_bindings_file("MPATHa WWID0\n" -- "MPATHc WWID1", 1); -+ "MPATHc WWID1"); - expect_condlog(3, FOUND_STR("MPATHc", "WWID1")); -- rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", check_if_taken); -+ rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1); - assert_int_equal(rc, 0); - assert_ptr_not_equal(alias, NULL); - assert_string_equal(alias, "MPATHc"); -@@ -640,12 +689,12 @@ static void do_lb_match_c(void **state, int check_if_taken) - - static void lb_match_c(void **state) - { -- do_lb_match_c(state, 0); -+ do_lb_match_c(state); - } - - static void lb_match_c_check(void **state) - { -- do_lb_match_c(state, 1); -+ do_lb_match_c(state); - } - - static void lb_nomatch_a_c(void **state) -@@ -654,9 +703,10 @@ static void lb_nomatch_a_c(void **state) - char *alias; - - mock_bindings_file("MPATHa WWID0\n" -- "MPATHc WWID1", -1); -+ "MPATHc WWID1"); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); -- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); -+ mock_unused_alias("MPATHb"); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, 2); - assert_ptr_equal(alias, NULL); - } -@@ -667,7 +717,7 @@ static void lb_nomatch_a_d_unused(void **state) - char *alias; - - mock_bindings_file("MPATHa WWID0\n" -- "MPATHd WWID1", -1); -+ "MPATHd WWID1"); - mock_unused_alias("MPATHb"); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -@@ -681,10 +731,10 @@ static void lb_nomatch_a_d_1_used(void **state) - char *alias; - - mock_bindings_file("MPATHa WWID0\n" -- "MPATHd WWID1", -1); -+ "MPATHd WWID1"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - mock_used_alias("MPATHb", "WWID2"); - mock_unused_alias("MPATHc"); -- expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, 3); - assert_ptr_equal(alias, NULL); -@@ -696,11 +746,11 @@ static void lb_nomatch_a_d_2_used(void **state) - char *alias; - - mock_bindings_file("MPATHa WWID0\n" -- "MPATHd WWID1", -1); -+ "MPATHd WWID1"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - mock_used_alias("MPATHb", "WWID2"); - mock_used_alias("MPATHc", "WWID2"); - mock_unused_alias("MPATHe"); -- expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, 5); - assert_ptr_equal(alias, NULL); -@@ -712,12 +762,12 @@ static void lb_nomatch_a_d_3_used(void **state) - char *alias; - - mock_bindings_file("MPATHa WWID0\n" -- "MPATHd WWID1", -1); -+ "MPATHd WWID1"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - mock_used_alias("MPATHb", "WWID2"); - mock_used_alias("MPATHc", "WWID2"); - mock_used_alias("MPATHe", "WWID2"); - mock_unused_alias("MPATHf"); -- expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, 6); - assert_ptr_equal(alias, NULL); -@@ -729,9 +779,10 @@ static void lb_nomatch_c_a(void **state) - char *alias; - - mock_bindings_file("MPATHc WWID1\n" -- "MPATHa WWID0\n", -1); -+ "MPATHa WWID0\n"); -+ mock_unused_alias("MPATHb"); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); -- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, 2); - assert_ptr_equal(alias, NULL); - } -@@ -743,7 +794,7 @@ static void lb_nomatch_d_a_unused(void **state) - - mock_bindings_file("MPATHc WWID1\n" - "MPATHa WWID0\n" -- "MPATHd WWID0\n", -1); -+ "MPATHd WWID0\n"); - mock_unused_alias("MPATHb"); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -@@ -758,10 +809,10 @@ static void lb_nomatch_d_a_1_used(void **state) - - mock_bindings_file("MPATHc WWID1\n" - "MPATHa WWID0\n" -- "MPATHd WWID0\n", -1); -+ "MPATHd WWID0\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - mock_used_alias("MPATHb", "WWID2"); - mock_unused_alias("MPATHe"); -- expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, 5); - assert_ptr_equal(alias, NULL); -@@ -774,9 +825,10 @@ static void lb_nomatch_a_b(void **state) - - mock_bindings_file("MPATHa WWID0\n" - "MPATHz WWID26\n" -- "MPATHb WWID1\n", -1); -+ "MPATHb WWID1\n"); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); -- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); -+ mock_unused_alias("MPATHc"); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, 3); - assert_ptr_equal(alias, NULL); - } -@@ -786,13 +838,19 @@ static void lb_nomatch_a_b_bad(void **state) - int rc; - char *alias; - -+ expect_condlog(1, "invalid line 3 in bindings file, missing WWID\n"); -+ /* -+ * The broken line will be ignored when constructing the bindings vector. -+ * Thus in lookup_binding() MPATHb is never encountered, -+ * and MPATHb appears usable. -+ */ - mock_bindings_file("MPATHa WWID0\n" - "MPATHz WWID26\n" -- "MPATHb\n", -1); -- expect_condlog(3, "Ignoring malformed line 3 in bindings file\n"); -+ "MPATHb\n"); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); -- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); -- assert_int_equal(rc, 3); -+ mock_unused_alias("MPATHb"); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -+ assert_int_equal(rc, 2); - assert_ptr_equal(alias, NULL); - } - -@@ -801,84 +859,200 @@ static void lb_nomatch_a_b_bad_self(void **state) - int rc; - char *alias; - -+ expect_condlog(1, "invalid line 3 in bindings file, missing WWID\n"); - mock_bindings_file("MPATHa WWID0\n" - "MPATHz WWID26\n" -- "MPATHb\n", -1); -- expect_condlog(3, "Ignoring malformed line 3 in bindings file\n"); -- mock_self_alias("MPATHc", "WWID2"); -+ "MPATHb\n"); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); -+ mock_self_alias("MPATHb", "WWID2"); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -- assert_int_equal(rc, 3); -+ assert_int_equal(rc, 2); - assert_ptr_equal(alias, NULL); - } - --static void lb_nomatch_b_a(void **state) -+static void lb_nomatch_b_z_a(void **state) - { - int rc; - char *alias; - -+ /* -+ * add_bindings() sorts alphabetically. Therefore get_free_id() -+ * finds MPATHc as a free entry. -+ */ - mock_bindings_file("MPATHb WWID1\n" - "MPATHz WWID26\n" -- "MPATHa WWID0\n", -1); -+ "MPATHa WWID0\n"); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); -- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); -- assert_int_equal(rc, 27); -+ mock_unused_alias("MPATHc"); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -+ assert_int_equal(rc, 3); - assert_ptr_equal(alias, NULL); - } - --static void lb_nomatch_b_a_3_used(void **state) -+static void lb_nomatch_b_aa_a(void **state) - { - int rc; - char *alias; - -+ /* -+ * add_bindings() sorts alphabetically. ("a", "aa", b"). -+ * The get_free_id() algorithm finds the "hole" after "b". -+ */ - mock_bindings_file("MPATHb WWID1\n" - "MPATHz WWID26\n" -- "MPATHa WWID0\n", -1); -- mock_used_alias("MPATHaa", "WWID2"); -- mock_used_alias("MPATHab", "WWID2"); -- mock_used_alias("MPATHac", "WWID2"); -- mock_unused_alias("MPATHad"); -+ "MPATHa WWID0\n"); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); -+ mock_unused_alias("MPATHc"); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -- assert_int_equal(rc, 30); -+ assert_int_equal(rc, 3); - assert_ptr_equal(alias, NULL); - } - --#ifdef MPATH_ID_INT_MAX --static void do_lb_nomatch_int_max(void **state, int check_if_taken) -+static void fill_bindings(struct strbuf *buf, int start, int end) -+{ -+ int i; -+ -+ for (i = start; i <= end; i++) { -+ print_strbuf(buf, "MPATH"); -+ format_devname(buf, i + 1); -+ print_strbuf(buf, " WWID%d\n", i); -+ } -+} -+ -+static void lb_nomatch_b_a_aa(void **state) -+{ -+ int rc; -+ char *alias; -+ STRBUF_ON_STACK(buf); -+ -+ /* -+ * add_bindings() sorts alphabetically. ("a", "aa", "ab", "b", "c", ...) -+ * lookup_binding finds MPATHac as next free entry. -+ */ -+ fill_bindings(&buf, 0, 26); -+ mock_bindings_file(get_strbuf_str(&buf)); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID28")); -+ mock_unused_alias("MPATHab"); -+ rc = lookup_binding(NULL, "WWID28", &alias, "MPATH", 1); -+ assert_int_equal(rc, 28); -+ assert_ptr_equal(alias, NULL); -+} -+ -+static void lb_nomatch_b_a_aa_zz(void **state) -+{ -+ int rc, i; -+ char *alias; -+ STRBUF_ON_STACK(buf); -+ -+ /* -+ * add_bindings() sorts alphabetically. ("a", "aa", "ab", "b", "c", ...) -+ * lookup_binding finds MPATHaaa as next free entry, because MPATHaa is -+ * found before MPATHb, and MPATHzz was in the bindings, too. -+ */ -+ for (i = 0; i <= 26; i++) { -+ print_strbuf(&buf, "MPATH"); -+ format_devname(&buf, i + 1); -+ print_strbuf(&buf, " WWID%d\n", i); -+ } -+ print_strbuf(&buf, "MPATHzz WWID676\n"); -+ mock_bindings_file(get_strbuf_str(&buf)); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID703")); -+ mock_unused_alias("MPATHaaa"); -+ rc = lookup_binding(NULL, "WWID703", &alias, "MPATH", 1); -+ assert_int_equal(rc, 703); -+ assert_ptr_equal(alias, NULL); -+} -+ -+static void lb_nomatch_b_z_a_unsorted(void **state) -+{ -+ int rc; -+ char *alias; -+ -+ /* -+ * With unsorted bindings (shouldn't happen normally), get_free_id() -+ * plays safe and returns MPATHaa as first free entry. -+ */ -+ mock_bindings_file_unsorted("MPATHb WWID1\n" -+ "MPATHz WWID26\n" -+ "MPATHa WWID0\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); -+ mock_unused_alias("MPATHaa"); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -+ assert_int_equal(rc, 27); -+ assert_ptr_equal(alias, NULL); -+} -+ -+static void lb_nomatch_b_a(void **state) - { - int rc; - char *alias; - - mock_bindings_file("MPATHb WWID1\n" -- "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n" -- "MPATHa WWID0\n", -1); -- expect_condlog(0, NOMORE_STR); -- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", check_if_taken); -- assert_int_equal(rc, -1); -+ "MPATHa WWID0\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); -+ mock_unused_alias("MPATHc"); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -+ assert_int_equal(rc, 3); - assert_ptr_equal(alias, NULL); - } - --static void lb_nomatch_int_max(void **state) -+static void lb_nomatch_b_a_3_used(void **state) - { -- do_lb_nomatch_int_max(state, 0); -+ int rc; -+ char *alias; -+ STRBUF_ON_STACK(buf); -+ -+ fill_bindings(&buf, 0, 26); -+ mock_bindings_file(get_strbuf_str(&buf)); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID31")); -+ mock_used_alias("MPATHab", "WWID31"); -+ mock_used_alias("MPATHac", "WWID31"); -+ mock_used_alias("MPATHad", "WWID31"); -+ mock_unused_alias("MPATHae"); -+ rc = lookup_binding(NULL, "WWID31", &alias, "MPATH", 1); -+ assert_int_equal(rc, 31); -+ assert_ptr_equal(alias, NULL); - } - --static void lb_nomatch_int_max_check(void **state) -+#ifdef MPATH_ID_INT_MAX -+/* -+ * The bindings will be sorted by alias, alphabetically, which is not -+ * the same as the "numeric" sort order for user-friendly aliases. -+ * get_free_id() selects the highest used ID + 1 if an unsorted entry -+ * is encountered in the bindings table and it's id is equal to the -+ * next "expected" id. This happens if all IDs from "a" to "aa" are -+ * in the table. If the INT_MAX entry is in the table, too, it will -+ * overflow. -+ */ -+static void lb_nomatch_int_max(void **state) - { -- do_lb_nomatch_int_max(state, 1); -+ int rc; -+ char *alias; -+ STRBUF_ON_STACK(buf); -+ -+ fill_bindings(&buf, 0, 26); -+ print_strbuf(&buf, "MPATH%s WWIDMAX\n", MPATH_ID_INT_MAX); -+ mock_bindings_file(get_strbuf_str(&buf)); -+ expect_condlog(3, NOMATCH_WWID_STR("WWIDNOMORE")); -+ expect_condlog(0, NOMORE_STR); -+ rc = lookup_binding(NULL, "WWIDNOMORE", &alias, "MPATH", 1); -+ assert_int_equal(rc, -1); -+ assert_ptr_equal(alias, NULL); - } - - static void lb_nomatch_int_max_used(void **state) - { - int rc; - char *alias; -+ STRBUF_ON_STACK(buf); - -- mock_bindings_file("MPATHb WWID1\n" -- "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n", -1); -- mock_used_alias("MPATHa", "WWID2"); -+ fill_bindings(&buf, 1, 26); -+ print_strbuf(&buf, "MPATH%s WWIDMAX\n", MPATH_ID_INT_MAX); -+ mock_bindings_file(get_strbuf_str(&buf)); -+ expect_condlog(3, NOMATCH_WWID_STR("WWIDNOMORE")); -+ mock_used_alias("MPATHa", "WWIDNOMORE"); - expect_condlog(0, NOMORE_STR); -- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -+ rc = lookup_binding(NULL, "WWIDNOMORE", &alias, "MPATH", 1); - assert_int_equal(rc, -1); - assert_ptr_equal(alias, NULL); - } -@@ -887,12 +1061,14 @@ static void lb_nomatch_int_max_m1(void **state) - { - int rc; - char *alias; -+ STRBUF_ON_STACK(buf); - -- mock_bindings_file("MPATHb WWID1\n" -- "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n" -- "MPATHa WWID0\n", -1); -- expect_condlog(3, NOMATCH_WWID_STR("WWID2")); -- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); -+ fill_bindings(&buf, 0, 26); -+ print_strbuf(&buf, "MPATH%s WWIDMAXM1\n", MPATH_ID_INT_MAX_m1); -+ mock_bindings_file(get_strbuf_str(&buf)); -+ expect_condlog(3, NOMATCH_WWID_STR("WWIDMAX")); -+ mock_unused_alias("MPATH" MPATH_ID_INT_MAX); -+ rc = lookup_binding(NULL, "WWIDMAX", &alias, "MPATH", 1); - assert_int_equal(rc, INT_MAX); - assert_ptr_equal(alias, NULL); - } -@@ -901,13 +1077,15 @@ static void lb_nomatch_int_max_m1_used(void **state) - { - int rc; - char *alias; -+ STRBUF_ON_STACK(buf); - -- mock_bindings_file("MPATHb WWID1\n" -- "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n" -- "MPATHa WWID0\n", -1); -- mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWID2"); -+ fill_bindings(&buf, 0, 26); -+ print_strbuf(&buf, "MPATH%s WWIDMAXM1\n", MPATH_ID_INT_MAX_m1); -+ mock_bindings_file(get_strbuf_str(&buf)); -+ expect_condlog(3, NOMATCH_WWID_STR("WWIDMAX")); -+ mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWIDMAX"); - expect_condlog(0, NOMORE_STR); -- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -+ rc = lookup_binding(NULL, "WWIDMAX", &alias, "MPATH", 1); - assert_int_equal(rc, -1); - assert_ptr_equal(alias, NULL); - } -@@ -916,13 +1094,15 @@ static void lb_nomatch_int_max_m1_1_used(void **state) - { - int rc; - char *alias; -+ STRBUF_ON_STACK(buf); - -- mock_bindings_file("MPATHb WWID1\n" -- "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n", -1); -- mock_used_alias("MPATHa", "WWID2"); -+ fill_bindings(&buf, 1, 26); -+ print_strbuf(&buf, "MPATH%s WWIDMAXM1\n", MPATH_ID_INT_MAX_m1); -+ mock_bindings_file(get_strbuf_str(&buf)); -+ expect_condlog(3, NOMATCH_WWID_STR("WWIDMAX")); -+ mock_used_alias("MPATHa", "WWIDMAX"); - mock_unused_alias("MPATH" MPATH_ID_INT_MAX); -- expect_condlog(3, NOMATCH_WWID_STR("WWID2")); -- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -+ rc = lookup_binding(NULL, "WWIDMAX", &alias, "MPATH", 1); - assert_int_equal(rc, INT_MAX); - assert_ptr_equal(alias, NULL); - } -@@ -931,13 +1111,17 @@ static void lb_nomatch_int_max_m1_2_used(void **state) - { - int rc; - char *alias; -+ STRBUF_ON_STACK(buf); - -- mock_bindings_file("MPATHb WWID1\n" -- "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n", -1); -- mock_used_alias("MPATHa", "WWID2"); -- mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWID2"); -+ fill_bindings(&buf, 1, 26); -+ print_strbuf(&buf, "MPATH%s WWIDMAXM1\n", MPATH_ID_INT_MAX_m1); -+ mock_bindings_file(get_strbuf_str(&buf)); -+ -+ expect_condlog(3, NOMATCH_WWID_STR("WWIDMAX")); -+ mock_used_alias("MPATHa", "WWIDMAX"); -+ mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWIDMAX"); - expect_condlog(0, NOMORE_STR); -- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -+ rc = lookup_binding(NULL, "WWIDMAX", &alias, "MPATH", 1); - assert_int_equal(rc, -1); - assert_ptr_equal(alias, NULL); - } -@@ -946,52 +1130,68 @@ static void lb_nomatch_int_max_m1_2_used(void **state) - static int test_lookup_binding(void) - { - const struct CMUnitTest tests[] = { -- cmocka_unit_test(lb_empty), -- cmocka_unit_test(lb_empty_unused), -- cmocka_unit_test(lb_empty_failed), -- cmocka_unit_test(lb_empty_1_used), -- cmocka_unit_test(lb_empty_1_used_self), -- cmocka_unit_test(lb_match_a), -- cmocka_unit_test(lb_nomatch_a), -- cmocka_unit_test(lb_nomatch_a_bad_check), -- cmocka_unit_test(lb_nomatch_a_unused), -- cmocka_unit_test(lb_nomatch_a_3_used_failed_self), -- cmocka_unit_test(lb_match_c), -- cmocka_unit_test(lb_match_c_check), -- cmocka_unit_test(lb_nomatch_a_c), -- cmocka_unit_test(lb_nomatch_a_d_unused), -- cmocka_unit_test(lb_nomatch_a_d_1_used), -- cmocka_unit_test(lb_nomatch_a_d_2_used), -- cmocka_unit_test(lb_nomatch_a_d_3_used), -- cmocka_unit_test(lb_nomatch_c_a), -- cmocka_unit_test(lb_nomatch_d_a_unused), -- cmocka_unit_test(lb_nomatch_d_a_1_used), -- cmocka_unit_test(lb_nomatch_a_b), -- cmocka_unit_test(lb_nomatch_a_b_bad), -- cmocka_unit_test(lb_nomatch_a_b_bad_self), -- cmocka_unit_test(lb_nomatch_b_a), -- cmocka_unit_test(lb_nomatch_b_a_3_used), -+ cmocka_unit_test_teardown(lb_empty, teardown_bindings), -+ cmocka_unit_test_teardown(lb_empty_unused, teardown_bindings), -+ cmocka_unit_test_teardown(lb_empty_failed, teardown_bindings), -+ cmocka_unit_test_teardown(lb_empty_1_used, teardown_bindings), -+ cmocka_unit_test_teardown(lb_empty_1_used_self, teardown_bindings), -+ cmocka_unit_test_teardown(lb_match_a, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_a, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_a_bad_check, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_a_unused, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_a_3_used_failed_self, teardown_bindings), -+ cmocka_unit_test_teardown(lb_match_c, teardown_bindings), -+ cmocka_unit_test_teardown(lb_match_c_check, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_a_c, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_a_d_unused, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_a_d_1_used, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_a_d_2_used, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_a_d_3_used, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_c_a, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_d_a_unused, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_d_a_1_used, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_a_b, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_a_b_bad, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_a_b_bad_self, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_b_z_a, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_b_aa_a, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_b_a_aa, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_b_a_aa_zz, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_b_z_a_unsorted, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_b_a, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_b_a_3_used, teardown_bindings), - #ifdef MPATH_ID_INT_MAX -- cmocka_unit_test(lb_nomatch_int_max), -- cmocka_unit_test(lb_nomatch_int_max_check), -- cmocka_unit_test(lb_nomatch_int_max_used), -- cmocka_unit_test(lb_nomatch_int_max_m1), -- cmocka_unit_test(lb_nomatch_int_max_m1_used), -- cmocka_unit_test(lb_nomatch_int_max_m1_1_used), -- cmocka_unit_test(lb_nomatch_int_max_m1_2_used), -+ cmocka_unit_test_teardown(lb_nomatch_int_max, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_int_max_used, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_int_max_m1, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_int_max_m1_used, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_int_max_m1_1_used, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_int_max_m1_2_used, teardown_bindings), - #endif - }; - - return cmocka_run_group_tests(tests, NULL, NULL); - } - -+static int rlookup_binding(FILE *dummy, char *buf, const char *alias) { -+ -+ const struct binding *bdg; -+ -+ bdg = get_binding_for_alias(&global_bindings, alias); -+ if (!bdg) { -+ return -1; -+ } -+ strlcpy(buf, bdg->wwid, WWID_SIZE); -+ return 0; -+} -+ - static void rl_empty(void **state) - { - int rc; - char buf[WWID_SIZE]; - - buf[0] = '\0'; -- mock_bindings_file("", -1); -+ mock_bindings_file(""); - expect_condlog(3, NOMATCH_STR("MPATHa")); - rc = rlookup_binding(NULL, buf, "MPATHa"); - assert_int_equal(rc, -1); -@@ -1004,7 +1204,7 @@ static void rl_match_a(void **state) - char buf[WWID_SIZE]; - - buf[0] = '\0'; -- mock_bindings_file("MPATHa WWID0\n", 0); -+ mock_bindings_file("MPATHa WWID0\n"); - expect_condlog(3, FOUND_ALIAS_STR("MPATHa", "WWID0")); - rc = rlookup_binding(NULL, buf, "MPATHa"); - assert_int_equal(rc, 0); -@@ -1017,7 +1217,7 @@ static void rl_nomatch_a(void **state) - char buf[WWID_SIZE]; - - buf[0] = '\0'; -- mock_bindings_file("MPATHa WWID0\n", -1); -+ mock_bindings_file("MPATHa WWID0\n"); - expect_condlog(3, NOMATCH_STR("MPATHb")); - rc = rlookup_binding(NULL, buf, "MPATHb"); - assert_int_equal(rc, -1); -@@ -1030,8 +1230,8 @@ static void rl_malformed_a(void **state) - char buf[WWID_SIZE]; - - buf[0] = '\0'; -- mock_bindings_file("MPATHa \n", -1); -- expect_condlog(3, "Ignoring malformed line 1 in bindings file\n"); -+ expect_condlog(1, "invalid line 1 in bindings file, missing WWID\n"); -+ mock_bindings_file("MPATHa \n"); - expect_condlog(3, NOMATCH_STR("MPATHa")); - rc = rlookup_binding(NULL, buf, "MPATHa"); - assert_int_equal(rc, -1); -@@ -1049,8 +1249,8 @@ static void rl_overlong_a(void **state) - snprintf(line + sizeof(line) - 2, 2, "\n"); - - buf[0] = '\0'; -- mock_bindings_file(line, -1); - expect_condlog(3, "Ignoring too large wwid at 1 in bindings file\n"); -+ mock_bindings_file(line); - expect_condlog(3, NOMATCH_STR("MPATHa")); - rc = rlookup_binding(NULL, buf, "MPATHa"); - assert_int_equal(rc, -1); -@@ -1065,7 +1265,7 @@ static void rl_match_b(void **state) - buf[0] = '\0'; - mock_bindings_file("MPATHa WWID0\n" - "MPATHz WWID26\n" -- "MPATHb WWID2\n", 2); -+ "MPATHb WWID2\n"); - expect_condlog(3, FOUND_ALIAS_STR("MPATHb", "WWID2")); - rc = rlookup_binding(NULL, buf, "MPATHb"); - assert_int_equal(rc, 0); -@@ -1075,31 +1275,41 @@ static void rl_match_b(void **state) - static int test_rlookup_binding(void) - { - const struct CMUnitTest tests[] = { -- cmocka_unit_test(rl_empty), -- cmocka_unit_test(rl_match_a), -- cmocka_unit_test(rl_nomatch_a), -- cmocka_unit_test(rl_malformed_a), -- cmocka_unit_test(rl_overlong_a), -- cmocka_unit_test(rl_match_b), -+ cmocka_unit_test_teardown(rl_empty, teardown_bindings), -+ cmocka_unit_test_teardown(rl_match_a, teardown_bindings), -+ cmocka_unit_test_teardown(rl_nomatch_a, teardown_bindings), -+ cmocka_unit_test_teardown(rl_malformed_a, teardown_bindings), -+ cmocka_unit_test_teardown(rl_overlong_a, teardown_bindings), -+ cmocka_unit_test_teardown(rl_match_b, teardown_bindings), - }; - - return cmocka_run_group_tests(tests, NULL, NULL); - } - -+void check_bindings_size(int n) -+{ -+ /* avoid -Waddress problem */ -+ Bindings *bindings = &global_bindings; -+ -+ assert_int_equal(VECTOR_SIZE(bindings), n); -+} -+ - static void al_a(void **state) - { - static const char ln[] = "MPATHa WWIDa\n"; - char *alias; - -- will_return(__wrap_lseek, 0); -- expect_value(__wrap_write, count, strlen(ln)); -- expect_string(__wrap_write, buf, ln); -- will_return(__wrap_write, strlen(ln)); -+ expect_value(__wrap_write, count, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); -+ will_return(__wrap_write, ln); -+ will_return(__wrap_write, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); -+ will_return(__wrap_rename, 0); -+ expect_condlog(1, "updated bindings file foo"); - expect_condlog(3, NEW_STR("MPATHa", "WWIDa")); - -- alias = allocate_binding(0, "WWIDa", 1, "MPATH"); -+ alias = allocate_binding("foo", "WWIDa", 1, "MPATH"); - assert_ptr_not_equal(alias, NULL); - assert_string_equal(alias, "MPATHa"); -+ check_bindings_size(1); - free(alias); - } - -@@ -1108,15 +1318,17 @@ static void al_zz(void **state) - static const char ln[] = "MPATHzz WWIDzz\n"; - char *alias; - -- will_return(__wrap_lseek, 0); -- expect_value(__wrap_write, count, strlen(ln)); -- expect_string(__wrap_write, buf, ln); -- will_return(__wrap_write, strlen(ln)); -+ expect_value(__wrap_write, count, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); -+ will_return(__wrap_write, ln); -+ will_return(__wrap_write, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); -+ will_return(__wrap_rename, 0); -+ expect_condlog(1, "updated bindings file foo"); - expect_condlog(3, NEW_STR("MPATHzz", "WWIDzz")); - -- alias = allocate_binding(0, "WWIDzz", 26*26 + 26, "MPATH"); -+ alias = allocate_binding("foo", "WWIDzz", 26*26 + 26, "MPATH"); - assert_ptr_not_equal(alias, NULL); - assert_string_equal(alias, "MPATHzz"); -+ check_bindings_size(1); - free(alias); - } - -@@ -1127,6 +1339,7 @@ static void al_0(void **state) - expect_condlog(0, "allocate_binding: cannot allocate new binding for id 0\n"); - alias = allocate_binding(0, "WWIDa", 0, "MPATH"); - assert_ptr_equal(alias, NULL); -+ check_bindings_size(0); - } - - static void al_m2(void **state) -@@ -1136,67 +1349,133 @@ static void al_m2(void **state) - expect_condlog(0, "allocate_binding: cannot allocate new binding for id -2\n"); - alias = allocate_binding(0, "WWIDa", -2, "MPATH"); - assert_ptr_equal(alias, NULL); -+ check_bindings_size(0); -+} -+ -+static void al_write_partial(void **state) -+{ -+ static const char ln[] = "MPATHa WWIDa\n"; -+ char *alias; -+ -+ expect_value(__wrap_write, count, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); -+ will_return(__wrap_write, ln); -+ will_return(__wrap_write, strlen(BINDINGS_FILE_HEADER) + strlen(ln) - 1); -+ expect_value(__wrap_write, count, 1); -+ will_return(__wrap_write, ln + sizeof(ln) - 2); -+ will_return(__wrap_write, 1); -+ will_return(__wrap_rename, 0); -+ expect_condlog(1, "updated bindings file foo"); -+ expect_condlog(3, "Created new binding [MPATHa] for WWID [WWIDa]\n"); -+ -+ alias = allocate_binding("foo", "WWIDa", 1, "MPATH"); -+ assert_ptr_not_equal(alias, NULL); -+ assert_string_equal(alias, "MPATHa"); -+ check_bindings_size(1); -+ free(alias); - } - --static void al_lseek_err(void **state) -+static void al_write_short(void **state) - { -+ static const char ln[] = "MPATHa WWIDa\n"; - char *alias; - -- will_return(__wrap_lseek, -ENODEV); -- expect_condlog(0, "Cannot seek to end of bindings file : No such device\n"); -- alias = allocate_binding(0, "WWIDa", 1, "MPATH"); -+ expect_value(__wrap_write, count, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); -+ will_return(__wrap_write, ln); -+ will_return(__wrap_write, strlen(BINDINGS_FILE_HEADER) + strlen(ln) - 1); -+ expect_value(__wrap_write, count, 1); -+ will_return(__wrap_write, ln + sizeof(ln) - 2); -+ will_return(__wrap_write, 0); -+ expect_condlog(2, "write_bindings_file: short write"); -+ expect_condlog(1, "failed to write new bindings file"); -+ expect_condlog(1, "allocate_binding: deleting binding MPATHa for WWIDa"); -+ -+ alias = allocate_binding("foo", "WWIDa", 1, "MPATH"); - assert_ptr_equal(alias, NULL); -+ check_bindings_size(0); - } - - static void al_write_err(void **state) - { - static const char ln[] = "MPATHa WWIDa\n"; -- const int offset = 20; - char *alias; - -- will_return(__wrap_lseek, offset); -- expect_value(__wrap_write, count, strlen(ln)); -- expect_string(__wrap_write, buf, ln); -- will_return(__wrap_write, strlen(ln) - 1); -- expect_value(__wrap_ftruncate, length, offset); -- will_return(__wrap_ftruncate, 0); -- expect_condlog(0, "Cannot write binding to bindings file :"); -+ expect_value(__wrap_write, count, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); -+ will_return(__wrap_write, ln); -+ will_return(__wrap_write, -EPERM); -+ expect_condlog(1, "failed to write new bindings file"); -+ expect_condlog(1, "allocate_binding: deleting binding MPATHa for WWIDa"); - -- alias = allocate_binding(0, "WWIDa", 1, "MPATH"); -+ alias = allocate_binding("foo", "WWIDa", 1, "MPATH"); - assert_ptr_equal(alias, NULL); -+ check_bindings_size(0); -+} -+ -+static void al_rename_err(void **state) -+{ -+ static const char ln[] = "MPATHa WWIDa\n"; -+ char *alias; -+ -+ expect_value(__wrap_write, count, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); -+ will_return(__wrap_write, ln); -+ will_return(__wrap_write, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); -+ will_return(__wrap_rename, -EROFS); -+ -+ expect_condlog(0, "update_bindings_file: rename: Read-only file system"); -+ expect_condlog(1, "allocate_binding: deleting binding MPATHa for WWIDa"); -+ alias = allocate_binding("foo", "WWIDa", 1, "MPATH"); -+ assert_ptr_equal(alias, NULL); -+ check_bindings_size(0); - } - - static int test_allocate_binding(void) - { - const struct CMUnitTest tests[] = { -- cmocka_unit_test(al_a), -- cmocka_unit_test(al_zz), -- cmocka_unit_test(al_0), -- cmocka_unit_test(al_m2), -- cmocka_unit_test(al_lseek_err), -- cmocka_unit_test(al_write_err), -+ cmocka_unit_test_teardown(al_a, teardown_bindings), -+ cmocka_unit_test_teardown(al_zz, teardown_bindings), -+ cmocka_unit_test_teardown(al_0, teardown_bindings), -+ cmocka_unit_test_teardown(al_m2, teardown_bindings), -+ cmocka_unit_test_teardown(al_write_partial, teardown_bindings), -+ cmocka_unit_test_teardown(al_write_short, teardown_bindings), -+ cmocka_unit_test_teardown(al_write_err, teardown_bindings), -+ cmocka_unit_test_teardown(al_rename_err, teardown_bindings), - }; - - return cmocka_run_group_tests(tests, NULL, NULL); - } - --#define mock_allocate_binding(alias, wwid) \ -+#define mock_allocate_binding_err_len(alias, wwid, len, err, msg) \ - do { \ - static const char ln[] = BINDING_STR(alias, wwid); \ - \ -- will_return(__wrap_lseek, 0); \ -- expect_value(__wrap_write, count, strlen(ln)); \ -- expect_string(__wrap_write, buf, ln); \ -- will_return(__wrap_write, strlen(ln)); \ -- expect_condlog(3, NEW_STR(alias, wwid)); \ -+ expect_value(__wrap_write, count, \ -+ strlen(BINDINGS_FILE_HEADER) + (len) + strlen(ln)); \ -+ will_return(__wrap_write, ln); \ -+ will_return(__wrap_write, \ -+ strlen(BINDINGS_FILE_HEADER) + (len) + strlen(ln)); \ -+ will_return(__wrap_rename, err); \ -+ if (err == 0) { \ -+ expect_condlog(1, "updated bindings file x\n"); \ -+ expect_condlog(3, NEW_STR(alias, wwid)); \ -+ } else { \ -+ expect_condlog(0, "update_bindings_file: rename: " msg "\n"); \ -+ expect_condlog(1, "allocate_binding: deleting binding " \ -+ alias " for " wwid "\n"); \ -+ } \ - } while (0) - -+#define mock_allocate_binding_err(alias, wwid, err, msg) \ -+ mock_allocate_binding_err_len(alias, wwid, 0, err, msg) -+ -+#define mock_allocate_binding(alias, wwid) \ -+ mock_allocate_binding_err(alias, wwid, 0, "") -+ -+#define mock_allocate_binding_len(alias, wwid, len) \ -+ mock_allocate_binding_err_len(alias, wwid, len, 0, "") -+ - static void gufa_empty_new_rw(void **state) { - char *alias; - -- will_return(__wrap_open_file, true); -- -- mock_bindings_file("", -1); -+ mock_bindings_file(""); - mock_unused_alias("MPATHa"); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - -@@ -1208,10 +1487,11 @@ static void gufa_empty_new_rw(void **state) { - - static void gufa_empty_new_ro_1(void **state) { - char *alias; -- will_return(__wrap_open_file, false); -- mock_bindings_file("", -1); -+ -+ mock_bindings_file(""); - mock_unused_alias("MPATHa"); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); -+ mock_allocate_binding_err("MPATHa", "WWID0", -EROFS, "Read-only file system"); - - alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false); - assert_ptr_equal(alias, NULL); -@@ -1220,11 +1500,9 @@ static void gufa_empty_new_ro_1(void **state) { - static void gufa_empty_new_ro_2(void **state) { - char *alias; - -- will_return(__wrap_open_file, true); -- -- mock_bindings_file("", -1); -- mock_unused_alias("MPATHa"); -+ mock_bindings_file(""); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); -+ mock_unused_alias("MPATHa"); - - alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); - assert_ptr_equal(alias, NULL); -@@ -1233,11 +1511,10 @@ static void gufa_empty_new_ro_2(void **state) { - static void gufa_match_a_unused(void **state) { - char *alias; - -- will_return(__wrap_open_file, true); -- -- mock_bindings_file("MPATHa WWID0", 0); -+ mock_bindings_file("MPATHa WWID0"); - expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); - mock_unused_alias("MPATHa"); -+ expect_condlog(3, EXISTING_STR("MPATHa", "WWID0")); - - alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); - assert_string_equal(alias, "MPATHa"); -@@ -1247,11 +1524,10 @@ static void gufa_match_a_unused(void **state) { - static void gufa_match_a_self(void **state) { - char *alias; - -- will_return(__wrap_open_file, true); -- -- mock_bindings_file("MPATHa WWID0", 0); -+ mock_bindings_file("MPATHa WWID0"); - expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); - mock_self_alias("MPATHa", "WWID0"); -+ expect_condlog(3, EXISTING_STR("MPATHa", "WWID0")); - - alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); - assert_string_equal(alias, "MPATHa"); -@@ -1261,9 +1537,8 @@ static void gufa_match_a_self(void **state) { - static void gufa_match_a_used(void **state) { - char *alias; - -- will_return(__wrap_open_file, true); - -- mock_bindings_file("MPATHa WWID0", 0); -+ mock_bindings_file("MPATHa WWID0"); - expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); - mock_used_alias("MPATHa", "WWID0"); - -@@ -1273,15 +1548,14 @@ static void gufa_match_a_used(void **state) { - - static void gufa_nomatch_a_c(void **state) { - char *alias; -- will_return(__wrap_open_file, true); -+ static const char bindings[] = ("MPATHa WWID0\n" -+ "MPATHc WWID2\n"); - -- mock_bindings_file("MPATHa WWID0\n" -- "MPATHc WWID2", -- -1); -+ mock_bindings_file(bindings); - mock_unused_alias("MPATHb"); - expect_condlog(3, NOMATCH_WWID_STR("WWID1")); - -- mock_allocate_binding("MPATHb", "WWID1"); -+ mock_allocate_binding_len("MPATHb", "WWID1", strlen(bindings)); - - alias = get_user_friendly_alias("WWID1", "x", "", "MPATH", false); - assert_string_equal(alias, "MPATHb"); -@@ -1290,15 +1564,14 @@ static void gufa_nomatch_a_c(void **state) { - - static void gufa_nomatch_c_a(void **state) { - char *alias; -- will_return(__wrap_open_file, true); -+ const char bindings[] = ("MPATHc WWID2\n" -+ "MPATHa WWID0\n"); - -- mock_bindings_file("MPATHc WWID2\n" -- "MPATHa WWID0", -- -1); -+ mock_bindings_file(bindings); - mock_unused_alias("MPATHb"); - expect_condlog(3, NOMATCH_WWID_STR("WWID1")); - -- mock_allocate_binding("MPATHb", "WWID1"); -+ mock_allocate_binding_len("MPATHb", "WWID1", sizeof(bindings) - 1); - - alias = get_user_friendly_alias("WWID1", "x", "", "MPATH", false); - assert_string_equal(alias, "MPATHb"); -@@ -1307,15 +1580,14 @@ static void gufa_nomatch_c_a(void **state) { - - static void gufa_nomatch_c_b(void **state) { - char *alias; -- will_return(__wrap_open_file, true); -+ const char bindings[] = ("MPATHc WWID2\n" -+ "MPATHb WWID1\n"); - -- mock_bindings_file("MPATHc WWID2\n" -- "MPATHb WWID1\n", -- -1); -- mock_unused_alias("MPATHa"); -+ mock_bindings_file(bindings); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); -+ mock_unused_alias("MPATHa"); - -- mock_allocate_binding("MPATHa", "WWID0"); -+ mock_allocate_binding_len("MPATHa", "WWID0", sizeof(bindings) - 1); - - alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false); - assert_string_equal(alias, "MPATHa"); -@@ -1324,16 +1596,15 @@ static void gufa_nomatch_c_b(void **state) { - - static void gufa_nomatch_c_b_used(void **state) { - char *alias; -- will_return(__wrap_open_file, true); -+ const char bindings[] = ("MPATHc WWID2\n" -+ "MPATHb WWID1\n"); - -- mock_bindings_file("MPATHc WWID2\n" -- "MPATHb WWID1", -- -1); -- mock_used_alias("MPATHa", "WWID4"); -+ mock_bindings_file(bindings); - expect_condlog(3, NOMATCH_WWID_STR("WWID4")); -+ mock_used_alias("MPATHa", "WWID4"); - mock_unused_alias("MPATHd"); - -- mock_allocate_binding("MPATHd", "WWID4"); -+ mock_allocate_binding_len("MPATHd", "WWID4", sizeof(bindings) - 1); - - alias = get_user_friendly_alias("WWID4", "x", "", "MPATH", false); - assert_string_equal(alias, "MPATHd"); -@@ -1342,32 +1613,59 @@ static void gufa_nomatch_c_b_used(void **state) { - - static void gufa_nomatch_b_f_a(void **state) { - char *alias; -- will_return(__wrap_open_file, true); -+ const char bindings[] = ("MPATHb WWID1\n" -+ "MPATHf WWID6\n" -+ "MPATHa WWID0\n"); - -- mock_bindings_file("MPATHb WWID1\n" -- "MPATHf WWID6\n" -- "MPATHa WWID0\n", -- -1); -+ mock_bindings_file_unsorted(bindings); - expect_condlog(3, NOMATCH_WWID_STR("WWID7")); - mock_unused_alias("MPATHg"); - -- mock_allocate_binding("MPATHg", "WWID7"); -+ mock_allocate_binding_len("MPATHg", "WWID7", sizeof(bindings) - 1); - - alias = get_user_friendly_alias("WWID7", "x", "", "MPATH", false); - assert_string_equal(alias, "MPATHg"); - free(alias); - } - -+static void gufa_nomatch_b_aa_a(void **state) { -+ char *alias; -+ STRBUF_ON_STACK(buf); -+ -+ fill_bindings(&buf, 0, 26); -+ mock_bindings_file(get_strbuf_str(&buf)); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID28")); -+ mock_unused_alias("MPATHab"); -+ mock_allocate_binding_len("MPATHab", "WWID28", get_strbuf_len(&buf)); -+ -+ alias = get_user_friendly_alias("WWID28", "x", "", "MPATH", false); -+ assert_string_equal(alias, "MPATHab"); -+ free(alias); -+} -+ -+static void gufa_nomatch_b_f_a_sorted(void **state) { -+ char *alias; -+ const char bindings[] = ("MPATHb WWID1\n" -+ "MPATHf WWID6\n" -+ "MPATHa WWID0\n"); -+ -+ mock_bindings_file(bindings); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID7")); -+ mock_unused_alias("MPATHc"); -+ -+ mock_allocate_binding_len("MPATHc", "WWID7", sizeof(bindings) - 1); -+ -+ alias = get_user_friendly_alias("WWID7", "x", "", "MPATH", false); -+ assert_string_equal(alias, "MPATHc"); -+ free(alias); -+} -+ - static void gufa_old_empty(void **state) { - char *alias; -- will_return(__wrap_open_file, true); - - /* rlookup_binding for ALIAS */ -- mock_bindings_file("", -1); -+ mock_bindings_file(""); - expect_condlog(3, NOMATCH_STR("MPATHz")); -- -- /* lookup_binding */ -- mock_bindings_file("", -1); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - - mock_allocate_binding("MPATHz", "WWID0"); -@@ -1380,11 +1678,9 @@ static void gufa_old_empty(void **state) { - - static void gufa_old_match(void **state) { - char *alias; -- will_return(__wrap_open_file, true); - - mock_bindings_file("MPATHb WWID1\n" -- "MPATHz WWID0", -- 1); -+ "MPATHz WWID0"); - expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID0")); - - alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); -@@ -1394,19 +1690,15 @@ static void gufa_old_match(void **state) { - - static void gufa_old_match_other(void **state) { - char *alias; -- static const char bindings[] = "MPATHz WWID9"; -- -- will_return(__wrap_open_file, true); -+ static const char bindings[] = "MPATHz WWID9\n"; - -- mock_bindings_file(bindings, 0); -+ mock_bindings_file(bindings); - expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID9")); - expect_condlog(0, REUSE_STR("MPATHz", "WWID9")); -- -- mock_bindings_file(bindings, -1); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - mock_unused_alias("MPATHa"); - -- mock_allocate_binding("MPATHa", "WWID0"); -+ mock_allocate_binding_len("MPATHa", "WWID0", sizeof(bindings) - 1); - - alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); - assert_string_equal(alias, "MPATHa"); -@@ -1415,21 +1707,16 @@ static void gufa_old_match_other(void **state) { - - static void gufa_old_match_other_used(void **state) { - char *alias; -- static const char bindings[] = "MPATHz WWID9"; -+ static const char bindings[] = "MPATHz WWID9\n"; - -- will_return(__wrap_open_file, true); -- -- mock_bindings_file(bindings, 0); -+ mock_bindings_file(bindings); - expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID9")); - expect_condlog(0, REUSE_STR("MPATHz", "WWID9")); -- -- mock_bindings_file(bindings, -1); -- mock_used_alias("MPATHa", "WWID0"); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); -+ mock_used_alias("MPATHa", "WWID0"); - mock_unused_alias("MPATHb"); - -- mock_allocate_binding("MPATHb", "WWID0"); -- -+ mock_allocate_binding_len("MPATHb", "WWID0", sizeof(bindings) - 1); - alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); - assert_string_equal(alias, "MPATHb"); - free(alias); -@@ -1439,15 +1726,13 @@ static void gufa_old_match_other_wwidmatch(void **state) { - char *alias; - static const char bindings[] = ("MPATHz WWID9\n" - "MPATHc WWID2"); -- will_return(__wrap_open_file, true); - -- mock_bindings_file(bindings, 0); -+ mock_bindings_file(bindings); - expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID9")); - expect_condlog(0, REUSE_STR("MPATHz", "WWID9")); -- -- mock_bindings_file(bindings, 1); - expect_condlog(3, FOUND_STR("MPATHc", "WWID2")); - mock_unused_alias("MPATHc"); -+ expect_condlog(3, EXISTING_STR("MPATHc", "WWID2")); - - alias = get_user_friendly_alias("WWID2", "x", "MPATHz", "MPATH", false); - assert_string_equal(alias, "MPATHc"); -@@ -1459,13 +1744,9 @@ static void gufa_old_match_other_wwidmatch_used(void **state) { - static const char bindings[] = ("MPATHz WWID9\n" - "MPATHc WWID2"); - -- will_return(__wrap_open_file, true); -- -- mock_bindings_file(bindings, 0); -+ mock_bindings_file(bindings); - expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID9")); - expect_condlog(0, REUSE_STR("MPATHz", "WWID9")); -- -- mock_bindings_file(bindings, 1); - expect_condlog(3, FOUND_STR("MPATHc", "WWID2")); - mock_used_alias("MPATHc", "WWID2"); - -@@ -1477,12 +1758,8 @@ static void gufa_old_nomatch_wwidmatch(void **state) { - char *alias; - static const char bindings[] = "MPATHa WWID0"; - -- will_return(__wrap_open_file, true); -- -- mock_bindings_file(bindings, -1); -+ mock_bindings_file(bindings); - expect_condlog(3, NOMATCH_STR("MPATHz")); -- -- mock_bindings_file(bindings, 0); - expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); - mock_unused_alias("MPATHa"); - expect_condlog(3, EXISTING_STR("MPATHa", "WWID0")); -@@ -1495,12 +1772,9 @@ static void gufa_old_nomatch_wwidmatch(void **state) { - static void gufa_old_nomatch_wwidmatch_used(void **state) { - char *alias; - static const char bindings[] = "MPATHa WWID0"; -- will_return(__wrap_open_file, true); - -- mock_bindings_file(bindings, -1); -+ mock_bindings_file(bindings); - expect_condlog(3, NOMATCH_STR("MPATHz")); -- -- mock_bindings_file(bindings, 0); - expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); - mock_used_alias("MPATHa", "WWID0"); - -@@ -1510,17 +1784,13 @@ static void gufa_old_nomatch_wwidmatch_used(void **state) { - - static void gufa_old_nomatch_nowwidmatch(void **state) { - char *alias; -- static const char bindings[] = "MPATHb WWID1"; -- -- will_return(__wrap_open_file, true); -+ static const char bindings[] = "MPATHb WWID1\n"; - -- mock_bindings_file(bindings, -1); -+ mock_bindings_file(bindings); - expect_condlog(3, NOMATCH_STR("MPATHz")); -- -- mock_bindings_file(bindings, -1); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - -- mock_allocate_binding("MPATHz", "WWID0"); -+ mock_allocate_binding_len("MPATHz", "WWID0", sizeof(bindings) - 1); - expect_condlog(2, ALLOC_STR("MPATHz", "WWID0")); - - alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); -@@ -1531,26 +1801,28 @@ static void gufa_old_nomatch_nowwidmatch(void **state) { - static int test_get_user_friendly_alias() - { - const struct CMUnitTest tests[] = { -- cmocka_unit_test(gufa_empty_new_rw), -- cmocka_unit_test(gufa_empty_new_ro_1), -- cmocka_unit_test(gufa_empty_new_ro_2), -- cmocka_unit_test(gufa_match_a_unused), -- cmocka_unit_test(gufa_match_a_self), -- cmocka_unit_test(gufa_match_a_used), -- cmocka_unit_test(gufa_nomatch_a_c), -- cmocka_unit_test(gufa_nomatch_c_a), -- cmocka_unit_test(gufa_nomatch_c_b), -- cmocka_unit_test(gufa_nomatch_c_b_used), -- cmocka_unit_test(gufa_nomatch_b_f_a), -- cmocka_unit_test(gufa_old_empty), -- cmocka_unit_test(gufa_old_match), -- cmocka_unit_test(gufa_old_match_other), -- cmocka_unit_test(gufa_old_match_other_used), -- cmocka_unit_test(gufa_old_match_other_wwidmatch), -- cmocka_unit_test(gufa_old_match_other_wwidmatch_used), -- cmocka_unit_test(gufa_old_nomatch_wwidmatch), -- cmocka_unit_test(gufa_old_nomatch_wwidmatch_used), -- cmocka_unit_test(gufa_old_nomatch_nowwidmatch), -+ cmocka_unit_test_teardown(gufa_empty_new_rw, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_empty_new_ro_1, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_empty_new_ro_2, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_match_a_unused, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_match_a_self, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_match_a_used, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_nomatch_a_c, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_nomatch_c_a, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_nomatch_c_b, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_nomatch_c_b_used, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_nomatch_b_f_a, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_nomatch_b_aa_a, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_nomatch_b_f_a_sorted, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_old_empty, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_old_match, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_old_match_other, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_old_match_other_used, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_old_match_other_wwidmatch, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_old_match_other_wwidmatch_used, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_old_nomatch_wwidmatch, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_old_nomatch_wwidmatch_used, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_old_nomatch_nowwidmatch, teardown_bindings), - }; - - return cmocka_run_group_tests(tests, NULL, NULL); -@@ -1566,7 +1838,6 @@ int main(void) - ret += test_lookup_binding(); - ret += test_rlookup_binding(); - ret += test_allocate_binding(); -- ret += test_allocate_binding(); - ret += test_get_user_friendly_alias(); - - return ret; diff --git a/0020-libmultipath-dm_get_uuid-return-emtpy-UUID-for-non-e.patch b/0020-libmultipath-dm_get_uuid-return-emtpy-UUID-for-non-e.patch deleted file mode 100644 index c105b01..0000000 --- a/0020-libmultipath-dm_get_uuid-return-emtpy-UUID-for-non-e.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 25 Aug 2023 20:35:19 +0200 -Subject: [PATCH] libmultipath: dm_get_uuid(): return emtpy UUID for - non-existing maps - -libdevmapper will most probably not return a UUID for non-existing -maps anyway. But it's cheap to double-check here. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/devmapper.c | 10 ++++++++-- - 1 file changed, 8 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index 248c3734..9be82f4e 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -706,12 +706,16 @@ dm_get_prefixed_uuid(const char *name, char *uuid, int uuid_len) - { - struct dm_task *dmt; - const char *uuidtmp; -+ struct dm_info info; - int r = 1; - - dmt = libmp_dm_task_create(DM_DEVICE_INFO); - if (!dmt) - return 1; - -+ if (uuid_len > 0) -+ uuid[0] = '\0'; -+ - if (!dm_task_set_name (dmt, name)) - goto uuidout; - -@@ -720,11 +724,13 @@ dm_get_prefixed_uuid(const char *name, char *uuid, int uuid_len) - goto uuidout; - } - -+ if (!dm_task_get_info(dmt, &info) || -+ !info.exists) -+ goto uuidout; -+ - uuidtmp = dm_task_get_uuid(dmt); - if (uuidtmp) - strlcpy(uuid, uuidtmp, uuid_len); -- else -- uuid[0] = '\0'; - - r = 0; - uuidout: diff --git a/0021-libmultipath-adapt-to-new-semantics-of-dm_get_uuid.patch b/0021-libmultipath-adapt-to-new-semantics-of-dm_get_uuid.patch deleted file mode 100644 index 4d15554..0000000 --- a/0021-libmultipath-adapt-to-new-semantics-of-dm_get_uuid.patch +++ /dev/null @@ -1,158 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 28 Aug 2023 12:26:37 +0200 -Subject: [PATCH] libmultipath: adapt to new semantics of dm_get_uuid() - -dm_get_uuid() will return 1 for non-existing maps. Thus we don't need -to call dm_map_present() any more in alias_already_taken(). This changes -our semantics: previously we'd avoid using an alias for which dm_get_uuid() -had failed. Now we treat failure in dm_get_uuid() as indication that the -map doesn't exist. This is not dangerous because dm_task_get_uuid() cannot -fail, and thus the modified dm_get_uuid() will fail if and only if -dm_map_present() would return false. - -This makes the "failed alias" test mostly obsolete, as "failed" is now -treated as "unused". - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/alias.c | 25 +++++++++++++------------ - tests/alias.c | 32 +++++++------------------------- - 2 files changed, 20 insertions(+), 37 deletions(-) - -diff --git a/libmultipath/alias.c b/libmultipath/alias.c -index d6563749..58436ec0 100644 ---- a/libmultipath/alias.c -+++ b/libmultipath/alias.c -@@ -295,18 +295,19 @@ scan_devname(const char *alias, const char *prefix) - static bool alias_already_taken(const char *alias, const char *map_wwid) - { - -- if (dm_map_present(alias)) { -- char wwid[WWID_SIZE]; -- -- /* If both the name and the wwid match, then it's fine.*/ -- if (dm_get_uuid(alias, wwid, sizeof(wwid)) == 0 && -- strncmp(map_wwid, wwid, sizeof(wwid)) == 0) -- return false; -- condlog(3, "%s: alias '%s' already taken, reselecting alias", -- map_wwid, alias); -- return true; -- } -- return false; -+ char wwid[WWID_SIZE]; -+ -+ /* If the map doesn't exist, it's fine */ -+ if (dm_get_uuid(alias, wwid, sizeof(wwid)) != 0) -+ return false; -+ -+ /* If both the name and the wwid match, it's fine.*/ -+ if (strncmp(map_wwid, wwid, sizeof(wwid)) == 0) -+ return false; -+ -+ condlog(3, "%s: alias '%s' already taken, reselecting alias", -+ map_wwid, alias); -+ return true; - } - - static bool id_already_taken(int id, const char *prefix, const char *map_wwid) -diff --git a/tests/alias.c b/tests/alias.c -index 50a21ecf..d1cc487b 100644 ---- a/tests/alias.c -+++ b/tests/alias.c -@@ -73,12 +73,6 @@ int __wrap_mkstemp(char *template) - return 10; - } - --int __wrap_dm_map_present(const char * str) --{ -- check_expected(str); -- return mock_type(int); --} -- - int __wrap_dm_get_uuid(const char *name, char *uuid, int uuid_len) - { - int ret; -@@ -398,14 +392,13 @@ static int test_scan_devname(void) - - static void mock_unused_alias(const char *alias) - { -- expect_string(__wrap_dm_map_present, str, alias); -- will_return(__wrap_dm_map_present, 0); -+ expect_string(__wrap_dm_get_uuid, name, alias); -+ expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); -+ will_return(__wrap_dm_get_uuid, 1); - } - - static void mock_self_alias(const char *alias, const char *wwid) - { -- expect_string(__wrap_dm_map_present, str, alias); -- will_return(__wrap_dm_map_present, 1); - expect_string(__wrap_dm_get_uuid, name, alias); - expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); - will_return(__wrap_dm_get_uuid, 0); -@@ -432,18 +425,13 @@ static void mock_self_alias(const char *alias, const char *wwid) - - #define mock_failed_alias(alias, wwid) \ - do { \ -- expect_string(__wrap_dm_map_present, str, alias); \ -- will_return(__wrap_dm_map_present, 1); \ - expect_string(__wrap_dm_get_uuid, name, alias); \ - expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); \ - will_return(__wrap_dm_get_uuid, 1); \ -- expect_condlog(3, USED_STR(alias, wwid)); \ - } while (0) - - #define mock_used_alias(alias, wwid) \ - do { \ -- expect_string(__wrap_dm_map_present, str, alias); \ -- will_return(__wrap_dm_map_present, 1); \ - expect_string(__wrap_dm_get_uuid, name, alias); \ - expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); \ - will_return(__wrap_dm_get_uuid, 0); \ -@@ -566,9 +554,8 @@ static void lb_empty_failed(void **state) - mock_bindings_file(""); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - mock_failed_alias("MPATHa", "WWID0"); -- mock_unused_alias("MPATHb"); - rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); -- assert_int_equal(rc, 2); -+ assert_int_equal(rc, 1); - assert_ptr_equal(alias, NULL); - free(alias); - } -@@ -666,9 +653,8 @@ static void lb_nomatch_a_3_used_failed_self(void **state) - mock_used_alias("MPATHc", "WWID1"); - mock_used_alias("MPATHd", "WWID1"); - mock_failed_alias("MPATHe", "WWID1"); -- mock_self_alias("MPATHf", "WWID1"); - rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1); -- assert_int_equal(rc, 6); -+ assert_int_equal(rc, 5); - assert_ptr_equal(alias, NULL); - } - -@@ -940,7 +926,7 @@ static void lb_nomatch_b_a_aa(void **state) - - static void lb_nomatch_b_a_aa_zz(void **state) - { -- int rc, i; -+ int rc; - char *alias; - STRBUF_ON_STACK(buf); - -@@ -949,11 +935,7 @@ static void lb_nomatch_b_a_aa_zz(void **state) - * lookup_binding finds MPATHaaa as next free entry, because MPATHaa is - * found before MPATHb, and MPATHzz was in the bindings, too. - */ -- for (i = 0; i <= 26; i++) { -- print_strbuf(&buf, "MPATH"); -- format_devname(&buf, i + 1); -- print_strbuf(&buf, " WWID%d\n", i); -- } -+ fill_bindings(&buf, 0, 26); - print_strbuf(&buf, "MPATHzz WWID676\n"); - mock_bindings_file(get_strbuf_str(&buf)); - expect_condlog(3, NOMATCH_WWID_STR("WWID703")); diff --git a/0022-libmultipath-sort-aliases-by-length-and-strcmp.patch b/0022-libmultipath-sort-aliases-by-length-and-strcmp.patch deleted file mode 100644 index 1504bec..0000000 --- a/0022-libmultipath-sort-aliases-by-length-and-strcmp.patch +++ /dev/null @@ -1,98 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 8 Sep 2023 15:19:54 +0200 -Subject: [PATCH] libmultipath: sort aliases by length and strcmp - -The current sort order of aliases is alphabetical, which is does not match -the actual order of aliases, where "mpathaa" > "mpathz". Change the ordering as -follows: first sort by string length, then alphabetically. This will make -sure that for aliases with the same prefix, alias order is correct ("mpathaaa" -will be sorted after "mpathzz", etc). Even for mixed prefixes, the alias -order will be correct for every individual prefix, even though aliases with -different prefixes may alternate in the file. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/alias.c | 45 +++++++++++++++++++++++++++++++++----------- - 1 file changed, 34 insertions(+), 11 deletions(-) - -diff --git a/libmultipath/alias.c b/libmultipath/alias.c -index 58436ec0..af6565b1 100644 ---- a/libmultipath/alias.c -+++ b/libmultipath/alias.c -@@ -117,6 +117,35 @@ static const struct binding *get_binding_for_wwid(const Bindings *bindings, - return NULL; - } - -+/* -+ * Sort order for aliases. -+ * -+ * The "numeric" ordering of aliases for a given prefix P is -+ * Pa, ..., Pz, Paa, ..., Paz, Pba, ... , Pzz, Paaa, ..., Pzzz, Paaaa, ... -+ * We use the fact that for equal prefix, longer strings are always -+ * higher than shorter ones. Strings of equal length are sorted alphabetically. -+ * This is achieved by sorting be length first, then using strcmp(). -+ * If multiple prefixes are in use, the aliases with a given prefix will -+ * not necessarily be in a contiguous range of the vector, but they will -+ * be ordered such that for a given prefix, numercally higher aliases will -+ * always be sorted after lower ones. -+ */ -+static int alias_compar(const void *p1, const void *p2) -+{ -+ const char *alias1 = *((char * const *)p1); -+ const char *alias2 = *((char * const *)p2); -+ -+ if (alias1 && alias2) { -+ ssize_t ldif = strlen(alias1) - strlen(alias2); -+ -+ if (ldif) -+ return ldif; -+ return strcmp(alias1, alias2); -+ } else -+ /* Move NULL alias to the end */ -+ return alias1 ? -1 : alias2 ? 1 : 0; -+} -+ - static int add_binding(Bindings *bindings, const char *alias, const char *wwid) - { - struct binding *bdg; -@@ -128,7 +157,7 @@ static int add_binding(Bindings *bindings, const char *alias, const char *wwid) - * sorted already. - */ - vector_foreach_slot_backwards(bindings, bdg, i) { -- if ((cmp = strcmp(bdg->alias, alias)) <= 0) -+ if ((cmp = alias_compar(&bdg->alias, &alias)) <= 0) - break; - } - -@@ -657,16 +686,10 @@ static int _check_bindings_file(const struct config *conf, FILE *file, - return rc; - } - --static int alias_compar(const void *p1, const void *p2) -+static int mp_alias_compar(const void *p1, const void *p2) - { -- const char *alias1 = (*(struct mpentry * const *)p1)->alias; -- const char *alias2 = (*(struct mpentry * const *)p2)->alias; -- -- if (alias1 && alias2) -- return strcmp(alias1, alias2); -- else -- /* Move NULL alias to the end */ -- return alias1 ? -1 : alias2 ? 1 : 0; -+ return alias_compar(&((*(struct mpentry * const *)p1)->alias), -+ &((*(struct mpentry * const *)p2)->alias)); - } - - /* -@@ -700,7 +723,7 @@ int check_alias_settings(const struct config *conf) - pthread_cleanup_push_cast(free_bindings, &bindings); - pthread_cleanup_push(cleanup_vector_free, mptable); - -- vector_sort(mptable, alias_compar); -+ vector_sort(mptable, mp_alias_compar); - vector_foreach_slot(mptable, mpe, i) { - if (!mpe->alias) - /* diff --git a/0023-multipath-tools-tests-fix-alias-test-after-sort-orde.patch b/0023-multipath-tools-tests-fix-alias-test-after-sort-orde.patch deleted file mode 100644 index dd0f29d..0000000 --- a/0023-multipath-tools-tests-fix-alias-test-after-sort-orde.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 8 Sep 2023 15:46:02 +0200 -Subject: [PATCH] multipath-tools tests: fix alias test after sort order change - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - tests/alias.c | 30 ++++++++++++------------------ - 1 file changed, 12 insertions(+), 18 deletions(-) - -diff --git a/tests/alias.c b/tests/alias.c -index d1cc487b..8ed95d7a 100644 ---- a/tests/alias.c -+++ b/tests/alias.c -@@ -932,16 +932,15 @@ static void lb_nomatch_b_a_aa_zz(void **state) - - /* - * add_bindings() sorts alphabetically. ("a", "aa", "ab", "b", "c", ...) -- * lookup_binding finds MPATHaaa as next free entry, because MPATHaa is -- * found before MPATHb, and MPATHzz was in the bindings, too. -+ * lookup_binding finds MPATHab as next free entry. - */ - fill_bindings(&buf, 0, 26); - print_strbuf(&buf, "MPATHzz WWID676\n"); - mock_bindings_file(get_strbuf_str(&buf)); - expect_condlog(3, NOMATCH_WWID_STR("WWID703")); -- mock_unused_alias("MPATHaaa"); -+ mock_unused_alias("MPATHab"); - rc = lookup_binding(NULL, "WWID703", &alias, "MPATH", 1); -- assert_int_equal(rc, 703); -+ assert_int_equal(rc, 28); - assert_ptr_equal(alias, NULL); - } - -@@ -998,13 +997,8 @@ static void lb_nomatch_b_a_3_used(void **state) - - #ifdef MPATH_ID_INT_MAX - /* -- * The bindings will be sorted by alias, alphabetically, which is not -- * the same as the "numeric" sort order for user-friendly aliases. -- * get_free_id() selects the highest used ID + 1 if an unsorted entry -- * is encountered in the bindings table and it's id is equal to the -- * next "expected" id. This happens if all IDs from "a" to "aa" are -- * in the table. If the INT_MAX entry is in the table, too, it will -- * overflow. -+ * The bindings will be sorted by alias. Therefore we have no chance to -+ * simulate a "full" table. - */ - static void lb_nomatch_int_max(void **state) - { -@@ -1016,9 +1010,9 @@ static void lb_nomatch_int_max(void **state) - print_strbuf(&buf, "MPATH%s WWIDMAX\n", MPATH_ID_INT_MAX); - mock_bindings_file(get_strbuf_str(&buf)); - expect_condlog(3, NOMATCH_WWID_STR("WWIDNOMORE")); -- expect_condlog(0, NOMORE_STR); -+ mock_unused_alias("MPATHab"); - rc = lookup_binding(NULL, "WWIDNOMORE", &alias, "MPATH", 1); -- assert_int_equal(rc, -1); -+ assert_int_equal(rc, 28); - assert_ptr_equal(alias, NULL); - } - -@@ -1049,9 +1043,9 @@ static void lb_nomatch_int_max_m1(void **state) - print_strbuf(&buf, "MPATH%s WWIDMAXM1\n", MPATH_ID_INT_MAX_m1); - mock_bindings_file(get_strbuf_str(&buf)); - expect_condlog(3, NOMATCH_WWID_STR("WWIDMAX")); -- mock_unused_alias("MPATH" MPATH_ID_INT_MAX); -+ mock_unused_alias("MPATHab"); - rc = lookup_binding(NULL, "WWIDMAX", &alias, "MPATH", 1); -- assert_int_equal(rc, INT_MAX); -+ assert_int_equal(rc, 28); - assert_ptr_equal(alias, NULL); - } - -@@ -1065,10 +1059,10 @@ static void lb_nomatch_int_max_m1_used(void **state) - print_strbuf(&buf, "MPATH%s WWIDMAXM1\n", MPATH_ID_INT_MAX_m1); - mock_bindings_file(get_strbuf_str(&buf)); - expect_condlog(3, NOMATCH_WWID_STR("WWIDMAX")); -- mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWIDMAX"); -- expect_condlog(0, NOMORE_STR); -+ mock_used_alias("MPATHab", "WWIDMAX"); -+ mock_unused_alias("MPATHac"); - rc = lookup_binding(NULL, "WWIDMAX", &alias, "MPATH", 1); -- assert_int_equal(rc, -1); -+ assert_int_equal(rc, 29); - assert_ptr_equal(alias, NULL); - } - diff --git a/0024-libmultipath-simplify-get_free_id-assuming-total-ord.patch b/0024-libmultipath-simplify-get_free_id-assuming-total-ord.patch deleted file mode 100644 index b16b3da..0000000 --- a/0024-libmultipath-simplify-get_free_id-assuming-total-ord.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 8 Sep 2023 19:50:51 +0200 -Subject: [PATCH] libmultipath: simplify get_free_id() assuming total ordering - -If we can assume that the bindings array is totally ordered for every -prefix, which the previous patch guarantees, the search for a free ID can be -simplified. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/alias.c | 85 ++++++++++---------------------------------- - 1 file changed, 18 insertions(+), 67 deletions(-) - -diff --git a/libmultipath/alias.c b/libmultipath/alias.c -index af6565b1..66e34e31 100644 ---- a/libmultipath/alias.c -+++ b/libmultipath/alias.c -@@ -356,83 +356,34 @@ int get_free_id(const Bindings *bindings, const char *prefix, const char *map_ww - { - const struct binding *bdg; - int i, id = 1; -- int biggest_id = 1; -- int smallest_bigger_id = INT_MAX; - - vector_foreach_slot(bindings, bdg, i) { - int curr_id = scan_devname(bdg->alias, prefix); - -- /* -- * Find an unused index - explanation of the algorithm -- * -- * ID: 1 = mpatha, 2 = mpathb, ... -- * -- * We assume the bindings are unsorted. The only constraint -- * is that no ID occurs more than once. IDs that occur in the -- * bindings are called "used". -- * -- * We call the list 1,2,3,..., exactly in this order, the list -- * of "expected" IDs. The variable "id" always holds the next -- * "expected" ID, IOW the last "expected" ID encountered plus 1. -- * Thus all IDs below "id" are known to be used. However, at the -- * end of the loop, the value of "id" isn't necessarily unused. -- * -- * "smallest_bigger_id" is the smallest used ID that was -- * encountered while it was larger than the next "expected" ID -- * at that iteration. Let X be some used ID. If all IDs below X -- * are used and encountered in the right sequence before X, "id" -- * will be > X when the loop ends. Otherwise, X was encountered -- * "out of order", the condition (X > id) holds when X is -- * encountered, and "smallest_bigger_id" will be set to X; i.e. -- * it will be less or equal than X when the loop ends. -- * -- * At the end of the loop, (id < smallest_bigger_id) means that -- * the value of "id" had been encountered neither in order nor -- * out of order, and is thus unused. (id >= smallest_bigger_id) -- * means that "id"'s value is in use. In this case, we play safe -- * and use "biggest_id + 1" as the next value to try. -- * -- * biggest_id is always > smallest_bigger_id, except in the -- * "perfectly ordered" case. -- */ -- if (curr_id == id) { -- if (id < INT_MAX) -- id++; -- else { -- id = -1; -- break; -- } -+ if (curr_id == -1) -+ continue; -+ if (id > curr_id) { -+ condlog(0, "%s: ERROR: bindings are not sorted", __func__); -+ return -1; - } -- if (curr_id > biggest_id) -- biggest_id = curr_id; -- -- if (curr_id > id && curr_id < smallest_bigger_id) -- smallest_bigger_id = curr_id; -+ while (id < curr_id && id_already_taken(id, prefix, map_wwid)) -+ id++; -+ if (id < curr_id) -+ return id; -+ id++; -+ if (id <= 0) -+ break; - } - -- if (id >= smallest_bigger_id) -- id = biggest_id < INT_MAX ? biggest_id + 1 : -1; -- -- if (id > 0) { -- while(id_already_taken(id, prefix, map_wwid)) { -- if (id == INT_MAX) { -- id = -1; -- break; -- } -- id++; -- if (id == smallest_bigger_id) { -- if (biggest_id == INT_MAX) { -- id = -1; -- break; -- } -- if (biggest_id >= smallest_bigger_id) -- id = biggest_id + 1; -- } -- } -+ for (; id > 0; id++) { -+ if (!id_already_taken(id, prefix, map_wwid)) -+ break; - } - -- if (id < 0) -+ if (id <= 0) { -+ id = -1; - condlog(0, "no more available user_friendly_names"); -+ } - return id; - } - diff --git a/0025-multipath-tools-tests-adapt-alias-tests-for-total-or.patch b/0025-multipath-tools-tests-adapt-alias-tests-for-total-or.patch deleted file mode 100644 index b1d6b15..0000000 --- a/0025-multipath-tools-tests-adapt-alias-tests-for-total-or.patch +++ /dev/null @@ -1,203 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 8 Sep 2023 19:58:03 +0200 -Subject: [PATCH] multipath-tools tests: adapt alias tests for total ordering - -The "unsorted" test fail now, and are removed. The algorithm is now -better at finding "gaps". - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - tests/alias.c | 88 ++++++++------------------------------------------- - 1 file changed, 14 insertions(+), 74 deletions(-) - -diff --git a/tests/alias.c b/tests/alias.c -index 8ed95d7a..dff5f93b 100644 ---- a/tests/alias.c -+++ b/tests/alias.c -@@ -439,27 +439,7 @@ static void mock_self_alias(const char *alias, const char *wwid) - expect_condlog(3, USED_STR(alias, wwid)); \ - } while(0) - --static int add_binding_unsorted(Bindings *bindings, -- const char *alias, const char *wwid) --{ -- struct binding *bdg = calloc(1, sizeof(*bdg)); -- -- if (!bdg) -- return -1; -- bdg->wwid = strdup(wwid); -- bdg->alias = strdup(alias); -- if (!bdg->wwid || !bdg->alias || !vector_alloc_slot(bindings)) { -- free(bdg->alias); -- free(bdg->wwid); -- free(bdg); -- return BINDING_ERROR; -- } -- vector_set_slot(bindings, bdg); -- return BINDING_ADDED; --} -- --static void __mock_bindings_file(const char *content, -- int (*add)(Bindings *, const char *, const char *)) -+static void __mock_bindings_file(const char *content) - { - char *cnt __attribute__((cleanup(cleanup_charp))) = NULL; - char *token, *savep = NULL; -@@ -478,17 +458,13 @@ static void __mock_bindings_file(const char *content, - == READ_BINDING_SKIP) - continue; - -- rc = add(&global_bindings, alias, wwid); -+ rc = add_binding(&global_bindings, alias, wwid); - assert_int_equal(rc, BINDING_ADDED); - } - } - - static void mock_bindings_file(const char *content) { -- return __mock_bindings_file(content, add_binding); --} -- --static void mock_bindings_file_unsorted(const char *content) { -- return __mock_bindings_file(content, add_binding_unsorted); -+ return __mock_bindings_file(content); - } - - static int teardown_bindings(void **state) -@@ -861,10 +837,6 @@ static void lb_nomatch_b_z_a(void **state) - int rc; - char *alias; - -- /* -- * add_bindings() sorts alphabetically. Therefore get_free_id() -- * finds MPATHc as a free entry. -- */ - mock_bindings_file("MPATHb WWID1\n" - "MPATHz WWID26\n" - "MPATHa WWID0\n"); -@@ -880,10 +852,6 @@ static void lb_nomatch_b_aa_a(void **state) - int rc; - char *alias; - -- /* -- * add_bindings() sorts alphabetically. ("a", "aa", b"). -- * The get_free_id() algorithm finds the "hole" after "b". -- */ - mock_bindings_file("MPATHb WWID1\n" - "MPATHz WWID26\n" - "MPATHa WWID0\n"); -@@ -911,10 +879,6 @@ static void lb_nomatch_b_a_aa(void **state) - char *alias; - STRBUF_ON_STACK(buf); - -- /* -- * add_bindings() sorts alphabetically. ("a", "aa", "ab", "b", "c", ...) -- * lookup_binding finds MPATHac as next free entry. -- */ - fill_bindings(&buf, 0, 26); - mock_bindings_file(get_strbuf_str(&buf)); - expect_condlog(3, NOMATCH_WWID_STR("WWID28")); -@@ -930,10 +894,6 @@ static void lb_nomatch_b_a_aa_zz(void **state) - char *alias; - STRBUF_ON_STACK(buf); - -- /* -- * add_bindings() sorts alphabetically. ("a", "aa", "ab", "b", "c", ...) -- * lookup_binding finds MPATHab as next free entry. -- */ - fill_bindings(&buf, 0, 26); - print_strbuf(&buf, "MPATHzz WWID676\n"); - mock_bindings_file(get_strbuf_str(&buf)); -@@ -944,25 +904,6 @@ static void lb_nomatch_b_a_aa_zz(void **state) - assert_ptr_equal(alias, NULL); - } - --static void lb_nomatch_b_z_a_unsorted(void **state) --{ -- int rc; -- char *alias; -- -- /* -- * With unsorted bindings (shouldn't happen normally), get_free_id() -- * plays safe and returns MPATHaa as first free entry. -- */ -- mock_bindings_file_unsorted("MPATHb WWID1\n" -- "MPATHz WWID26\n" -- "MPATHa WWID0\n"); -- expect_condlog(3, NOMATCH_WWID_STR("WWID2")); -- mock_unused_alias("MPATHaa"); -- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -- assert_int_equal(rc, 27); -- assert_ptr_equal(alias, NULL); --} -- - static void lb_nomatch_b_a(void **state) - { - int rc; -@@ -1027,9 +968,9 @@ static void lb_nomatch_int_max_used(void **state) - mock_bindings_file(get_strbuf_str(&buf)); - expect_condlog(3, NOMATCH_WWID_STR("WWIDNOMORE")); - mock_used_alias("MPATHa", "WWIDNOMORE"); -- expect_condlog(0, NOMORE_STR); -+ mock_unused_alias("MPATHab"); - rc = lookup_binding(NULL, "WWIDNOMORE", &alias, "MPATH", 1); -- assert_int_equal(rc, -1); -+ assert_int_equal(rc, 28); - assert_ptr_equal(alias, NULL); - } - -@@ -1077,9 +1018,9 @@ static void lb_nomatch_int_max_m1_1_used(void **state) - mock_bindings_file(get_strbuf_str(&buf)); - expect_condlog(3, NOMATCH_WWID_STR("WWIDMAX")); - mock_used_alias("MPATHa", "WWIDMAX"); -- mock_unused_alias("MPATH" MPATH_ID_INT_MAX); -+ mock_unused_alias("MPATHab"); - rc = lookup_binding(NULL, "WWIDMAX", &alias, "MPATH", 1); -- assert_int_equal(rc, INT_MAX); -+ assert_int_equal(rc, 28); - assert_ptr_equal(alias, NULL); - } - -@@ -1095,10 +1036,10 @@ static void lb_nomatch_int_max_m1_2_used(void **state) - - expect_condlog(3, NOMATCH_WWID_STR("WWIDMAX")); - mock_used_alias("MPATHa", "WWIDMAX"); -- mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWIDMAX"); -- expect_condlog(0, NOMORE_STR); -+ mock_used_alias("MPATHab", "WWIDMAX"); -+ mock_unused_alias("MPATHac"); - rc = lookup_binding(NULL, "WWIDMAX", &alias, "MPATH", 1); -- assert_int_equal(rc, -1); -+ assert_int_equal(rc, 29); - assert_ptr_equal(alias, NULL); - } - #endif -@@ -1133,7 +1074,6 @@ static int test_lookup_binding(void) - cmocka_unit_test_teardown(lb_nomatch_b_aa_a, teardown_bindings), - cmocka_unit_test_teardown(lb_nomatch_b_a_aa, teardown_bindings), - cmocka_unit_test_teardown(lb_nomatch_b_a_aa_zz, teardown_bindings), -- cmocka_unit_test_teardown(lb_nomatch_b_z_a_unsorted, teardown_bindings), - cmocka_unit_test_teardown(lb_nomatch_b_a, teardown_bindings), - cmocka_unit_test_teardown(lb_nomatch_b_a_3_used, teardown_bindings), - #ifdef MPATH_ID_INT_MAX -@@ -1593,14 +1533,14 @@ static void gufa_nomatch_b_f_a(void **state) { - "MPATHf WWID6\n" - "MPATHa WWID0\n"); - -- mock_bindings_file_unsorted(bindings); -+ mock_bindings_file(bindings); - expect_condlog(3, NOMATCH_WWID_STR("WWID7")); -- mock_unused_alias("MPATHg"); -+ mock_unused_alias("MPATHc"); - -- mock_allocate_binding_len("MPATHg", "WWID7", sizeof(bindings) - 1); -+ mock_allocate_binding_len("MPATHc", "WWID7", sizeof(bindings) - 1); - - alias = get_user_friendly_alias("WWID7", "x", "", "MPATH", false); -- assert_string_equal(alias, "MPATHg"); -+ assert_string_equal(alias, "MPATHc"); - free(alias); - } - diff --git a/0026-multipath-tools-tests-add-test-for-ordering-of-bindi.patch b/0026-multipath-tools-tests-add-test-for-ordering-of-bindi.patch deleted file mode 100644 index 5317ef9..0000000 --- a/0026-multipath-tools-tests-add-test-for-ordering-of-bindi.patch +++ /dev/null @@ -1,275 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 8 Sep 2023 21:39:44 +0200 -Subject: [PATCH] multipath-tools tests: add test for ordering of bindings - -As the assignment of free aliases now relies on the bindings being -properly sorted, add some unit tests to make sure the sorting algorithm -works. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - tests/alias.c | 212 +++++++++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 209 insertions(+), 3 deletions(-) - -diff --git a/tests/alias.c b/tests/alias.c -index dff5f93b..7f3ff38a 100644 ---- a/tests/alias.c -+++ b/tests/alias.c -@@ -13,6 +13,9 @@ - #include "globals.c" - #include "../libmultipath/alias.c" - -+/* For verbose printing of all aliases in the ordering tests */ -+#define ALIAS_DEBUG 0 -+ - #if INT_MAX == 0x7fffffff - /* user_friendly_name for map #INT_MAX */ - #define MPATH_ID_INT_MAX "fxshrxw" -@@ -439,11 +442,12 @@ static void mock_self_alias(const char *alias, const char *wwid) - expect_condlog(3, USED_STR(alias, wwid)); \ - } while(0) - --static void __mock_bindings_file(const char *content) -+static void __mock_bindings_file(const char *content, bool conflict_ok) - { - char *cnt __attribute__((cleanup(cleanup_charp))) = NULL; - char *token, *savep = NULL; - int i; -+ uintmax_t values[] = { BINDING_ADDED, BINDING_CONFLICT }; - - cnt = strdup(content); - assert_ptr_not_equal(cnt, NULL); -@@ -459,12 +463,12 @@ static void __mock_bindings_file(const char *content) - continue; - - rc = add_binding(&global_bindings, alias, wwid); -- assert_int_equal(rc, BINDING_ADDED); -+ assert_in_set(rc, values, conflict_ok ? 2 : 1); - } - } - - static void mock_bindings_file(const char *content) { -- return __mock_bindings_file(content); -+ return __mock_bindings_file(content, false); - } - - static int teardown_bindings(void **state) -@@ -1744,6 +1748,207 @@ static int test_get_user_friendly_alias() - return cmocka_run_group_tests(tests, NULL, NULL); - } - -+/* Numbers 1-1000, randomly shuffled */ -+static const int random_numbers[1000] = { -+ 694, 977, 224, 178, 841, 818, 914, 549, 831, 942, 263, 834, 919, 800, -+ 111, 517, 719, 297, 988, 98, 332, 516, 754, 772, 495, 488, 331, 529, -+ 142, 747, 848, 618, 375, 624, 74, 753, 782, 944, 623, 468, 862, 997, -+ 417, 258, 298, 774, 673, 904, 883, 766, 867, 400, 11, 950, 14, 784, -+ 655, 155, 396, 9, 743, 93, 651, 245, 968, 306, 785, 581, 880, 486, -+ 168, 631, 203, 4, 663, 294, 702, 762, 619, 684, 48, 181, 21, 443, 643, -+ 863, 1000, 327, 26, 126, 382, 765, 586, 76, 49, 925, 319, 865, 797, -+ 876, 693, 334, 433, 243, 419, 901, 854, 326, 985, 347, 874, 527, 282, -+ 290, 380, 167, 95, 3, 257, 936, 60, 426, 227, 345, 577, 492, 467, 580, -+ 967, 422, 823, 718, 610, 64, 700, 412, 163, 288, 506, 828, 432, 51, -+ 356, 348, 539, 478, 17, 945, 602, 123, 450, 660, 429, 113, 310, 358, -+ 512, 758, 508, 19, 542, 304, 286, 446, 918, 723, 333, 603, 731, 978, -+ 230, 697, 109, 872, 175, 853, 947, 965, 121, 222, 101, 811, 117, 601, -+ 191, 752, 384, 415, 938, 278, 915, 715, 240, 552, 912, 838, 150, 840, -+ 627, 29, 636, 464, 861, 481, 992, 249, 934, 82, 368, 724, 807, 593, -+ 157, 147, 199, 637, 41, 62, 902, 505, 621, 342, 174, 260, 729, 961, -+ 219, 311, 629, 789, 81, 739, 860, 712, 223, 165, 741, 981, 485, 363, -+ 346, 709, 125, 369, 279, 634, 399, 162, 193, 769, 149, 314, 868, 612, -+ 524, 675, 341, 343, 476, 606, 388, 613, 850, 264, 903, 451, 908, 779, -+ 453, 148, 497, 46, 132, 43, 885, 955, 269, 395, 72, 128, 767, 989, -+ 929, 423, 742, 55, 13, 79, 924, 182, 295, 563, 668, 169, 974, 154, -+ 970, 54, 674, 52, 437, 570, 550, 531, 554, 793, 678, 218, 367, 105, -+ 197, 315, 958, 892, 86, 47, 284, 37, 561, 522, 198, 689, 817, 573, -+ 877, 201, 803, 501, 881, 546, 530, 523, 780, 579, 953, 135, 23, 620, -+ 84, 698, 303, 656, 357, 323, 494, 58, 131, 913, 995, 120, 70, 1, 195, -+ 365, 210, 25, 898, 173, 307, 239, 77, 418, 952, 963, 92, 455, 425, 12, -+ 536, 161, 328, 933, 401, 251, 735, 725, 362, 322, 557, 681, 302, 53, -+ 786, 801, 391, 946, 748, 133, 717, 851, 7, 372, 993, 387, 906, 373, -+ 667, 33, 670, 389, 209, 611, 896, 652, 69, 999, 344, 845, 633, 36, -+ 487, 192, 180, 45, 640, 427, 707, 805, 188, 152, 905, 217, 30, 252, -+ 386, 665, 299, 541, 410, 787, 5, 857, 751, 392, 44, 595, 146, 745, -+ 641, 957, 866, 773, 806, 815, 659, 102, 704, 430, 106, 296, 129, 847, -+ 130, 990, 669, 236, 225, 680, 159, 213, 438, 189, 447, 600, 232, 594, -+ 32, 56, 390, 647, 855, 428, 330, 714, 738, 706, 666, 461, 469, 482, -+ 558, 814, 559, 177, 575, 538, 309, 383, 261, 156, 420, 761, 630, 893, -+ 10, 116, 940, 844, 71, 377, 662, 312, 520, 244, 143, 759, 119, 186, -+ 592, 909, 864, 376, 768, 254, 265, 394, 511, 760, 574, 6, 436, 514, -+ 59, 226, 644, 956, 578, 825, 548, 145, 736, 597, 378, 821, 987, 897, -+ 354, 144, 722, 895, 589, 503, 826, 498, 543, 617, 763, 231, 808, 528, -+ 89, 479, 607, 737, 170, 404, 371, 65, 103, 340, 283, 141, 313, 858, -+ 289, 124, 971, 687, 954, 732, 39, 926, 176, 100, 267, 519, 890, 535, -+ 276, 448, 27, 457, 899, 385, 184, 275, 770, 544, 614, 449, 160, 658, -+ 259, 973, 108, 604, 24, 207, 562, 757, 744, 324, 444, 962, 591, 480, -+ 398, 409, 998, 253, 325, 445, 979, 8, 35, 118, 73, 683, 208, 85, 190, -+ 791, 408, 871, 657, 179, 18, 556, 496, 475, 20, 894, 484, 775, 889, -+ 463, 241, 730, 57, 907, 551, 859, 943, 185, 416, 870, 590, 435, 471, -+ 932, 268, 381, 626, 502, 565, 273, 534, 672, 778, 292, 473, 566, 104, -+ 172, 285, 832, 411, 329, 628, 397, 472, 271, 910, 711, 690, 969, 585, -+ 809, 941, 923, 555, 228, 685, 242, 94, 96, 211, 140, 61, 922, 795, -+ 869, 34, 255, 38, 984, 676, 15, 560, 632, 434, 921, 355, 582, 351, -+ 212, 200, 819, 960, 649, 852, 75, 771, 361, 996, 238, 316, 720, 671, -+ 462, 112, 569, 171, 664, 625, 588, 405, 553, 270, 533, 353, 842, 114, -+ 972, 83, 937, 63, 194, 237, 537, 980, 802, 916, 959, 688, 839, 350, -+ 917, 650, 545, 615, 151, 352, 686, 726, 266, 509, 439, 491, 935, 608, -+ 518, 653, 339, 609, 277, 635, 836, 88, 407, 440, 642, 927, 229, 727, -+ 360, 477, 846, 413, 454, 616, 28, 598, 567, 540, 790, 424, 247, 317, -+ 746, 911, 798, 321, 547, 248, 734, 829, 220, 138, 756, 500, 691, 196, -+ 740, 930, 843, 733, 221, 827, 50, 813, 949, 525, 349, 474, 134, 875, -+ 695, 513, 414, 515, 638, 99, 366, 490, 975, 246, 465, 206, 281, 583, -+ 256, 587, 749, 2, 951, 679, 215, 364, 458, 402, 646, 991, 335, 982, -+ 835, 300, 900, 703, 994, 983, 234, 888, 532, 804, 584, 305, 792, 442, -+ 291, 964, 158, 370, 452, 250, 521, 166, 948, 812, 794, 272, 699, 205, -+ 183, 507, 301, 920, 781, 233, 824, 137, 489, 833, 887, 966, 856, 78, -+ 830, 153, 359, 696, 526, 216, 66, 701, 403, 891, 849, 571, 308, 483, -+ 164, 293, 928, 677, 320, 837, 441, 639, 564, 510, 648, 274, 336, 661, -+ 878, 777, 816, 976, 493, 810, 67, 87, 91, 187, 882, 986, 80, 22, 499, -+ 90, 705, 139, 136, 122, 708, 716, 886, 572, 127, 40, 721, 764, 16, -+ 379, 692, 645, 456, 710, 460, 783, 97, 776, 713, 884, 115, 466, 596, -+ 374, 406, 110, 568, 68, 214, 622, 470, 107, 504, 682, 31, 421, 576, -+ 654, 605, 788, 799, 280, 338, 931, 873, 204, 287, 459, 755, 939, 599, -+ 431, 796, 235, 42, 750, 262, 318, 393, 202, 822, 879, 820, 728, 337, -+}; -+ -+static void fill_bindings_random(struct strbuf *buf, int start, int end, -+ const char *prefix) -+{ -+ int i; -+ -+ for (i = start; i < end; i++) { -+ print_strbuf(buf, "%s", prefix); -+ format_devname(buf, random_numbers[i]); -+ print_strbuf(buf, " WWID%d\n", random_numbers[i]); -+ } -+} -+ -+struct random_aliases { -+ int start; -+ int end; -+ const char *prefix; -+}; -+ -+static void order_test(int n, const struct random_aliases ra[], bool conflict_ok) -+{ -+ STRBUF_ON_STACK(buf); -+ int i, j, prev, curr, tmp; -+ struct binding *bdg; -+ Bindings *bindings = &global_bindings; -+ -+ for (j = 0; j < n; j++) -+ fill_bindings_random(&buf, ra[j].start, ra[j].end, ra[j].prefix); -+ __mock_bindings_file(get_strbuf_str(&buf), conflict_ok); -+ -+ for (j = 0; j < n; j++) { -+ bdg = VECTOR_SLOT(bindings, 0); -+ if (ALIAS_DEBUG && j == 0) -+ printf("%d: %s\n", 0, bdg->alias); -+ prev = scan_devname(bdg->alias, ra[j].prefix); -+ i = 1; -+ vector_foreach_slot_after(bindings, bdg, i) { -+ if (ALIAS_DEBUG && j == 0) -+ printf("%d: %s\n", i, bdg->alias); -+ tmp = scan_devname(bdg->alias, ra[j].prefix); -+ if (tmp == -1) -+ continue; -+ curr = tmp; -+ if (prev > 0) { -+ if (curr <= prev) -+ printf("ERROR: %d (%s) %d >= %d\n", -+ i, bdg->alias, prev, curr); -+ assert_true(curr > prev); -+ } -+ prev = curr; -+ } -+ } -+} -+ -+static void order_01(void **state) -+{ -+ const struct random_aliases ra[] = { -+ { 0, 1000, "MPATH" }, -+ }; -+ -+ order_test(ARRAY_SIZE(ra), ra, false); -+} -+ -+static void order_02(void **state) -+{ -+ const struct random_aliases ra[] = { -+ { 0, 500, "MPATH" }, -+ { 200, 700, "mpath" }, -+ }; -+ order_test(ARRAY_SIZE(ra), ra, false); -+} -+ -+static void order_03(void **state) -+{ -+ const struct random_aliases ra[] = { -+ { 500, 1000, "MPTH" }, -+ { 0, 500, "MPATH" }, -+ }; -+ order_test(ARRAY_SIZE(ra), ra, false); -+} -+ -+static void order_04(void **state) -+{ -+ const struct random_aliases ra[] = { -+ { 0, 500, "mpa" }, -+ { 250, 750, "mp" }, -+ }; -+ order_test(ARRAY_SIZE(ra), ra, true); -+} -+ -+static void order_05(void **state) -+{ -+ const struct random_aliases ra[] = { -+ { 0, 100, "A" }, -+ { 0, 100, "B" }, -+ { 0, 100, "C" }, -+ { 0, 100, "D" }, -+ }; -+ order_test(ARRAY_SIZE(ra), ra, false); -+} -+ -+static void order_06(void **state) -+{ -+ const struct random_aliases ra[] = { -+ { 0, 100, "" }, -+ { 0, 100, "a" }, -+ { 0, 100, "aa" }, -+ { 0, 100, "ab" }, -+ { 0, 100, "aaa" }, -+ }; -+ order_test(ARRAY_SIZE(ra), ra, true); -+} -+ -+static int test_bindings_order() -+{ -+ const struct CMUnitTest tests[] = { -+ cmocka_unit_test_teardown(order_01, teardown_bindings), -+ cmocka_unit_test_teardown(order_02, teardown_bindings), -+ cmocka_unit_test_teardown(order_03, teardown_bindings), -+ cmocka_unit_test_teardown(order_04, teardown_bindings), -+ cmocka_unit_test_teardown(order_05, teardown_bindings), -+ cmocka_unit_test_teardown(order_06, teardown_bindings), -+ }; -+ -+ return cmocka_run_group_tests(tests, NULL, NULL); -+} -+ - int main(void) - { - int ret = 0; -@@ -1755,6 +1960,7 @@ int main(void) - ret += test_rlookup_binding(); - ret += test_allocate_binding(); - ret += test_get_user_friendly_alias(); -+ ret += test_bindings_order(); - - return ret; - } diff --git a/0027-multipathd-watch-bindings-file-with-inotify-timestam.patch b/0027-multipathd-watch-bindings-file-with-inotify-timestam.patch deleted file mode 100644 index af21b74..0000000 --- a/0027-multipathd-watch-bindings-file-with-inotify-timestam.patch +++ /dev/null @@ -1,597 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 7 Sep 2023 22:22:43 +0200 -Subject: [PATCH] multipathd: watch bindings file with inotify + timestamp - -Since "libmultipath: keep bindings in memory", we don't re-read the -bindings file after every modification. Add a notification mechanism -that makes multipathd aware of changes to the bindings file. Because -multipathd itself will change the bindings file, it must compare -timestamps in order to avoid reading the file repeatedly. - -Because select_alias() can be called from multiple thread contexts (uxlsnr, -uevent handler), we need to add locking for the bindings file. The -timestamp must also be protected by a lock, because it can't be read -or written atomically. - -Note: The notification mechanism expects the bindings file to be -atomically replaced by rename(2). Changes must be made in a temporary file and -applied using rename(2), as in update_bindings_file(). The inotify -mechanism deliberately does not listen to close-after-write events -that would be generated by editing the bindings file directly. This - -Note also: new bindings will only be read from add_map_with_path(), -i.e. either during reconfigure(), or when a new map is created during -runtime. Existing maps will not be renamed if the binding file changes, -unless the user runs "multipathd reconfigure". This is not a change -wrt the previous code, but it should be mentioned anyway. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/alias.c | 256 +++++++++++++++++++++++++----- - libmultipath/alias.h | 3 +- - libmultipath/libmultipath.version | 5 + - multipathd/uxlsnr.c | 36 ++++- - tests/alias.c | 3 + - 5 files changed, 256 insertions(+), 47 deletions(-) - -diff --git a/libmultipath/alias.c b/libmultipath/alias.c -index 66e34e31..964b8a7b 100644 ---- a/libmultipath/alias.c -+++ b/libmultipath/alias.c -@@ -10,6 +10,7 @@ - #include - #include - #include -+#include - - #include "debug.h" - #include "util.h" -@@ -22,6 +23,7 @@ - #include "config.h" - #include "devmapper.h" - #include "strbuf.h" -+#include "time-util.h" - - /* - * significant parts of this file were taken from iscsi-bindings.c of the -@@ -50,6 +52,12 @@ - "# alias wwid\n" \ - "#\n" - -+/* uatomic access only */ -+static int bindings_file_changed = 1; -+ -+static pthread_mutex_t timestamp_mutex = PTHREAD_MUTEX_INITIALIZER; -+static struct timespec bindings_last_updated; -+ - struct binding { - char *alias; - char *wwid; -@@ -60,6 +68,9 @@ struct binding { - * an abstract type. - */ - typedef struct _vector Bindings; -+ -+/* Protect global_bindings */ -+static pthread_mutex_t bindings_mutex = PTHREAD_MUTEX_INITIALIZER; - static Bindings global_bindings = { .allocated = 0 }; - - enum { -@@ -78,6 +89,27 @@ static void _free_binding(struct binding *bdg) - free(bdg); - } - -+static void free_bindings(Bindings *bindings) -+{ -+ struct binding *bdg; -+ int i; -+ -+ vector_foreach_slot(bindings, bdg, i) -+ _free_binding(bdg); -+ vector_reset(bindings); -+} -+ -+static void set_global_bindings(Bindings *bindings) -+{ -+ Bindings old_bindings; -+ -+ pthread_mutex_lock(&bindings_mutex); -+ old_bindings = global_bindings; -+ global_bindings = *bindings; -+ pthread_mutex_unlock(&bindings_mutex); -+ free_bindings(&old_bindings); -+} -+ - static const struct binding *get_binding_for_alias(const Bindings *bindings, - const char *alias) - { -@@ -199,7 +231,8 @@ static int delete_binding(Bindings *bindings, const char *wwid) - return BINDING_DELETED; - } - --static int write_bindings_file(const Bindings *bindings, int fd) -+static int write_bindings_file(const Bindings *bindings, int fd, -+ struct timespec *ts) - { - struct binding *bnd; - STRBUF_ON_STACK(content); -@@ -227,9 +260,56 @@ static int write_bindings_file(const Bindings *bindings, int fd) - } - len -= n; - } -+ fsync(fd); -+ if (ts) { -+ struct stat st; -+ -+ if (fstat(fd, &st) == 0) -+ *ts = st.st_mtim; -+ else -+ clock_gettime(CLOCK_REALTIME_COARSE, ts); -+ } - return 0; - } - -+void handle_bindings_file_inotify(const struct inotify_event *event) -+{ -+ struct config *conf; -+ const char *base; -+ bool changed = false; -+ struct stat st; -+ struct timespec ts = { 0, 0 }; -+ int ret; -+ -+ if (!(event->mask & IN_MOVED_TO)) -+ return; -+ -+ conf = get_multipath_config(); -+ base = strrchr(conf->bindings_file, '/'); -+ changed = base && base > conf->bindings_file && -+ !strcmp(base + 1, event->name); -+ ret = stat(conf->bindings_file, &st); -+ put_multipath_config(conf); -+ -+ if (!changed) -+ return; -+ -+ pthread_mutex_lock(×tamp_mutex); -+ if (ret == 0) { -+ ts = st.st_mtim; -+ changed = timespeccmp(&ts, &bindings_last_updated) > 0; -+ } -+ pthread_mutex_unlock(×tamp_mutex); -+ -+ if (changed) { -+ uatomic_xchg(&bindings_file_changed, 1); -+ condlog(3, "%s: bindings file must be re-read, new timestamp: %ld.%06ld", -+ __func__, (long)ts.tv_sec, (long)ts.tv_nsec / 1000); -+ } else -+ condlog(3, "%s: bindings file is up-to-date, timestamp: %ld.%06ld", -+ __func__, (long)ts.tv_sec, (long)ts.tv_nsec / 1000); -+} -+ - static int update_bindings_file(const Bindings *bindings, - const char *bindings_file) - { -@@ -237,6 +317,7 @@ static int update_bindings_file(const Bindings *bindings, - int fd = -1; - char tempname[PATH_MAX]; - mode_t old_umask; -+ struct timespec ts; - - if (safe_sprintf(tempname, "%s.XXXXXX", bindings_file)) - return -1; -@@ -248,7 +329,7 @@ static int update_bindings_file(const Bindings *bindings, - } - umask(old_umask); - pthread_cleanup_push(cleanup_fd_ptr, &fd); -- rc = write_bindings_file(bindings, fd); -+ rc = write_bindings_file(bindings, fd, &ts); - pthread_cleanup_pop(1); - if (rc == -1) { - condlog(1, "failed to write new bindings file"); -@@ -257,8 +338,12 @@ static int update_bindings_file(const Bindings *bindings, - } - if ((rc = rename(tempname, bindings_file)) == -1) - condlog(0, "%s: rename: %m", __func__); -- else -+ else { -+ pthread_mutex_lock(×tamp_mutex); -+ bindings_last_updated = ts; -+ pthread_mutex_unlock(×tamp_mutex); - condlog(1, "updated bindings file %s", bindings_file); -+ } - return rc; - } - -@@ -387,6 +472,7 @@ int get_free_id(const Bindings *bindings, const char *prefix, const char *map_ww - return id; - } - -+/* Called with binding_mutex held */ - static char * - allocate_binding(const char *filename, const char *wwid, int id, const char *prefix) - { -@@ -423,6 +509,30 @@ allocate_binding(const char *filename, const char *wwid, int id, const char *pre - return alias; - } - -+enum { -+ BINDINGS_FILE_UP2DATE, -+ BINDINGS_FILE_READ, -+ BINDINGS_FILE_ERROR, -+ BINDINGS_FILE_BAD, -+}; -+ -+static int _read_bindings_file(const struct config *conf, Bindings *bindings, -+ bool force); -+ -+static void read_bindings_file(void) -+{ -+ struct config *conf; -+ Bindings bindings = {.allocated = 0, }; -+ int rc; -+ -+ conf = get_multipath_config(); -+ pthread_cleanup_push(put_multipath_config, conf); -+ rc = _read_bindings_file(conf, &bindings, false); -+ pthread_cleanup_pop(1); -+ if (rc == BINDINGS_FILE_READ) -+ set_global_bindings(&bindings); -+} -+ - /* - * get_user_friendly_alias() action table - * -@@ -463,6 +573,11 @@ char *get_user_friendly_alias(const char *wwid, const char *file, const char *al - bool new_binding = false; - const struct binding *bdg; - -+ read_bindings_file(); -+ -+ pthread_mutex_lock(&bindings_mutex); -+ pthread_cleanup_push(cleanup_mutex, &bindings_mutex); -+ - if (!*alias_old) - goto new_alias; - -@@ -514,40 +629,40 @@ new_alias: - alias, wwid); - - out: -+ /* unlock bindings_mutex */ -+ pthread_cleanup_pop(1); - return alias; - } - - int get_user_friendly_wwid(const char *alias, char *buff) - { - const struct binding *bdg; -+ int rc = -1; - - if (!alias || *alias == '\0') { - condlog(3, "Cannot find binding for empty alias"); - return -1; - } - -+ read_bindings_file(); -+ -+ pthread_mutex_lock(&bindings_mutex); -+ pthread_cleanup_push(cleanup_mutex, &bindings_mutex); - bdg = get_binding_for_alias(&global_bindings, alias); -- if (!bdg) { -+ if (bdg) { -+ strlcpy(buff, bdg->wwid, WWID_SIZE); -+ rc = 0; -+ } else - *buff = '\0'; -- return -1; -- } -- strlcpy(buff, bdg->wwid, WWID_SIZE); -- return 0; --} -- --static void free_bindings(Bindings *bindings) --{ -- struct binding *bdg; -- int i; -- -- vector_foreach_slot(bindings, bdg, i) -- _free_binding(bdg); -- vector_reset(bindings); -+ pthread_cleanup_pop(1); -+ return rc; - } - - void cleanup_bindings(void) - { -+ pthread_mutex_lock(&bindings_mutex); - free_bindings(&global_bindings); -+ pthread_mutex_unlock(&bindings_mutex); - } - - enum { -@@ -595,7 +710,20 @@ static int _check_bindings_file(const struct config *conf, FILE *file, - char *line = NULL; - size_t line_len = 0; - ssize_t n; -- -+ char header[sizeof(BINDINGS_FILE_HEADER)]; -+ -+ header[sizeof(BINDINGS_FILE_HEADER) - 1] = '\0'; -+ if (fread(header, sizeof(BINDINGS_FILE_HEADER) - 1, 1, file) < 1) { -+ condlog(2, "%s: failed to read header from %s", __func__, -+ conf->bindings_file); -+ fseek(file, 0, SEEK_SET); -+ rc = -1; -+ } else if (strcmp(header, BINDINGS_FILE_HEADER)) { -+ condlog(2, "%s: invalid header in %s", __func__, -+ conf->bindings_file); -+ fseek(file, 0, SEEK_SET); -+ rc = -1; -+ } - pthread_cleanup_push(cleanup_free_ptr, &line); - while ((n = getline(&line, &line_len, file)) >= 0) { - char *alias, *wwid; -@@ -643,6 +771,68 @@ static int mp_alias_compar(const void *p1, const void *p2) - &((*(struct mpentry * const *)p2)->alias)); - } - -+static int _read_bindings_file(const struct config *conf, Bindings *bindings, -+ bool force) -+{ -+ int can_write; -+ int rc = 0, ret, fd; -+ FILE *file; -+ struct stat st; -+ int has_changed = uatomic_xchg(&bindings_file_changed, 0); -+ -+ if (!force) { -+ if (!has_changed) { -+ condlog(4, "%s: bindings are unchanged", __func__); -+ return BINDINGS_FILE_UP2DATE; -+ } -+ } -+ -+ fd = open_file(conf->bindings_file, &can_write, BINDINGS_FILE_HEADER); -+ if (fd == -1) -+ return BINDINGS_FILE_ERROR; -+ -+ file = fdopen(fd, "r"); -+ if (file != NULL) { -+ condlog(3, "%s: reading %s", __func__, conf->bindings_file); -+ -+ pthread_cleanup_push(cleanup_fclose, file); -+ ret = _check_bindings_file(conf, file, bindings); -+ if (ret == 0) { -+ struct timespec ts; -+ -+ rc = BINDINGS_FILE_READ; -+ ret = fstat(fd, &st); -+ if (ret == 0) -+ ts = st.st_mtim; -+ else { -+ condlog(1, "%s: fstat failed (%m), using current time", __func__); -+ clock_gettime(CLOCK_REALTIME_COARSE, &ts); -+ } -+ pthread_mutex_lock(×tamp_mutex); -+ bindings_last_updated = ts; -+ pthread_mutex_unlock(×tamp_mutex); -+ } else if (ret == -1 && can_write && !conf->bindings_read_only) { -+ ret = update_bindings_file(bindings, conf->bindings_file); -+ if (ret == 0) -+ rc = BINDINGS_FILE_READ; -+ else -+ rc = BINDINGS_FILE_BAD; -+ } else { -+ condlog(0, "ERROR: bad settings in read-only bindings file %s", -+ conf->bindings_file); -+ rc = BINDINGS_FILE_BAD; -+ } -+ pthread_cleanup_pop(1); -+ } else { -+ condlog(1, "failed to fdopen %s: %m", -+ conf->bindings_file); -+ close(fd); -+ rc = BINDINGS_FILE_ERROR; -+ } -+ -+ return rc; -+} -+ - /* - * check_alias_settings(): test for inconsistent alias configuration - * -@@ -661,8 +851,7 @@ static int mp_alias_compar(const void *p1, const void *p2) - */ - int check_alias_settings(const struct config *conf) - { -- int can_write; -- int rc = 0, i, fd; -+ int i, rc; - Bindings bindings = {.allocated = 0, }; - vector mptable = NULL; - struct mpentry *mpe; -@@ -695,27 +884,12 @@ int check_alias_settings(const struct config *conf) - pthread_cleanup_pop(1); - pthread_cleanup_pop(1); - -- fd = open_file(conf->bindings_file, &can_write, BINDINGS_FILE_HEADER); -- if (fd != -1) { -- FILE *file = fdopen(fd, "r"); -- -- if (file != NULL) { -- pthread_cleanup_push(cleanup_fclose, file); -- rc = _check_bindings_file(conf, file, &bindings); -- pthread_cleanup_pop(1); -- if (rc == -1 && can_write && !conf->bindings_read_only) -- rc = update_bindings_file(&bindings, conf->bindings_file); -- else if (rc == -1) -- condlog(0, "ERROR: bad settings in read-only bindings file %s", -- conf->bindings_file); -- } else { -- condlog(1, "failed to fdopen %s: %m", -- conf->bindings_file); -- close(fd); -- } -+ rc = _read_bindings_file(conf, &bindings, true); -+ -+ if (rc == BINDINGS_FILE_READ) { -+ set_global_bindings(&bindings); -+ rc = 0; - } - -- cleanup_bindings(); -- global_bindings = bindings; - return rc; - } -diff --git a/libmultipath/alias.h b/libmultipath/alias.h -index 5ef6720b..ca8911f4 100644 ---- a/libmultipath/alias.h -+++ b/libmultipath/alias.h -@@ -10,5 +10,6 @@ char *get_user_friendly_alias(const char *wwid, const char *file, - struct config; - int check_alias_settings(const struct config *); - void cleanup_bindings(void); -- -+struct inotify_event; -+void handle_bindings_file_inotify(const struct inotify_event *event); - #endif /* _ALIAS_H */ -diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version -index ddd302f5..57e50c12 100644 ---- a/libmultipath/libmultipath.version -+++ b/libmultipath/libmultipath.version -@@ -238,3 +238,8 @@ global: - local: - *; - }; -+ -+LIBMULTIPATH_20.1.0 { -+global: -+ handle_bindings_file_inotify; -+}; -diff --git a/multipathd/uxlsnr.c b/multipathd/uxlsnr.c -index 02e89fb4..d1f8f234 100644 ---- a/multipathd/uxlsnr.c -+++ b/multipathd/uxlsnr.c -@@ -41,6 +41,7 @@ - #include "cli.h" - #include "uxlsnr.h" - #include "strbuf.h" -+#include "alias.h" - - /* state of client connection */ - enum { -@@ -190,6 +191,7 @@ void wakeup_cleanup(void *arg) - struct watch_descriptors { - int conf_wd; - int dir_wd; -+ int mp_wd; /* /etc/multipath; for bindings file */ - }; - - /* failing to set the watch descriptor is o.k. we just miss a warning -@@ -200,6 +202,8 @@ static void reset_watch(int notify_fd, struct watch_descriptors *wds, - struct config *conf; - int dir_reset = 0; - int conf_reset = 0; -+ int mp_reset = 0; -+ char *bindings_file __attribute__((cleanup(cleanup_charp))) = NULL; - - if (notify_fd == -1) - return; -@@ -214,7 +218,10 @@ static void reset_watch(int notify_fd, struct watch_descriptors *wds, - conf_reset = 1; - if (wds->dir_wd == -1) - dir_reset = 1; -+ if (wds->mp_wd == -1) -+ mp_reset = 1; - } -+ bindings_file = strdup(conf->bindings_file); - put_multipath_config(conf); - - if (dir_reset) { -@@ -235,7 +242,18 @@ static void reset_watch(int notify_fd, struct watch_descriptors *wds, - if (wds->conf_wd == -1) - condlog(3, "didn't set up notifications on /etc/multipath.conf: %m"); - } -- return; -+ if (mp_reset && bindings_file) { -+ char *slash = strrchr(bindings_file, '/'); -+ -+ if (slash && slash > bindings_file) { -+ *slash = '\0'; -+ wds->mp_wd = inotify_add_watch(notify_fd, bindings_file, -+ IN_MOVED_TO|IN_ONLYDIR); -+ if (wds->mp_wd == -1) -+ condlog(3, "didn't set up notifications on %s: %m", -+ bindings_file); -+ } -+ } - } - - static void handle_inotify(int fd, struct watch_descriptors *wds) -@@ -256,12 +274,13 @@ static void handle_inotify(int fd, struct watch_descriptors *wds) - inotify_rm_watch(fd, wds->conf_wd); - if (wds->dir_wd != -1) - inotify_rm_watch(fd, wds->dir_wd); -- wds->conf_wd = wds->dir_wd = -1; -+ if (wds->mp_wd != -1) -+ inotify_rm_watch(fd, wds->mp_wd); -+ wds->conf_wd = wds->dir_wd = wds->mp_wd = -1; - } - break; - } - -- got_notify = 1; - for (ptr = buff; ptr < buff + len; - ptr += sizeof(struct inotify_event) + event->len) { - event = (const struct inotify_event *) ptr; -@@ -273,7 +292,13 @@ static void handle_inotify(int fd, struct watch_descriptors *wds) - wds->conf_wd = inotify_add_watch(notify_fd, DEFAULT_CONFIGFILE, IN_CLOSE_WRITE); - else if (wds->dir_wd == event->wd) - wds->dir_wd = -1; -+ else if (wds->mp_wd == event->wd) -+ wds->mp_wd = -1; - } -+ if (wds->mp_wd != -1 && wds->mp_wd == event->wd) -+ handle_bindings_file_inotify(event); -+ else -+ got_notify = 1; - } - } - if (got_notify) -@@ -599,7 +624,7 @@ void *uxsock_listen(long ux_sock, void *trigger_data) - int max_pfds = MIN_POLLS + POLLFDS_BASE; - /* conf->sequence_nr will be 1 when uxsock_listen is first called */ - unsigned int sequence_nr = 0; -- struct watch_descriptors wds = { .conf_wd = -1, .dir_wd = -1 }; -+ struct watch_descriptors wds = { .conf_wd = -1, .dir_wd = -1, .mp_wd = -1, }; - struct vectors *vecs = trigger_data; - - condlog(3, "uxsock: startup listener"); -@@ -666,7 +691,8 @@ void *uxsock_listen(long ux_sock, void *trigger_data) - - reset_watch(notify_fd, &wds, &sequence_nr); - polls[POLLFD_NOTIFY].fd = notify_fd; -- if (notify_fd == -1 || (wds.conf_wd == -1 && wds.dir_wd == -1)) -+ if (notify_fd == -1 || (wds.conf_wd == -1 && wds.dir_wd == -1 -+ && wds.mp_wd == -1)) - polls[POLLFD_NOTIFY].events = 0; - else - polls[POLLFD_NOTIFY].events = POLLIN; -diff --git a/tests/alias.c b/tests/alias.c -index 7f3ff38a..9ae27567 100644 ---- a/tests/alias.c -+++ b/tests/alias.c -@@ -1954,6 +1954,9 @@ int main(void) - int ret = 0; - init_test_verbosity(3); - -+ /* avoid open_file() call in _read_bindings_file */ -+ bindings_file_changed = 0; -+ - ret += test_format_devname(); - ret += test_scan_devname(); - ret += test_lookup_binding(); diff --git a/0028-multipath-tools-tests-mock-pthread_mutex_-lock-unloc.patch b/0028-multipath-tools-tests-mock-pthread_mutex_-lock-unloc.patch deleted file mode 100644 index bba92f3..0000000 --- a/0028-multipath-tools-tests-mock-pthread_mutex_-lock-unloc.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 8 Sep 2023 19:54:07 +0200 -Subject: [PATCH] multipath-tools tests: mock pthread_mutex_{lock,unlock} - -If some test fails with a lock held, cmocka doesn't deal well with -pthread_cleanup_pop(). Such tests can cause deadlock with the locking -primitives in the alias code, because locks don't get properly unlocked. Just -mock the lock/unlock functions and generate an error if they weren't paired at -the end of the test. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - tests/Makefile | 1 + - tests/alias.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 47 insertions(+) - -diff --git a/tests/Makefile b/tests/Makefile -index c777d07a..7dac8a8f 100644 ---- a/tests/Makefile -+++ b/tests/Makefile -@@ -52,6 +52,7 @@ blacklist-test_LIBDEPS := -ludev - vpd-test_OBJDEPS := $(multipathdir)/discovery.o - vpd-test_LIBDEPS := -ludev -lpthread -ldl - alias-test_TESTDEPS := test-log.o -+alias-test_OBJDEPS := $(mpathutildir)/util.o - alias-test_LIBDEPS := -lpthread -ldl - valid-test_OBJDEPS := $(multipathdir)/valid.o $(multipathdir)/discovery.o - valid-test_LIBDEPS := -lmount -ludev -lpthread -ldl -diff --git a/tests/alias.c b/tests/alias.c -index 9ae27567..94df36d8 100644 ---- a/tests/alias.c -+++ b/tests/alias.c -@@ -89,6 +89,47 @@ int __wrap_dm_get_uuid(const char *name, char *uuid, int uuid_len) - return ret; - } - -+static int lock_errors; -+static int bindings_locked; -+static int timestamp_locked; -+int __wrap_pthread_mutex_lock(pthread_mutex_t *mutex) -+{ -+ if (mutex == &bindings_mutex) { -+ if (bindings_locked) { -+ fprintf(stderr, "%s: bindings_mutex LOCKED\n", __func__); -+ lock_errors++; -+ } -+ bindings_locked = 1; -+ } else if (mutex == ×tamp_mutex) { -+ if (timestamp_locked) { -+ fprintf(stderr, "%s: timestamp_mutex LOCKED\n", __func__); -+ lock_errors++; -+ } -+ timestamp_locked = 1; -+ } else -+ fprintf(stderr, "%s called for unknown mutex %p\n", __func__, mutex); -+ return 0; -+} -+ -+int __wrap_pthread_mutex_unlock(pthread_mutex_t *mutex) -+{ -+ if (mutex == &bindings_mutex) { -+ if (!bindings_locked) { -+ fprintf(stderr, "%s: bindings_mutex UNLOCKED\n", __func__); -+ lock_errors++; -+ } -+ bindings_locked = 0; -+ } else if (mutex == ×tamp_mutex) { -+ if (!timestamp_locked) { -+ fprintf(stderr, "%s: timestamp_mutex UNLOCKED\n", __func__); -+ lock_errors++; -+ } -+ timestamp_locked = 0; -+ } else -+ fprintf(stderr, "%s called for unknown mutex %p\n", __func__, mutex); -+ return 0; -+} -+ - #define TEST_FDNO 1234 - #define TEST_FPTR ((FILE *) 0xaffe) - -@@ -1718,6 +1759,10 @@ static void gufa_old_nomatch_nowwidmatch(void **state) { - free(alias); - } - -+static void gufa_check_locking(void **state) { -+ assert_int_equal(lock_errors, 0); -+} -+ - static int test_get_user_friendly_alias() - { - const struct CMUnitTest tests[] = { -@@ -1743,6 +1788,7 @@ static int test_get_user_friendly_alias() - cmocka_unit_test_teardown(gufa_old_nomatch_wwidmatch, teardown_bindings), - cmocka_unit_test_teardown(gufa_old_nomatch_wwidmatch_used, teardown_bindings), - cmocka_unit_test_teardown(gufa_old_nomatch_nowwidmatch, teardown_bindings), -+ cmocka_unit_test(gufa_check_locking), - }; - - return cmocka_run_group_tests(tests, NULL, NULL); diff --git a/0029-multipath-tools-Makefile-sanitize-paths-for-configur.patch b/0029-multipath-tools-Makefile-sanitize-paths-for-configur.patch deleted file mode 100644 index 26b79a8..0000000 --- a/0029-multipath-tools-Makefile-sanitize-paths-for-configur.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 8 Sep 2023 22:13:51 +0200 -Subject: [PATCH] multipath-tools Makefile: sanitize paths for configuration - files - -Make the path to multipath.conf configurable, and use the same prefix -by default for multipath.conf and multipath/conf.d. For "usr-merged" -distributions with immutable /usr, we'll want to have the configuration -under a different prefix. This can be achieved by using e.g. - - make prefix=/usr etc_prefix="" - -Note that with prefix=/usr, before this patch the code would use -/usr/etc/multipath/conf.d, but /etc/multipath.conf. If this (rather -inconsistent) behavior is desired, use the following command line: - - make prefix=/usr configfile=/etc/multipath.conf - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 9 ++++++--- - libmultipath/defaults.h | 1 - - 2 files changed, 6 insertions(+), 4 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 502cd0f1..39972d93 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -37,6 +37,8 @@ prefix := - exec_prefix := $(prefix) - # Prefix for non-essential libraries (libdmmp) - usr_prefix := $(prefix) -+# Prefix for configfuration files (multipath.conf) -+etc_prefix := $(prefix) - # Where to install systemd-related files. systemd is usually installed under /usr - # Note: some systemd installations use separate "prefix" and "rootprefix". - # In this case, override only unitdir to use systemd's "rootprefix" instead of $(systemd_prefix) -@@ -54,7 +56,8 @@ usrlibdir := $(usr_prefix)/$(LIB) - includedir := $(usr_prefix)/include - pkgconfdir := $(usrlibdir)/pkgconfig - plugindir := $(prefix)/$(LIB)/multipath --configdir := $(prefix)/etc/multipath/conf.d -+configdir := $(etc_prefix)/etc/multipath/conf.d -+configfile := $(etc_prefix)/etc/multipath.conf - runtimedir := $(if $(shell test -L /var/run -o ! -d /var/run && echo 1),/run,/var/run) - devmapper_incdir := $(or $(shell $(PKG_CONFIG) --variable=includedir devmapper),/usr/include) - libudev_incdir := $(or $(shell $(PKG_CONFIG) --variable=includedir libudev),/usr/include) -@@ -84,8 +87,8 @@ WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implici - $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) $(W_URCU_TYPE_LIMITS) - CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) \ - -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \ -- -DRUNTIME_DIR=\"$(runtimedir)\" \ -- -DCONFIG_DIR=\"$(configdir)\" -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP -+ -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(configdir)\" \ -+ -DDEFAULT_CONFIGFILE=\"$(configfile)\" -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP - CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe - BIN_CFLAGS := -fPIE -DPIE - LIB_CFLAGS := -fPIC -diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h -index b3f11d4c..bc2d6388 100644 ---- a/libmultipath/defaults.h -+++ b/libmultipath/defaults.h -@@ -66,7 +66,6 @@ - #define MAX_DEV_LOSS_TMO UINT_MAX - #define DEFAULT_PIDFILE RUNTIME_DIR "/multipathd.pid" - #define DEFAULT_SOCKET "/org/kernel/linux/storage/multipathd" --#define DEFAULT_CONFIGFILE "/etc/multipath.conf" - #define DEFAULT_BINDINGS_FILE "/etc/multipath/bindings" - #define DEFAULT_WWIDS_FILE "/etc/multipath/wwids" - #define DEFAULT_PRKEYS_FILE "/etc/multipath/prkeys" diff --git a/0030-multipath-tools-add-compile-time-configuration-for-e.patch b/0030-multipath-tools-add-compile-time-configuration-for-e.patch deleted file mode 100644 index afdf833..0000000 --- a/0030-multipath-tools-add-compile-time-configuration-for-e.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 8 Sep 2023 22:26:22 +0200 -Subject: [PATCH] multipath-tools: add compile time configuration for - "/etc/multipath" - -Instead of hard-conding "/etc/multipath" as the path for the state -files "bindings", "prkeys", and "wwids", make this path configurable -via the "statedir" compile-time option. The default is currently still -/etc, it might change to /var/lib or similar in the future. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 4 +++- - libmultipath/defaults.h | 6 +++--- - 2 files changed, 6 insertions(+), 4 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 39972d93..96206b2f 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -58,6 +58,7 @@ pkgconfdir := $(usrlibdir)/pkgconfig - plugindir := $(prefix)/$(LIB)/multipath - configdir := $(etc_prefix)/etc/multipath/conf.d - configfile := $(etc_prefix)/etc/multipath.conf -+statedir := $(etc_prefix)/etc/multipath - runtimedir := $(if $(shell test -L /var/run -o ! -d /var/run && echo 1),/run,/var/run) - devmapper_incdir := $(or $(shell $(PKG_CONFIG) --variable=includedir devmapper),/usr/include) - libudev_incdir := $(or $(shell $(PKG_CONFIG) --variable=includedir libudev),/usr/include) -@@ -88,7 +89,8 @@ WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implici - CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) \ - -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \ - -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(configdir)\" \ -- -DDEFAULT_CONFIGFILE=\"$(configfile)\" -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP -+ -DDEFAULT_CONFIGFILE=\"$(configfile)\" -DSTATE_DIR=\"$(statedir)\" \ -+ -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP - CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe - BIN_CFLAGS := -fPIE -DPIE - LIB_CFLAGS := -fPIC -diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h -index bc2d6388..d01f9712 100644 ---- a/libmultipath/defaults.h -+++ b/libmultipath/defaults.h -@@ -66,9 +66,9 @@ - #define MAX_DEV_LOSS_TMO UINT_MAX - #define DEFAULT_PIDFILE RUNTIME_DIR "/multipathd.pid" - #define DEFAULT_SOCKET "/org/kernel/linux/storage/multipathd" --#define DEFAULT_BINDINGS_FILE "/etc/multipath/bindings" --#define DEFAULT_WWIDS_FILE "/etc/multipath/wwids" --#define DEFAULT_PRKEYS_FILE "/etc/multipath/prkeys" -+#define DEFAULT_BINDINGS_FILE STATE_DIR "/bindings" -+#define DEFAULT_WWIDS_FILE STATE_DIR "/wwids" -+#define DEFAULT_PRKEYS_FILE STATE_DIR "/prkeys" - #define MULTIPATH_SHM_BASE RUNTIME_DIR "/multipath/" - - diff --git a/0031-multipath-tools-man-pages-generate-with-correct-path.patch b/0031-multipath-tools-man-pages-generate-with-correct-path.patch deleted file mode 100644 index 65fc077..0000000 --- a/0031-multipath-tools-man-pages-generate-with-correct-path.patch +++ /dev/null @@ -1,366 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 8 Sep 2023 22:48:16 +0200 -Subject: [PATCH] multipath-tools man pages: generate with correct paths - -Generate the man pages using the compile-time settings for paths -to multipath.conf etc. - -Add a paragraph about the CONFIGDIR (/etc/multipath/conf.d) -and the drop-in configuration files in the multipath.conf man page. - -Also, make sure all generated man pages and other files are correctly -removed by "make clean". - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - .gitignore | 4 +++ - Makefile.inc | 3 +++ - mpathpersist/Makefile | 5 ++-- - .../{mpathpersist.8 => mpathpersist.8.in} | 2 +- - multipath/Makefile | 13 +++++---- - multipath/{multipath.8 => multipath.8.in} | 10 +++---- - .../{multipath.conf.5 => multipath.conf.5.in} | 27 ++++++++++++------- - multipathd/Makefile | 9 ++++--- - multipathd/{multipathd.8 => multipathd.8.in} | 8 +++--- - 9 files changed, 49 insertions(+), 32 deletions(-) - rename mpathpersist/{mpathpersist.8 => mpathpersist.8.in} (99%) - rename multipath/{multipath.8 => multipath.8.in} (97%) - rename multipath/{multipath.conf.5 => multipath.conf.5.in} (98%) - rename multipathd/{multipathd.8 => multipathd.8.in} (97%) - -diff --git a/.gitignore b/.gitignore -index 535353e5..2986578f 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -13,11 +13,15 @@ cscope.files - cscope.out - kpartx/kpartx - multipath/multipath -+multipath/multipath.8 -+multipath/multipath.conf.5 - multipath/multipath.rules - multipath/tmpfiles.conf - multipathd/multipathd -+multipathd/multipathd.8 - multipathd/multipathc - mpathpersist/mpathpersist -+mpathpersist/mpathpersist.8 - abi.tar.gz - abi - abi-test -diff --git a/Makefile.inc b/Makefile.inc -index 96206b2f..79e521e1 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -133,3 +133,6 @@ NV_VERSION_SCRIPT = $(DEVLIB:%.so=%-nv.version) - @grep -P '^[ \t]+[a-zA-Z_][a-zA-Z0-9_]*;' $< >>$@ - @printf 'local:\n\t*;\n};\n' >>$@ - -+%: %.in -+ @echo creating $@ -+ $(Q)sed 's:@CONFIGFILE@:'$(configfile)':g;s:@CONFIGDIR@:'$(configdir)':g;s:@STATE_DIR@:'$(statedir)':g;s:@RUNTIME_DIR@:'$(runtimedir)':g' $< >$@ -diff --git a/mpathpersist/Makefile b/mpathpersist/Makefile -index f57c105c..f3749467 100644 ---- a/mpathpersist/Makefile -+++ b/mpathpersist/Makefile -@@ -8,10 +8,11 @@ LIBDEPS += -L$(mpathpersistdir) -lmpathpersist -L$(multipathdir) -lmultipath \ - -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd -lpthread -ldevmapper -ludev - - EXEC = mpathpersist -+MANPAGES := mpathpersist.8 - - OBJS = main.o - --all: $(EXEC) -+all: $(EXEC) $(MANPAGES) - - $(EXEC): $(OBJS) - $(Q)$(CC) $(OBJS) -o $(EXEC) $(LDFLAGS) $(CFLAGS) $(LIBDEPS) -@@ -23,7 +24,7 @@ install: - $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 - - clean: dep_clean -- $(Q)$(RM) core *.o $(EXEC) -+ $(Q)$(RM) core *.o $(EXEC) $(MANPAGES) - - include $(wildcard $(OBJS:.o=.d)) - -diff --git a/mpathpersist/mpathpersist.8 b/mpathpersist/mpathpersist.8.in -similarity index 99% -rename from mpathpersist/mpathpersist.8 -rename to mpathpersist/mpathpersist.8.in -index 8d26b37c..fecef0d6 100644 ---- a/mpathpersist/mpathpersist.8 -+++ b/mpathpersist/mpathpersist.8.in -@@ -31,7 +31,7 @@ mpathpersist \- Manages SCSI persistent reservations on dm multipath devices. - . - This utility is used to manage SCSI persistent reservations on Device Mapper - Multipath devices. To be able to use this functionality, the \fIreservation_key\fR --attribute must be defined in the \fI/etc/multipath.conf\fR file. Otherwise the -+attribute must be defined in the \fI@CONFIGFILE@\fR file. Otherwise the - \fBmultipathd\fR daemon will not check for persistent reservation for newly - discovered paths or reinstated paths. - . -diff --git a/multipath/Makefile b/multipath/Makefile -index 73db991a..68cb5ce7 100644 ---- a/multipath/Makefile -+++ b/multipath/Makefile -@@ -3,7 +3,9 @@ - # - include ../Makefile.inc - --EXEC := multipath -+EXEC := multipath -+MANPAGES := multipath.8 multipath.conf.5 -+GENERATED := $(MANPAGES) multipath.rules tmpfiles.conf - - CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathcmddir) - CFLAGS += $(BIN_CFLAGS) -@@ -13,7 +15,7 @@ LIBDEPS += -L$(multipathdir) -lmultipath -L$(mpathutildir) -lmpathutil \ - - OBJS := main.o - --all: $(EXEC) multipath.rules tmpfiles.conf -+all: $(EXEC) $(GENERATED) - - $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so - @echo building $@ because of $? -@@ -47,15 +49,12 @@ uninstall: - $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules - $(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 - $(Q)$(RM) $(DESTDIR)$(mandir)/man5/$(EXEC).conf.5 -+ $(Q)$(RM) $(DESTDIR)$(tmpfilesdir)/multipath.conf - - clean: dep_clean -- $(Q)$(RM) core *.o $(EXEC) multipath.rules tmpfiles.conf -+ $(Q)$(RM) core *.o $(EXEC) $(GENERATED) - - include $(wildcard $(OBJS:.o=.d)) - - dep_clean: - $(Q)$(RM) $(OBJS:.o=.d) -- --%: %.in -- @echo creating $@ -- $(Q)sed 's,@RUNTIME_DIR@,$(runtimedir),' $< >$@ -diff --git a/multipath/multipath.8 b/multipath/multipath.8.in -similarity index 97% -rename from multipath/multipath.8 -rename to multipath/multipath.8.in -index 5fed6df7..348eb220 100644 ---- a/multipath/multipath.8 -+++ b/multipath/multipath.8.in -@@ -185,7 +185,7 @@ Display the currently used multipathd configuration. - .B \-T - Display the currently used multipathd configuration, limiting the output to - those devices actually present in the system. This can be used a template for --creating \fImultipath.conf\fR. -+creating \fI@CONFIGFILE@\fR. - . - .\" ---------------------------------------------------------------------------- - .SH OPTIONS -@@ -233,11 +233,11 @@ option from \fBmultipath.conf(5)\fR. - .B \-i - Ignore WWIDs file when processing devices. If - \fIfind_multipaths strict\fR or \fIfind_multipaths no\fR is set in --\fImultipath.conf\fR, multipath only considers devices that are -+\fI@CONFIGFILE@\fR, multipath only considers devices that are - listed in the WWIDs file. This option overrides that behavior. For other values - of \fIfind_multipaths\fR, this option has no effect. See the description of - \fIfind_multipaths\fR in --.BR multipath.conf (5). -+.BR @CONFIGFILE@ (5). - This option should only be used in rare circumstances. - . - .TP -@@ -246,8 +246,8 @@ Treat the bindings file as read only. - . - .TP - .BI \-b " file" --Set \fIuser_friendly_names\fR bindings file location. The default is --\fI/etc/multipath/bindings\fR. -+(\fBdeprecated, do not use\fR) Set \fIuser_friendly_names\fR bindings file location. The default is -+\fI@STATE_DIR@/bindings\fR. - . - .TP - .B \-q -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5.in -similarity index 98% -rename from multipath/multipath.conf.5 -rename to multipath/multipath.conf.5.in -index 93af17db..20df2232 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5.in -@@ -13,14 +13,14 @@ - .SH NAME - .\" ---------------------------------------------------------------------------- - . --multipath.conf \- multipath daemon configuration file. -+@CONFIGFILE@, @CONFIGDIR@/*.conf \- multipath daemon configuration file. - . - . - .\" ---------------------------------------------------------------------------- - .SH DESCRIPTION - .\" ---------------------------------------------------------------------------- - . --.B "/etc/multipath.conf" -+.B "@CONFIGFILE@" - is the configuration file for the multipath daemon. It is used to - overwrite the built-in configuration table of \fBmultipathd\fP. - Any line whose first non-white-space character is a '#' is considered -@@ -29,6 +29,15 @@ a comment line. Empty lines are ignored. - Currently used multipathd configuration can be displayed with the \fBmultipath -t\fR - or \fBmultipathd show config\fR command. - . -+.PP -+Additional configuration can be made in drop-in files under -+.B @CONFIGDIR@. -+Files ending in \fI.conf\fR in this directory are read -+in alphabetical order, after reading \fI@CONFIGFILE@\fR. -+They use the same syntax as \fI@CONFIGFILE@\fR itself, -+and support all sections and keywords. If a keyword occurs in the same section -+in multiple files, the last occurence will take precedence over all others. -+. - . - .\" ---------------------------------------------------------------------------- - .SH SYNTAX -@@ -85,7 +94,7 @@ not mandatory. - . - .LP - .B Note on regular expressions: --The \fImultipath.conf\fR syntax allows many attribute values to be specified as POSIX -+The \fI@CONFIGFILE@\fR syntax allows many attribute values to be specified as POSIX - Extended Regular Expressions (see \fBregex\fR(7)). These regular expressions - are \fBcase sensitive\fR and \fBnot anchored\fR, thus the expression "bar" matches "barbie", - "rhabarber", and "wunderbar", but not "Barbie". To avoid unwanted substring -@@ -711,7 +720,7 @@ The default is: \fBno\fR - .B user_friendly_names - If set to - .I yes --, using the bindings file \fI/etc/multipath/bindings\fR to assign a persistent -+, using the bindings file \fI@STATE_DIR@/bindings\fR to assign a persistent - and unique alias to the multipath, in the form of mpath. If set to - .I no - use the WWID as the alias. In either case this be will -@@ -790,7 +799,7 @@ The full pathname of the binding file to be used when the user_friendly_names - option is set. - .RS - .TP --The default is: \fB/etc/multipath/bindings\fR -+The default is: \fB@STATE_DIR@/bindings\fR - .RE - . - . -@@ -801,7 +810,7 @@ The full pathname of the WWIDs file, which is used by multipath to keep track - of the WWIDs for LUNs it has created multipath devices on in the past. - .RS - .TP --The default is: \fB/etc/multipath/wwids\fR -+The default is: \fB@STATE_DIR@/wwids\fR - .RE - . - . -@@ -813,7 +822,7 @@ track of the persistent reservation key used for a specific WWID, when - \fIreservation_key\fR is set to \fBfile\fR. - .RS - .TP --The default is: \fB/etc/multipath/prkeys\fR -+The default is: \fB@STATE_DIR@/prkeys\fR - .RE - . - . -@@ -872,7 +881,7 @@ The default is: \fBno\fR - .I yes - and the SCSI layer has already attached a hardware_handler to the device, - multipath will not force the device to use the hardware_handler specified by --multipath.conf. If the SCSI layer has not attached a hardware handler, -+@CONFIGFILE@. If the SCSI layer has not attached a hardware handler, - multipath will continue to use its configured hardware handler. - .RS - .PP -@@ -1559,7 +1568,7 @@ given device, the attributes of all matching entries are applied to it. - If an attribute is specified in several matching device subsections, - later entries take precedence. Thus, entries in files under \fIconfig_dir\fR (in - reverse alphabetical order) have the highest precedence, followed by entries --in \fImultipath.conf\fR; the built-in hardware table has the lowest -+in \fI@CONFIGFILE@\fR; the built-in hardware table has the lowest - precedence. Inside a configuration file, later entries have higher precedence - than earlier ones. - .LP -diff --git a/multipathd/Makefile b/multipathd/Makefile -index 0d0146c5..cdba3db1 100644 ---- a/multipathd/Makefile -+++ b/multipathd/Makefile -@@ -1,7 +1,8 @@ - include ../Makefile.inc - --EXEC := multipathd --CLI := multipathc -+EXEC := multipathd -+CLI := multipathc -+MANPAGES := multipathd.8 - - CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathpersistdir) -I$(mpathcmddir) -I$(thirdpartydir) \ - $(shell $(PKG_CONFIG) --modversion liburcu 2>/dev/null | \ -@@ -42,7 +43,7 @@ ifeq ($(FPIN_SUPPORT),1) - OBJS += fpin_handlers.o - endif - --all : $(EXEC) $(CLI) -+all : $(EXEC) $(CLI) $(MANPAGES) - - $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so - @echo building $@ because of $? -@@ -79,7 +80,7 @@ uninstall: - $(Q)$(RM) $(DESTDIR)$(unitdir)/$(EXEC).socket - - clean: dep_clean -- $(Q)$(RM) core *.o $(EXEC) $(CLI) -+ $(Q)$(RM) core *.o $(EXEC) $(CLI) $(MANPAGES) - - include $(wildcard $(OBJS:.o=.d) $(CLI_OBJS:.o=.d)) - -diff --git a/multipathd/multipathd.8 b/multipathd/multipathd.8.in -similarity index 97% -rename from multipathd/multipathd.8 -rename to multipathd/multipathd.8.in -index cc72b775..e98c27fd 100644 ---- a/multipathd/multipathd.8 -+++ b/multipathd/multipathd.8.in -@@ -155,7 +155,7 @@ Show the format wildcards used in interactive commands taking $format. - .TP - .B list|show config - Show the currently used configuration, derived from default values and values --specified within the configuration file \fI/etc/multipath.conf\fR. -+specified within the configuration file \fI@CONFIGFILE@\fR. - . - .TP - .B list|show config local -@@ -165,7 +165,7 @@ the devices section to those devices that are actually present in the system. - .TP - .B list|show blacklist - Show the currently used blacklist rules, derived from default values and values --specified within the configuration file \fI/etc/multipath.conf\fR. -+specified within the configuration file \fI@CONFIGFILE@\fR. - . - .TP - .B list|show devices -@@ -290,13 +290,13 @@ Get the current persistent reservation key associated with $map. - .B map|multipath $map setprkey key $key - Set the persistent reservation key associated with $map to $key in the - \fIprkeys_file\fR. This key will only be used by multipathd if --\fIreservation_key\fR is set to \fBfile\fR in \fI/etc/multipath.conf\fR. -+\fIreservation_key\fR is set to \fBfile\fR in \fI@CONFIGFILE@\fR. - . - .TP - .B map|multipath $map unsetprkey - Remove the persistent reservation key associated with $map from the - \fIprkeys_file\fR. This will only unset the key used by multipathd if --\fIreservation_key\fR is set to \fBfile\fR in \fI/etc/multipath.conf\fR. -+\fIreservation_key\fR is set to \fBfile\fR in \fI@CONFIGFILE@\fR. - . - .TP - .B path $path setmarginal diff --git a/0032-libdmmp-Makefile-fix-bug-in-install-section.patch b/0032-libdmmp-Makefile-fix-bug-in-install-section.patch deleted file mode 100644 index a3f2470..0000000 --- a/0032-libdmmp-Makefile-fix-bug-in-install-section.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 11 Sep 2023 09:30:13 +0200 -Subject: [PATCH] libdmmp/Makefile: fix bug in install section - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libdmmp/Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libdmmp/Makefile b/libdmmp/Makefile -index 078eca8f..172ba045 100644 ---- a/libdmmp/Makefile -+++ b/libdmmp/Makefile -@@ -44,7 +44,7 @@ install: - $(DESTDIR)$(pkgconfdir)/$(PKGFILE) - $(Q)sed -i 's|__INCLUDEDIR__|$(includedir)|g' \ - $(DESTDIR)$(pkgconfdir)/$(PKGFILE) -- $(Q)$(INSTALL_PROGRAM) -d 755 $(DESTDIR)$(mandir)/man3 -+ $(Q)$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(mandir)/man3 - $(Q)$(INSTALL_PROGRAM) -m 644 -t $(DESTDIR)$(mandir)/man3 docs/man/*.3 - - uninstall: diff --git a/0033-multipath-tools-README.md-improve-documentation-for-.patch b/0033-multipath-tools-README.md-improve-documentation-for-.patch deleted file mode 100644 index 3c7edd0..0000000 --- a/0033-multipath-tools-README.md-improve-documentation-for-.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 11 Sep 2023 10:22:13 +0200 -Subject: [PATCH] multipath-tools: README.md: improve documentation for - compile-time options - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - README.md | 38 ++++++++++++++++++++++++++------------ - 1 file changed, 26 insertions(+), 12 deletions(-) - -diff --git a/README.md b/README.md -index a7f994ae..679e55bf 100644 ---- a/README.md -+++ b/README.md -@@ -89,9 +89,17 @@ The following variables can be passed to the `make` command line: - * `plugindir="/some/path"`: directory where libmultipath plugins (path - checkers, prioritizers, and foreign multipath support) will be looked up. - This used to be the run-time option `multipath_dir` in earlier versions. -- * `configdir="/some/path"` : directory to search for configuration files. -+ The default is `$(prefix)/$(LIB)/multipath`, where `$(LIB)` is `lib64` on -+ systems that have `/lib64`, and `lib` otherwise. -+ * `configfile="/some/path`": The path to the main configuration file. -+ The defalt is `$(etc_prefix)/etc/multipath.conf`. -+ * `configdir="/some/path"` : directory to search for additional configuration files. - This used to be the run-time option `config_dir` in earlier versions. -- The default is `/etc/multipath/conf.d`. -+ The default is `$(etc_prefix)/etc/multipath/conf.d`. -+ * `statedir="/some/path"`: The path of the directory where multipath-tools -+ stores run-time settings that need persist between reboots, such as known -+ WWIDs, user-friendly names, and persistent reservation keys. -+ The default is `$(etc_prefix)/etc/multipath`. - * `READLINE=libedit` or `READLINE=libreadline`: enable command line history - and TAB completion in the interactive mode *(which is entered with `multipathd -k` or `multipathc`)*. - The respective development package will be required for building. -@@ -119,21 +127,27 @@ The following variables can be passed to the `make` command line: - ### Installation Paths - - * `prefix`: The directory prefix for (almost) all files to be installed. -- Distributions may want to set this to `/usr`. -- **Note**: for multipath-tools, unlike many other packages, `prefix` -- defaults to the empty string, which resolves to the root directory (`/`). -+ "Usr-merged" distributions[^systemd] may want to set this to `/usr`. The -+ default is empty (`""`). - * `usr_prefix`: where to install those parts of the code that aren't necessary -- for booting. You may want to set this to `/usr` if `prefix` is empty. -- * `systemd_prefix`: Prefix for systemd-related files. It defaults to `/usr`. -- Some systemd installations use separate `prefix` and `rootprefix`. On such -- a distribution, set `prefix`, and override `unitdir` to use systemd's -- `rootprefix`. -+ for booting. Non-usr-merged distributions[^systemd] may want to set this to -+ `/usr`. The default is `$(prefix)`. -+ * `systemd_prefix`: Prefix for systemd-related files[^systemd]. The default is `/usr`. -+ * `etc_prefix`: The prefix for configuration files. "Usr-merged" -+ distributions with immutable `/usr`[^systemd] may want to set this to -+ `/etc`. The default is `$(prefix)`. - * `LIB`: the subdirectory under `prefix` where shared libraries will be - installed. By default, the makefile uses `/lib64` if this directory is - found on the build system, and `/lib` otherwise. - --See also `configdir` and `plugindir` above. See `Makefile.inc` for more --fine-grained control. -+The options `configdir`, `plugindir`, `configfile`, and `statedir` above can -+be used for setting indvidual paths where the `prefix` variables don't provide -+sufficient control. See `Makefile.inc` for even more fine-grained control. -+ -+[^systemd]: Some systemd installations use separate `prefix` and `rootprefix`. -+ On such a distribution, set `prefix`, and override `unitdir` to use systemd's -+ `rootprefix`. Recent systemd releases generally require everything to be -+ installed under `/usr` (so-called "usr-merged" distribution). On "usr- - - ### Compiler Options - diff --git a/0034-libmultipath-print-built-in-values-for-deprecated-op.patch b/0034-libmultipath-print-built-in-values-for-deprecated-op.patch deleted file mode 100644 index 45e7874..0000000 --- a/0034-libmultipath-print-built-in-values-for-deprecated-op.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 11 Sep 2023 11:36:25 +0200 -Subject: [PATCH] libmultipath: print built-in values for deprecated options - -In the error messages we print when a deprecated option is encountered, -print the compile-time value of the option. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/dict.c | 16 +++++++++------- - 1 file changed, 9 insertions(+), 7 deletions(-) - -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index f81c84aa..dace343d 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -314,14 +314,16 @@ def_ ## option ## _handler (struct config *conf, vector strvec, \ - static int deprecated_handler(struct config *conf, vector strvec, const char *file, - int line_nr); - --#define declare_deprecated_handler(option) \ -+#define declare_deprecated_handler(option, default) \ - static int \ - deprecated_ ## option ## _handler (struct config *conf, vector strvec, \ - const char *file, int line_nr) \ - { \ - static bool warned; \ - if (!warned) { \ -- condlog(1, "%s line %d: ignoring deprecated option \"" #option "\"", file, line_nr); \ -+ condlog(1, "%s line %d: ignoring deprecated option \"" \ -+ #option "\", using built-in value: \"%s\"", \ -+ file, line_nr, default); \ - warned = true; \ - } \ - return deprecated_handler(conf, strvec, file, line_nr); \ -@@ -2057,11 +2059,11 @@ snprint_deprecated (struct config *conf, struct strbuf *buff, const void * data) - } - - // Deprecated keywords --declare_deprecated_handler(config_dir) --declare_deprecated_handler(disable_changed_wwids) --declare_deprecated_handler(getuid_callout) --declare_deprecated_handler(multipath_dir) --declare_deprecated_handler(pg_timeout) -+declare_deprecated_handler(config_dir, CONFIG_DIR) -+declare_deprecated_handler(disable_changed_wwids, "yes") -+declare_deprecated_handler(getuid_callout, "(not set)") -+declare_deprecated_handler(multipath_dir, MULTIPATH_DIR) -+declare_deprecated_handler(pg_timeout, "(not set)") - - /* - * If you add or remove a keyword also update multipath/multipath.conf.5 diff --git a/0035-multipath-add-a-missing-newline.patch b/0035-multipath-add-a-missing-newline.patch deleted file mode 100644 index 706b7d3..0000000 --- a/0035-multipath-add-a-missing-newline.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 11 Sep 2023 11:37:37 +0200 -Subject: [PATCH] multipath: add a missing newline - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/main.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/multipath/main.c b/multipath/main.c -index 45e9745f..b91289e8 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -1025,7 +1025,7 @@ main (int argc, char *argv[]) - } - - if (check_alias_settings(conf)) { -- fprintf(stderr, "fatal configuration error, aborting"); -+ fprintf(stderr, "fatal configuration error, aborting\n"); - exit(RTVL_FAIL); - } - diff --git a/0036-multipath-tools-allow-prefixes-with-and-w-o-trailing.patch b/0036-multipath-tools-allow-prefixes-with-and-w-o-trailing.patch deleted file mode 100644 index c48240b..0000000 --- a/0036-multipath-tools-allow-prefixes-with-and-w-o-trailing.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 11 Sep 2023 16:03:34 +0200 -Subject: [PATCH] multipath-tools: allow prefixes with and w/o trailing slash - -Add some logic to Makefile.inc that leads to the same result -for "prefix=" and "prefix=/", or "prefix=/usr" and "prefix=/usr/". -The logic does not work for multiple trailing slashes. It applies -to all XYZ_prefix variables in Makefile.inc. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 35 ++++++++++++++++++++++------------- - 1 file changed, 22 insertions(+), 13 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 79e521e1..6e384e68 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -43,22 +43,31 @@ etc_prefix := $(prefix) - # Note: some systemd installations use separate "prefix" and "rootprefix". - # In this case, override only unitdir to use systemd's "rootprefix" instead of $(systemd_prefix) - systemd_prefix := /usr --unitdir := $(systemd_prefix)/lib/systemd/system --tmpfilesdir := $(systemd_prefix)/lib/tmpfiles.d --modulesloaddir := $(systemd_prefix)/lib/modules-load.d --libudevdir := $(systemd_prefix)/lib/udev -+ -+# Make sure all prefix variables end in "/" -+append-slash = $(1)$(if $(filter %/,$(1)),,/) -+override prefix := $(call append-slash,$(prefix)) -+override exec_prefix := $(call append-slash,$(exec_prefix)) -+override usr_prefix := $(call append-slash,$(usr_prefix)) -+override etc_prefix := $(call append-slash,$(etc_prefix)) -+override systemd_prefix := $(call append-slash,$(systemd_prefix)) -+ -+unitdir := $(systemd_prefix)lib/systemd/system -+tmpfilesdir := $(systemd_prefix)lib/tmpfiles.d -+modulesloaddir := $(systemd_prefix)lib/modules-load.d -+libudevdir := $(systemd_prefix)lib/udev - udevrulesdir := $(libudevdir)/rules.d --bindir := $(exec_prefix)/sbin --mandir := $(usr_prefix)/share/man -+bindir := $(exec_prefix)sbin -+mandir := $(usr_prefix)share/man - LIB := $(if $(shell test -d /lib64 && echo 1),lib64,lib) --syslibdir := $(prefix)/$(LIB) --usrlibdir := $(usr_prefix)/$(LIB) --includedir := $(usr_prefix)/include -+syslibdir := $(prefix)$(LIB) -+usrlibdir := $(usr_prefix)$(LIB) -+includedir := $(usr_prefix)include - pkgconfdir := $(usrlibdir)/pkgconfig --plugindir := $(prefix)/$(LIB)/multipath --configdir := $(etc_prefix)/etc/multipath/conf.d --configfile := $(etc_prefix)/etc/multipath.conf --statedir := $(etc_prefix)/etc/multipath -+plugindir := $(prefix)$(LIB)/multipath -+configdir := $(etc_prefix)etc/multipath/conf.d -+configfile := $(etc_prefix)etc/multipath.conf -+statedir := $(etc_prefix)etc/multipath - runtimedir := $(if $(shell test -L /var/run -o ! -d /var/run && echo 1),/run,/var/run) - devmapper_incdir := $(or $(shell $(PKG_CONFIG) --variable=includedir devmapper),/usr/include) - libudev_incdir := $(or $(shell $(PKG_CONFIG) --variable=includedir libudev),/usr/include) diff --git a/0037-libmultipath-deprecate-bindings_file-wwids_file-prke.patch b/0037-libmultipath-deprecate-bindings_file-wwids_file-prke.patch deleted file mode 100644 index 6e066ee..0000000 --- a/0037-libmultipath-deprecate-bindings_file-wwids_file-prke.patch +++ /dev/null @@ -1,897 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 11 Sep 2023 17:58:13 +0200 -Subject: [PATCH] libmultipath: deprecate bindings_file, wwids_file, - prkeys_file - -The options bindings_file, wwids_file, and prkeys_file have been -deprecated since cb4d6db ("libmultipath: deprecate file and directory config -options") (multipath-tools 0.8.8). Deprecate and ignore them now. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/alias.c | 43 +++++++++---------- - libmultipath/alias.h | 3 +- - libmultipath/config.c | 18 -------- - libmultipath/config.h | 3 -- - libmultipath/dict.c | 39 +++--------------- - libmultipath/libmultipath.version | 8 +--- - libmultipath/prkey.c | 7 ++-- - libmultipath/prkey.h | 7 ++-- - libmultipath/propsel.c | 5 +-- - libmultipath/wwids.c | 18 ++------ - multipath/main.c | 2 +- - multipath/multipath.conf.5.in | 23 +++++------ - multipathd/uxlsnr.c | 17 +++----- - tests/alias.c | 68 +++++++++++++++---------------- - 14 files changed, 90 insertions(+), 171 deletions(-) - -diff --git a/libmultipath/alias.c b/libmultipath/alias.c -index 964b8a7b..e5d3f151 100644 ---- a/libmultipath/alias.c -+++ b/libmultipath/alias.c -@@ -55,6 +55,8 @@ - /* uatomic access only */ - static int bindings_file_changed = 1; - -+static const char bindings_file_path[] = DEFAULT_BINDINGS_FILE; -+ - static pthread_mutex_t timestamp_mutex = PTHREAD_MUTEX_INITIALIZER; - static struct timespec bindings_last_updated; - -@@ -274,7 +276,6 @@ static int write_bindings_file(const Bindings *bindings, int fd, - - void handle_bindings_file_inotify(const struct inotify_event *event) - { -- struct config *conf; - const char *base; - bool changed = false; - struct stat st; -@@ -284,12 +285,9 @@ void handle_bindings_file_inotify(const struct inotify_event *event) - if (!(event->mask & IN_MOVED_TO)) - return; - -- conf = get_multipath_config(); -- base = strrchr(conf->bindings_file, '/'); -- changed = base && base > conf->bindings_file && -- !strcmp(base + 1, event->name); -- ret = stat(conf->bindings_file, &st); -- put_multipath_config(conf); -+ base = strrchr(bindings_file_path, '/'); -+ changed = base && !strcmp(base + 1, event->name); -+ ret = stat(bindings_file_path, &st); - - if (!changed) - return; -@@ -310,8 +308,7 @@ void handle_bindings_file_inotify(const struct inotify_event *event) - __func__, (long)ts.tv_sec, (long)ts.tv_nsec / 1000); - } - --static int update_bindings_file(const Bindings *bindings, -- const char *bindings_file) -+static int update_bindings_file(const Bindings *bindings) - { - int rc; - int fd = -1; -@@ -319,7 +316,7 @@ static int update_bindings_file(const Bindings *bindings, - mode_t old_umask; - struct timespec ts; - -- if (safe_sprintf(tempname, "%s.XXXXXX", bindings_file)) -+ if (safe_sprintf(tempname, "%s.XXXXXX", bindings_file_path)) - return -1; - /* coverity: SECURE_TEMP */ - old_umask = umask(0077); -@@ -336,13 +333,13 @@ static int update_bindings_file(const Bindings *bindings, - unlink(tempname); - return rc; - } -- if ((rc = rename(tempname, bindings_file)) == -1) -+ if ((rc = rename(tempname, bindings_file_path)) == -1) - condlog(0, "%s: rename: %m", __func__); - else { - pthread_mutex_lock(×tamp_mutex); - bindings_last_updated = ts; - pthread_mutex_unlock(×tamp_mutex); -- condlog(1, "updated bindings file %s", bindings_file); -+ condlog(1, "updated bindings file %s", bindings_file_path); - } - return rc; - } -@@ -474,7 +471,7 @@ int get_free_id(const Bindings *bindings, const char *prefix, const char *map_ww - - /* Called with binding_mutex held */ - static char * --allocate_binding(const char *filename, const char *wwid, int id, const char *prefix) -+allocate_binding(const char *wwid, int id, const char *prefix) - { - STRBUF_ON_STACK(buf); - char *alias; -@@ -498,7 +495,7 @@ allocate_binding(const char *filename, const char *wwid, int id, const char *pre - return NULL; - } - -- if (update_bindings_file(&global_bindings, filename) == -1) { -+ if (update_bindings_file(&global_bindings) == -1) { - condlog(1, "%s: deleting binding %s for %s", __func__, alias, wwid); - delete_binding(&global_bindings, wwid); - free(alias); -@@ -565,7 +562,7 @@ static void read_bindings_file(void) - * that the mpvec corrcectly represents kernel state. - */ - --char *get_user_friendly_alias(const char *wwid, const char *file, const char *alias_old, -+char *get_user_friendly_alias(const char *wwid, const char *alias_old, - const char *prefix, bool bindings_read_only) - { - char *alias = NULL; -@@ -622,7 +619,7 @@ new_alias: - } - - if (!bindings_read_only && id > 0) -- alias = allocate_binding(file, wwid, id, prefix); -+ alias = allocate_binding(wwid, id, prefix); - - if (alias && !new_binding) - condlog(2, "Allocated existing binding [%s] for WWID [%s]", -@@ -715,12 +712,12 @@ static int _check_bindings_file(const struct config *conf, FILE *file, - header[sizeof(BINDINGS_FILE_HEADER) - 1] = '\0'; - if (fread(header, sizeof(BINDINGS_FILE_HEADER) - 1, 1, file) < 1) { - condlog(2, "%s: failed to read header from %s", __func__, -- conf->bindings_file); -+ bindings_file_path); - fseek(file, 0, SEEK_SET); - rc = -1; - } else if (strcmp(header, BINDINGS_FILE_HEADER)) { - condlog(2, "%s: invalid header in %s", __func__, -- conf->bindings_file); -+ bindings_file_path); - fseek(file, 0, SEEK_SET); - rc = -1; - } -@@ -787,13 +784,13 @@ static int _read_bindings_file(const struct config *conf, Bindings *bindings, - } - } - -- fd = open_file(conf->bindings_file, &can_write, BINDINGS_FILE_HEADER); -+ fd = open_file(bindings_file_path, &can_write, BINDINGS_FILE_HEADER); - if (fd == -1) - return BINDINGS_FILE_ERROR; - - file = fdopen(fd, "r"); - if (file != NULL) { -- condlog(3, "%s: reading %s", __func__, conf->bindings_file); -+ condlog(3, "%s: reading %s", __func__, bindings_file_path); - - pthread_cleanup_push(cleanup_fclose, file); - ret = _check_bindings_file(conf, file, bindings); -@@ -812,20 +809,20 @@ static int _read_bindings_file(const struct config *conf, Bindings *bindings, - bindings_last_updated = ts; - pthread_mutex_unlock(×tamp_mutex); - } else if (ret == -1 && can_write && !conf->bindings_read_only) { -- ret = update_bindings_file(bindings, conf->bindings_file); -+ ret = update_bindings_file(bindings); - if (ret == 0) - rc = BINDINGS_FILE_READ; - else - rc = BINDINGS_FILE_BAD; - } else { - condlog(0, "ERROR: bad settings in read-only bindings file %s", -- conf->bindings_file); -+ bindings_file_path); - rc = BINDINGS_FILE_BAD; - } - pthread_cleanup_pop(1); - } else { - condlog(1, "failed to fdopen %s: %m", -- conf->bindings_file); -+ bindings_file_path); - close(fd); - rc = BINDINGS_FILE_ERROR; - } -diff --git a/libmultipath/alias.h b/libmultipath/alias.h -index ca8911f4..629e8d56 100644 ---- a/libmultipath/alias.h -+++ b/libmultipath/alias.h -@@ -3,8 +3,7 @@ - - int valid_alias(const char *alias); - int get_user_friendly_wwid(const char *alias, char *buff); --char *get_user_friendly_alias(const char *wwid, const char *file, -- const char *alias_old, -+char *get_user_friendly_alias(const char *wwid, const char *alias_old, - const char *prefix, bool bindings_read_only); - - struct config; -diff --git a/libmultipath/config.c b/libmultipath/config.c -index 7b207590..b7dbc6f5 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -752,15 +752,6 @@ static void _uninit_config(struct config *conf) - if (conf->hwhandler) - free(conf->hwhandler); - -- if (conf->bindings_file) -- free(conf->bindings_file); -- -- if (conf->wwids_file) -- free(conf->wwids_file); -- -- if (conf->prkeys_file) -- free(conf->prkeys_file); -- - if (conf->prio_name) - free(conf->prio_name); - -@@ -922,9 +913,6 @@ int _init_config (const char *file, struct config *conf) - * internal defaults - */ - get_sys_max_fds(&conf->max_fds); -- conf->bindings_file = set_default(DEFAULT_BINDINGS_FILE); -- conf->wwids_file = set_default(DEFAULT_WWIDS_FILE); -- conf->prkeys_file = set_default(DEFAULT_PRKEYS_FILE); - conf->attribute_flags = 0; - conf->reassign_maps = DEFAULT_REASSIGN_MAPS; - conf->checkint = CHECKINT_UNDEF; -@@ -1078,12 +1066,6 @@ int _init_config (const char *file, struct config *conf) - merge_blacklist(conf->elist_wwid); - merge_blacklist_device(conf->elist_device); - -- if (conf->bindings_file == NULL) -- conf->bindings_file = set_default(DEFAULT_BINDINGS_FILE); -- -- if (!conf->bindings_file || !conf->wwids_file || !conf->prkeys_file) -- goto out; -- - libmp_verbosity = conf->verbosity; - return 0; - out: -diff --git a/libmultipath/config.h b/libmultipath/config.h -index 0a2c297b..8c22ce75 100644 ---- a/libmultipath/config.h -+++ b/libmultipath/config.h -@@ -207,9 +207,6 @@ struct config { - char * uid_attribute; - char * features; - char * hwhandler; -- char * bindings_file; -- char * wwids_file; -- char * prkeys_file; - char * prio_name; - char * prio_args; - char * checker_name; -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index dace343d..044067af 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -168,27 +168,6 @@ fail: - return 0; - } - --static int --set_path(vector strvec, void *ptr, const char *file, int line_nr) --{ -- char **str_ptr = (char **)ptr; -- char *old_str = *str_ptr; -- -- *str_ptr = set_value(strvec); -- if (!*str_ptr) { -- free(old_str); -- return 1; -- } -- if ((*str_ptr)[0] != '/'){ -- condlog(1, "%s line %d, %s is not an absolute path. Ignoring", -- file, line_nr, *str_ptr); -- free(*str_ptr); -- *str_ptr = old_str; -- } else -- free(old_str); -- return 0; --} -- - static int - set_str_noslash(vector strvec, void *ptr, const char *file, int line_nr) - { -@@ -831,15 +810,6 @@ declare_hw_snprint(user_friendly_names, print_yes_no_undef) - declare_mp_handler(user_friendly_names, set_yes_no_undef) - declare_mp_snprint(user_friendly_names, print_yes_no_undef) - --declare_def_warn_handler(bindings_file, set_path) --declare_def_snprint(bindings_file, print_str) -- --declare_def_warn_handler(wwids_file, set_path) --declare_def_snprint(wwids_file, print_str) -- --declare_def_warn_handler(prkeys_file, set_path) --declare_def_snprint(prkeys_file, print_str) -- - declare_def_handler(retain_hwhandler, set_yes_no_undef) - declare_def_snprint_defint(retain_hwhandler, print_yes_no_undef, - DEFAULT_RETAIN_HWHANDLER) -@@ -2064,6 +2034,9 @@ declare_deprecated_handler(disable_changed_wwids, "yes") - declare_deprecated_handler(getuid_callout, "(not set)") - declare_deprecated_handler(multipath_dir, MULTIPATH_DIR) - declare_deprecated_handler(pg_timeout, "(not set)") -+declare_deprecated_handler(bindings_file, DEFAULT_BINDINGS_FILE) -+declare_deprecated_handler(wwids_file, DEFAULT_WWIDS_FILE) -+declare_deprecated_handler(prkeys_file, DEFAULT_PRKEYS_FILE) - - /* - * If you add or remove a keyword also update multipath/multipath.conf.5 -@@ -2106,9 +2079,9 @@ init_keywords(vector keywords) - install_keyword("fast_io_fail_tmo", &def_fast_io_fail_handler, &snprint_def_fast_io_fail); - install_keyword("dev_loss_tmo", &def_dev_loss_handler, &snprint_def_dev_loss); - install_keyword("eh_deadline", &def_eh_deadline_handler, &snprint_def_eh_deadline); -- install_keyword("bindings_file", &def_bindings_file_handler, &snprint_def_bindings_file); -- install_keyword("wwids_file", &def_wwids_file_handler, &snprint_def_wwids_file); -- install_keyword("prkeys_file", &def_prkeys_file_handler, &snprint_def_prkeys_file); -+ install_keyword("bindings_file", &deprecated_bindings_file_handler, &snprint_deprecated); -+ install_keyword("wwids_file", &deprecated_wwids_file_handler, &snprint_deprecated); -+ install_keyword("prkeys_file", &deprecated_prkeys_file_handler, &snprint_deprecated); - 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); -diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version -index 57e50c12..8368ef7a 100644 ---- a/libmultipath/libmultipath.version -+++ b/libmultipath/libmultipath.version -@@ -43,7 +43,7 @@ LIBMPATHCOMMON_1.0.0 { - put_multipath_config; - }; - --LIBMULTIPATH_20.0.0 { -+LIBMULTIPATH_21.0.0 { - global: - /* symbols referenced by multipath and multipathd */ - add_foreign; -@@ -121,6 +121,7 @@ global: - get_used_hwes; - get_vpd_sgio; - group_by_prio; -+ handle_bindings_file_inotify; - has_dm_info; - init_checkers; - init_config; -@@ -238,8 +239,3 @@ global: - local: - *; - }; -- --LIBMULTIPATH_20.1.0 { --global: -- handle_bindings_file_inotify; --}; -diff --git a/libmultipath/prkey.c b/libmultipath/prkey.c -index a215499d..c66d293b 100644 ---- a/libmultipath/prkey.c -+++ b/libmultipath/prkey.c -@@ -157,8 +157,7 @@ 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, -- uint8_t *sa_flags) -+int get_prkey(struct multipath *mpp, uint64_t *prkey, uint8_t *sa_flags) - { - int fd; - int unused; -@@ -168,7 +167,7 @@ int get_prkey(struct config *conf, struct multipath *mpp, uint64_t *prkey, - if (!strlen(mpp->wwid)) - goto out; - -- fd = open_file(conf->prkeys_file, &unused, PRKEYS_FILE_HEADER); -+ fd = open_file(DEFAULT_PRKEYS_FILE, &unused, PRKEYS_FILE_HEADER); - if (fd < 0) - goto out; - ret = do_prkey(fd, mpp->wwid, keystr, PRKEY_READ); -@@ -201,7 +200,7 @@ int set_prkey(struct config *conf, struct multipath *mpp, uint64_t prkey, - sa_flags &= MPATH_F_APTPL_MASK; - } - -- fd = open_file(conf->prkeys_file, &can_write, PRKEYS_FILE_HEADER); -+ fd = open_file(DEFAULT_PRKEYS_FILE, &can_write, PRKEYS_FILE_HEADER); - if (fd < 0) - goto out; - if (!can_write) { -diff --git a/libmultipath/prkey.h b/libmultipath/prkey.h -index a16de106..43afd5e4 100644 ---- a/libmultipath/prkey.h -+++ b/libmultipath/prkey.h -@@ -16,9 +16,8 @@ - int print_reservation_key(struct strbuf *buff, - struct be64 key, uint8_t flags, int source); - int parse_prkey_flags(const char *ptr, uint64_t *prkey, uint8_t *flags); --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); -+int set_prkey(struct config *conf, struct multipath *mpp, -+ uint64_t prkey, uint8_t sa_flags); -+int get_prkey(struct multipath *mpp, uint64_t *prkey, uint8_t *sa_flags); - - #endif /* _PRKEY_H */ -diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c -index 354e883f..44241e2a 100644 ---- a/libmultipath/propsel.c -+++ b/libmultipath/propsel.c -@@ -401,8 +401,7 @@ int select_alias(struct config *conf, struct multipath * mp) - - select_alias_prefix(conf, mp); - -- mp->alias = get_user_friendly_alias(mp->wwid, conf->bindings_file, -- mp->alias_old, mp->alias_prefix, -+ mp->alias = get_user_friendly_alias(mp->wwid, mp->alias_old, mp->alias_prefix, - conf->bindings_read_only); - - if (mp->alias && !strncmp(mp->alias, mp->alias_old, WWID_SIZE)) -@@ -992,7 +991,7 @@ int select_reservation_key(struct config *conf, struct multipath *mp) - out: - if (mp->prkey_source == PRKEY_SOURCE_FILE) { - from_file = " (from prkeys file)"; -- if (get_prkey(conf, mp, &prkey, &mp->sa_flags) != 0) -+ if (get_prkey(mp, &prkey, &mp->sa_flags) != 0) - put_be64(mp->reservation_key, 0); - else - put_be64(mp->reservation_key, prkey); -diff --git a/libmultipath/wwids.c b/libmultipath/wwids.c -index 89bb60ca..591cd09b 100644 ---- a/libmultipath/wwids.c -+++ b/libmultipath/wwids.c -@@ -94,12 +94,8 @@ replace_wwids(vector mp) - struct multipath * mpp; - size_t len; - int ret = -1; -- struct config *conf; - -- conf = get_multipath_config(); -- pthread_cleanup_push(put_multipath_config, conf); -- fd = open_file(conf->wwids_file, &can_write, WWIDS_FILE_HEADER); -- pthread_cleanup_pop(1); -+ fd = open_file(DEFAULT_WWIDS_FILE, &can_write, WWIDS_FILE_HEADER); - if (fd < 0) - goto out; - -@@ -200,7 +196,6 @@ remove_wwid(char *wwid) { - int len, can_write; - char *str; - int ret = -1; -- struct config *conf; - - len = strlen(wwid) + 4; /* two slashes the newline and a zero byte */ - str = malloc(len); -@@ -216,10 +211,7 @@ remove_wwid(char *wwid) { - goto out; - } - condlog(3, "removing line '%s' from wwids file", str); -- conf = get_multipath_config(); -- pthread_cleanup_push(put_multipath_config, conf); -- fd = open_file(conf->wwids_file, &can_write, WWIDS_FILE_HEADER); -- pthread_cleanup_pop(1); -+ fd = open_file(DEFAULT_WWIDS_FILE, &can_write, WWIDS_FILE_HEADER); - - if (fd < 0) { - ret = -1; -@@ -244,12 +236,8 @@ check_wwids_file(char *wwid, int write_wwid) - { - int fd, can_write, found, ret; - FILE *f; -- struct config *conf; - -- conf = get_multipath_config(); -- pthread_cleanup_push(put_multipath_config, conf); -- fd = open_file(conf->wwids_file, &can_write, WWIDS_FILE_HEADER); -- pthread_cleanup_pop(1); -+ fd = open_file(DEFAULT_WWIDS_FILE, &can_write, WWIDS_FILE_HEADER); - if (fd < 0) - return -1; - -diff --git a/multipath/main.c b/multipath/main.c -index b91289e8..9e1c5052 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -856,7 +856,7 @@ main (int argc, char *argv[]) - libmp_verbosity = atoi(optarg); - break; - case 'b': -- conf->bindings_file = strdup(optarg); -+ condlog(1, "option -b ignored"); - break; - case 'B': - conf->bindings_read_only = 1; -diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in -index 20df2232..d320a88f 100644 ---- a/multipath/multipath.conf.5.in -+++ b/multipath/multipath.conf.5.in -@@ -794,35 +794,28 @@ The default is: \fB\fR - . - .TP - .B bindings_file --(Deprecated) This option is deprecated, and will be removed in a future release. --The full pathname of the binding file to be used when the user_friendly_names --option is set. -+(Deprecated) This option is not supported any more, and will be ignored. - .RS - .TP --The default is: \fB@STATE_DIR@/bindings\fR -+The compiled-in value is: \fB@STATE_DIR@/bindings\fR - .RE - . - . - .TP - .B wwids_file --(Deprecated) This option is deprecated, and will be removed in a future release. --The full pathname of the WWIDs file, which is used by multipath to keep track --of the WWIDs for LUNs it has created multipath devices on in the past. -+(Deprecated) This option is not supported any more, and will be ignored. - .RS - .TP --The default is: \fB@STATE_DIR@/wwids\fR -+The compiled-in value is: \fB@STATE_DIR@/wwids\fR - .RE - . - . - .TP - .B prkeys_file --(Deprecated) This option is deprecated, and will be removed in a future release. --The full pathname of the prkeys file, which is used by multipathd to keep --track of the persistent reservation key used for a specific WWID, when --\fIreservation_key\fR is set to \fBfile\fR. -+(Deprecated) This option is not supported any more, and will be ignored. - .RS - .TP --The default is: \fB@STATE_DIR@/prkeys\fR -+The compiled-in value is: \fB@STATE_DIR@/prkeys\fR - .RE - . - . -@@ -989,6 +982,10 @@ The default is: \fB\fR - .TP - .B config_dir - (Deprecated) This option is not supported any more, and the value is ignored. -+.RS -+.TP -+The compiled-in value is: \fB@CONFIGDIR@\fR -+.RE - . - . - .TP -diff --git a/multipathd/uxlsnr.c b/multipathd/uxlsnr.c -index d1f8f234..4d6f258c 100644 ---- a/multipathd/uxlsnr.c -+++ b/multipathd/uxlsnr.c -@@ -203,7 +203,6 @@ static void reset_watch(int notify_fd, struct watch_descriptors *wds, - int dir_reset = 0; - int conf_reset = 0; - int mp_reset = 0; -- char *bindings_file __attribute__((cleanup(cleanup_charp))) = NULL; - - if (notify_fd == -1) - return; -@@ -221,7 +220,6 @@ static void reset_watch(int notify_fd, struct watch_descriptors *wds, - if (wds->mp_wd == -1) - mp_reset = 1; - } -- bindings_file = strdup(conf->bindings_file); - put_multipath_config(conf); - - if (dir_reset) { -@@ -242,17 +240,12 @@ static void reset_watch(int notify_fd, struct watch_descriptors *wds, - if (wds->conf_wd == -1) - condlog(3, "didn't set up notifications on /etc/multipath.conf: %m"); - } -- if (mp_reset && bindings_file) { -- char *slash = strrchr(bindings_file, '/'); -- -- if (slash && slash > bindings_file) { -- *slash = '\0'; -- wds->mp_wd = inotify_add_watch(notify_fd, bindings_file, -- IN_MOVED_TO|IN_ONLYDIR); -- if (wds->mp_wd == -1) -+ if (mp_reset) { -+ wds->mp_wd = inotify_add_watch(notify_fd, STATE_DIR, -+ IN_MOVED_TO|IN_ONLYDIR); -+ if (wds->mp_wd == -1) - condlog(3, "didn't set up notifications on %s: %m", -- bindings_file); -- } -+ STATE_DIR); - } - } - -diff --git a/tests/alias.c b/tests/alias.c -index 94df36d8..f893d174 100644 ---- a/tests/alias.c -+++ b/tests/alias.c -@@ -1264,10 +1264,10 @@ static void al_a(void **state) - will_return(__wrap_write, ln); - will_return(__wrap_write, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); - will_return(__wrap_rename, 0); -- expect_condlog(1, "updated bindings file foo"); -+ expect_condlog(1, "updated bindings file " DEFAULT_BINDINGS_FILE); - expect_condlog(3, NEW_STR("MPATHa", "WWIDa")); - -- alias = allocate_binding("foo", "WWIDa", 1, "MPATH"); -+ alias = allocate_binding("WWIDa", 1, "MPATH"); - assert_ptr_not_equal(alias, NULL); - assert_string_equal(alias, "MPATHa"); - check_bindings_size(1); -@@ -1283,10 +1283,10 @@ static void al_zz(void **state) - will_return(__wrap_write, ln); - will_return(__wrap_write, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); - will_return(__wrap_rename, 0); -- expect_condlog(1, "updated bindings file foo"); -+ expect_condlog(1, "updated bindings file " DEFAULT_BINDINGS_FILE); - expect_condlog(3, NEW_STR("MPATHzz", "WWIDzz")); - -- alias = allocate_binding("foo", "WWIDzz", 26*26 + 26, "MPATH"); -+ alias = allocate_binding("WWIDzz", 26*26 + 26, "MPATH"); - assert_ptr_not_equal(alias, NULL); - assert_string_equal(alias, "MPATHzz"); - check_bindings_size(1); -@@ -1298,7 +1298,7 @@ static void al_0(void **state) - char *alias; - - expect_condlog(0, "allocate_binding: cannot allocate new binding for id 0\n"); -- alias = allocate_binding(0, "WWIDa", 0, "MPATH"); -+ alias = allocate_binding("WWIDa", 0, "MPATH"); - assert_ptr_equal(alias, NULL); - check_bindings_size(0); - } -@@ -1308,7 +1308,7 @@ static void al_m2(void **state) - char *alias; - - expect_condlog(0, "allocate_binding: cannot allocate new binding for id -2\n"); -- alias = allocate_binding(0, "WWIDa", -2, "MPATH"); -+ alias = allocate_binding("WWIDa", -2, "MPATH"); - assert_ptr_equal(alias, NULL); - check_bindings_size(0); - } -@@ -1325,10 +1325,10 @@ static void al_write_partial(void **state) - will_return(__wrap_write, ln + sizeof(ln) - 2); - will_return(__wrap_write, 1); - will_return(__wrap_rename, 0); -- expect_condlog(1, "updated bindings file foo"); -+ expect_condlog(1, "updated bindings file " DEFAULT_BINDINGS_FILE); - expect_condlog(3, "Created new binding [MPATHa] for WWID [WWIDa]\n"); - -- alias = allocate_binding("foo", "WWIDa", 1, "MPATH"); -+ alias = allocate_binding("WWIDa", 1, "MPATH"); - assert_ptr_not_equal(alias, NULL); - assert_string_equal(alias, "MPATHa"); - check_bindings_size(1); -@@ -1350,7 +1350,7 @@ static void al_write_short(void **state) - expect_condlog(1, "failed to write new bindings file"); - expect_condlog(1, "allocate_binding: deleting binding MPATHa for WWIDa"); - -- alias = allocate_binding("foo", "WWIDa", 1, "MPATH"); -+ alias = allocate_binding("WWIDa", 1, "MPATH"); - assert_ptr_equal(alias, NULL); - check_bindings_size(0); - } -@@ -1366,7 +1366,7 @@ static void al_write_err(void **state) - expect_condlog(1, "failed to write new bindings file"); - expect_condlog(1, "allocate_binding: deleting binding MPATHa for WWIDa"); - -- alias = allocate_binding("foo", "WWIDa", 1, "MPATH"); -+ alias = allocate_binding("WWIDa", 1, "MPATH"); - assert_ptr_equal(alias, NULL); - check_bindings_size(0); - } -@@ -1383,7 +1383,7 @@ static void al_rename_err(void **state) - - expect_condlog(0, "update_bindings_file: rename: Read-only file system"); - expect_condlog(1, "allocate_binding: deleting binding MPATHa for WWIDa"); -- alias = allocate_binding("foo", "WWIDa", 1, "MPATH"); -+ alias = allocate_binding("WWIDa", 1, "MPATH"); - assert_ptr_equal(alias, NULL); - check_bindings_size(0); - } -@@ -1415,7 +1415,7 @@ static int test_allocate_binding(void) - strlen(BINDINGS_FILE_HEADER) + (len) + strlen(ln)); \ - will_return(__wrap_rename, err); \ - if (err == 0) { \ -- expect_condlog(1, "updated bindings file x\n"); \ -+ expect_condlog(1, "updated bindings file " DEFAULT_BINDINGS_FILE); \ - expect_condlog(3, NEW_STR(alias, wwid)); \ - } else { \ - expect_condlog(0, "update_bindings_file: rename: " msg "\n"); \ -@@ -1441,7 +1441,7 @@ static void gufa_empty_new_rw(void **state) { - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - - mock_allocate_binding("MPATHa", "WWID0"); -- alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false); -+ alias = get_user_friendly_alias("WWID0", "", "MPATH", false); - assert_string_equal(alias, "MPATHa"); - free(alias); - } -@@ -1454,7 +1454,7 @@ static void gufa_empty_new_ro_1(void **state) { - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - mock_allocate_binding_err("MPATHa", "WWID0", -EROFS, "Read-only file system"); - -- alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false); -+ alias = get_user_friendly_alias("WWID0", "", "MPATH", false); - assert_ptr_equal(alias, NULL); - } - -@@ -1465,7 +1465,7 @@ static void gufa_empty_new_ro_2(void **state) { - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - mock_unused_alias("MPATHa"); - -- alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); -+ alias = get_user_friendly_alias("WWID0", "", "MPATH", true); - assert_ptr_equal(alias, NULL); - } - -@@ -1477,7 +1477,7 @@ static void gufa_match_a_unused(void **state) { - mock_unused_alias("MPATHa"); - expect_condlog(3, EXISTING_STR("MPATHa", "WWID0")); - -- alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); -+ alias = get_user_friendly_alias("WWID0", "", "MPATH", true); - assert_string_equal(alias, "MPATHa"); - free(alias); - } -@@ -1490,7 +1490,7 @@ static void gufa_match_a_self(void **state) { - mock_self_alias("MPATHa", "WWID0"); - expect_condlog(3, EXISTING_STR("MPATHa", "WWID0")); - -- alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); -+ alias = get_user_friendly_alias("WWID0", "", "MPATH", true); - assert_string_equal(alias, "MPATHa"); - free(alias); - } -@@ -1503,7 +1503,7 @@ static void gufa_match_a_used(void **state) { - expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); - mock_used_alias("MPATHa", "WWID0"); - -- alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); -+ alias = get_user_friendly_alias("WWID0", "", "MPATH", true); - assert_ptr_equal(alias, NULL); - } - -@@ -1518,7 +1518,7 @@ static void gufa_nomatch_a_c(void **state) { - - mock_allocate_binding_len("MPATHb", "WWID1", strlen(bindings)); - -- alias = get_user_friendly_alias("WWID1", "x", "", "MPATH", false); -+ alias = get_user_friendly_alias("WWID1", "", "MPATH", false); - assert_string_equal(alias, "MPATHb"); - free(alias); - } -@@ -1534,7 +1534,7 @@ static void gufa_nomatch_c_a(void **state) { - - mock_allocate_binding_len("MPATHb", "WWID1", sizeof(bindings) - 1); - -- alias = get_user_friendly_alias("WWID1", "x", "", "MPATH", false); -+ alias = get_user_friendly_alias("WWID1", "", "MPATH", false); - assert_string_equal(alias, "MPATHb"); - free(alias); - } -@@ -1550,7 +1550,7 @@ static void gufa_nomatch_c_b(void **state) { - - mock_allocate_binding_len("MPATHa", "WWID0", sizeof(bindings) - 1); - -- alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false); -+ alias = get_user_friendly_alias("WWID0", "", "MPATH", false); - assert_string_equal(alias, "MPATHa"); - free(alias); - } -@@ -1567,7 +1567,7 @@ static void gufa_nomatch_c_b_used(void **state) { - - mock_allocate_binding_len("MPATHd", "WWID4", sizeof(bindings) - 1); - -- alias = get_user_friendly_alias("WWID4", "x", "", "MPATH", false); -+ alias = get_user_friendly_alias("WWID4", "", "MPATH", false); - assert_string_equal(alias, "MPATHd"); - free(alias); - } -@@ -1584,7 +1584,7 @@ static void gufa_nomatch_b_f_a(void **state) { - - mock_allocate_binding_len("MPATHc", "WWID7", sizeof(bindings) - 1); - -- alias = get_user_friendly_alias("WWID7", "x", "", "MPATH", false); -+ alias = get_user_friendly_alias("WWID7", "", "MPATH", false); - assert_string_equal(alias, "MPATHc"); - free(alias); - } -@@ -1599,7 +1599,7 @@ static void gufa_nomatch_b_aa_a(void **state) { - mock_unused_alias("MPATHab"); - mock_allocate_binding_len("MPATHab", "WWID28", get_strbuf_len(&buf)); - -- alias = get_user_friendly_alias("WWID28", "x", "", "MPATH", false); -+ alias = get_user_friendly_alias("WWID28", "", "MPATH", false); - assert_string_equal(alias, "MPATHab"); - free(alias); - } -@@ -1616,7 +1616,7 @@ static void gufa_nomatch_b_f_a_sorted(void **state) { - - mock_allocate_binding_len("MPATHc", "WWID7", sizeof(bindings) - 1); - -- alias = get_user_friendly_alias("WWID7", "x", "", "MPATH", false); -+ alias = get_user_friendly_alias("WWID7", "", "MPATH", false); - assert_string_equal(alias, "MPATHc"); - free(alias); - } -@@ -1632,7 +1632,7 @@ static void gufa_old_empty(void **state) { - mock_allocate_binding("MPATHz", "WWID0"); - expect_condlog(2, ALLOC_STR("MPATHz", "WWID0")); - -- alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); -+ alias = get_user_friendly_alias("WWID0", "MPATHz", "MPATH", false); - assert_string_equal(alias, "MPATHz"); - free(alias); - } -@@ -1644,7 +1644,7 @@ static void gufa_old_match(void **state) { - "MPATHz WWID0"); - expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID0")); - -- alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); -+ alias = get_user_friendly_alias("WWID0", "MPATHz", "MPATH", false); - assert_string_equal(alias, "MPATHz"); - free(alias); - } -@@ -1661,7 +1661,7 @@ static void gufa_old_match_other(void **state) { - - mock_allocate_binding_len("MPATHa", "WWID0", sizeof(bindings) - 1); - -- alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); -+ alias = get_user_friendly_alias("WWID0", "MPATHz", "MPATH", false); - assert_string_equal(alias, "MPATHa"); - free(alias); - } -@@ -1678,7 +1678,7 @@ static void gufa_old_match_other_used(void **state) { - mock_unused_alias("MPATHb"); - - mock_allocate_binding_len("MPATHb", "WWID0", sizeof(bindings) - 1); -- alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); -+ alias = get_user_friendly_alias("WWID0", "MPATHz", "MPATH", false); - assert_string_equal(alias, "MPATHb"); - free(alias); - } -@@ -1695,7 +1695,7 @@ static void gufa_old_match_other_wwidmatch(void **state) { - mock_unused_alias("MPATHc"); - expect_condlog(3, EXISTING_STR("MPATHc", "WWID2")); - -- alias = get_user_friendly_alias("WWID2", "x", "MPATHz", "MPATH", false); -+ alias = get_user_friendly_alias("WWID2", "MPATHz", "MPATH", false); - assert_string_equal(alias, "MPATHc"); - free(alias); - } -@@ -1711,7 +1711,7 @@ static void gufa_old_match_other_wwidmatch_used(void **state) { - expect_condlog(3, FOUND_STR("MPATHc", "WWID2")); - mock_used_alias("MPATHc", "WWID2"); - -- alias = get_user_friendly_alias("WWID2", "x", "MPATHz", "MPATH", false); -+ alias = get_user_friendly_alias("WWID2", "MPATHz", "MPATH", false); - assert_ptr_equal(alias, NULL); - } - -@@ -1725,7 +1725,7 @@ static void gufa_old_nomatch_wwidmatch(void **state) { - mock_unused_alias("MPATHa"); - expect_condlog(3, EXISTING_STR("MPATHa", "WWID0")); - -- alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); -+ alias = get_user_friendly_alias("WWID0", "MPATHz", "MPATH", false); - assert_string_equal(alias, "MPATHa"); - free(alias); - } -@@ -1739,7 +1739,7 @@ static void gufa_old_nomatch_wwidmatch_used(void **state) { - expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); - mock_used_alias("MPATHa", "WWID0"); - -- alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); -+ alias = get_user_friendly_alias("WWID0", "MPATHz", "MPATH", false); - assert_ptr_equal(alias, NULL); - } - -@@ -1754,7 +1754,7 @@ static void gufa_old_nomatch_nowwidmatch(void **state) { - mock_allocate_binding_len("MPATHz", "WWID0", sizeof(bindings) - 1); - expect_condlog(2, ALLOC_STR("MPATHz", "WWID0")); - -- alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); -+ alias = get_user_friendly_alias("WWID0", "MPATHz", "MPATH", false); - assert_string_equal(alias, "MPATHz"); - free(alias); - } diff --git a/0038-libmultipath-avoid-Warray-bounds-error-in-uatomic-op.patch b/0038-libmultipath-avoid-Warray-bounds-error-in-uatomic-op.patch deleted file mode 100644 index 269efcf..0000000 --- a/0038-libmultipath-avoid-Warray-bounds-error-in-uatomic-op.patch +++ /dev/null @@ -1,158 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 12 Sep 2023 11:54:47 +0200 -Subject: [PATCH] libmultipath: avoid -Warray-bounds error in uatomic - operations - -The use of uatomic_xchg() in alias.c causes a -Warray-bounds error -on distributions using gcc 12, such as Fedora 37. This is a similar -error to 2534c4f ("libmultipath: avoid -Warray-bounds error with gcc -12 and musl libc"). This happens only with liburcu 0.13 and earlier, -and only with certain gcc versions. See liburcu commit 835b9ab -("Fix: x86 and s390 uatomic: __hp() macro warning with gcc 11"). - -Enhance the fix for 2534c4f by a adding a workaround for uatomic_xchg(), -and introduce the macro URCU_VERSION (originally only used for multipathd) -globally. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 2 +- - create-config.mk | 5 +++++ - libmultipath/alias.c | 5 +++-- - libmultipath/lock.h | 21 +++++++++++++-------- - multipathd/Makefile | 2 -- - 5 files changed, 22 insertions(+), 13 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 6e384e68..04bfa56e 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -95,7 +95,7 @@ OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 - WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int \ - -Werror=implicit-function-declaration -Werror=format-security \ - $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) $(W_URCU_TYPE_LIMITS) --CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) \ -+CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) $(D_URCU_VERSION) \ - -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \ - -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(configdir)\" \ - -DDEFAULT_CONFIGFILE=\"$(configfile)\" -DSTATE_DIR=\"$(statedir)\" \ -diff --git a/create-config.mk b/create-config.mk -index d1255971..4d318b96 100644 ---- a/create-config.mk -+++ b/create-config.mk -@@ -73,6 +73,10 @@ TEST_URCU_TYPE_LIMITS = $(shell \ - $(CC) -c -Werror=type-limits -o /dev/null -xc - 2>/dev/null \ - || echo -Wno-type-limits ) - -+URCU_VERSION = $(shell \ -+ $(PKG_CONFIG) --modversion liburcu 2>/dev/null | \ -+ awk -F. '{ printf("-DURCU_VERSION=0x%06x", 256 * ( 256 * $$1 + $$2) + $$3); }') -+ - DEFINES := - - ifneq ($(call check_func,dm_task_no_flush,$(devmapper_incdir)/libdevmapper.h),0) -@@ -168,6 +172,7 @@ $(TOPDIR)/config.mk: $(multipathdir)/autoconfig.h - @echo creating $@ - @echo "FPIN_SUPPORT := $(FPIN_SUPPORT)" >$@ - @echo "FORTIFY_OPT := $(FORTIFY_OPT)" >>$@ -+ @echo "D_URCU_VERSION := $(call URCU_VERSION)" >>$@ - @echo "SYSTEMD := $(SYSTEMD)" >>$@ - @echo "ANA_SUPPORT := $(ANA_SUPPORT)" >>$@ - @echo "STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector)" >>$@ -diff --git a/libmultipath/alias.c b/libmultipath/alias.c -index e5d3f151..74431f3f 100644 ---- a/libmultipath/alias.c -+++ b/libmultipath/alias.c -@@ -24,6 +24,7 @@ - #include "devmapper.h" - #include "strbuf.h" - #include "time-util.h" -+#include "lock.h" - - /* - * significant parts of this file were taken from iscsi-bindings.c of the -@@ -300,7 +301,7 @@ void handle_bindings_file_inotify(const struct inotify_event *event) - pthread_mutex_unlock(×tamp_mutex); - - if (changed) { -- uatomic_xchg(&bindings_file_changed, 1); -+ uatomic_xchg_int(&bindings_file_changed, 1); - condlog(3, "%s: bindings file must be re-read, new timestamp: %ld.%06ld", - __func__, (long)ts.tv_sec, (long)ts.tv_nsec / 1000); - } else -@@ -775,7 +776,7 @@ static int _read_bindings_file(const struct config *conf, Bindings *bindings, - int rc = 0, ret, fd; - FILE *file; - struct stat st; -- int has_changed = uatomic_xchg(&bindings_file_changed, 0); -+ int has_changed = uatomic_xchg_int(&bindings_file_changed, 0); - - if (!force) { - if (!has_changed) { -diff --git a/libmultipath/lock.h b/libmultipath/lock.h -index 9814be76..ac80d1d8 100644 ---- a/libmultipath/lock.h -+++ b/libmultipath/lock.h -@@ -13,15 +13,20 @@ struct mutex_lock { - int waiters; /* uatomic access only */ - }; - --#if !defined(__GLIBC__) && defined(__GNUC__) && __GNUC__ == 12 -+static inline void init_lock(struct mutex_lock *a) -+{ -+ pthread_mutex_init(&a->mutex, NULL); -+ uatomic_set(&a->waiters, 0); -+} -+ -+#if defined(__GNUC__) && __GNUC__ == 12 && URCU_VERSION < 0xe00 - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Warray-bounds" - #endif - --static inline void init_lock(struct mutex_lock *a) -+static inline int uatomic_xchg_int(int *ptr, int val) - { -- pthread_mutex_init(&a->mutex, NULL); -- uatomic_set(&a->waiters, 0); -+ return uatomic_xchg(ptr, val); - } - - static inline void lock(struct mutex_lock *a) -@@ -31,6 +36,10 @@ static inline void lock(struct mutex_lock *a) - uatomic_dec(&a->waiters); - } - -+#if defined(__GNUC__) && __GNUC__ == 12 && URCU_VERSION < 0xe00 -+#pragma GCC diagnostic pop -+#endif -+ - static inline int trylock(struct mutex_lock *a) - { - return pthread_mutex_trylock(&a->mutex); -@@ -51,10 +60,6 @@ static inline bool lock_has_waiters(struct mutex_lock *a) - return (uatomic_read(&a->waiters) > 0); - } - --#if !defined(__GLIBC__) && defined(__GNUC__) && __GNUC__ == 12 --#pragma GCC diagnostic pop --#endif -- - #define lock_cleanup_pop(a) pthread_cleanup_pop(1) - - void cleanup_lock (void * data); -diff --git a/multipathd/Makefile b/multipathd/Makefile -index cdba3db1..0ba6ecb7 100644 ---- a/multipathd/Makefile -+++ b/multipathd/Makefile -@@ -5,8 +5,6 @@ CLI := multipathc - MANPAGES := multipathd.8 - - CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathpersistdir) -I$(mpathcmddir) -I$(thirdpartydir) \ -- $(shell $(PKG_CONFIG) --modversion liburcu 2>/dev/null | \ -- awk -F. '{ printf("-DURCU_VERSION=0x%06x", 256 * ( 256 * $$1 + $$2) + $$3); }') \ - -DBINDIR='"$(bindir)"' $(SYSTEMD_CPPFLAGS) - - # diff --git a/0039-multipath-tools-fix-spelling.patch b/0039-multipath-tools-fix-spelling.patch deleted file mode 100644 index c0c86f9..0000000 --- a/0039-multipath-tools-fix-spelling.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Fri, 15 Sep 2023 22:22:06 +0200 -Subject: [PATCH] multipath-tools: fix spelling - -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - README.md | 4 ++-- - multipath/multipath.conf.5.in | 2 +- - 2 files changed, 3 insertions(+), 3 deletions(-) - -diff --git a/README.md b/README.md -index 679e55bf..524c9fb1 100644 ---- a/README.md -+++ b/README.md -@@ -92,7 +92,7 @@ The following variables can be passed to the `make` command line: - The default is `$(prefix)/$(LIB)/multipath`, where `$(LIB)` is `lib64` on - systems that have `/lib64`, and `lib` otherwise. - * `configfile="/some/path`": The path to the main configuration file. -- The defalt is `$(etc_prefix)/etc/multipath.conf`. -+ The default is `$(etc_prefix)/etc/multipath.conf`. - * `configdir="/some/path"` : directory to search for additional configuration files. - This used to be the run-time option `config_dir` in earlier versions. - The default is `$(etc_prefix)/etc/multipath/conf.d`. -@@ -141,7 +141,7 @@ The following variables can be passed to the `make` command line: - found on the build system, and `/lib` otherwise. - - The options `configdir`, `plugindir`, `configfile`, and `statedir` above can --be used for setting indvidual paths where the `prefix` variables don't provide -+be used for setting individual paths where the `prefix` variables don't provide - sufficient control. See `Makefile.inc` for even more fine-grained control. - - [^systemd]: Some systemd installations use separate `prefix` and `rootprefix`. -diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in -index d320a88f..226d0019 100644 ---- a/multipath/multipath.conf.5.in -+++ b/multipath/multipath.conf.5.in -@@ -36,7 +36,7 @@ Files ending in \fI.conf\fR in this directory are read - in alphabetical order, after reading \fI@CONFIGFILE@\fR. - They use the same syntax as \fI@CONFIGFILE@\fR itself, - and support all sections and keywords. If a keyword occurs in the same section --in multiple files, the last occurence will take precedence over all others. -+in multiple files, the last occurrence will take precedence over all others. - . - . - .\" ---------------------------------------------------------------------------- diff --git a/0040-multipathd-Added-support-to-handle-FPIN-Li-events-fo.patch b/0040-multipathd-Added-support-to-handle-FPIN-Li-events-fo.patch deleted file mode 100644 index 7ed50a3..0000000 --- a/0040-multipathd-Added-support-to-handle-FPIN-Li-events-fo.patch +++ /dev/null @@ -1,300 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Muneendra -Date: Wed, 20 Sep 2023 20:41:15 -0700 -Subject: [PATCH] multipathd: Added support to handle FPIN-Li events for - FC-NVMe - - This patch adds the support to handle FPIN-Li for FC-NVMe. - On receiving the FPIN-Li events this patch moves the devices paths - which are affected due to link integrity to marginal path groups. - The paths which are set to marginal path group will be unset - on receiving the RSCN events - -(mwilck: minor compile fix for 32-bit architectures) - -Signed-off-by: Muneendra -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - multipathd/fpin_handlers.c | 206 +++++++++++++++++++++++++++---------- - 1 file changed, 151 insertions(+), 55 deletions(-) - -diff --git a/multipathd/fpin_handlers.c b/multipathd/fpin_handlers.c -index aa0f63c9..be087ca0 100644 ---- a/multipathd/fpin_handlers.c -+++ b/multipathd/fpin_handlers.c -@@ -60,18 +60,15 @@ static void _udev_device_unref(void *p) - - - /*set/unset the path state to marginal*/ --static int fpin_set_pathstate(struct path *pp, bool set) -+static void fpin_set_pathstate(struct path *pp, bool set) - { - const char *action = set ? "set" : "unset"; - -- if (!pp || !pp->mpp || !pp->mpp->alias) -- return -1; -- -- condlog(3, "\n%s: %s marginal path %s (fpin)", -- action, pp->mpp->alias, pp->dev_t); -+ condlog(3, "%s: %s marginal path %s (fpin)", -+ pp->mpp ? pp->mpp->alias : "orphan", action, pp->dev_t); - pp->marginal = set; -- pp->mpp->fpin_must_reload = true; -- return 0; -+ if (pp->mpp) -+ pp->mpp->fpin_must_reload = true; - } - - /* This will unset marginal state of a device*/ -@@ -82,14 +79,14 @@ static void fpin_path_unsetmarginal(char *devname, struct vectors *vecs) - pp = find_path_by_dev(vecs->pathvec, devname); - if (!pp) - pp = find_path_by_devt(vecs->pathvec, devname); -- -- fpin_set_pathstate(pp, false); -+ if (pp) -+ fpin_set_pathstate(pp, false); - } - - /*This will set the marginal state of a device*/ --static int fpin_path_setmarginal(struct path *pp) -+static void fpin_path_setmarginal(struct path *pp) - { -- return fpin_set_pathstate(pp, true); -+ fpin_set_pathstate(pp, true); - } - - /* Unsets all the devices in the list from marginal state */ -@@ -183,8 +180,8 @@ static void fpin_set_rport_marginal(struct udev_device *rport_dev) - udev_device_get_syspath(rport_dev)); - } - --/*Add the marginal devices info into the list*/ --static void -+/*Add the marginal devices info into the list and return 0 on success*/ -+static int - fpin_add_marginal_dev_info(uint32_t host_num, char *devname) - { - struct marginal_dev_list *newdev = NULL; -@@ -199,65 +196,160 @@ fpin_add_marginal_dev_info(uint32_t host_num, char *devname) - list_add_tail(&(newdev->node), - &fpin_li_marginal_dev_list_head); - pthread_mutex_unlock(&fpin_li_marginal_dev_mutex); -- } -+ } else -+ return -ENOMEM; -+ return 0; - } - - /* -- * This function goes through the vecs->pathvec, and for -- * each path, check that the host number, -- * the target WWPN associated with the path matches -- * with the els wwpn and sets the path and port state to -+ * This function compares Transport Address Controller Port pn, -+ * Host Transport Address Controller Port pn with the els wwpn ,attached_wwpn -+ * and return 1 (match) or 0 (no match) or a negative error code -+ */ -+static int extract_nvme_addresses_chk_path_pwwn(const char *address, -+ uint64_t els_wwpn, uint64_t els_attached_wwpn) -+ -+{ -+ uint64_t traddr; -+ uint64_t host_traddr; -+ -+ /* -+ * Find the position of "traddr=" and "host_traddr=" -+ * and the address will be in the below format -+ * "traddr=nn-0x200400110dff9400:pn-0x200400110dff9400, -+ * host_traddr=nn-0x200400110dff9400:pn-0x200400110dff9400" -+ */ -+ const char *traddr_start = strstr(address, "traddr="); -+ const char *host_traddr_start = strstr(address, "host_traddr="); -+ -+ if (!traddr_start || !host_traddr_start) -+ return -EINVAL; -+ -+ /* Extract traddr pn */ -+ if (sscanf(traddr_start, "traddr=nn-%*[^:]:pn-%" SCNx64, &traddr) != 1) -+ return -EINVAL; -+ -+ /* Extract host_traddr pn*/ -+ if (sscanf(host_traddr_start, "host_traddr=nn-%*[^:]:pn-%" SCNx64, -+ &host_traddr) != 1) -+ return -EINVAL; -+ condlog(4, "traddr 0x%" PRIx64 " hosttraddr 0x%" PRIx64 " els_wwpn 0x%" -+ PRIx64" els_host_traddr 0x%" PRIx64, -+ traddr, host_traddr, -+ els_wwpn, els_attached_wwpn); -+ if ((host_traddr == els_attached_wwpn) && (traddr == els_wwpn)) -+ return 1; -+ return 0; -+} -+ -+/* -+ * This function check that the Transport Address Controller Port pn, -+ * Host Transport Address Controller Port pn associated with the path matches -+ * with the els wwpn ,attached_wwpn and sets the path state to - * Marginal - */ --static int fpin_chk_wwn_setpath_marginal(uint16_t host_num, struct vectors *vecs, -+static void fpin_check_set_nvme_path_marginal(uint16_t host_num, struct path *pp, -+ uint64_t els_wwpn, uint64_t attached_wwpn) -+{ -+ struct udev_device *ctl = NULL; -+ const char *address = NULL; -+ int ret = 0; -+ -+ ctl = udev_device_get_parent_with_subsystem_devtype(pp->udev, "nvme", NULL); -+ if (ctl == NULL) { -+ condlog(2, "%s: No parent device for ", pp->dev); -+ return; -+ } -+ address = udev_device_get_sysattr_value(ctl, "address"); -+ if (!address) { -+ condlog(2, "%s: unable to get the address ", pp->dev); -+ return; -+ } -+ condlog(4, "\n address %s: dev :%s\n", address, pp->dev); -+ ret = extract_nvme_addresses_chk_path_pwwn(address, els_wwpn, attached_wwpn); -+ if (ret <= 0) -+ return; -+ ret = fpin_add_marginal_dev_info(host_num, pp->dev); -+ if (ret < 0) -+ return; -+ fpin_path_setmarginal(pp); -+} -+ -+/* -+ * This function check the host number, the target WWPN -+ * associated with the path matches with the els wwpn and -+ * sets the path and port state to Marginal -+ */ -+static void fpin_check_set_scsi_path_marginal(uint16_t host_num, struct path *pp, - uint64_t els_wwpn) - { -- struct path *pp; -- struct multipath *mpp; -- int i, k; - char rport_id[42]; - const char *value = NULL; - struct udev_device *rport_dev = NULL; - uint64_t wwpn; - int ret = 0; -+ sprintf(rport_id, "rport-%d:%d-%d", -+ pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.transport_id); -+ rport_dev = udev_device_new_from_subsystem_sysname(udev, -+ "fc_remote_ports", rport_id); -+ if (!rport_dev) { -+ condlog(2, "%s: No fc_remote_port device for '%s'", pp->dev, -+ rport_id); -+ return; -+ } -+ pthread_cleanup_push(_udev_device_unref, rport_dev); -+ value = udev_device_get_sysattr_value(rport_dev, "port_name"); -+ if (!value) -+ goto unref; -+ -+ wwpn = strtol(value, NULL, 16); -+ /* -+ * If the port wwpn matches sets the path and port state -+ * to marginal -+ */ -+ if (wwpn == els_wwpn) { -+ ret = fpin_add_marginal_dev_info(host_num, pp->dev); -+ if (ret < 0) -+ goto unref; -+ fpin_path_setmarginal(pp); -+ fpin_set_rport_marginal(rport_dev); -+ } -+unref: -+ pthread_cleanup_pop(1); -+ return; -+ -+} -+ -+/* -+ * This function goes through the vecs->pathvec, and for -+ * each path, it checks and sets the path state to marginal -+ * if the path's associated port wwpn ,hostnum matches with -+ * els wwnpn ,attached_wwpn -+ */ -+static int fpin_chk_wwn_setpath_marginal(uint16_t host_num, struct vectors *vecs, -+ uint64_t els_wwpn, uint64_t attached_wwpn) -+{ -+ struct path *pp; -+ struct multipath *mpp; -+ int i, k; -+ int ret = 0; - - pthread_cleanup_push(cleanup_lock, &vecs->lock); - lock(&vecs->lock); - pthread_testcancel(); - - vector_foreach_slot(vecs->pathvec, pp, k) { -- /* Checks the host number and also for the SCSI FCP */ -- if (pp->bus != SYSFS_BUS_SCSI || pp->sg_id.proto_id != SCSI_PROTOCOL_FCP || host_num != pp->sg_id.host_no) -+ if (!pp->mpp) - continue; -- sprintf(rport_id, "rport-%d:%d-%d", -- pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.transport_id); -- rport_dev = udev_device_new_from_subsystem_sysname(udev, -- "fc_remote_ports", rport_id); -- if (!rport_dev) { -- condlog(2, "%s: No fc_remote_port device for '%s'", pp->dev, -- rport_id); -- continue; -- } -- pthread_cleanup_push(_udev_device_unref, rport_dev); -- value = udev_device_get_sysattr_value(rport_dev, "port_name"); -- if (!value) -- goto unref; -- -- if (value) -- wwpn = strtol(value, NULL, 16); -- /* -- * If the port wwpn matches sets the path and port state -- * to marginal -- */ -- if (wwpn == els_wwpn) { -- ret = fpin_path_setmarginal(pp); -- if (ret < 0) -- goto unref; -- fpin_set_rport_marginal(rport_dev); -- fpin_add_marginal_dev_info(host_num, pp->dev); -+ /*checks if the bus type is nvme and the protocol is FC-NVMe*/ -+ if ((pp->bus == SYSFS_BUS_NVME) && (pp->sg_id.proto_id == NVME_PROTOCOL_FC)) { -+ fpin_check_set_nvme_path_marginal(host_num, pp, els_wwpn, attached_wwpn); -+ } else if ((pp->bus == SYSFS_BUS_SCSI) && -+ (pp->sg_id.proto_id == SCSI_PROTOCOL_FCP) && -+ (host_num == pp->sg_id.host_no)) { -+ /* Checks the host number and also for the SCSI FCP */ -+ fpin_check_set_scsi_path_marginal(host_num, pp, els_wwpn); - } --unref: -- pthread_cleanup_pop(1); - } - /* walk backwards because reload_and_sync_map() can remove mpp */ - vector_foreach_slot_backwards(vecs->mpvec, mpp, i) { -@@ -286,14 +378,18 @@ fpin_parse_li_els_setpath_marginal(uint16_t host_num, struct fc_tlv_desc *tlv, - struct fc_fn_li_desc *li_desc = (struct fc_fn_li_desc *)tlv; - int count = 0; - int ret = 0; -+ uint64_t attached_wwpn; - - /* Update the wwn to list */ - wwn_count = be32_to_cpu(li_desc->pname_count); -- condlog(4, "Got wwn count as %d\n", wwn_count); -+ attached_wwpn = be64_to_cpu(li_desc->attached_wwpn); -+ condlog(4, "Got wwn count as %d detecting wwn 0x%" PRIx64 -+ " attached_wwpn 0x%" PRIx64 "\n", -+ wwn_count, be64_to_cpu(li_desc->detecting_wwpn), attached_wwpn); - - for (iter = 0; iter < wwn_count; iter++) { - wwpn = be64_to_cpu(li_desc->pname_list[iter]); -- ret = fpin_chk_wwn_setpath_marginal(host_num, vecs, wwpn); -+ ret = fpin_chk_wwn_setpath_marginal(host_num, vecs, wwpn, attached_wwpn); - if (ret < 0) - condlog(2, "failed to set the path marginal associated with wwpn: 0x%" PRIx64 "\n", wwpn); - diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 30c0bbf..5a9b492 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,5 +1,5 @@ Name: device-mapper-multipath -Version: 0.9.6 +Version: 0.9.7 Release: 1%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 @@ -7,62 +7,22 @@ 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 -L https://github.com/opensvc/multipath-tools/archive/0.9.6.tar.gz -o multipath-tools-0.9.6.tgz -Source0: multipath-tools-0.9.6.tgz +# curl -L https://github.com/opensvc/multipath-tools/archive/0.9.7.tar.gz -o multipath-tools-0.9.7.tgz +Source0: multipath-tools-0.9.7.tgz Source1: multipath.conf -Patch0001: 0001-libmultipath-sysfs_set_scsi_tmo-do-nothing-for-ACT_D.patch -Patch0002: 0002-libmultipath-add-alias_already_taken.patch -Patch0003: 0003-libmultipath-unify-use_existing_alias-and-get_user_f.patch -Patch0004: 0004-libmultipath-never-allocate-an-alias-that-s-already-.patch -Patch0005: 0005-libmultipath-lookup_binding-add-comment-about-the-al.patch -Patch0006: 0006-multipath-tools-test-simplify-debugging-for-condlog-.patch -Patch0007: 0007-multipath-tools-tests-add-tests-for-get_user_friendl.patch -Patch0008: 0008-multipath-tools-test-consistent-use-of-macros-in-ali.patch -Patch0009: 0009-multipath-tools-tests-convert-mock_-failed-used-_ali.patch -Patch0010: 0010-multipath-tools-test-use-mock_bindings_file-consiste.patch -Patch0011: 0011-libmultipath-add-global-variable-for-current-binding.patch -Patch0012: 0012-libmultipath-rename-fix_bindings_file-to-update_bind.patch -Patch0013: 0013-libmultipath-alias.c-move-bindings-related-code-up.patch -Patch0014: 0014-libmultipath-update_bindings_file-take-filename-argu.patch -Patch0015: 0015-libmultipath-update_bindings_file-use-a-single-write.patch -Patch0016: 0016-libmultipath-update_bindings_file-don-t-log-temp-fil.patch -Patch0017: 0017-libmultipath-alias.c-factor-out-read_binding.patch -Patch0018: 0018-libmultipath-keep-bindings-in-memory.patch -Patch0019: 0019-multipath-tools-tests-fix-alias-tests.patch -Patch0020: 0020-libmultipath-dm_get_uuid-return-emtpy-UUID-for-non-e.patch -Patch0021: 0021-libmultipath-adapt-to-new-semantics-of-dm_get_uuid.patch -Patch0022: 0022-libmultipath-sort-aliases-by-length-and-strcmp.patch -Patch0023: 0023-multipath-tools-tests-fix-alias-test-after-sort-orde.patch -Patch0024: 0024-libmultipath-simplify-get_free_id-assuming-total-ord.patch -Patch0025: 0025-multipath-tools-tests-adapt-alias-tests-for-total-or.patch -Patch0026: 0026-multipath-tools-tests-add-test-for-ordering-of-bindi.patch -Patch0027: 0027-multipathd-watch-bindings-file-with-inotify-timestam.patch -Patch0028: 0028-multipath-tools-tests-mock-pthread_mutex_-lock-unloc.patch -Patch0029: 0029-multipath-tools-Makefile-sanitize-paths-for-configur.patch -Patch0030: 0030-multipath-tools-add-compile-time-configuration-for-e.patch -Patch0031: 0031-multipath-tools-man-pages-generate-with-correct-path.patch -Patch0032: 0032-libdmmp-Makefile-fix-bug-in-install-section.patch -Patch0033: 0033-multipath-tools-README.md-improve-documentation-for-.patch -Patch0034: 0034-libmultipath-print-built-in-values-for-deprecated-op.patch -Patch0035: 0035-multipath-add-a-missing-newline.patch -Patch0036: 0036-multipath-tools-allow-prefixes-with-and-w-o-trailing.patch -Patch0037: 0037-libmultipath-deprecate-bindings_file-wwids_file-prke.patch -Patch0038: 0038-libmultipath-avoid-Warray-bounds-error-in-uatomic-op.patch -Patch0039: 0039-multipath-tools-fix-spelling.patch -Patch0040: 0040-multipathd-Added-support-to-handle-FPIN-Li-events-fo.patch -Patch0041: 0041-RH-fixup-udev-rules-for-redhat.patch -Patch0042: 0042-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0043: 0043-RH-don-t-start-without-a-config-file.patch -Patch0044: 0044-RH-Fix-nvme-function-missing-argument.patch -Patch0045: 0045-RH-use-rpm-optflags-if-present.patch -Patch0046: 0046-RH-add-mpathconf.patch -Patch0047: 0047-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0048: 0048-RH-reset-default-find_mutipaths-value-to-off.patch -Patch0049: 0049-RH-attempt-to-get-ANA-info-via-sysfs-first.patch -Patch0050: 0050-RH-make-parse_vpd_pg83-match-scsi_id-output.patch -Patch0051: 0051-RH-add-scsi-device-handlers-to-modules-load.d.patch -Patch0052: 0052-RH-compile-with-libreadline-support.patch -Patch0053: 0053-RH-Add-mpathcleanup.patch +Patch0001: 0001-RH-fixup-udev-rules-for-redhat.patch +Patch0002: 0002-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0003: 0003-RH-don-t-start-without-a-config-file.patch +Patch0004: 0004-RH-Fix-nvme-function-missing-argument.patch +Patch0005: 0005-RH-use-rpm-optflags-if-present.patch +Patch0006: 0006-RH-add-mpathconf.patch +Patch0007: 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0008: 0008-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0009: 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0010: 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +Patch0011: 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch +Patch0012: 0012-RH-compile-with-libreadline-support.patch +Patch0013: 0013-RH-Add-mpathcleanup.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -149,7 +109,7 @@ This package contains the files needed to develop applications that use device-mapper-multipath's libdmmp C API library %prep -%autosetup -n multipath-tools-0.9.6 -p1 +%autosetup -n multipath-tools-0.9.7 -p1 cp %{SOURCE1} . %build @@ -212,7 +172,6 @@ fi %config /usr/lib/udev/rules.d/62-multipath.rules %config /usr/lib/udev/rules.d/11-dm-mpath.rules %dir /usr/lib/modules-load.d -/usr/lib/modules-load.d/multipath.conf /usr/lib/modules-load.d/scsi_dh.conf %{_tmpfilesdir}/multipath.conf %doc README.md @@ -272,6 +231,14 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Tue Nov 21 2023 Benjamin Marzinski - 0.9.7-1 +- Update source to upstream version 0.9.7 + * Previous patches 0001-0040 are included in the source tarball +- Rename redhat patches + * Previous patches 0041-0053 are now patches 0001-0013 +- Remove /usr/lib/modules-load.d/multipath.conf + * has been replaced with modprobe@dm_multipath.service unit Wants. + * Fri Sep 22 2023 Benjamin Marzinski - 0.9.6-1 - Update to the head of the upstream staging branch - Rename redhat patches diff --git a/sources b/sources index 5d41f65..89f8f37 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (multipath-tools-0.9.6.tgz) = 17d2b46ead9df6826b3266035bc077a2f4d4bea01e2cd59e32d3917cda40c320f11bc8572da7ba66251e312b46d9be317737069193d481d202d49f9aa5fd71b9 +SHA512 (multipath-tools-0.9.7.tgz) = 0f4c97179a3de5a0c77893fec229eb183293fed8e5e01a9945b261845ccf5d13f8ef2c2ff0c17c9345217d236275caed4765422ec95aed80821f11658bf96e26 SHA512 (multipath.conf) = 71953dce5a68adcf60a942305f5a66023e6f4c4baf53b1bfdb4edf65ed5b8e03db804363c36d1dcfd85591f4766f52b515269904c53b84d7b076da0b80b09942 From f52f69af955c7d182060b0ed07f3bda9b0dabd86 Mon Sep 17 00:00:00 2001 From: Paul Donohue Date: Tue, 28 Nov 2023 17:34:41 -0500 Subject: [PATCH 43/67] device-mapper-multipath-0.9.7-2 Modify 0006-RH-add-mpathconf.patch Modify 0008-RH-reset-default-find_mutipaths-value-to-off.patch * Fix find_multipaths values in docs and mpathconf Signed-off-by: Benjamin Marzinski --- 0006-RH-add-mpathconf.patch | 25 ++++++++++--------- ...-default-find_mutipaths-value-to-off.patch | 19 ++++++++++++-- device-mapper-multipath.spec | 7 +++++- 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/0006-RH-add-mpathconf.patch b/0006-RH-add-mpathconf.patch index 7782f65..fd47a6c 100644 --- a/0006-RH-add-mpathconf.patch +++ b/0006-RH-add-mpathconf.patch @@ -10,6 +10,7 @@ command line. But, mostly it is used to get a multipath.conf file with the OS defaults, and to enable and disable multipathing via a single command. +Co-authored-by: Paul Donohue Signed-off-by: Benjamin Marzinski --- libmultipath/config.c | 2 + @@ -69,7 +70,7 @@ index 504d6892..9f14036c 100644 diff --git a/multipath/mpathconf b/multipath/mpathconf new file mode 100644 -index 00000000..319664b1 +index 00000000..ce430075 --- /dev/null +++ b/multipath/mpathconf @@ -0,0 +1,658 @@ @@ -106,7 +107,7 @@ index 00000000..319664b1 + +defaults { + user_friendly_names yes -+ find_multipaths yes ++ find_multipaths on +}" + +CONFIGFILE="/etc/multipath.conf" @@ -124,7 +125,7 @@ index 00000000..319664b1 + echo "Disable: --disable" + echo "Only allow certain wwids (instead of enable): --allow " + echo "Set user_friendly_names (Default y): --user_friendly_names " -+ echo "Set find_multipaths (Default y): --find_multipaths " ++ echo "Set find_multipaths (Default on): --find_multipaths " + echo "Set default property blacklist (Default n): --property_blacklist " + echo "Set enable_foreign to show foreign devices (Default n): --enable_foreign " + echo "Set recheck_wwid (Defaut n): --recheck_wwid " @@ -328,11 +329,11 @@ index 00000000..319664b1 + exit 1 + fi + if [ "$FIND" = "y" ]; then -+ FIND="yes" ++ FIND="on" + elif [ "$FIND" = "n" ]; then -+ FIND="no" -+ elif [ -n "$FIND" ] && [ "$FIND" != "yes" -a "$FIND" != "no" -a "$FIND" != "strict" -a "$FIND" != "greedy" -a "$FIND" != "smart" ]; then -+ echo "--find_multipaths must be one of 'yes' 'no' 'strict' 'greedy' or 'smart'" ++ FIND="off" ++ elif [ -n "$FIND" ] && [ "$FIND" != "on" -a "$FIND" != "yes" -a "$FIND" != "off" -a "$FIND" != "no" -a "$FIND" != "strict" -a "$FIND" != "greedy" -a "$FIND" != "smart" ]; then ++ echo "--find_multipaths must be one of 'on' 'yes' 'y' 'off' 'no' 'n' 'strict' 'greedy' or 'smart'" + exit 1 + fi + if [ -n "$PROPERTY" ] && [ "$PROPERTY" != "y" -a "$PROPERTY" != "n" ]; then @@ -497,7 +498,7 @@ index 00000000..319664b1 + echo "multipath is disabled" + fi + if [ -z "$HAVE_FIND" ]; then -+ echo "find_multipaths is no" ++ echo "find_multipaths is off" + else + echo "find_multipaths is $HAVE_FIND" + fi @@ -733,7 +734,7 @@ index 00000000..319664b1 +fi diff --git a/multipath/mpathconf.8 b/multipath/mpathconf.8 new file mode 100644 -index 00000000..9c2fb835 +index 00000000..ea025f31 --- /dev/null +++ b/multipath/mpathconf.8 @@ -0,0 +1,151 @@ @@ -779,10 +780,10 @@ index 00000000..9c2fb835 +.B user_friendly_names +set and +.B find_multipaths -+set to \fByes\fP. To disable these, use the ++set to \fBon\fP. To disable these, use the +.B --user_friendly_names n +and -+.B --find_multipaths n ++.B --find_multipaths off +options +.SH COMMANDS +.TP @@ -825,7 +826,7 @@ index 00000000..9c2fb835 +sets an existing \fBrecheck_wwid\fP line to \fBno\fP. This command can be used +along with any other command. +.TP -+.B --find_multipaths\fP { \fByes\fP | \fBno\fP | \fBstrict\fP | \fBgreedy\fP | \fBsmart\fP } ++.B --find_multipaths\fP { \fBon\fP | \fByes\fP | \fBy\fP | \fBoff\fP | \fBno\fP | \fBn\fP | \fBstrict\fP | \fBgreedy\fP | \fBsmart\fP } +If set to \fB\fP, this adds the line +.B find_multipaths +to the diff --git a/0008-RH-reset-default-find_mutipaths-value-to-off.patch b/0008-RH-reset-default-find_mutipaths-value-to-off.patch index 4e1253c..cf7317e 100644 --- a/0008-RH-reset-default-find_mutipaths-value-to-off.patch +++ b/0008-RH-reset-default-find_mutipaths-value-to-off.patch @@ -6,10 +6,12 @@ Subject: [PATCH] RH: reset default find_mutipaths value to off Upstream has changed to default find_multipaths to "strict". For now Redhat will retain the previous default of "off". +Co-authored-by: Paul Donohue Signed-off-by: Benjamin Marzinski --- - libmultipath/defaults.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) + libmultipath/defaults.h | 2 +- + multipath/multipath.conf.5.in | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h index 64b633f2..5bda9f93 100644 @@ -24,3 +26,16 @@ index 64b633f2..5bda9f93 100644 #define DEFAULT_FAST_IO_FAIL 5 #define DEFAULT_DEV_LOSS_TMO 600 #define DEFAULT_RETAIN_HWHANDLER RETAIN_HWHANDLER_ON +diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in +index 87b3b2a5..8e246571 100644 +--- a/multipath/multipath.conf.5.in ++++ b/multipath/multipath.conf.5.in +@@ -1213,7 +1213,7 @@ as non-multipath and passed on to upper layers. + \fBNote:\fR this may cause delays during device detection if + there are single-path devices which aren\'t blacklisted. + .TP +-The default is: \fBstrict\fR ++The default is: \fBoff\fR + .RE + . + . diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 5a9b492..aea93d7 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.9.7 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -231,6 +231,11 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Tue Nov 28 2023 Paul Donohue - 0.9.7-2 +- Modify 0006-RH-add-mpathconf.patch +- Modify 0008-RH-reset-default-find_mutipaths-value-to-off.patch + * Fix find_multipaths values in docs and mpathconf + * Tue Nov 21 2023 Benjamin Marzinski - 0.9.7-1 - Update source to upstream version 0.9.7 * Previous patches 0001-0040 are included in the source tarball From 0f3122f75fe934276c0e8672f11b8d0a8abada11 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Wed, 29 Nov 2023 22:24:39 -0500 Subject: [PATCH 44/67] device-mapper-multipath-0.9.7-3 Fix multipath_conf_syntax test Fix restate_module test Fix find_multipaths test --- device-mapper-multipath.spec | 6 +++++- tests/find_multipaths/main.sh | 1 + tests/multipath_conf_syntax/main.sh | 2 +- tests/restate_module/main.sh | 2 +- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index aea93d7..1fdaa06 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.9.7 -Release: 2%{?dist} +Release: 3%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -231,6 +231,10 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Wed Nov 29 2023 Benjamin Marzinski - 0.9.7-3 +- Fix multipath_conf_syntax test +- Fix restate_module test + * Tue Nov 28 2023 Paul Donohue - 0.9.7-2 - Modify 0006-RH-add-mpathconf.patch - Modify 0008-RH-reset-default-find_mutipaths-value-to-off.patch diff --git a/tests/find_multipaths/main.sh b/tests/find_multipaths/main.sh index a39af79..4d94c87 100755 --- a/tests/find_multipaths/main.sh +++ b/tests/find_multipaths/main.sh @@ -40,6 +40,7 @@ rpm -q device-mapper-multipath || yum install -y device-mapper-multipath # test with find_multipath=y, will not multipath for the single device; reload/start the service to enable the config cleanup trun "rm -f /etc/multipath.conf" +trun "rm -f /etc/multipath/wwids" trun "mpathconf --enable --user_friendly_names y --find_multipaths y --with_multipathd n" sed -i '/^blacklist[[:space:]]*{/ a\ device {\n vendor ".*"\n product ".*"\n } diff --git a/tests/multipath_conf_syntax/main.sh b/tests/multipath_conf_syntax/main.sh index 331d65e..fb303c3 100755 --- a/tests/multipath_conf_syntax/main.sh +++ b/tests/multipath_conf_syntax/main.sh @@ -119,7 +119,7 @@ tok "multipath -ll | grep mypath" # test wrong alias keyword trun "sed -i 's/alias.*$/alia mypath/g' /etc/multipath.conf" -tok "multipath 2>&1 | grep 'invalid keyword: alia'" +tok "multipath 2>&1 | grep 'invalid keyword in the multipath section: alia'" trun "multipath -r" tok "multipath -ll | grep mpath" trun "sed -i 's/alia.*$/alias mypath/g' /etc/multipath.conf" diff --git a/tests/restate_module/main.sh b/tests/restate_module/main.sh index 7f3279d..565e59c 100755 --- a/tests/restate_module/main.sh +++ b/tests/restate_module/main.sh @@ -69,7 +69,7 @@ tlog "Checking if active path count equals 2" assert "[[ $pathcount -eq 2 ]]" tlog "offline one path device" -pathname=`multipathd show paths raw format "%d %m" | grep ${mpathdev} | head -1 | awk '{print $1}'` +pathname=`multipathd show paths raw format "%d %m %p" | grep ${mpathdev} | sort -k 3n | head -1 | awk '{print $1}'` tlog "path to offline: ${pathname}" trun "echo 'offline' > /sys/block/${pathname}/device/state" tlog "waiting for multipathd to fail path" From b0b20d4f7b4de67597a1db368eb183c938714547 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 30 Nov 2023 16:30:05 -0500 Subject: [PATCH 45/67] device-mapper-multipath-0.9.7-4 Use modulesloaddir macro for installing scsi_dh.conf --- device-mapper-multipath.spec | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 1fdaa06..2a92a06 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.9.7 -Release: 3%{?dist} +Release: 4%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -171,8 +171,8 @@ fi %{_mandir}/man8/mpathpersist.8* %config /usr/lib/udev/rules.d/62-multipath.rules %config /usr/lib/udev/rules.d/11-dm-mpath.rules -%dir /usr/lib/modules-load.d -/usr/lib/modules-load.d/scsi_dh.conf +%dir %{_modulesloaddir} +%{_modulesloaddir}/scsi_dh.conf %{_tmpfilesdir}/multipath.conf %doc README.md %doc multipath.conf @@ -231,6 +231,9 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Thu Nov 30 2023 Benjamin Marzinski - 0.9.7-4 +- Use modulesloaddir macro for installing scsi_dh.conf + * Wed Nov 29 2023 Benjamin Marzinski - 0.9.7-3 - Fix multipath_conf_syntax test - Fix restate_module test From 835a8a43de1620fcb450510713cbdeb859b318d5 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Tue, 16 Jan 2024 22:54:08 -0500 Subject: [PATCH 46/67] device-mapper-multipath-0.9.7-5 Add 0014-multipathd-fix-null-pointer-dereference-in-uev_updat.patch * Fix auto_resize code to avoid a segfault Add 0015-multipathd-fix-auto-resize-configuration.patch * Fix auto_resize default value --- ...ull-pointer-dereference-in-uev_updat.patch | 27 ++++++++++++ ...ipathd-fix-auto-resize-configuration.patch | 42 +++++++++++++++++++ device-mapper-multipath.spec | 10 ++++- 3 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 0014-multipathd-fix-null-pointer-dereference-in-uev_updat.patch create mode 100644 0015-multipathd-fix-auto-resize-configuration.patch diff --git a/0014-multipathd-fix-null-pointer-dereference-in-uev_updat.patch b/0014-multipathd-fix-null-pointer-dereference-in-uev_updat.patch new file mode 100644 index 0000000..7655591 --- /dev/null +++ b/0014-multipathd-fix-null-pointer-dereference-in-uev_updat.patch @@ -0,0 +1,27 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 16 Jan 2024 00:54:37 -0500 +Subject: [PATCH] multipathd: fix null pointer dereference in uev_update_path + +The Auto-resize code added a check that deferences pp->mpp without +checking that it's non-NULL. Fix it. + +Fixes: 981b83ad1 ("multipathd: Add auto_resize config option") +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 230c9d10..57c04364 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -1653,7 +1653,7 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) + } + } + } +- if (auto_resize != AUTO_RESIZE_NEVER && ++ if (auto_resize != AUTO_RESIZE_NEVER && mpp && + !mpp->wait_for_udev) { + struct pathgroup *pgp; + struct path *pp2; diff --git a/0015-multipathd-fix-auto-resize-configuration.patch b/0015-multipathd-fix-auto-resize-configuration.patch new file mode 100644 index 0000000..35e4d48 --- /dev/null +++ b/0015-multipathd-fix-auto-resize-configuration.patch @@ -0,0 +1,42 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 16 Jan 2024 01:11:02 -0500 +Subject: [PATCH] multipathd: fix auto-resize configuration + +The code acted like AUTO_RESIZE_UNDEFINED didn't exist, but since +conf->auto_resize was never set to AUTO_RESIZE_NEVER, the default was in +fact AUTO_RESIZE_UNDEFINED, which ended up getting treated like +AUTO_RESIZE_GROW_SHRINK. Remove AUTO_RESIZE_UNDEFINED and explicitly +default auto_resize tp AUTO_RESIZE_NEVER. + +Fixes: 981b83ad1 ("multipathd: Add auto_resize config option") +Signed-off-by: Benjamin Marzinski +--- + libmultipath/config.c | 1 + + libmultipath/structs.h | 1 - + 2 files changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmultipath/config.c b/libmultipath/config.c +index 4544f484..3d5943d3 100644 +--- a/libmultipath/config.c ++++ b/libmultipath/config.c +@@ -927,6 +927,7 @@ int _init_config (const char *file, struct config *conf) + conf->retrigger_tries = DEFAULT_RETRIGGER_TRIES; + conf->retrigger_delay = DEFAULT_RETRIGGER_DELAY; + conf->uev_wait_timeout = DEFAULT_UEV_WAIT_TIMEOUT; ++ conf->auto_resize = DEFAULT_AUTO_RESIZE; + conf->remove_retries = 0; + conf->ghost_delay = DEFAULT_GHOST_DELAY; + conf->all_tg_pt = DEFAULT_ALL_TG_PT; +diff --git a/libmultipath/structs.h b/libmultipath/structs.h +index a1aac1b4..734905e2 100644 +--- a/libmultipath/structs.h ++++ b/libmultipath/structs.h +@@ -180,7 +180,6 @@ enum queue_mode_states { + }; + + enum auto_resize_state { +- AUTO_RESIZE_UNDEF = 0, + AUTO_RESIZE_NEVER, + AUTO_RESIZE_GROW_ONLY, + AUTO_RESIZE_GROW_SHRINK, diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 2a92a06..b448595 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.9.7 -Release: 4%{?dist} +Release: 5%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -23,6 +23,8 @@ Patch0010: 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch Patch0011: 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch Patch0012: 0012-RH-compile-with-libreadline-support.patch Patch0013: 0013-RH-Add-mpathcleanup.patch +Patch0014: 0014-multipathd-fix-null-pointer-dereference-in-uev_updat.patch +Patch0015: 0015-multipathd-fix-auto-resize-configuration.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -231,6 +233,12 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Tue Jan 16 2024 Benjamin Marzinski - 0.9.7-5 +- Add 0014-multipathd-fix-null-pointer-dereference-in-uev_updat.patch + * Fix auto_resize code to avoid a segfault +- Add 0015-multipathd-fix-auto-resize-configuration.patch + * Fix auto_resize default value + * Thu Nov 30 2023 Benjamin Marzinski - 0.9.7-4 - Use modulesloaddir macro for installing scsi_dh.conf From c9568c86e6bd6a57461f3ca10225a45b57a664ca Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Fri, 19 Jan 2024 17:03:18 +0000 Subject: [PATCH 47/67] Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild --- device-mapper-multipath.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index b448595..2b4e20d 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.9.7 -Release: 5%{?dist} +Release: 6%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -233,6 +233,9 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Fri Jan 19 2024 Fedora Release Engineering - 0.9.7-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + * Tue Jan 16 2024 Benjamin Marzinski - 0.9.7-5 - Add 0014-multipathd-fix-null-pointer-dereference-in-uev_updat.patch * Fix auto_resize code to avoid a segfault From 6956fa4aa7f800ccf59fd8d4569975fd36fd9f11 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 24 Jan 2024 09:20:08 +0000 Subject: [PATCH 48/67] Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild --- device-mapper-multipath.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 2b4e20d..3cf8fb0 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.9.7 -Release: 6%{?dist} +Release: 7%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -233,6 +233,9 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Wed Jan 24 2024 Fedora Release Engineering - 0.9.7-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + * Fri Jan 19 2024 Fedora Release Engineering - 0.9.7-6 - Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild From 6496193f3f25e1033cd68e6248baaa16bd4bf4ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 17 Apr 2024 22:49:31 +0200 Subject: [PATCH 49/67] Stop harcoding paths Preparation for https://fedoraproject.org/wiki/Changes/Unify_bin_and_sbin. Packages must honour macros for directories, in particular %_sbindir may be set to /usr/bin. --- device-mapper-multipath.spec | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 3cf8fb0..78bef5a 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -115,7 +115,6 @@ device-mapper-multipath's libdmmp C API library cp %{SOURCE1} . %build -%define _sbindir /usr/sbin %define _libdir /usr/%{_lib} %define _libmpathdir %{_libdir}/multipath %define _pkgconfdir %{_libdir}/pkgconfig @@ -146,7 +145,7 @@ rm -rf %{buildroot}/%{_initrddir} %postun if [ $1 -ge 1 ] ; then - /sbin/multipathd forcequeueing daemon > /dev/null 2>&1 || : + multipathd forcequeueing daemon > /dev/null 2>&1 || : fi %systemd_postun_with_restart multipathd.service From 588b3f63e9e24d8b4e5e810601fd417301f95e5a Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Mon, 20 May 2024 22:01:48 -0400 Subject: [PATCH 50/67] device-mapper-multipath-0.9.8-1 Update source to upstream version 0.9.8 plus latest staging branch * Previous patches 0014 & 0015 are included in the source tarball * patches 0001-0044 are from the upstream staging branch. Rename redhat patches * Previous patches 0001-0013 are now patches 0045-0057 --- .gitignore | 1 + ...s-fix-misspelled-DM_UDEV_DISABLE_OTH.patch | 27 ++ ...ondlog-level-for-setscheduler-error-.patch | 27 ++ ...e-multipathd-scheduling-configurable.patch | 87 +++++ ...til-really-always-use-glibc-basename.patch | 144 ++++++++ ...multipathd-set-priority-to-RLIMIT_RT.patch | 134 +++++++ ...PUWeight-to-1000-and-LimitRTPRIO-to-.patch | 33 ++ ...s-explain-logic-for-device-becoming-.patch | 30 ++ ...s-don-t-import-DM_NOSCAN-from-udev-d.patch | 37 ++ ...s-don-t-import-ID_FS_VERSION-from-ud.patch | 27 ++ ...s-adapt-MPATH_DEVICE_READY-0-logic-t.patch | 67 ++++ ...s-adapt-coldplug-event-handling-ro-1.patch | 43 +++ ...s-don-t-import-properties-with-new-1.patch | 36 ++ ...s-replace-DM_SUSPENDED-by-.DM_SUSPEN.patch | 75 ++++ ...ules-replace-DM_NOSCAN-by-.DM_NOSCAN.patch | 55 +++ ...ull-pointer-dereference-in-uev_updat.patch | 27 -- ...path.rules-simplify-PATH_FAILED-case.patch | 38 ++ ...ipathd-fix-auto-resize-configuration.patch | 42 --- ...ules-make-label-names-more-intuitive.patch | 109 ++++++ 0017-kpartx.rules-ignore-DM_SUSPENDED.patch | 29 ++ ...tests-fix-CI-failures-on-arm-v7-with.patch | 270 ++++++++++++++ ...tests-fix-CI-failures-with-clang-on-.patch | 246 +++++++++++++ ...GitHub-actions-fixes-for-spelling-CI.patch | 31 ++ ...-run-workflows-if-workflow-file-has-.patch | 146 ++++++++ 0022-multipath-tools-add-TGTDIR-option.patch | 106 ++++++ ...ath-move-get_udev_for_mpp-to-sysfs.c.patch | 87 +++++ ...ibmultipath-add-mp_find_path_by_devt.patch | 60 +++ ...ath-fix-max_sectors_kb-on-adding-pat.patch | 33 ++ ...y-set-max_sectors_kb-on-map-creation.patch | 122 ++++++ ...th-set-max_sectors_kb-in-adopt_paths.patch | 233 ++++++++++++ ...-wildcard-k-for-printing-max_sectors.patch | 89 +++++ ...-update-documentation-for-max_sector.patch | 57 +++ ...th-tools-simplify-comment-in-hwtable.patch | 34 ++ ...tools-unify-text-in-multipath.conf.5.patch | 75 ++++ ...ltipath-tools-update-man-pages-dates.patch | 86 +++++ 0033-libmultipath-export-partmap_in_use.patch | 53 +++ ...nge-flush_on_last_del-to-fix-a-multi.patch | 346 ++++++++++++++++++ ...ove-redundant-config-option-from-Inf.patch | 31 ++ ...-dev_loss_tmo-to-avoid-race-with-no_.patch | 40 ++ ...x-deferred_remove-function-arguments.patch | 107 ++++++ ...e-bitwise-flags-for-map-flushing-API.patch | 212 +++++++++++ ...e-bitwise-flags-for-dm_simplecmd-API.patch | 117 ++++++ ...dd-argument-names-to-some-prototypes.patch | 34 ++ 0041-libmultipath-bump-version-to-0.9.9.patch | 27 ++ ...kflows-native.yaml-run-for-Fedora-40.patch | 24 ++ 0043-update-NEWS.md.patch | 134 +++++++ ...ultipath.conf.5.in-fix-man-page-date.patch | 24 ++ ... 0045-RH-fixup-udev-rules-for-redhat.patch | 16 +- ...property-blacklist-exception-builtin.patch | 6 +- ...RH-don-t-start-without-a-config-file.patch | 20 +- ...H-Fix-nvme-function-missing-argument.patch | 0 ... 0049-RH-use-rpm-optflags-if-present.patch | 10 +- ...hconf.patch => 0050-RH-add-mpathconf.patch | 13 +- ...om-kernel-cmdline-mpath.wwids-with-A.patch | 10 +- ...-default-find_mutipaths-value-to-off.patch | 6 +- ...empt-to-get-ANA-info-via-sysfs-first.patch | 0 ...-parse_vpd_pg83-match-scsi_id-output.patch | 18 +- ...si-device-handlers-to-modules-load.d.patch | 2 +- ...-RH-compile-with-libreadline-support.patch | 2 +- ...up.patch => 0057-RH-Add-mpathcleanup.patch | 8 +- device-mapper-multipath.spec | 91 ++++- sources | 2 +- 62 files changed, 3951 insertions(+), 145 deletions(-) create mode 100644 0001-11-dm-mpath.rules-fix-misspelled-DM_UDEV_DISABLE_OTH.patch create mode 100644 0002-multipathd-use-condlog-level-for-setscheduler-error-.patch create mode 100644 0003-multipathd-make-multipathd-scheduling-configurable.patch create mode 100644 0004-libmpathutil-really-always-use-glibc-basename.patch create mode 100644 0005-multipathd-make-multipathd-set-priority-to-RLIMIT_RT.patch create mode 100644 0006-multipathd-Set-CPUWeight-to-1000-and-LimitRTPRIO-to-.patch create mode 100644 0007-11-dm-mpath.rules-explain-logic-for-device-becoming-.patch create mode 100644 0008-11-dm-mpath.rules-don-t-import-DM_NOSCAN-from-udev-d.patch create mode 100644 0009-11-dm-mpath.rules-don-t-import-ID_FS_VERSION-from-ud.patch create mode 100644 0010-11-dm-mpath.rules-adapt-MPATH_DEVICE_READY-0-logic-t.patch create mode 100644 0011-11-dm-mpath.rules-adapt-coldplug-event-handling-ro-1.patch create mode 100644 0012-11-dm-mpath.rules-don-t-import-properties-with-new-1.patch create mode 100644 0013-11-dm-mpath.rules-replace-DM_SUSPENDED-by-.DM_SUSPEN.patch create mode 100644 0014-11-dm-mpath.rules-replace-DM_NOSCAN-by-.DM_NOSCAN.patch delete mode 100644 0014-multipathd-fix-null-pointer-dereference-in-uev_updat.patch create mode 100644 0015-11-dm-mpath.rules-simplify-PATH_FAILED-case.patch delete mode 100644 0015-multipathd-fix-auto-resize-configuration.patch create mode 100644 0016-11-dm-mpath.rules-make-label-names-more-intuitive.patch create mode 100644 0017-kpartx.rules-ignore-DM_SUSPENDED.patch create mode 100644 0018-multipath-tools-tests-fix-CI-failures-on-arm-v7-with.patch create mode 100644 0019-multipath-tools-tests-fix-CI-failures-with-clang-on-.patch create mode 100644 0020-GitHub-actions-fixes-for-spelling-CI.patch create mode 100644 0021-GitHub-workflows-run-workflows-if-workflow-file-has-.patch create mode 100644 0022-multipath-tools-add-TGTDIR-option.patch create mode 100644 0023-libmultipath-move-get_udev_for_mpp-to-sysfs.c.patch create mode 100644 0024-libmultipath-add-mp_find_path_by_devt.patch create mode 100644 0025-Revert-libmultipath-fix-max_sectors_kb-on-adding-pat.patch create mode 100644 0026-libmultipath-Only-set-max_sectors_kb-on-map-creation.patch create mode 100644 0027-libmultipath-set-max_sectors_kb-in-adopt_paths.patch create mode 100644 0028-libmultipath-add-wildcard-k-for-printing-max_sectors.patch create mode 100644 0029-multipath.conf-5-update-documentation-for-max_sector.patch create mode 100644 0030-multipath-tools-simplify-comment-in-hwtable.patch create mode 100644 0031-multipath-tools-unify-text-in-multipath.conf.5.patch create mode 100644 0032-multipath-tools-update-man-pages-dates.patch create mode 100644 0033-libmultipath-export-partmap_in_use.patch create mode 100644 0034-libmultipath-change-flush_on_last_del-to-fix-a-multi.patch create mode 100644 0035-libmultipath-remove-redundant-config-option-from-Inf.patch create mode 100644 0036-libmultipath-pad-dev_loss_tmo-to-avoid-race-with-no_.patch create mode 100644 0037-libmultipath-fix-deferred_remove-function-arguments.patch create mode 100644 0038-libmultipath-use-bitwise-flags-for-map-flushing-API.patch create mode 100644 0039-libmultipath-use-bitwise-flags-for-dm_simplecmd-API.patch create mode 100644 0040-libmultipath-add-argument-names-to-some-prototypes.patch create mode 100644 0041-libmultipath-bump-version-to-0.9.9.patch create mode 100644 0042-GitHub-Workflows-native.yaml-run-for-Fedora-40.patch create mode 100644 0043-update-NEWS.md.patch create mode 100644 0044-multipath.conf.5.in-fix-man-page-date.patch rename 0001-RH-fixup-udev-rules-for-redhat.patch => 0045-RH-fixup-udev-rules-for-redhat.patch (86%) rename 0002-RH-Remove-the-property-blacklist-exception-builtin.patch => 0046-RH-Remove-the-property-blacklist-exception-builtin.patch (96%) rename 0003-RH-don-t-start-without-a-config-file.patch => 0047-RH-don-t-start-without-a-config-file.patch (92%) rename 0004-RH-Fix-nvme-function-missing-argument.patch => 0048-RH-Fix-nvme-function-missing-argument.patch (100%) rename 0005-RH-use-rpm-optflags-if-present.patch => 0049-RH-use-rpm-optflags-if-present.patch (87%) rename 0006-RH-add-mpathconf.patch => 0050-RH-add-mpathconf.patch (98%) rename 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch => 0051-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch (96%) rename 0008-RH-reset-default-find_mutipaths-value-to-off.patch => 0052-RH-reset-default-find_mutipaths-value-to-off.patch (91%) rename 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch => 0053-RH-attempt-to-get-ANA-info-via-sysfs-first.patch (100%) rename 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch => 0054-RH-make-parse_vpd_pg83-match-scsi_id-output.patch (84%) rename 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch => 0055-RH-add-scsi-device-handlers-to-modules-load.d.patch (96%) rename 0012-RH-compile-with-libreadline-support.patch => 0056-RH-compile-with-libreadline-support.patch (96%) rename 0013-RH-Add-mpathcleanup.patch => 0057-RH-Add-mpathcleanup.patch (96%) diff --git a/.gitignore b/.gitignore index f698d08..80e9936 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,4 @@ multipath-tools-091027.tar.gz /multipath-tools-0.9.5.tgz /multipath-tools-0.9.6.tgz /multipath-tools-0.9.7.tgz +/multipath-tools-0.9.8.tgz diff --git a/0001-11-dm-mpath.rules-fix-misspelled-DM_UDEV_DISABLE_OTH.patch b/0001-11-dm-mpath.rules-fix-misspelled-DM_UDEV_DISABLE_OTH.patch new file mode 100644 index 0000000..4b9d7fc --- /dev/null +++ b/0001-11-dm-mpath.rules-fix-misspelled-DM_UDEV_DISABLE_OTH.patch @@ -0,0 +1,27 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 1 Mar 2024 18:16:32 +0100 +Subject: [PATCH] 11-dm-mpath.rules: fix misspelled + DM_UDEV_DISABLE_OTHER_RULES_FLAG + +Fixes: b3582da ("11-dm-mpath.rules: use import logic like 13-dm-disk.rules") +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/11-dm-mpath.rules.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in +index d364f9bc..d9585abf 100644 +--- a/multipath/11-dm-mpath.rules.in ++++ b/multipath/11-dm-mpath.rules.in +@@ -116,7 +116,7 @@ LABEL="scan_import" + ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}!="1", GOTO="import_end" + + # Don't import the properties from db if we will run blkid later. +-ENV{DM_NOSCAN}!="1", ENV{DM_DISABLE_OTHER_RULES_FLAG}!="1", GOTO="import_end" ++ENV{DM_NOSCAN}!="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}!="1", GOTO="import_end" + + IMPORT{db}="ID_FS_TYPE" + IMPORT{db}="ID_FS_USAGE" diff --git a/0002-multipathd-use-condlog-level-for-setscheduler-error-.patch b/0002-multipathd-use-condlog-level-for-setscheduler-error-.patch new file mode 100644 index 0000000..8a6ff99 --- /dev/null +++ b/0002-multipathd-use-condlog-level-for-setscheduler-error-.patch @@ -0,0 +1,27 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Fri, 1 Mar 2024 19:37:29 -0500 +Subject: [PATCH] multipathd: use condlog level for setscheduler error message + +condlog uses its own log levels, so LOG_WARNING makes no sense. It +actually translates to a message sent at the LOG_DEBUG level. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + multipathd/main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 6193e691..85ac540f 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -3178,7 +3178,7 @@ setscheduler (void) + res = sched_setscheduler (0, SCHED_RR, &sched_param); + + if (res == -1) +- condlog(LOG_WARNING, "Could not set SCHED_RR at priority 99"); ++ condlog(2, "Could not set SCHED_RR at priority 99"); + return; + } + diff --git a/0003-multipathd-make-multipathd-scheduling-configurable.patch b/0003-multipathd-make-multipathd-scheduling-configurable.patch new file mode 100644 index 0000000..8529152 --- /dev/null +++ b/0003-multipathd-make-multipathd-scheduling-configurable.patch @@ -0,0 +1,87 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Fri, 1 Mar 2024 19:37:30 -0500 +Subject: [PATCH] multipathd: make multipathd scheduling configurable + +Currently multipathd always tries to run as a realtime process with a +priority of 99. This is excessive. As a first step towards fixing this, +make it possible at compile time to lower the priority or keep +multipathd from making itself a realtime process. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + Makefile.inc | 6 ++++++ + README.md | 3 +++ + multipathd/Makefile | 3 +++ + multipathd/main.c | 5 +++-- + 4 files changed, 15 insertions(+), 2 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 5668e638..6d206281 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -18,6 +18,12 @@ READLINE := + # SCSI_DH_MODULES_PRELOAD := scsi_dh_alua scsi_dh_rdac + SCSI_DH_MODULES_PRELOAD := + ++# Multipathd scheduling priority. Set value from 1 to 99 to make multipathd ++# change its scheduling policy to SCHED_RR and its priority to the specified ++# value. set to 0 to stop multipathd from changing the scheduling policy and ++# priority it was started with. ++SCHED_RT_PRIO := 99 ++ + EXTRAVERSION := $(shell rev=$$(git rev-parse --short=7 HEAD 2>/dev/null); echo $${rev:+-g$$rev}) + + # PKG_CONFIG must be read from the environment to enable compilation +diff --git a/README.md b/README.md +index d4f35f57..bb41bf0e 100644 +--- a/README.md ++++ b/README.md +@@ -98,6 +98,9 @@ The following variables can be passed to the `make` command line: + By default, command line editing is disabled. + Note that using libreadline may + [make binary indistributable due to license incompatibility](https://github.com/opensvc/multipath-tools/issues/36). ++ * `SCHED_RT_PRIO={0-99}`: for values {1-99} set the realtime priority ++ multipathd will attempt to run with. for value 0, disable multipathd ++ changing itself to a realtime process. + * `ENABLE_LIBDMMP=0`: disable building libdmmp + * `ENABLE_DMEVENTS_POLL=0`: disable support for the device-mapper event + polling API. For use with pre-5.0 kernels that don't support dmevent polling +diff --git a/multipathd/Makefile b/multipathd/Makefile +index 997b40cf..7300f07a 100644 +--- a/multipathd/Makefile ++++ b/multipathd/Makefile +@@ -57,6 +57,9 @@ $(CLI): $(CLI_OBJS) + cli_handlers.o: cli_handlers.c + $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-parameter -c -o $@ $< + ++main.o: main.c ++ $(Q)$(CC) $(CPPFLAGS) -DSCHED_RT_PRIO=$(SCHED_RT_PRIO) $(CFLAGS) -c -o $@ $< ++ + install: + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) + $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir) +diff --git a/multipathd/main.c b/multipathd/main.c +index 85ac540f..9486a8a3 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -3172,7 +3172,7 @@ setscheduler (void) + { + int res; + static struct sched_param sched_param = { +- .sched_priority = 99 ++ .sched_priority = SCHED_RT_PRIO + }; + + res = sched_setscheduler (0, SCHED_RR, &sched_param); +@@ -3471,7 +3471,8 @@ child (__attribute__((unused)) void *param) + if (!vecs) + goto failed; + +- setscheduler(); ++ if (SCHED_RT_PRIO) ++ setscheduler(); + set_oom_adj(); + #ifdef FPIN_EVENT_HANDLER + if (conf->marginal_pathgroups == MARGINAL_PATHGROUP_FPIN) diff --git a/0004-libmpathutil-really-always-use-glibc-basename.patch b/0004-libmpathutil-really-always-use-glibc-basename.patch new file mode 100644 index 0000000..78f8859 --- /dev/null +++ b/0004-libmpathutil-really-always-use-glibc-basename.patch @@ -0,0 +1,144 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 3 Apr 2024 18:55:54 +0200 +Subject: [PATCH] libmpathutil: really always use glibc basename() + +Despite 03a5456 ("libmultipath: always use glibc basename()"), we +still call the system library's basename() from libmultipath. +musl libc until 1.24 provided a prototype for basename() in string.h, +which was not correct and was resolved to the destructive POSIX +basename(). musl libc 1.25 removed this prototype. + +While the remaining code path doesn't strictly depend on the non-destructive +behavior of glibc's basename(), it's cleaner and safer to use the same +implementation everywhere. + +Fixes: 03a5456 ("libmultipath: always use glibc basename()") +Fixes: https://github.com/opensvc/multipath-tools/pull/84 + +Signed-off-by: Martin Wilck +Reviewed-by: Khem Raj +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmpathutil/libmpathutil.version | 4 ++++ + libmpathutil/util.c | 5 +---- + libmpathutil/util.h | 5 +++++ + tests/util.c | 31 +++++++++++++++++++++++++++++++ + 4 files changed, 41 insertions(+), 4 deletions(-) + +diff --git a/libmpathutil/libmpathutil.version b/libmpathutil/libmpathutil.version +index 80d64a3e..fee74a32 100644 +--- a/libmpathutil/libmpathutil.version ++++ b/libmpathutil/libmpathutil.version +@@ -129,3 +129,7 @@ LIBMPATHUTIL_2.0 { + vector_move_up; + vector_sort; + }; ++ ++LIBMPATHUTIL_2.1 { ++ libmp_basename; ++}; +diff --git a/libmpathutil/util.c b/libmpathutil/util.c +index 9d147fca..23d303f9 100644 +--- a/libmpathutil/util.c ++++ b/libmpathutil/util.c +@@ -32,18 +32,15 @@ strchop(char *str) + return i; + } + +-#ifndef __GLIBC__ + /* + * glibc's non-destructive version of basename() + * License: LGPL-2.1-or-later + */ +-static const char *__basename(const char *filename) ++const char *libmp_basename(const char *filename) + { + char *p = strrchr(filename, '/'); + return p ? p + 1 : filename; + } +-#define basename(x) __basename(x) +-#endif + + int + basenamecpy (const char *src, char *dst, size_t size) +diff --git a/libmpathutil/util.h b/libmpathutil/util.h +index de9fcfdd..4997fed6 100644 +--- a/libmpathutil/util.h ++++ b/libmpathutil/util.h +@@ -12,6 +12,11 @@ + #include + + size_t strchop(char *); ++ ++const char *libmp_basename(const char *filename); ++#ifndef __GLIBC__ ++#define basename(x) libmp_basename(x) ++#endif + int basenamecpy (const char *src, char *dst, size_t size); + int filepresent (const char *run); + char *get_next_string(char **temp, const char *split_char); +diff --git a/tests/util.c b/tests/util.c +index d6083dce..4850ddcb 100644 +--- a/tests/util.c ++++ b/tests/util.c +@@ -16,6 +16,7 @@ + * + */ + ++#define _GNU_SOURCE + #include + #include + #include +@@ -23,6 +24,7 @@ + #include + #include + #include ++#include + #include "util.h" + + #include "globals.c" +@@ -163,6 +165,34 @@ static int test_basenamecpy(void) + return cmocka_run_group_tests(tests, NULL, NULL); + } + ++static void test_basename_01(void **state) ++{ ++ const char *path = "/foo/bar"; ++ const char *base; ++ ++ base = basename(path); ++ assert_string_equal(base, "bar"); ++ assert_string_equal(path, "/foo/bar"); ++} ++ ++static void test_basename_02(void **state) ++{ ++ const char *path = "/foo/bar/"; ++ const char *base; ++ ++ base = basename(path); ++ assert_string_equal(base, ""); ++ assert_string_equal(path, "/foo/bar/"); ++} ++ ++static int test_basename(void) { ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test(test_basename_01), ++ cmocka_unit_test(test_basename_02), ++ }; ++ return cmocka_run_group_tests(tests, NULL, NULL); ++} ++ + /* + * On big endian systems, if bitfield_t is 32bit, we need + * to swap the two 32 bit parts of a 64bit value to make +@@ -946,6 +976,7 @@ int main(void) + + init_test_verbosity(-1); + ret += test_basenamecpy(); ++ ret += test_basename(); + ret += test_bitmasks(); + ret += test_strlcpy(); + ret += test_strlcat(); diff --git a/0005-multipathd-make-multipathd-set-priority-to-RLIMIT_RT.patch b/0005-multipathd-make-multipathd-set-priority-to-RLIMIT_RT.patch new file mode 100644 index 0000000..fd12767 --- /dev/null +++ b/0005-multipathd-make-multipathd-set-priority-to-RLIMIT_RT.patch @@ -0,0 +1,134 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 9 Apr 2024 18:56:12 -0400 +Subject: [PATCH] multipathd: make multipathd set priority to RLIMIT_RTPRIO + +With this change, if the SCHED_RT_PRIO compiler flag has been removed. +Instead multipathd will call getrlimit(RLIMIT_RTPRIO, ...) and look at +the hard limit. It it's 0, multipath will do nothing. Otherwise it will +change its scheduling policy to SCHED_RR and its priority to the hard +limit. + +This allows users to change the priority of that multipathd runs with by +adding + +LimitRTPRIO= + +to the [Service] section of the multipathd.service unit file. Setting +LimitRTPRIO=0 will make multipathd run as a normal process, while +setting LimitRTPRIO=infinity will make it use the maximum SCHED_RR prio, +which is 99. + +To keep the existing behavior, multipathd.service now sets +LimitRTPRIO=infinity + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + Makefile.inc | 6 ------ + README.md | 3 --- + multipathd/Makefile | 3 --- + multipathd/main.c | 22 +++++++++++++++------- + multipathd/multipathd.service.in | 1 + + 5 files changed, 16 insertions(+), 19 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 6d206281..5668e638 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -18,12 +18,6 @@ READLINE := + # SCSI_DH_MODULES_PRELOAD := scsi_dh_alua scsi_dh_rdac + SCSI_DH_MODULES_PRELOAD := + +-# Multipathd scheduling priority. Set value from 1 to 99 to make multipathd +-# change its scheduling policy to SCHED_RR and its priority to the specified +-# value. set to 0 to stop multipathd from changing the scheduling policy and +-# priority it was started with. +-SCHED_RT_PRIO := 99 +- + EXTRAVERSION := $(shell rev=$$(git rev-parse --short=7 HEAD 2>/dev/null); echo $${rev:+-g$$rev}) + + # PKG_CONFIG must be read from the environment to enable compilation +diff --git a/README.md b/README.md +index bb41bf0e..d4f35f57 100644 +--- a/README.md ++++ b/README.md +@@ -98,9 +98,6 @@ The following variables can be passed to the `make` command line: + By default, command line editing is disabled. + Note that using libreadline may + [make binary indistributable due to license incompatibility](https://github.com/opensvc/multipath-tools/issues/36). +- * `SCHED_RT_PRIO={0-99}`: for values {1-99} set the realtime priority +- multipathd will attempt to run with. for value 0, disable multipathd +- changing itself to a realtime process. + * `ENABLE_LIBDMMP=0`: disable building libdmmp + * `ENABLE_DMEVENTS_POLL=0`: disable support for the device-mapper event + polling API. For use with pre-5.0 kernels that don't support dmevent polling +diff --git a/multipathd/Makefile b/multipathd/Makefile +index 7300f07a..997b40cf 100644 +--- a/multipathd/Makefile ++++ b/multipathd/Makefile +@@ -57,9 +57,6 @@ $(CLI): $(CLI_OBJS) + cli_handlers.o: cli_handlers.c + $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-parameter -c -o $@ $< + +-main.o: main.c +- $(Q)$(CC) $(CPPFLAGS) -DSCHED_RT_PRIO=$(SCHED_RT_PRIO) $(CFLAGS) -c -o $@ $< +- + install: + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) + $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir) +diff --git a/multipathd/main.c b/multipathd/main.c +index 9486a8a3..dd17d5c3 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -3171,14 +3171,23 @@ static void + setscheduler (void) + { + int res; +- static struct sched_param sched_param = { +- .sched_priority = SCHED_RT_PRIO +- }; ++ static struct sched_param sched_param; ++ struct rlimit rlim; ++ ++ if (getrlimit(RLIMIT_RTPRIO, &rlim) < 0 || rlim.rlim_max == 0) ++ return; ++ ++ sched_param.sched_priority = rlim.rlim_max > INT_MAX ? INT_MAX : ++ rlim.rlim_max; ++ res = sched_get_priority_max(SCHED_RR); ++ if (res > 0 && res < sched_param.sched_priority) ++ sched_param.sched_priority = res; + +- res = sched_setscheduler (0, SCHED_RR, &sched_param); ++ res = sched_setscheduler(0, SCHED_RR, &sched_param); + + if (res == -1) +- condlog(2, "Could not set SCHED_RR at priority 99"); ++ condlog(2, "Could not set SCHED_RR at priority %d", ++ sched_param.sched_priority); + return; + } + +@@ -3471,8 +3480,7 @@ child (__attribute__((unused)) void *param) + if (!vecs) + goto failed; + +- if (SCHED_RT_PRIO) +- setscheduler(); ++ setscheduler(); + set_oom_adj(); + #ifdef FPIN_EVENT_HANDLER + if (conf->marginal_pathgroups == MARGINAL_PATHGROUP_FPIN) +diff --git a/multipathd/multipathd.service.in b/multipathd/multipathd.service.in +index 6d03ff71..18bb367e 100644 +--- a/multipathd/multipathd.service.in ++++ b/multipathd/multipathd.service.in +@@ -19,6 +19,7 @@ NotifyAccess=main + ExecStart=/sbin/multipathd -d -s + ExecReload=/sbin/multipathd reconfigure + TasksMax=infinity ++LimitRTPRIO=infinity + + [Install] + WantedBy=sysinit.target diff --git a/0006-multipathd-Set-CPUWeight-to-1000-and-LimitRTPRIO-to-.patch b/0006-multipathd-Set-CPUWeight-to-1000-and-LimitRTPRIO-to-.patch new file mode 100644 index 0000000..0cbe997 --- /dev/null +++ b/0006-multipathd-Set-CPUWeight-to-1000-and-LimitRTPRIO-to-.patch @@ -0,0 +1,33 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 15 Apr 2024 19:43:06 -0400 +Subject: [PATCH] multipathd: Set CPUWeight to 1000 and LimitRTPRIO to 10 + +If multipathd doesn't become a real time process, it was scheduled as a +normal process, without any priority increase. Bump up the CPUWeight so +that even as a normal process, it will still run with increased +priority. + +If multipathd did become a real time process, it set itself to the +highest priority, which is excessive. A priority of 10 is plenty. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + multipathd/multipathd.service.in | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/multipathd/multipathd.service.in b/multipathd/multipathd.service.in +index 18bb367e..a63ddd9a 100644 +--- a/multipathd/multipathd.service.in ++++ b/multipathd/multipathd.service.in +@@ -19,7 +19,8 @@ NotifyAccess=main + ExecStart=/sbin/multipathd -d -s + ExecReload=/sbin/multipathd reconfigure + TasksMax=infinity +-LimitRTPRIO=infinity ++LimitRTPRIO=10 ++CPUWeight=1000 + + [Install] + WantedBy=sysinit.target diff --git a/0007-11-dm-mpath.rules-explain-logic-for-device-becoming-.patch b/0007-11-dm-mpath.rules-explain-logic-for-device-becoming-.patch new file mode 100644 index 0000000..6241459 --- /dev/null +++ b/0007-11-dm-mpath.rules-explain-logic-for-device-becoming-.patch @@ -0,0 +1,30 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 1 Mar 2024 19:53:14 +0100 +Subject: [PATCH] 11-dm-mpath.rules: explain logic for device becoming ready + while suspended + +Add a comment to explain why we must set MPATH_DEVICE_READY=0 when +we see a device becoming ready (number of active paths 0 -> 1) while +the device is suspended. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/11-dm-mpath.rules.in | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in +index d9585abf..b8d19d01 100644 +--- a/multipath/11-dm-mpath.rules.in ++++ b/multipath/11-dm-mpath.rules.in +@@ -98,6 +98,8 @@ ENV{MPATH_DEVICE_READY}=="0", \ + # If the device comes back online, set DM_ACTIVATION so that + # upper layers do a rescan. If the device is currently suspended, + # we have to postpone the activation until the next event. ++# In this case, we have to set MPATH_DEVICE_READY=0; otherwise, the ++# MPATH_UNCHANGED logic will cause later rules to skipped in the next event. + ENV{MPATH_DEVICE_READY}=="0", GOTO="dont_activate" + ENV{.MPATH_DEVICE_READY_OLD}!="0", GOTO="dont_activate" + ENV{DM_SUSPENDED}=="1", ENV{MPATH_DEVICE_READY}="0", GOTO="dont_activate" diff --git a/0008-11-dm-mpath.rules-don-t-import-DM_NOSCAN-from-udev-d.patch b/0008-11-dm-mpath.rules-don-t-import-DM_NOSCAN-from-udev-d.patch new file mode 100644 index 0000000..3900b39 --- /dev/null +++ b/0008-11-dm-mpath.rules-don-t-import-DM_NOSCAN-from-udev-d.patch @@ -0,0 +1,37 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 1 Mar 2024 19:57:59 +0100 +Subject: [PATCH] 11-dm-mpath.rules: don't import DM_NOSCAN from udev db + +DM_NOSCAN is our "output" flag for 13-dm-disk.rules, and it should +be treated the same way as DM_UDEV_DISABLE_OTHER_RULES_FLAG, which +isn't imported from the udev database. The state that we need to +remember is MPATH_DEVICE_READY, which we've already imported above, +and we will set the "output" flags accordingly in the "force_activation" +code path further down. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/11-dm-mpath.rules.in | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in +index b8d19d01..eb12b0c6 100644 +--- a/multipath/11-dm-mpath.rules.in ++++ b/multipath/11-dm-mpath.rules.in +@@ -18,9 +18,11 @@ ACTION=="add", ENV{DM_ACTIVATION}=="1", ENV{DM_SUSPENDED}!="1", ENV{DISK_RO}!="1 + + # If this uevent didn't come from dm, don't try to update the + # device state ++# Note that .MPATH_DEVICE_READY_OLD=="" here. Thus we won't activate the ++# device below at force_activation, which is correct. + ENV{DM_COOKIE}!="?*", ENV{DM_ACTION}!="PATH_*", \ +- IMPORT{db}="DM_NOSCAN", IMPORT{db}="DM_COLDPLUG_SUSPENDED", \ +- GOTO="scan_import" ++ IMPORT{db}="DM_COLDPLUG_SUSPENDED", \ ++ GOTO="force_activation" + + ENV{.MPATH_DEVICE_READY_OLD}="$env{MPATH_DEVICE_READY}" + diff --git a/0009-11-dm-mpath.rules-don-t-import-ID_FS_VERSION-from-ud.patch b/0009-11-dm-mpath.rules-don-t-import-ID_FS_VERSION-from-ud.patch new file mode 100644 index 0000000..933a43a --- /dev/null +++ b/0009-11-dm-mpath.rules-don-t-import-ID_FS_VERSION-from-ud.patch @@ -0,0 +1,27 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 1 Mar 2024 21:02:49 +0100 +Subject: [PATCH] 11-dm-mpath.rules: don't import ID_FS_VERSION from udev db + +Use the same set of properties to import as 13-dm-disk.rules. +ID_FS_VERSION isn't used in any udev rule I am aware of. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/11-dm-mpath.rules.in | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in +index eb12b0c6..4386b6ca 100644 +--- a/multipath/11-dm-mpath.rules.in ++++ b/multipath/11-dm-mpath.rules.in +@@ -126,7 +126,6 @@ IMPORT{db}="ID_FS_TYPE" + IMPORT{db}="ID_FS_USAGE" + IMPORT{db}="ID_FS_UUID_ENC" + IMPORT{db}="ID_FS_LABEL_ENC" +-IMPORT{db}="ID_FS_VERSION" + IMPORT{db}="ID_PART_ENTRY_NAME" + IMPORT{db}="ID_PART_ENTRY_UUID" + IMPORT{db}="ID_PART_ENTRY_SCHEME" diff --git a/0010-11-dm-mpath.rules-adapt-MPATH_DEVICE_READY-0-logic-t.patch b/0010-11-dm-mpath.rules-adapt-MPATH_DEVICE_READY-0-logic-t.patch new file mode 100644 index 0000000..97b3901 --- /dev/null +++ b/0010-11-dm-mpath.rules-adapt-MPATH_DEVICE_READY-0-logic-t.patch @@ -0,0 +1,67 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 1 Mar 2024 20:53:50 +0100 +Subject: [PATCH] 11-dm-mpath.rules: adapt MPATH_DEVICE_READY=0 logic to + 10-dm.rules update + +With the late patches for 10-dm.rules, DM_UDEV_DISABLE_OTHER_RULES_FLAG isn't +restored from the udev database any more, so we don't need to restore +the flag to its original state before it is saved to the db. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/11-dm-mpath.rules.in | 22 ++++++++++++---------- + 1 file changed, 12 insertions(+), 10 deletions(-) + +diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in +index 4386b6ca..2f909c3a 100644 +--- a/multipath/11-dm-mpath.rules.in ++++ b/multipath/11-dm-mpath.rules.in +@@ -19,7 +19,7 @@ ACTION=="add", ENV{DM_ACTIVATION}=="1", ENV{DM_SUSPENDED}!="1", ENV{DISK_RO}!="1 + # If this uevent didn't come from dm, don't try to update the + # device state + # Note that .MPATH_DEVICE_READY_OLD=="" here. Thus we won't activate the +-# device below at force_activation, which is correct. ++# device below at mpath_is_ready, which is correct. + ENV{DM_COOKIE}!="?*", ENV{DM_ACTION}!="PATH_*", \ + IMPORT{db}="DM_COLDPLUG_SUSPENDED", \ + GOTO="force_activation" +@@ -84,25 +84,27 @@ ENV{DM_ACTION}=="PATH_FAILED|PATH_REINSTATED", \ + + LABEL="force_activation" + ++ENV{MPATH_DEVICE_READY}!="0", GOTO="mpath_is_ready" + # Do not initiate scanning if no path is available, + # otherwise there would be a hang or IO error on access. + # We'd like to avoid this, especially within udev processing. +-ENV{MPATH_DEVICE_READY}=="0", ENV{DM_NOSCAN}="1" +- +-# Skip all foreign rules if no path is available. ++# This is communicated to later rules in DM_NOSCAN. ++# Likewise, skip all foreign rules if no path is available. + # Use DM_UDEV_DISABLE_OTHER_RULES_FLAG to communicate this +-# to upper layers. The original value will be restored in a late +-# udev rule. +-ENV{MPATH_DEVICE_READY}=="0", \ +- ENV{.MPATH_SAVE_DISABLE_OTHER_RULES_FLAG}="$env{DM_UDEV_DISABLE_OTHER_RULES_FLAG}", \ +- ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1" ++# to upper layers. With dm rules < v3, save the original value here; ++# it will be restored in a late udev rule. ++ENV{DM_UDEV_RULES_VSN}=="1|2", \ ++ ENV{.MPATH_SAVE_DISABLE_OTHER_RULES_FLAG}="$env{DM_UDEV_DISABLE_OTHER_RULES_FLAG}" ++ENV{DM_NOSCAN}="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1" ++GOTO="dont_activate" ++ ++LABEL="mpath_is_ready" + + # If the device comes back online, set DM_ACTIVATION so that + # upper layers do a rescan. If the device is currently suspended, + # we have to postpone the activation until the next event. + # In this case, we have to set MPATH_DEVICE_READY=0; otherwise, the + # MPATH_UNCHANGED logic will cause later rules to skipped in the next event. +-ENV{MPATH_DEVICE_READY}=="0", GOTO="dont_activate" + ENV{.MPATH_DEVICE_READY_OLD}!="0", GOTO="dont_activate" + ENV{DM_SUSPENDED}=="1", ENV{MPATH_DEVICE_READY}="0", GOTO="dont_activate" + diff --git a/0011-11-dm-mpath.rules-adapt-coldplug-event-handling-ro-1.patch b/0011-11-dm-mpath.rules-adapt-coldplug-event-handling-ro-1.patch new file mode 100644 index 0000000..938a07f --- /dev/null +++ b/0011-11-dm-mpath.rules-adapt-coldplug-event-handling-ro-1.patch @@ -0,0 +1,43 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 1 Mar 2024 20:55:40 +0100 +Subject: [PATCH] 11-dm-mpath.rules: adapt coldplug event handling ro + 10-dm.rules update + +With late late patches for 10-dm.rules, DM_UDEV_DISABLE_OTHER_RULES_FLAG is +never restored from the udev db. Thus we don't need to clear it here +any more for coldplug events. Also, we must use .DM_SUSPENDED instead of +DM_SUSPENDED as input flag with the v3 rule set (other occurences of +DM_SUSPENDED will be replaced in a follow-up patch). + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/11-dm-mpath.rules.in | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in +index 2f909c3a..5f547cab 100644 +--- a/multipath/11-dm-mpath.rules.in ++++ b/multipath/11-dm-mpath.rules.in +@@ -9,12 +9,17 @@ ACTION=="add", ENV{DM_ACTIVATION}=="1", ENV{DM_SUSPENDED}=="1", \ + PROGRAM="/bin/logger -t 11-dm-mpath.rules -p daemon.warning \"Coldplug event for suspended device\"", \ + ENV{DM_COLDPLUG_SUSPENDED}="1", GOTO="scan_import" + +-# Coldplug event. DM_UDEV_DISABLE_OTHER_RULES_FLAG has been restored ++# Coldplug event. Import previously set properties. ++ACTION!="add", GOTO="mpath_coldplug_end" ++ENV{DM_ACTIVATION}!="1", GOTO="mpath_coldplug_end" ++ENV{DM_UDEV_RULES_VSN}!="1|2", ENV{.DM_SUSPENDED}!="1", GOTO="scan_import" ++# With DM rules < v3, DM_UDEV_DISABLE_OTHER_RULES_FLAG has been restored + # from DB in 10-dm.rules. If the device is not suspended, clear the flag. + # This is safe for multipath where DM_UDEV_DISABLE_OTHER_RULES_FLAG is basically + # equivalent to DM_SUSPENDED==1 || DISK_RO==1 +-ACTION=="add", ENV{DM_ACTIVATION}=="1", ENV{DM_SUSPENDED}!="1", ENV{DISK_RO}!="1", \ ++ENV{DM_UDEV_RULES_VSN}=="1|2", ENV{DM_SUSPENDED}!="1", ENV{DISK_RO}!="1", \ + ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="", GOTO="scan_import" ++LABEL="mpath_coldplug_end" + + # If this uevent didn't come from dm, don't try to update the + # device state diff --git a/0012-11-dm-mpath.rules-don-t-import-properties-with-new-1.patch b/0012-11-dm-mpath.rules-don-t-import-properties-with-new-1.patch new file mode 100644 index 0000000..f4e69cf --- /dev/null +++ b/0012-11-dm-mpath.rules-don-t-import-properties-with-new-1.patch @@ -0,0 +1,36 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 1 Mar 2024 20:58:47 +0100 +Subject: [PATCH] 11-dm-mpath.rules: don't import properties with new + 13-dm-disk.rules + +With the late changes to 13-dm-disk.rules, we don't need to import any +blkid-generated properties from the udev database, because they will +be imported later. + +Except for ID_FS_TYPE, this actually holds since lvm2 commit 94f77a4 ("udev: +import previous results of blkid when in suspended state"), included in lvm2 +2.03.19, but we have no simple way to detect the version of the lvm2 rules. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/11-dm-mpath.rules.in | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in +index 5f547cab..95126bf2 100644 +--- a/multipath/11-dm-mpath.rules.in ++++ b/multipath/11-dm-mpath.rules.in +@@ -126,6 +126,10 @@ LABEL="scan_import" + # have never been properly set. Don't import them. + ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}!="1", GOTO="import_end" + ++# DM rules v3 will import missing properties on 13-dm-disk.rules. ++# No need to do it here. ++ENV{DM_UDEV_RULES_VSN}!="1|2", GOTO="import_end" ++ + # Don't import the properties from db if we will run blkid later. + ENV{DM_NOSCAN}!="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}!="1", GOTO="import_end" + diff --git a/0013-11-dm-mpath.rules-replace-DM_SUSPENDED-by-.DM_SUSPEN.patch b/0013-11-dm-mpath.rules-replace-DM_SUSPENDED-by-.DM_SUSPEN.patch new file mode 100644 index 0000000..e922427 --- /dev/null +++ b/0013-11-dm-mpath.rules-replace-DM_SUSPENDED-by-.DM_SUSPEN.patch @@ -0,0 +1,75 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 1 Mar 2024 22:33:59 +0100 +Subject: [PATCH] 11-dm-mpath.rules: replace DM_SUSPENDED by .DM_SUSPENDED + +With the late changes to the device mapper rules, DM_SUSPENDED +is not exported any more. Use .DM_SUSPENDED instead. + +Note that although 11-dm-mpath.rules is not a part of lvm2, it +can be considered as part of the device-mapper layer (everything +before 13-dm-disk.rules can), and is thus allowed to use +.DM_SUSPENDED. In practice .DM_SUSPENDED is equivalent to +DM_UDEV_DISABLE_OTHER_RULES_FLAG for multipath devices, but +using .DM_SUSPENDED here makes the intention more obvious. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/11-dm-mpath.rules.in | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in +index 95126bf2..efc6416f 100644 +--- a/multipath/11-dm-mpath.rules.in ++++ b/multipath/11-dm-mpath.rules.in +@@ -4,8 +4,11 @@ ENV{DM_UUID}!="mpath-?*", GOTO="mpath_end" + + IMPORT{db}="MPATH_DEVICE_READY" + ++# device-mapper rules v2 compatibility ++ENV{.DM_SUSPENDED}!="?*", ENV{.DM_SUSPENDED}="$env{DM_SUSPENDED}" ++ + # Coldplug event while device is suspended (e.g. during a reload) +-ACTION=="add", ENV{DM_ACTIVATION}=="1", ENV{DM_SUSPENDED}=="1", \ ++ACTION=="add", ENV{DM_ACTIVATION}=="1", ENV{.DM_SUSPENDED}=="1", \ + PROGRAM="/bin/logger -t 11-dm-mpath.rules -p daemon.warning \"Coldplug event for suspended device\"", \ + ENV{DM_COLDPLUG_SUSPENDED}="1", GOTO="scan_import" + +@@ -17,7 +20,7 @@ ENV{DM_UDEV_RULES_VSN}!="1|2", ENV{.DM_SUSPENDED}!="1", GOTO="scan_import" + # from DB in 10-dm.rules. If the device is not suspended, clear the flag. + # This is safe for multipath where DM_UDEV_DISABLE_OTHER_RULES_FLAG is basically + # equivalent to DM_SUSPENDED==1 || DISK_RO==1 +-ENV{DM_UDEV_RULES_VSN}=="1|2", ENV{DM_SUSPENDED}!="1", ENV{DISK_RO}!="1", \ ++ENV{DM_UDEV_RULES_VSN}=="1|2", ENV{.DM_SUSPENDED}!="1", ENV{DISK_RO}!="1", \ + ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="", GOTO="scan_import" + LABEL="mpath_coldplug_end" + +@@ -68,7 +71,7 @@ LABEL="mpath_action" + # Activation might have been partially skipped. Activate the device now, + # i.e. disable the MPATH_UNCHANGED logic and set DM_ACTIVATION=1. + IMPORT{db}="DM_COLDPLUG_SUSPENDED" +-ENV{DM_COLDPLUG_SUSPENDED}=="1", ENV{DM_SUSPENDED}!="1", \ ++ENV{DM_COLDPLUG_SUSPENDED}=="1", ENV{.DM_SUSPENDED}!="1", \ + ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0", \ + PROGRAM="/bin/logger -t 11-dm-mpath.rules -p daemon.notice \"Forcing activation of previously suspended device\"", \ + GOTO="force_activation" +@@ -111,7 +114,7 @@ LABEL="mpath_is_ready" + # In this case, we have to set MPATH_DEVICE_READY=0; otherwise, the + # MPATH_UNCHANGED logic will cause later rules to skipped in the next event. + ENV{.MPATH_DEVICE_READY_OLD}!="0", GOTO="dont_activate" +-ENV{DM_SUSPENDED}=="1", ENV{MPATH_DEVICE_READY}="0", GOTO="dont_activate" ++ENV{.DM_SUSPENDED}=="1", ENV{MPATH_DEVICE_READY}="0", GOTO="dont_activate" + + ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0" + LABEL="dont_activate" +@@ -145,7 +148,7 @@ IMPORT{db}="ID_PART_GPT_AUTO_ROOT" + LABEL="import_end" + + # Reset previous DM_COLDPLUG_SUSPENDED if activation happens now +-ENV{DM_SUSPENDED}!="1", ENV{DM_ACTIVATION}=="1", ENV{DM_COLDPLUG_SUSPENDED}="" ++ENV{.DM_SUSPENDED}!="1", ENV{DM_ACTIVATION}=="1", ENV{DM_COLDPLUG_SUSPENDED}="" + + # Multipath maps should take precedence over their members. + ENV{DM_UDEV_LOW_PRIORITY_FLAG}!="1", OPTIONS+="link_priority=50" diff --git a/0014-11-dm-mpath.rules-replace-DM_NOSCAN-by-.DM_NOSCAN.patch b/0014-11-dm-mpath.rules-replace-DM_NOSCAN-by-.DM_NOSCAN.patch new file mode 100644 index 0000000..a5eecaf --- /dev/null +++ b/0014-11-dm-mpath.rules-replace-DM_NOSCAN-by-.DM_NOSCAN.patch @@ -0,0 +1,55 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 1 Mar 2024 23:23:53 +0100 +Subject: [PATCH] 11-dm-mpath.rules: replace DM_NOSCAN by .DM_NOSCAN + +We don't need to restore DM_NOSCAN from the db anymore, so we can rename +it to .DM_NOSCAN, making it a temporary property. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/11-dm-mpath.rules.in | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in +index efc6416f..3ae3c054 100644 +--- a/multipath/11-dm-mpath.rules.in ++++ b/multipath/11-dm-mpath.rules.in +@@ -96,14 +96,14 @@ ENV{MPATH_DEVICE_READY}!="0", GOTO="mpath_is_ready" + # Do not initiate scanning if no path is available, + # otherwise there would be a hang or IO error on access. + # We'd like to avoid this, especially within udev processing. +-# This is communicated to later rules in DM_NOSCAN. ++# This is communicated to later rules in .DM_NOSCAN. + # Likewise, skip all foreign rules if no path is available. + # Use DM_UDEV_DISABLE_OTHER_RULES_FLAG to communicate this + # to upper layers. With dm rules < v3, save the original value here; + # it will be restored in a late udev rule. + ENV{DM_UDEV_RULES_VSN}=="1|2", \ + ENV{.MPATH_SAVE_DISABLE_OTHER_RULES_FLAG}="$env{DM_UDEV_DISABLE_OTHER_RULES_FLAG}" +-ENV{DM_NOSCAN}="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1" ++ENV{.DM_NOSCAN}="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1" + GOTO="dont_activate" + + LABEL="mpath_is_ready" +@@ -134,7 +134,7 @@ ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}!="1", GOTO="import_end" + ENV{DM_UDEV_RULES_VSN}!="1|2", GOTO="import_end" + + # Don't import the properties from db if we will run blkid later. +-ENV{DM_NOSCAN}!="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}!="1", GOTO="import_end" ++ENV{.DM_NOSCAN}!="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}!="1", GOTO="import_end" + + IMPORT{db}="ID_FS_TYPE" + IMPORT{db}="ID_FS_USAGE" +@@ -150,6 +150,9 @@ LABEL="import_end" + # Reset previous DM_COLDPLUG_SUSPENDED if activation happens now + ENV{.DM_SUSPENDED}!="1", ENV{DM_ACTIVATION}=="1", ENV{DM_COLDPLUG_SUSPENDED}="" + ++# device-mapper rules v2 compatibility for 13-dm-disk.rules ++ENV{DM_UDEV_RULES_VSN}=="1|2", ENV{DM_NOSCAN}="$env{.DM_NOSCAN}" ++ + # Multipath maps should take precedence over their members. + ENV{DM_UDEV_LOW_PRIORITY_FLAG}!="1", OPTIONS+="link_priority=50" + diff --git a/0014-multipathd-fix-null-pointer-dereference-in-uev_updat.patch b/0014-multipathd-fix-null-pointer-dereference-in-uev_updat.patch deleted file mode 100644 index 7655591..0000000 --- a/0014-multipathd-fix-null-pointer-dereference-in-uev_updat.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 16 Jan 2024 00:54:37 -0500 -Subject: [PATCH] multipathd: fix null pointer dereference in uev_update_path - -The Auto-resize code added a check that deferences pp->mpp without -checking that it's non-NULL. Fix it. - -Fixes: 981b83ad1 ("multipathd: Add auto_resize config option") -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 230c9d10..57c04364 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -1653,7 +1653,7 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) - } - } - } -- if (auto_resize != AUTO_RESIZE_NEVER && -+ if (auto_resize != AUTO_RESIZE_NEVER && mpp && - !mpp->wait_for_udev) { - struct pathgroup *pgp; - struct path *pp2; diff --git a/0015-11-dm-mpath.rules-simplify-PATH_FAILED-case.patch b/0015-11-dm-mpath.rules-simplify-PATH_FAILED-case.patch new file mode 100644 index 0000000..ce393ae --- /dev/null +++ b/0015-11-dm-mpath.rules-simplify-PATH_FAILED-case.patch @@ -0,0 +1,38 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 6 Mar 2024 21:17:51 +0100 +Subject: [PATCH] 11-dm-mpath.rules: simplify PATH_FAILED case + +This combination of a GOTO and a simple rule can be combined +into a single rule. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/11-dm-mpath.rules.in | 12 ++++-------- + 1 file changed, 4 insertions(+), 8 deletions(-) + +diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in +index 3ae3c054..4777fbec 100644 +--- a/multipath/11-dm-mpath.rules.in ++++ b/multipath/11-dm-mpath.rules.in +@@ -56,14 +56,10 @@ PROGRAM=="@BINDIR@/multipath -U -v1 %k", GOTO="paths_ok" + ENV{MPATH_DEVICE_READY}="0", GOTO="mpath_action" + LABEL="paths_ok" + +-# Don't mark a device ready on a PATH_FAILED event. even if +-# DM_NR_VALID_PATHS is greater than 0. Just keep the existing +-# value +-ENV{DM_ACTION}=="PATH_FAILED", GOTO="mpath_action" +- +-# This event is either a PATH_REINSTATED or a table reload where +-# there are active paths. Mark the device ready +-ENV{MPATH_DEVICE_READY}="1" ++# For PATH_FAILED events, keep the existing value of MPATH_DEVICE_READY. ++# If it's not PATH_FAILED, this event is either a PATH_REINSTATED or a ++# table reload where there are active paths. Mark the device ready. ++ENV{DM_ACTION}!="PATH_FAILED", ENV{MPATH_DEVICE_READY}="1" + + LABEL="mpath_action" + diff --git a/0015-multipathd-fix-auto-resize-configuration.patch b/0015-multipathd-fix-auto-resize-configuration.patch deleted file mode 100644 index 35e4d48..0000000 --- a/0015-multipathd-fix-auto-resize-configuration.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 16 Jan 2024 01:11:02 -0500 -Subject: [PATCH] multipathd: fix auto-resize configuration - -The code acted like AUTO_RESIZE_UNDEFINED didn't exist, but since -conf->auto_resize was never set to AUTO_RESIZE_NEVER, the default was in -fact AUTO_RESIZE_UNDEFINED, which ended up getting treated like -AUTO_RESIZE_GROW_SHRINK. Remove AUTO_RESIZE_UNDEFINED and explicitly -default auto_resize tp AUTO_RESIZE_NEVER. - -Fixes: 981b83ad1 ("multipathd: Add auto_resize config option") -Signed-off-by: Benjamin Marzinski ---- - libmultipath/config.c | 1 + - libmultipath/structs.h | 1 - - 2 files changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/config.c b/libmultipath/config.c -index 4544f484..3d5943d3 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -927,6 +927,7 @@ int _init_config (const char *file, struct config *conf) - conf->retrigger_tries = DEFAULT_RETRIGGER_TRIES; - conf->retrigger_delay = DEFAULT_RETRIGGER_DELAY; - conf->uev_wait_timeout = DEFAULT_UEV_WAIT_TIMEOUT; -+ conf->auto_resize = DEFAULT_AUTO_RESIZE; - conf->remove_retries = 0; - conf->ghost_delay = DEFAULT_GHOST_DELAY; - conf->all_tg_pt = DEFAULT_ALL_TG_PT; -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index a1aac1b4..734905e2 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -180,7 +180,6 @@ enum queue_mode_states { - }; - - enum auto_resize_state { -- AUTO_RESIZE_UNDEF = 0, - AUTO_RESIZE_NEVER, - AUTO_RESIZE_GROW_ONLY, - AUTO_RESIZE_GROW_SHRINK, diff --git a/0016-11-dm-mpath.rules-make-label-names-more-intuitive.patch b/0016-11-dm-mpath.rules-make-label-names-more-intuitive.patch new file mode 100644 index 0000000..e81f04f --- /dev/null +++ b/0016-11-dm-mpath.rules-make-label-names-more-intuitive.patch @@ -0,0 +1,109 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 1 Mar 2024 21:54:26 +0100 +Subject: [PATCH] 11-dm-mpath.rules: make label names more intuitive + +The labels "dont_activate" and "scan_import" denote the same code line. +Remove "dont_activate". Improve two misleading label names. + +Substitutions: + dont_activate -> scan_import + force_activation -> check_mpath_ready + mpath_action -> check_mpath_unchanged + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/11-dm-mpath.rules.in | 22 +++++++++++----------- + 1 file changed, 11 insertions(+), 11 deletions(-) + +diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in +index 4777fbec..0562eddf 100644 +--- a/multipath/11-dm-mpath.rules.in ++++ b/multipath/11-dm-mpath.rules.in +@@ -30,7 +30,7 @@ LABEL="mpath_coldplug_end" + # device below at mpath_is_ready, which is correct. + ENV{DM_COOKIE}!="?*", ENV{DM_ACTION}!="PATH_*", \ + IMPORT{db}="DM_COLDPLUG_SUSPENDED", \ +- GOTO="force_activation" ++ GOTO="check_mpath_ready" + + ENV{.MPATH_DEVICE_READY_OLD}="$env{MPATH_DEVICE_READY}" + +@@ -38,13 +38,13 @@ ENV{.MPATH_DEVICE_READY_OLD}="$env{MPATH_DEVICE_READY}" + # table with no active devices. If this happens, mark the + # device not ready + ENV{DM_SUBSYSTEM_UDEV_FLAG2}=="1", ENV{MPATH_DEVICE_READY}="0", \ +- GOTO="mpath_action" ++ GOTO="check_mpath_unchanged" + + # If the last path has failed mark the device not ready + # Note that DM_NR_VALID_PATHS is only set for PATH_FAILED|PATH_REINSTATED + # events. + # This may not be reliable, as events aren't necessarily received in order. +-ENV{DM_NR_VALID_PATHS}=="0", ENV{MPATH_DEVICE_READY}="0", GOTO="mpath_action" ++ENV{DM_NR_VALID_PATHS}=="0", ENV{MPATH_DEVICE_READY}="0", GOTO="check_mpath_unchanged" + + # Don't run multipath -U during "coldplug" after switching root, + # because paths are just being added to the udev db. +@@ -53,7 +53,8 @@ ACTION=="add", ENV{.MPATH_DEVICE_READY_OLD}=="1", GOTO="paths_ok" + # Check the map state directly with multipath -U. + # This doesn't attempt I/O on the device. + PROGRAM=="@BINDIR@/multipath -U -v1 %k", GOTO="paths_ok" +-ENV{MPATH_DEVICE_READY}="0", GOTO="mpath_action" ++ENV{MPATH_DEVICE_READY}="0", GOTO="check_mpath_unchanged" ++ + LABEL="paths_ok" + + # For PATH_FAILED events, keep the existing value of MPATH_DEVICE_READY. +@@ -61,7 +62,7 @@ LABEL="paths_ok" + # table reload where there are active paths. Mark the device ready. + ENV{DM_ACTION}!="PATH_FAILED", ENV{MPATH_DEVICE_READY}="1" + +-LABEL="mpath_action" ++LABEL="check_mpath_unchanged" + + # A previous coldplug event occurred while the device was suspended. + # Activation might have been partially skipped. Activate the device now, +@@ -70,7 +71,7 @@ IMPORT{db}="DM_COLDPLUG_SUSPENDED" + ENV{DM_COLDPLUG_SUSPENDED}=="1", ENV{.DM_SUSPENDED}!="1", \ + ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0", \ + PROGRAM="/bin/logger -t 11-dm-mpath.rules -p daemon.notice \"Forcing activation of previously suspended device\"", \ +- GOTO="force_activation" ++ GOTO="check_mpath_ready" + + # DM_SUBSYSTEM_UDEV_FLAG0 is the "RELOAD" flag for multipath subsystem. + # Drop the DM_ACTIVATION flag here as mpath reloads tables if any of its +@@ -86,7 +87,7 @@ ENV{DM_SUBSYSTEM_UDEV_FLAG0}=="1", \ + ENV{DM_ACTION}=="PATH_FAILED|PATH_REINSTATED", \ + ENV{DM_ACTIVATION}="0", ENV{MPATH_UNCHANGED}="1" + +-LABEL="force_activation" ++LABEL="check_mpath_ready" + + ENV{MPATH_DEVICE_READY}!="0", GOTO="mpath_is_ready" + # Do not initiate scanning if no path is available, +@@ -100,7 +101,7 @@ ENV{MPATH_DEVICE_READY}!="0", GOTO="mpath_is_ready" + ENV{DM_UDEV_RULES_VSN}=="1|2", \ + ENV{.MPATH_SAVE_DISABLE_OTHER_RULES_FLAG}="$env{DM_UDEV_DISABLE_OTHER_RULES_FLAG}" + ENV{.DM_NOSCAN}="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1" +-GOTO="dont_activate" ++GOTO="scan_import" + + LABEL="mpath_is_ready" + +@@ -109,11 +110,10 @@ LABEL="mpath_is_ready" + # we have to postpone the activation until the next event. + # In this case, we have to set MPATH_DEVICE_READY=0; otherwise, the + # MPATH_UNCHANGED logic will cause later rules to skipped in the next event. +-ENV{.MPATH_DEVICE_READY_OLD}!="0", GOTO="dont_activate" +-ENV{.DM_SUSPENDED}=="1", ENV{MPATH_DEVICE_READY}="0", GOTO="dont_activate" ++ENV{.MPATH_DEVICE_READY_OLD}!="0", GOTO="scan_import" ++ENV{.DM_SUSPENDED}=="1", ENV{MPATH_DEVICE_READY}="0", GOTO="scan_import" + + ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0" +-LABEL="dont_activate" + + # The code to check multipath state ends here. We need to set + # properties and symlinks regardless whether the map is usable or diff --git a/0017-kpartx.rules-ignore-DM_SUSPENDED.patch b/0017-kpartx.rules-ignore-DM_SUSPENDED.patch new file mode 100644 index 0000000..3b0ac76 --- /dev/null +++ b/0017-kpartx.rules-ignore-DM_SUSPENDED.patch @@ -0,0 +1,29 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 1 Mar 2024 21:17:26 +0100 +Subject: [PATCH] kpartx.rules: ignore DM_SUSPENDED + +DM_SUSPENDED=1 implies DM_UDEV_DISABLE_OTHER_RULES_FLAG=1, no +need to check it again. The DM_NOSCAN check needs to remain in +order to keep compatibility with dm rules v2. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + kpartx/kpartx.rules | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules +index 1969dee0..8dd3369c 100644 +--- a/kpartx/kpartx.rules ++++ b/kpartx/kpartx.rules +@@ -27,7 +27,7 @@ ENV{DM_SUBSYSTEM_UDEV_FLAG1}=="1", GOTO="mpath_kpartx_end" + ENV{MPATH_UNCHANGED}=="1", GOTO="mpath_kpartx_end" + + # Don't run kpartx now if we know it will fail or hang. +-ENV{DM_SUSPENDED}=="1", GOTO="mpath_kpartx_end" ++# This is required for device mapper rules v2 compatibility. + ENV{DM_NOSCAN}=="1", GOTO="mpath_kpartx_end" + + # Run kpartx diff --git a/0018-multipath-tools-tests-fix-CI-failures-on-arm-v7-with.patch b/0018-multipath-tools-tests-fix-CI-failures-on-arm-v7-with.patch new file mode 100644 index 0000000..2840cec --- /dev/null +++ b/0018-multipath-tools-tests-fix-CI-failures-on-arm-v7-with.patch @@ -0,0 +1,270 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 4 Apr 2024 23:23:28 +0200 +Subject: [PATCH] multipath-tools tests: fix CI failures on arm/v7 with glibc + 2.37 + +glibc 2.37 has added several new wrappers around the ioctl and +io_getevents system calls on 32 bit systems, to deal with 64bit +time_t. These aren't resolved with cmocka's wrapping technique. + +Fix this with C preprocessor trickery, similar to +7b217f8 ("multipath-tools: Makefile.inc: set _FILE_OFFSET_BITS=64"). + +Note: the directio test with DIO_TEST_DEV for fails under qemu-linux-user +with foreign-arch binfmt, because aio-related system calls are unsupported +by qemu-linux-user. See https://gitlab.com/qemu-project/qemu/-/issues/210. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + tests/directio.c | 28 ++++++++++++++-------------- + tests/vpd.c | 35 ++++++++++++++++++----------------- + tests/wrap64.h | 25 ++++++++++++++++++++++++- + 3 files changed, 56 insertions(+), 32 deletions(-) + +diff --git a/tests/directio.c b/tests/directio.c +index cbedcc9c..d5f84f10 100644 +--- a/tests/directio.c ++++ b/tests/directio.c +@@ -41,13 +41,13 @@ struct timespec full_timeout = { .tv_sec = -1 }; + #define ioctl_request_t int + #endif + +-int __real_ioctl(int fd, ioctl_request_t request, void *argp); ++int REAL_IOCTL(int fd, ioctl_request_t request, void *argp); + +-int __wrap_ioctl(int fd, ioctl_request_t request, void *argp) ++int WRAP_IOCTL(int fd, ioctl_request_t request, void *argp) + { + #ifdef DIO_TEST_DEV + mock_type(int); +- return __real_ioctl(fd, request, argp); ++ return REAL_IOCTL(fd, request, argp); + #else + int *blocksize = (int *)argp; + +@@ -148,10 +148,10 @@ int __wrap_io_cancel(io_context_t ctx, struct iocb *iocb, struct io_event *evt) + #endif + } + +-int __real_io_getevents(io_context_t ctx, long min_nr, long nr, ++int REAL_IO_GETEVENTS(io_context_t ctx, long min_nr, long nr, + struct io_event *events, struct timespec *timeout); + +-int __wrap_io_getevents(io_context_t ctx, long min_nr, long nr, ++int WRAP_IO_GETEVENTS(io_context_t ctx, long min_nr, long nr, + struct io_event *events, struct timespec *timeout) + { + int nr_evs; +@@ -169,8 +169,8 @@ int __wrap_io_getevents(io_context_t ctx, long min_nr, long nr, + #ifdef DIO_TEST_DEV + mock_ptr_type(struct timespec *); + mock_ptr_type(struct io_event *); +- assert_int_equal(nr_evs, __real_io_getevents(ctx, min_nr, nr_evs, +- events, timeout)); ++ assert_int_equal(nr_evs, REAL_IO_GETEVENTS(ctx, min_nr, nr_evs, ++ events, timeout)); + #else + sleep_tmo = mock_ptr_type(struct timespec *); + if (sleep_tmo) { +@@ -193,7 +193,7 @@ int __wrap_io_getevents(io_context_t ctx, long min_nr, long nr, + + static void return_io_getevents_none(void) + { +- will_return(__wrap_io_getevents, 0); ++ wrap_will_return(WRAP_IO_GETEVENTS, 0); + } + + static void return_io_getevents_nr(struct timespec *ts, int nr, +@@ -207,15 +207,15 @@ static void return_io_getevents_nr(struct timespec *ts, int nr, + mock_events[i + ev_off].res = reqs[i]->blksize; + } + while (nr > 0) { +- will_return(__wrap_io_getevents, (nr > 128)? 128 : nr); +- will_return(__wrap_io_getevents, ts); +- will_return(__wrap_io_getevents, &mock_events[off + ev_off]); ++ wrap_will_return(WRAP_IO_GETEVENTS, (nr > 128)? 128 : nr); ++ wrap_will_return(WRAP_IO_GETEVENTS, ts); ++ wrap_will_return(WRAP_IO_GETEVENTS, &mock_events[off + ev_off]); + ts = NULL; + off += 128; + nr -= 128; + } + if (nr == 0) +- will_return(__wrap_io_getevents, 0); ++ wrap_will_return(WRAP_IO_GETEVENTS, 0); + ev_off += i; + } + +@@ -251,7 +251,7 @@ static void do_libcheck_init(struct checker *c, int blocksize, + struct directio_context * ct; + + c->fd = test_fd; +- will_return(__wrap_ioctl, blocksize); ++ wrap_will_return(WRAP_IOCTL, blocksize); + assert_int_equal(libcheck_init(c), 0); + ct = (struct directio_context *)c->context; + assert_non_null(ct); +@@ -762,7 +762,7 @@ int main(void) + { + int ret = 0; + +- init_test_verbosity(2); ++ init_test_verbosity(5); + ret += test_directio(); + return ret; + } +diff --git a/tests/vpd.c b/tests/vpd.c +index 1b2d62d6..e3212e61 100644 +--- a/tests/vpd.c ++++ b/tests/vpd.c +@@ -20,6 +20,7 @@ + #include "vector.h" + #include "structs.h" + #include "discovery.h" ++#include "wrap64.h" + #include "globals.c" + + #define VPD_BUFSIZ 4096 +@@ -58,7 +59,7 @@ static const char vendor_id[] = "Linux"; + static const char test_id[] = + "A123456789AbcDefB123456789AbcDefC123456789AbcDefD123456789AbcDef"; + +-int __wrap_ioctl(int fd, unsigned long request, void *param) ++int WRAP_IOCTL(int fd, unsigned long request, void *param) + { + int len; + struct sg_io_hdr *io_hdr; +@@ -428,8 +429,8 @@ static void test_vpd_vnd_ ## len ## _ ## wlen(void **state) \ + /* Replace spaces, like code under test */ \ + exp_subst = subst_spaces(exp_wwid); \ + free(exp_wwid); \ +- will_return(__wrap_ioctl, n); \ +- will_return(__wrap_ioctl, vt->vpdbuf); \ ++ wrap_will_return(WRAP_IOCTL, n); \ ++ wrap_will_return(WRAP_IOCTL, vt->vpdbuf); \ + ret = get_vpd_sgio(10, 0x83, 0, vt->wwid, wlen); \ + assert_correct_wwid("test_vpd_vnd_" #len "_" #wlen, \ + exp_len, ret, '1', 0, false, \ +@@ -458,8 +459,8 @@ static void test_vpd_str_ ## typ ## _ ## len ## _ ## wlen(void **state) \ + exp_len--; \ + if (exp_len >= wlen) \ + exp_len = wlen - 1; \ +- will_return(__wrap_ioctl, n); \ +- will_return(__wrap_ioctl, vt->vpdbuf); \ ++ wrap_will_return(WRAP_IOCTL, n); \ ++ wrap_will_return(WRAP_IOCTL, vt->vpdbuf); \ + ret = get_vpd_sgio(10, 0x83, 0, vt->wwid, wlen); \ + assert_correct_wwid("test_vpd_str_" #typ "_" #len "_" #wlen, \ + exp_len, ret, byte0[type], 0, \ +@@ -495,8 +496,8 @@ static void test_vpd_naa_ ## naa ## _ ## wlen(void **state) \ + \ + n = create_vpd83(vt->vpdbuf, sizeof(vt->vpdbuf), test_id, \ + 3, naa, 0); \ +- will_return(__wrap_ioctl, n); \ +- will_return(__wrap_ioctl, vt->vpdbuf); \ ++ wrap_will_return(WRAP_IOCTL, n); \ ++ wrap_will_return(WRAP_IOCTL, vt->vpdbuf); \ + ret = get_vpd_sgio(10, 0x83, 0, vt->wwid, wlen); \ + assert_correct_wwid("test_vpd_naa_" #naa "_" #wlen, \ + exp_len, ret, '3', '0' + naa, true, \ +@@ -518,8 +519,8 @@ static void test_vpd_naa_##NAA##_badlen_##BAD(void **state) \ + n = create_vpd83(vt->vpdbuf, sizeof(vt->vpdbuf), test_id, 3, NAA, 0); \ + \ + vt->vpdbuf[7] = BAD; \ +- will_return(__wrap_ioctl, n); \ +- will_return(__wrap_ioctl, vt->vpdbuf); \ ++ wrap_will_return(WRAP_IOCTL, n); \ ++ wrap_will_return(WRAP_IOCTL, vt->vpdbuf); \ + ret = get_vpd_sgio(10, 0x83, 0, vt->wwid, 40); \ + assert_int_equal(-ret, -ERR); \ + } +@@ -545,11 +546,11 @@ static void test_vpd_eui_ ## len ## _ ## wlen ## _ ## sml(void **state) \ + /* overwrite the page size to DEFAULT_SGIO_LEN + 1 */ \ + put_unaligned_be16(255, vt->vpdbuf + 2); \ + /* this causes get_vpd_sgio to do a second ioctl */ \ +- will_return(__wrap_ioctl, n); \ +- will_return(__wrap_ioctl, vt->vpdbuf); \ ++ wrap_will_return(WRAP_IOCTL, n); \ ++ wrap_will_return(WRAP_IOCTL, vt->vpdbuf); \ + } \ +- will_return(__wrap_ioctl, n); \ +- will_return(__wrap_ioctl, vt->vpdbuf); \ ++ wrap_will_return(WRAP_IOCTL, n); \ ++ wrap_will_return(WRAP_IOCTL, vt->vpdbuf); \ + ret = get_vpd_sgio(10, 0x83, 0, vt->wwid, wlen); \ + assert_correct_wwid("test_vpd_eui_" #len "_" #wlen "_" #sml, \ + exp_len, ret, '2', 0, true, \ +@@ -571,8 +572,8 @@ static void test_vpd_eui_badlen_##LEN##_##BAD(void **state) \ + n = create_vpd83(vt->vpdbuf, sizeof(vt->vpdbuf), test_id, 2, 0, LEN); \ + \ + vt->vpdbuf[7] = BAD; \ +- will_return(__wrap_ioctl, n); \ +- will_return(__wrap_ioctl, vt->vpdbuf); \ ++ wrap_will_return(WRAP_IOCTL, n); \ ++ wrap_will_return(WRAP_IOCTL, vt->vpdbuf); \ + ret = get_vpd_sgio(10, 0x83, 0, vt->wwid, 40); \ + assert_int_equal(ret, ERR); \ + if (ERR >= 0) \ +@@ -600,8 +601,8 @@ static void test_vpd80_ ## size ## _ ## len ## _ ## wlen(void **state) \ + exp_len = wlen - 1; \ + n = create_vpd80(vt->vpdbuf, sizeof(vt->vpdbuf), input, \ + size, len); \ +- will_return(__wrap_ioctl, n); \ +- will_return(__wrap_ioctl, vt->vpdbuf); \ ++ wrap_will_return(WRAP_IOCTL, n); \ ++ wrap_will_return(WRAP_IOCTL, vt->vpdbuf); \ + ret = get_vpd_sgio(10, 0x80, 0, vt->wwid, wlen); \ + assert_correct_wwid("test_vpd80_" #size "_" #len "_" #wlen, \ + exp_len, ret, 0, 0, false, \ +diff --git a/tests/wrap64.h b/tests/wrap64.h +index 8c91d279..b0a4d831 100644 +--- a/tests/wrap64.h ++++ b/tests/wrap64.h +@@ -1,5 +1,7 @@ + #ifndef _WRAP64_H + #define _WRAP64_H 1 ++#include ++#include + #include "util.h" + + /* +@@ -31,7 +33,9 @@ + * fcntl() needs special treatment; fcntl64() has been introduced in 2.28. + * https://savannah.gnu.org/forum/forum.php?forum_id=9205 + */ +-#if defined(__GLIBC__) && __GLIBC_PREREQ(2, 28) ++#if defined(__GLIBC__) && __GLIBC_PREREQ(2, 37) && defined(__arm__) && __ARM_ARCH == 7 ++#define WRAP_FCNTL_NAME __fcntl_time64 ++#elif defined(__GLIBC__) && __GLIBC_PREREQ(2, 28) + #define WRAP_FCNTL_NAME WRAP_NAME(fcntl) + #else + #define WRAP_FCNTL_NAME fcntl +@@ -39,6 +43,25 @@ + #define WRAP_FCNTL CONCAT2(__wrap_, WRAP_FCNTL_NAME) + #define REAL_FCNTL CONCAT2(__real_, WRAP_FCNTL_NAME) + ++/* ++ * glibc 2.37 uses __ioctl_time64 for ioctl ++ */ ++#if defined(__GLIBC__) && __GLIBC_PREREQ(2, 37) && defined(__arm__) && __ARM_ARCH == 7 ++#define WRAP_IOCTL_NAME __ioctl_time64 ++#else ++#define WRAP_IOCTL_NAME ioctl ++#endif ++#define WRAP_IOCTL CONCAT2(__wrap_, WRAP_IOCTL_NAME) ++#define REAL_IOCTL CONCAT2(__real_, WRAP_IOCTL_NAME) ++ ++#if defined(__NR_io_pgetevents) && __BITS_PER_LONG == 32 && defined(_TIME_BITS) && _TIME_BITS == 64 ++#define WRAP_IO_GETEVENTS_NAME io_getevents_time64 ++#else ++#define WRAP_IO_GETEVENTS_NAME io_getevents ++#endif ++#define WRAP_IO_GETEVENTS CONCAT2(__wrap_, WRAP_IO_GETEVENTS_NAME) ++#define REAL_IO_GETEVENTS CONCAT2(__real_, WRAP_IO_GETEVENTS_NAME) ++ + /* + * will_return() is itself a macro that uses CPP "stringizing". We need a + * macro indirection to make sure the *value* of WRAP_FUNC() is stringized diff --git a/0019-multipath-tools-tests-fix-CI-failures-with-clang-on-.patch b/0019-multipath-tools-tests-fix-CI-failures-with-clang-on-.patch new file mode 100644 index 0000000..d1dedac --- /dev/null +++ b/0019-multipath-tools-tests-fix-CI-failures-with-clang-on-.patch @@ -0,0 +1,246 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 5 Apr 2024 22:21:43 +0200 +Subject: [PATCH] multipath-tools tests: fix CI failures with clang on Fedora + Rawhide + +Fedora's glibc 2.39 includes the following patch: + +https://patches.linaro.org/project/libc-alpha/patch/20240208184622.332678-10-adhemerval.zanella@linaro.org/ + +It causes open("file", O_RDONLY) to resolve to __open64_2(), +whereas it resolves to open64() with gcc, causing CI failures because of +wrong wrapper substitutions. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + tests/dmevents.c | 6 ++--- + tests/sysfs.c | 58 ++++++++++++++++++++++++------------------------ + tests/test-lib.c | 6 ++--- + tests/wrap64.h | 14 ++++++++++++ + 4 files changed, 49 insertions(+), 35 deletions(-) + +diff --git a/tests/dmevents.c b/tests/dmevents.c +index 540bf0d3..395b16d7 100644 +--- a/tests/dmevents.c ++++ b/tests/dmevents.c +@@ -207,7 +207,7 @@ static int teardown(void **state) + return 0; + } + +-int WRAP_FUNC(open)(const char *pathname, int flags) ++int WRAP_OPEN(const char *pathname, int flags) + { + assert_ptr_equal(pathname, "/dev/mapper/control"); + assert_int_equal(flags, O_RDWR); +@@ -389,7 +389,7 @@ static void test_init_waiter_bad1(void **state) + struct test_data *datap = (struct test_data *)(*state); + if (datap == NULL) + skip(); +- wrap_will_return(WRAP_FUNC(open), -1); ++ wrap_will_return(WRAP_OPEN, -1); + assert_int_equal(init_dmevent_waiter(&datap->vecs), -1); + assert_ptr_equal(waiter, NULL); + } +@@ -400,7 +400,7 @@ static void test_init_waiter_good0(void **state) + struct test_data *datap = (struct test_data *)(*state); + if (datap == NULL) + skip(); +- wrap_will_return(WRAP_FUNC(open), 2); ++ wrap_will_return(WRAP_OPEN, 2); + assert_int_equal(init_dmevent_waiter(&datap->vecs), 0); + assert_ptr_not_equal(waiter, NULL); + } +diff --git a/tests/sysfs.c b/tests/sysfs.c +index fc256d87..c623d1bb 100644 +--- a/tests/sysfs.c ++++ b/tests/sysfs.c +@@ -29,7 +29,7 @@ char *__wrap_udev_device_get_syspath(struct udev_device *ud) + return val; + } + +-int WRAP_FUNC(open)(const char *pathname, int flags) ++int WRAP_OPEN(const char *pathname, int flags) + { + int ret; + +@@ -167,10 +167,10 @@ static void test_sagv_open_fail(void **state) + + will_return(__wrap_udev_device_get_syspath, "/foo"); + expect_condlog(4, "open '/foo/bar'"); +- expect_string(WRAP_FUNC(open), pathname, "/foo/bar"); +- expect_value(WRAP_FUNC(open), flags, O_RDONLY); ++ expect_string(WRAP_OPEN, pathname, "/foo/bar"); ++ expect_value(WRAP_OPEN, flags, O_RDONLY); + errno = ENOENT; +- wrap_will_return(WRAP_FUNC(open), -1); ++ wrap_will_return(WRAP_OPEN, -1); + expect_condlog(3, "__sysfs_attr_get_value: attribute '/foo/bar' cannot be opened"); + assert_int_equal(sysfs_attr_get_value((void *)state, "bar", + buf, sizeof(buf)), -ENOENT); +@@ -182,9 +182,9 @@ static void test_sagv_read_fail(void **state) + + will_return(__wrap_udev_device_get_syspath, "/foo"); + expect_condlog(4, "open '/foo/bar'"); +- expect_string(WRAP_FUNC(open), pathname, "/foo/bar"); +- expect_value(WRAP_FUNC(open), flags, O_RDONLY); +- wrap_will_return(WRAP_FUNC(open), TEST_FD); ++ expect_string(WRAP_OPEN, pathname, "/foo/bar"); ++ expect_value(WRAP_OPEN, flags, O_RDONLY); ++ wrap_will_return(WRAP_OPEN, TEST_FD); + expect_value(__wrap_read, fd, TEST_FD); + expect_value(__wrap_read, count, sizeof(buf)); + errno = EISDIR; +@@ -197,9 +197,9 @@ static void test_sagv_read_fail(void **state) + + will_return(__wrap_udev_device_get_syspath, "/foo"); + expect_condlog(4, "open '/foo/baz'"); +- expect_string(WRAP_FUNC(open), pathname, "/foo/baz"); +- expect_value(WRAP_FUNC(open), flags, O_RDONLY); +- wrap_will_return(WRAP_FUNC(open), TEST_FD); ++ expect_string(WRAP_OPEN, pathname, "/foo/baz"); ++ expect_value(WRAP_OPEN, flags, O_RDONLY); ++ wrap_will_return(WRAP_OPEN, TEST_FD); + expect_value(__wrap_read, fd, TEST_FD); + expect_value(__wrap_read, count, sizeof(buf)); + errno = EPERM; +@@ -223,9 +223,9 @@ static void _test_sagv_read(void **state, unsigned int bufsz) + memset(buf, '.', sizeof(buf)); + will_return(__wrap_udev_device_get_syspath, "/foo"); + expect_condlog(4, "open '/foo/bar'"); +- expect_string(WRAP_FUNC(open), pathname, "/foo/bar"); +- expect_value(WRAP_FUNC(open), flags, O_RDONLY); +- wrap_will_return(WRAP_FUNC(open), TEST_FD); ++ expect_string(WRAP_OPEN, pathname, "/foo/bar"); ++ expect_value(WRAP_OPEN, flags, O_RDONLY); ++ wrap_will_return(WRAP_OPEN, TEST_FD); + expect_value(__wrap_read, fd, TEST_FD); + expect_value(__wrap_read, count, bufsz); + will_return(__wrap_read, sizeof(input) - 1); +@@ -250,9 +250,9 @@ static void _test_sagv_read(void **state, unsigned int bufsz) + memset(buf, '.', sizeof(buf)); + will_return(__wrap_udev_device_get_syspath, "/foo"); + expect_condlog(4, "open '/foo/baz'"); +- expect_string(WRAP_FUNC(open), pathname, "/foo/baz"); +- expect_value(WRAP_FUNC(open), flags, O_RDONLY); +- wrap_will_return(WRAP_FUNC(open), TEST_FD); ++ expect_string(WRAP_OPEN, pathname, "/foo/baz"); ++ expect_value(WRAP_OPEN, flags, O_RDONLY); ++ wrap_will_return(WRAP_OPEN, TEST_FD); + expect_value(__wrap_read, fd, TEST_FD); + expect_value(__wrap_read, count, bufsz); + will_return(__wrap_read, sizeof(input) - 1); +@@ -301,9 +301,9 @@ static void _test_sagv_read_zeroes(void **state, unsigned int bufsz) + memset(buf, '.', sizeof(buf)); + will_return(__wrap_udev_device_get_syspath, "/foo"); + expect_condlog(4, "open '/foo/bar'"); +- expect_string(WRAP_FUNC(open), pathname, "/foo/bar"); +- expect_value(WRAP_FUNC(open), flags, O_RDONLY); +- wrap_will_return(WRAP_FUNC(open), TEST_FD); ++ expect_string(WRAP_OPEN, pathname, "/foo/bar"); ++ expect_value(WRAP_OPEN, flags, O_RDONLY); ++ wrap_will_return(WRAP_OPEN, TEST_FD); + expect_value(__wrap_read, fd, TEST_FD); + expect_value(__wrap_read, count, bufsz); + will_return(__wrap_read, sizeof(input) - 1); +@@ -386,10 +386,10 @@ static void test_sasv_open_fail(void **state) + + will_return(__wrap_udev_device_get_syspath, "/foo"); + expect_condlog(4, "open '/foo/bar'"); +- expect_string(WRAP_FUNC(open), pathname, "/foo/bar"); +- expect_value(WRAP_FUNC(open), flags, O_WRONLY); ++ expect_string(WRAP_OPEN, pathname, "/foo/bar"); ++ expect_value(WRAP_OPEN, flags, O_WRONLY); + errno = EPERM; +- wrap_will_return(WRAP_FUNC(open), -1); ++ wrap_will_return(WRAP_OPEN, -1); + expect_condlog(3, "sysfs_attr_set_value: attribute '/foo/bar' cannot be opened"); + assert_int_equal(sysfs_attr_set_value((void *)state, "bar", + buf, sizeof(buf)), -EPERM); +@@ -401,9 +401,9 @@ static void test_sasv_write_fail(void **state) + + will_return(__wrap_udev_device_get_syspath, "/foo"); + expect_condlog(4, "open '/foo/bar'"); +- expect_string(WRAP_FUNC(open), pathname, "/foo/bar"); +- expect_value(WRAP_FUNC(open), flags, O_WRONLY); +- wrap_will_return(WRAP_FUNC(open), TEST_FD); ++ expect_string(WRAP_OPEN, pathname, "/foo/bar"); ++ expect_value(WRAP_OPEN, flags, O_WRONLY); ++ wrap_will_return(WRAP_OPEN, TEST_FD); + expect_value(__wrap_write, fd, TEST_FD); + expect_value(__wrap_write, count, sizeof(buf)); + errno = EISDIR; +@@ -422,9 +422,9 @@ static void _test_sasv_write(void **state, unsigned int n_written) + assert_in_range(n_written, 0, sizeof(buf)); + will_return(__wrap_udev_device_get_syspath, "/foo"); + expect_condlog(4, "open '/foo/bar'"); +- expect_string(WRAP_FUNC(open), pathname, "/foo/bar"); +- expect_value(WRAP_FUNC(open), flags, O_WRONLY); +- wrap_will_return(WRAP_FUNC(open), TEST_FD); ++ expect_string(WRAP_OPEN, pathname, "/foo/bar"); ++ expect_value(WRAP_OPEN, flags, O_WRONLY); ++ wrap_will_return(WRAP_OPEN, TEST_FD); + expect_value(__wrap_write, fd, TEST_FD); + expect_value(__wrap_write, count, sizeof(buf)); + will_return(__wrap_write, n_written); +@@ -489,7 +489,7 @@ int main(void) + { + int ret = 0; + +- init_test_verbosity(4); ++ init_test_verbosity(5); + ret += test_sysfs(); + return ret; + } +diff --git a/tests/test-lib.c b/tests/test-lib.c +index 665d438e..cdb2780d 100644 +--- a/tests/test-lib.c ++++ b/tests/test-lib.c +@@ -40,17 +40,17 @@ const char default_wwid_1[] = "TEST-WWID-1"; + */ + + +-int REAL_FUNC(open)(const char *path, int flags, int mode); ++int REAL_OPEN(const char *path, int flags, int mode); + + static const char _mocked_filename[] = "mocked_path"; + +-int WRAP_FUNC(open)(const char *path, int flags, int mode) ++int WRAP_OPEN(const char *path, int flags, int mode) + { + condlog(4, "%s: %s", __func__, path); + + if (!strcmp(path, _mocked_filename)) + return 111; +- return REAL_FUNC(open)(path, flags, mode); ++ return REAL_OPEN(path, flags, mode); + } + + int __wrap_libmp_get_version(int which, unsigned int version[3]) +diff --git a/tests/wrap64.h b/tests/wrap64.h +index b0a4d831..7e434206 100644 +--- a/tests/wrap64.h ++++ b/tests/wrap64.h +@@ -29,6 +29,20 @@ + #define WRAP_FUNC(x) CONCAT2(__wrap_, WRAP_NAME(x)) + #define REAL_FUNC(x) CONCAT2(__real_, WRAP_NAME(x)) + ++/* ++ * With clang, glibc 2.39, and _FILE_OFFSET_BITS==64, ++ * open() resolves to __open64_2(). ++ */ ++#if defined(__GLIBC__) && __GLIBC_PREREQ(2, 39) && \ ++ defined(__clang__) && __clang__ == 1 && \ ++ defined(__fortify_use_clang) && __fortify_use_clang == 1 ++#define WRAP_OPEN_NAME __open64_2 ++#else ++#define WRAP_OPEN_NAME WRAP_NAME(open) ++#endif ++#define WRAP_OPEN CONCAT2(__wrap_, WRAP_OPEN_NAME) ++#define REAL_OPEN CONCAT2(__real_, WRAP_OPEN_NAME) ++ + /* + * fcntl() needs special treatment; fcntl64() has been introduced in 2.28. + * https://savannah.gnu.org/forum/forum.php?forum_id=9205 diff --git a/0020-GitHub-actions-fixes-for-spelling-CI.patch b/0020-GitHub-actions-fixes-for-spelling-CI.patch new file mode 100644 index 0000000..21b74ff --- /dev/null +++ b/0020-GitHub-actions-fixes-for-spelling-CI.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 8 Mar 2024 10:04:39 +0100 +Subject: [PATCH] GitHub actions: fixes for spelling CI + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .github/actions/spelling/patterns.txt | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/.github/actions/spelling/patterns.txt b/.github/actions/spelling/patterns.txt +index 57767ea1..858faee6 100644 +--- a/.github/actions/spelling/patterns.txt ++++ b/.github/actions/spelling/patterns.txt +@@ -22,6 +22,7 @@ + \bdmmp_pgs\b + \bdmmp_mpath_kdev_name_get\b + \bfast_io_fail_tmo\b ++\bLimitRTPRIO\b + \bmax_fds\b + \bmissing_uev_wait_timeout\b + \bMPATH_MAX_PARAM_LEN\b +@@ -86,6 +87,7 @@ + \bprin_resvdescr\b + \bprout_param_descriptor\b + \brq_servact\b ++\bSCHED_RT_PRIO\b + \bssize_t\b + \btrnptid_list\b + \buxsock_timeout\b diff --git a/0021-GitHub-workflows-run-workflows-if-workflow-file-has-.patch b/0021-GitHub-workflows-run-workflows-if-workflow-file-has-.patch new file mode 100644 index 0000000..59cdd0e --- /dev/null +++ b/0021-GitHub-workflows-run-workflows-if-workflow-file-has-.patch @@ -0,0 +1,146 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 27 Feb 2024 09:57:47 +0100 +Subject: [PATCH] GitHub workflows: run workflows if workflow file has changed + +We want to run workflows if the workflow file itself has changed. + +Fixes: 2cbe81a ("GitHub Workflows: run expensive workflows only on relevant changes") +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/abi.yaml | 1 + + .github/workflows/foreign.yaml | 2 ++ + .github/workflows/multiarch-stable.yaml | 2 ++ + .github/workflows/multiarch.yaml | 2 ++ + .github/workflows/native.yaml | 2 ++ + .github/workflows/rolling.yaml | 2 ++ + .github/workflows/spelling.yml | 2 ++ + 7 files changed, 13 insertions(+) + +diff --git a/.github/workflows/abi.yaml b/.github/workflows/abi.yaml +index 53382420..393322e5 100644 +--- a/.github/workflows/abi.yaml ++++ b/.github/workflows/abi.yaml +@@ -5,6 +5,7 @@ on: + - queue + - abi + paths: ++ - '.github/workflows/abi.yaml' + - '**.h' + - '**.c' + pull_request: +diff --git a/.github/workflows/foreign.yaml b/.github/workflows/foreign.yaml +index 92f6d17a..a62ae009 100644 +--- a/.github/workflows/foreign.yaml ++++ b/.github/workflows/foreign.yaml +@@ -6,6 +6,7 @@ on: + - queue + - tip + paths: ++ - '.github/workflows/foreign.yaml' + - '**.h' + - '**.c' + - '**Makefile*' +@@ -15,6 +16,7 @@ on: + - master + - queue + paths: ++ - '.github/workflows/foreign.yaml' + - '**.h' + - '**.c' + - '**Makefile*' +diff --git a/.github/workflows/multiarch-stable.yaml b/.github/workflows/multiarch-stable.yaml +index 45b74c51..e51d383c 100644 +--- a/.github/workflows/multiarch-stable.yaml ++++ b/.github/workflows/multiarch-stable.yaml +@@ -6,6 +6,7 @@ on: + - queue + - tip + paths: ++ - '.github/workflows/multiarch-stable.yaml' + - '**.h' + - '**.c' + - '**Makefile*' +@@ -15,6 +16,7 @@ on: + - master + - queue + paths: ++ - '.github/workflows/multiarch-stable.yaml' + - '**.h' + - '**.c' + - '**Makefile*' +diff --git a/.github/workflows/multiarch.yaml b/.github/workflows/multiarch.yaml +index b4dec9c7..7b762e5c 100644 +--- a/.github/workflows/multiarch.yaml ++++ b/.github/workflows/multiarch.yaml +@@ -6,6 +6,7 @@ on: + - queue + - tip + paths: ++ - '.github/workflows/multiarch.yaml' + - '**.h' + - '**.c' + - '**Makefile*' +@@ -15,6 +16,7 @@ on: + - master + - queue + paths: ++ - '.github/workflows/multiarch.yaml' + - '**.h' + - '**.c' + - '**Makefile*' +diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml +index 09133c1e..0ef9df94 100644 +--- a/.github/workflows/native.yaml ++++ b/.github/workflows/native.yaml +@@ -6,6 +6,7 @@ on: + - queue + - tip + paths: ++ - '.github/workflows/native.yaml' + - '**.h' + - '**.c' + - '**Makefile*' +@@ -15,6 +16,7 @@ on: + - master + - queue + paths: ++ - '.github/workflows/native.yaml' + - '**.h' + - '**.c' + - '**Makefile*' +diff --git a/.github/workflows/rolling.yaml b/.github/workflows/rolling.yaml +index 1f1507ee..3536b944 100644 +--- a/.github/workflows/rolling.yaml ++++ b/.github/workflows/rolling.yaml +@@ -6,6 +6,7 @@ on: + - queue + - tip + paths: ++ - '.github/workflows/rolling.yaml' + - '**.h' + - '**.c' + - '**Makefile*' +@@ -15,6 +16,7 @@ on: + - master + - queue + paths: ++ - '.github/workflows/rolling.yaml' + - '**.h' + - '**.c' + - '**Makefile*' +diff --git a/.github/workflows/spelling.yml b/.github/workflows/spelling.yml +index 0416fa9e..7943ebb8 100644 +--- a/.github/workflows/spelling.yml ++++ b/.github/workflows/spelling.yml +@@ -63,7 +63,9 @@ on: + tags-ignore: + - "**" + paths: ++ - '.github/workflows/spelling.yml' + - 'README*' ++ - 'NEWS.md' + - '**.3' + - '**.5' + - '**.8' diff --git a/0022-multipath-tools-add-TGTDIR-option.patch b/0022-multipath-tools-add-TGTDIR-option.patch new file mode 100644 index 0000000..d26fb18 --- /dev/null +++ b/0022-multipath-tools-add-TGTDIR-option.patch @@ -0,0 +1,106 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 17 Apr 2024 14:44:45 +0200 +Subject: [PATCH] multipath-tools: add TGTDIR option + +TGTDIR is a convenience option for developers for building multipath-tools such +that compiled-in paths of the plugins, config files, etc. match an +installation under some optional path. See README.md for instructions and +examples. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + .github/actions/spelling/expect.txt | 2 ++ + Makefile.inc | 8 +++---- + README.md | 33 +++++++++++++++++++++++++++++ + 3 files changed, 39 insertions(+), 4 deletions(-) + +diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt +index 5906403d..fc9f22f8 100644 +--- a/.github/actions/spelling/expect.txt ++++ b/.github/actions/spelling/expect.txt +@@ -167,6 +167,7 @@ retrigger + rhabarber + rootprefix + rootprefixdir ++rpmbuild + rport + rtpi + sas +@@ -200,6 +201,7 @@ tcp + TESTDEPS + testname + tgill ++TGTDIR + TIDS + tmo + tpg +diff --git a/Makefile.inc b/Makefile.inc +index 5668e638..81b86cd8 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -101,9 +101,9 @@ WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implici + $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) $(W_URCU_TYPE_LIMITS) + CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) $(D_URCU_VERSION) \ + -D_FILE_OFFSET_BITS=64 \ +- -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \ +- -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(configdir)\" \ +- -DDEFAULT_CONFIGFILE=\"$(configfile)\" -DSTATE_DIR=\"$(statedir)\" \ ++ -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(TGTDIR)$(plugindir)\" \ ++ -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(TGTDIR)$(configdir)\" \ ++ -DDEFAULT_CONFIGFILE=\"$(TGTDIR)$(configfile)\" -DSTATE_DIR=\"$(TGTDIR)$(statedir)\" \ + -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP + CFLAGS := -std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe + BIN_CFLAGS := -fPIE -DPIE +@@ -149,4 +149,4 @@ NV_VERSION_SCRIPT = $(DEVLIB:%.so=%-nv.version) + + %: %.in + @echo creating $@ +- $(Q)sed 's:@CONFIGFILE@:'$(configfile)':g;s:@CONFIGDIR@:'$(configdir)':g;s:@STATE_DIR@:'$(statedir)':g;s:@RUNTIME_DIR@:'$(runtimedir)':g;s/@MODPROBE_UNIT@/'$(MODPROBE_UNIT)'/g;s:@BINDIR@:'$(bindir)':g' $< >$@ ++ $(Q)sed 's:@CONFIGFILE@:'$(TGTDIR)$(configfile)':g;s:@CONFIGDIR@:'$(TGTDIR)$(configdir)':g;s:@STATE_DIR@:'$(TGTDIR)$(statedir)':g;s:@RUNTIME_DIR@:'$(runtimedir)':g;s/@MODPROBE_UNIT@/'$(MODPROBE_UNIT)'/g;s:@BINDIR@:'$(bindir)':g' $< >$@ +diff --git a/README.md b/README.md +index d4f35f57..7207b14c 100644 +--- a/README.md ++++ b/README.md +@@ -151,6 +151,39 @@ sufficient control. See `Makefile.inc` for even more fine-grained control. + On such distributions, override `unitdir` and `libudevdir` to use systemd's + `rootprefix`: `make libudevdir=/lib/udev unitdir=/lib/systemd/system` + ++### prefix, DESTDIR and TGTDIR ++ ++`prefix` and related variables are included in compiled-in paths like ++`plugindir` and are used by `make install`. Using `prefix` is useful if ++multipath-tools is built locally on the same host where it's supposed to be ++installed. ++ ++By convention, the `DESTDIR` variable is prepended to all paths by `make ++install`, but not to any compiled-in paths. ++It is useful if the software is built on one system (build host) but intended ++to be run on another system (installation host). This is typically used in build ++systems like *rpmbuild* to set a root directory for all the installed ++files. ++ ++On the contrary, the `TGTDIR` variable is used for compiled-in paths only, and ++ignored by `make install`. It is useful for running multipath-tools in a separate ++subdirectory in the installation host, mostly for testing / development ++purposes. ++ ++For example, ++ ++ make prefix=/opt DESTDIR=/build TGTDIR=/test install ++ ++will install plugins into `/build/opt/lib64/multipath` on the build ++host. On the installation host, the plugins will be expected to be found under ++`/test/opt/lib64/multipath`. If the developer runs ++ ++ rsync -a $BUILD_HOST:$DESTDIR/ $INSTALL_HOST:$TGTDIR/ ++ ++and adds `$TGTDIR/lib64` to `LD_LIBRARY_PATH` on the installation host, the ++multipath binaries installed under `$TGTDIR` will find their plugins and ++configuration files in the expected compiled-in paths. ++ + ### Compiler Options + + Use `OPTFLAGS` to change optimization-related compiler options; diff --git a/0023-libmultipath-move-get_udev_for_mpp-to-sysfs.c.patch b/0023-libmultipath-move-get_udev_for_mpp-to-sysfs.c.patch new file mode 100644 index 0000000..b59f879 --- /dev/null +++ b/0023-libmultipath-move-get_udev_for_mpp-to-sysfs.c.patch @@ -0,0 +1,87 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 17 Apr 2024 17:18:18 +0200 +Subject: [PATCH] libmultipath: move get_udev_for_mpp to sysfs.c + +No functional changes, just code movement. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/configure.c | 20 -------------------- + libmultipath/sysfs.c | 19 +++++++++++++++++++ + libmultipath/sysfs.h | 4 ++++ + 3 files changed, 23 insertions(+), 20 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index 4ecf6ba4..89ac03d5 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -453,26 +453,6 @@ pgcmp (struct multipath * mpp, struct multipath * cmpp) + return r; + } + +-static struct udev_device * +-get_udev_for_mpp(const struct multipath *mpp) +-{ +- dev_t devnum; +- struct udev_device *udd; +- +- if (!mpp || !has_dm_info(mpp)) { +- condlog(1, "%s called with empty mpp", __func__); +- return NULL; +- } +- +- devnum = makedev(mpp->dmi.major, mpp->dmi.minor); +- udd = udev_device_new_from_devnum(udev, 'b', devnum); +- if (!udd) { +- condlog(1, "failed to get udev device for %s", mpp->alias); +- return NULL; +- } +- return udd; +-} +- + void trigger_partitions_udev_change(struct udev_device *dev, + const char *action, int len) + { +diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c +index 328951ed..afe9de91 100644 +--- a/libmultipath/sysfs.c ++++ b/libmultipath/sysfs.c +@@ -339,3 +339,22 @@ bool sysfs_is_multipathed(struct path *pp, bool set_wwid) + + return found; + } ++ ++struct udev_device *get_udev_for_mpp(const struct multipath *mpp) ++{ ++ dev_t devnum; ++ struct udev_device *udd; ++ ++ if (!mpp || !has_dm_info(mpp)) { ++ condlog(1, "%s called with empty mpp", __func__); ++ return NULL; ++ } ++ ++ devnum = makedev(mpp->dmi.major, mpp->dmi.minor); ++ udd = udev_device_new_from_devnum(udev, 'b', devnum); ++ if (!udd) { ++ condlog(1, "failed to get udev device for %s", mpp->alias); ++ return NULL; ++ } ++ return udd; ++} +diff --git a/libmultipath/sysfs.h b/libmultipath/sysfs.h +index 2db86bd6..3be3f665 100644 +--- a/libmultipath/sysfs.h ++++ b/libmultipath/sysfs.h +@@ -39,4 +39,8 @@ do { \ + int sysfs_get_size (struct path *pp, unsigned long long * size); + int sysfs_check_holders(char * check_devt, char * new_devt); + bool sysfs_is_multipathed(struct path *pp, bool set_wwid); ++ ++struct multipath; ++struct udev_device *get_udev_for_mpp(const struct multipath *mpp); ++ + #endif diff --git a/0024-libmultipath-add-mp_find_path_by_devt.patch b/0024-libmultipath-add-mp_find_path_by_devt.patch new file mode 100644 index 0000000..8a85be2 --- /dev/null +++ b/0024-libmultipath-add-mp_find_path_by_devt.patch @@ -0,0 +1,60 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 17 Apr 2024 14:57:33 +0200 +Subject: [PATCH] libmultipath: add mp_find_path_by_devt() + +A helper function that searches a struct multipath by dev_t, and +works whether or not mpp->paths is currently available. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/structs.c | 19 +++++++++++++++++++ + libmultipath/structs.h | 3 +++ + 2 files changed, 22 insertions(+) + +diff --git a/libmultipath/structs.c b/libmultipath/structs.c +index 74e31a13..e248fb51 100644 +--- a/libmultipath/structs.c ++++ b/libmultipath/structs.c +@@ -526,6 +526,25 @@ find_path_by_devt (const struct _vector *pathvec, const char * dev_t) + return NULL; + } + ++struct path *mp_find_path_by_devt(const struct multipath *mpp, const char *devt) ++{ ++ struct path *pp; ++ struct pathgroup *pgp; ++ unsigned int i, j; ++ ++ pp = find_path_by_devt(mpp->paths, devt); ++ if (pp) ++ return pp; ++ ++ vector_foreach_slot (mpp->pg, pgp, i){ ++ vector_foreach_slot (pgp->paths, pp, j){ ++ if (!strcmp(pp->dev_t, devt)) ++ return pp; ++ } ++ } ++ return NULL; ++} ++ + static int do_pathcount(const struct multipath *mpp, const int *states, + unsigned int nr_states) + { +diff --git a/libmultipath/structs.h b/libmultipath/structs.h +index 734905e2..a25eb9d5 100644 +--- a/libmultipath/structs.h ++++ b/libmultipath/structs.h +@@ -568,6 +568,9 @@ struct path * find_path_by_devt (const struct _vector *pathvec, const char *devt + struct path * find_path_by_dev (const struct _vector *pathvec, const char *dev); + struct path * first_path (const struct multipath *mpp); + ++struct path *mp_find_path_by_devt(const struct multipath *mpp, const char *devt); ++ ++ + int pathcount (const struct multipath *, int); + int count_active_paths(const struct multipath *); + int count_active_pending_paths(const struct multipath *); diff --git a/0025-Revert-libmultipath-fix-max_sectors_kb-on-adding-pat.patch b/0025-Revert-libmultipath-fix-max_sectors_kb-on-adding-pat.patch new file mode 100644 index 0000000..aaa0e9f --- /dev/null +++ b/0025-Revert-libmultipath-fix-max_sectors_kb-on-adding-pat.patch @@ -0,0 +1,33 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 11 Apr 2024 17:20:14 +0200 +Subject: [PATCH] Revert "libmultipath: fix max_sectors_kb on adding path" + +This reverts commit bbb77f318ee483292f50a7782aecaecc7e60f727. +Reviewed-by: Benjamin Marzinski + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/configure.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index 89ac03d5..13602f3f 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -575,12 +575,11 @@ sysfs_set_max_sectors_kb(struct multipath *mpp, int is_reload) + ssize_t len; + int i, j, ret, err = 0; + struct udev_device *udd; +- int max_sectors_kb = mpp->max_sectors_kb; ++ int max_sectors_kb; + +- /* by default, do not initialize max_sectors_kb on the device */ +- if (max_sectors_kb == MAX_SECTORS_KB_UNDEF && !is_reload) ++ if (mpp->max_sectors_kb == MAX_SECTORS_KB_UNDEF) + return 0; +- /* on reload, re-apply the user tuning on all the path devices */ ++ max_sectors_kb = mpp->max_sectors_kb; + if (is_reload) { + if (!has_dm_info(mpp) && + dm_get_info(mpp->alias, &mpp->dmi) != 0) { diff --git a/0026-libmultipath-Only-set-max_sectors_kb-on-map-creation.patch b/0026-libmultipath-Only-set-max_sectors_kb-on-map-creation.patch new file mode 100644 index 0000000..c82cfe7 --- /dev/null +++ b/0026-libmultipath-Only-set-max_sectors_kb-on-map-creation.patch @@ -0,0 +1,122 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 16 Apr 2024 22:20:46 +0200 +Subject: [PATCH] libmultipath: Only set max_sectors_kb on map creation + +Changing max_sectors_kb on a live map is dangerous. When I/O occurs while the +max_sectors_kb value of a map is larger than that of any of its paths, I/O +errors like this may result: + + blk_insert_cloned_request: over max size limit. (127 > 126) + +This situation must be strictly avoided. The kernel makes sure that the +map's limits match those of the paths when the map is created. But setting +max_sectors_kb on path devices before reloading is dangerous, even if we +read the value from the map's max_sectors_kb beforehand. The reason for +this is that the sysfs value max_sectors_kb is the kernel's max_sectors +divided by 2, and user space has no way to figure out if the kernel-internal +value is odd or even. Thus by writing back the value just read to +max_sectors_kb, one might actually decrease the kernel value by one. + +The only safe way to set max_sectors_kb on a live map would be to suspend +it, flushing all outstanding IO, then the path max_sectors_kb, reload, +and resume. + +Since commit 8fd4868 ("libmultipath: don't set max_sectors_kb on reloads"), +we don't set the configured max_sectors_kb any more. But as shown above, +this is not safe. So really only set max_sectors_kb when creating a map. + +Users who have stacked block devices on top of multipath, as described in the +commit message of 8fd4868 must make sure that the max_sectors_kb setting is +correct when the multipath map is first created. Decreasing the map's +max_sectors_kb value (without touching the paths) should actually be possible +in this situation, because stacked block devices are usually bio-based, and +bio-based IO (in contrast to request-based) can be split if the lower-level +device has can't handle the size of the I/O. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/configure.c | 38 ++++---------------------------------- + 1 file changed, 4 insertions(+), 34 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index 13602f3f..8cbb2a88 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -566,46 +566,18 @@ trigger_paths_udev_change(struct multipath *mpp, bool is_mpath) + mpp->needs_paths_uevent = 0; + } + +-static int +-sysfs_set_max_sectors_kb(struct multipath *mpp, int is_reload) ++static int sysfs_set_max_sectors_kb(struct multipath *mpp) + { + struct pathgroup * pgp; + struct path *pp; + char buff[11]; + ssize_t len; + int i, j, ret, err = 0; +- struct udev_device *udd; +- int max_sectors_kb; + + if (mpp->max_sectors_kb == MAX_SECTORS_KB_UNDEF) + return 0; +- max_sectors_kb = mpp->max_sectors_kb; +- if (is_reload) { +- if (!has_dm_info(mpp) && +- dm_get_info(mpp->alias, &mpp->dmi) != 0) { +- condlog(1, "failed to get dm info for %s", mpp->alias); +- return 1; +- } +- udd = get_udev_for_mpp(mpp); +- if (!udd) { +- condlog(1, "failed to get udev device to set max_sectors_kb for %s", mpp->alias); +- return 1; +- } +- ret = sysfs_attr_get_value(udd, "queue/max_sectors_kb", buff, +- sizeof(buff)); +- udev_device_unref(udd); +- if (!sysfs_attr_value_ok(ret, sizeof(buff))) { +- condlog(1, "failed to get current max_sectors_kb from %s", mpp->alias); +- return 1; +- } +- if (sscanf(buff, "%u\n", &max_sectors_kb) != 1) { +- condlog(1, "can't parse current max_sectors_kb from %s", +- mpp->alias); +- return 1; +- } +- } +- snprintf(buff, 11, "%d", max_sectors_kb); +- len = strlen(buff); ++ ++ len = snprintf(buff, sizeof(buff), "%d", mpp->max_sectors_kb); + + vector_foreach_slot (mpp->pg, pgp, i) { + vector_foreach_slot(pgp->paths, pp, j) { +@@ -923,7 +895,7 @@ int domap(struct multipath *mpp, char *params, int is_daemon) + return DOMAP_RETRY; + } + +- sysfs_set_max_sectors_kb(mpp, 0); ++ sysfs_set_max_sectors_kb(mpp); + if (is_daemon && mpp->ghost_delay > 0 && count_active_paths(mpp) && + pathcount(mpp, PATH_UP) == 0) + mpp->ghost_delay_tick = mpp->ghost_delay; +@@ -934,7 +906,6 @@ int domap(struct multipath *mpp, char *params, int is_daemon) + + case ACT_RELOAD: + case ACT_RELOAD_RENAME: +- sysfs_set_max_sectors_kb(mpp, 1); + if (mpp->ghost_delay_tick > 0 && pathcount(mpp, PATH_UP)) + mpp->ghost_delay_tick = 0; + r = dm_addmap_reload(mpp, params, 0); +@@ -942,7 +913,6 @@ int domap(struct multipath *mpp, char *params, int is_daemon) + + case ACT_RESIZE: + case ACT_RESIZE_RENAME: +- sysfs_set_max_sectors_kb(mpp, 1); + if (mpp->ghost_delay_tick > 0 && pathcount(mpp, PATH_UP)) + mpp->ghost_delay_tick = 0; + r = dm_addmap_reload(mpp, params, 1); diff --git a/0027-libmultipath-set-max_sectors_kb-in-adopt_paths.patch b/0027-libmultipath-set-max_sectors_kb-in-adopt_paths.patch new file mode 100644 index 0000000..a4389df --- /dev/null +++ b/0027-libmultipath-set-max_sectors_kb-in-adopt_paths.patch @@ -0,0 +1,233 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 16 Apr 2024 23:59:03 +0200 +Subject: [PATCH] libmultipath: set max_sectors_kb in adopt_paths() + +As explained in the previous commit, setting max_sectors_kb for +paths that are members of a live map is dangerous. But as long as +a path is not a member of a map, setting max_sectors_kb poses no risk. +Set the parameter in adopt_paths(), for paths that aren't members +of the map yet. In order to determine whether or not a path is currently +member of the map, adopt_paths() needs to passed the current member list. If +(and only if) it's called from coalesce_paths(), the passed struct multipath +doesn not represent the current state of the map; adopt_paths() must therefore +get a new argument current_mpp that represents the kernel state. + +We must still call sysfs_set_max_sectors_kb() from domap() in the ACT_CREATE +case, because when adopt_paths is called from coalesce_paths() for a map that +doesn't exist yet, mpp->max_sectors_kb is not set. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/configure.c | 2 +- + libmultipath/structs_vec.c | 62 ++++++++++++++++++++++++++++++++++---- + libmultipath/structs_vec.h | 6 ++-- + multipathd/main.c | 6 ++-- + tests/Makefile | 2 +- + tests/test-lib.c | 9 +++++- + 6 files changed, 73 insertions(+), 14 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index 8cbb2a88..b5c701fa 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -1105,7 +1105,7 @@ int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid, + /* + * at this point, we know we really got a new mp + */ +- mpp = add_map_with_path(vecs, pp1, 0); ++ mpp = add_map_with_path(vecs, pp1, 0, cmpp); + if (!mpp) { + orphan_path(pp1, "failed to create multipath device"); + continue; +diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c +index 0fc608c2..c0c5cc90 100644 +--- a/libmultipath/structs_vec.c ++++ b/libmultipath/structs_vec.c +@@ -242,7 +242,38 @@ static bool update_pathvec_from_dm(vector pathvec, struct multipath *mpp, + return must_reload; + } + +-int adopt_paths(vector pathvec, struct multipath *mpp) ++static bool set_path_max_sectors_kb(const struct path *pp, int max_sectors_kb) ++{ ++ char buf[11]; ++ ssize_t len; ++ int ret, current; ++ bool rc = false; ++ ++ if (max_sectors_kb == MAX_SECTORS_KB_UNDEF) ++ return rc; ++ ++ if (sysfs_attr_get_value(pp->udev, "queue/max_sectors_kb", buf, sizeof(buf)) <= 0 ++ || sscanf(buf, "%d\n", ¤t) != 1) ++ current = MAX_SECTORS_KB_UNDEF; ++ if (current == max_sectors_kb) ++ return rc; ++ ++ len = snprintf(buf, sizeof(buf), "%d", max_sectors_kb); ++ ret = sysfs_attr_set_value(pp->udev, "queue/max_sectors_kb", buf, len); ++ if (ret != len) ++ log_sysfs_attr_set_value(3, ret, ++ "failed setting max_sectors_kb on %s", ++ pp->dev); ++ else { ++ condlog(3, "%s: set max_sectors_kb to %d for %s", __func__, ++ max_sectors_kb, pp->dev); ++ rc = true; ++ } ++ return rc; ++} ++ ++int adopt_paths(vector pathvec, struct multipath *mpp, ++ const struct multipath *current_mpp) + { + int i, ret; + struct path * pp; +@@ -285,9 +316,28 @@ int adopt_paths(vector pathvec, struct multipath *mpp) + continue; + } + +- if (!find_path_by_devt(mpp->paths, pp->dev_t) && +- store_path(mpp->paths, pp)) +- goto err; ++ if (!find_path_by_devt(mpp->paths, pp->dev_t)) { ++ ++ if (store_path(mpp->paths, pp)) ++ goto err; ++ /* ++ * Setting max_sectors_kb on live paths is dangerous. ++ * But we can do it here on a path that isn't yet part ++ * of the map. If this value is lower than the current ++ * max_sectors_kb and the map is reloaded, the map's ++ * max_sectors_kb will be safely adjusted by the kernel. ++ * ++ * We must make sure that the path is not part of the ++ * map yet. Normally we can check this in mpp->paths. ++ * But if adopt_paths is called from coalesce_paths, ++ * we need to check the separate struct multipath that ++ * has been obtained from map_discovery(). ++ */ ++ if (!current_mpp || ++ !mp_find_path_by_devt(current_mpp, pp->dev_t)) ++ mpp->need_reload = mpp->need_reload || ++ set_path_max_sectors_kb(pp, mpp->max_sectors_kb); ++ } + + pp->mpp = mpp; + condlog(3, "%s: ownership set to %s", +@@ -693,7 +743,7 @@ find_existing_alias (struct multipath * mpp, + } + + struct multipath *add_map_with_path(struct vectors *vecs, struct path *pp, +- int add_vec) ++ int add_vec, const struct multipath *current_mpp) + { + struct multipath * mpp; + struct config *conf = NULL; +@@ -721,7 +771,7 @@ struct multipath *add_map_with_path(struct vectors *vecs, struct path *pp, + goto out; + mpp->size = pp->size; + +- if (adopt_paths(vecs->pathvec, mpp) || pp->mpp != mpp || ++ if (adopt_paths(vecs->pathvec, mpp, current_mpp) || pp->mpp != mpp || + find_slot(mpp->paths, pp) == -1) + goto out; + +diff --git a/libmultipath/structs_vec.h b/libmultipath/structs_vec.h +index 3253f1bb..dbc43058 100644 +--- a/libmultipath/structs_vec.h ++++ b/libmultipath/structs_vec.h +@@ -13,7 +13,8 @@ struct vectors { + + void set_no_path_retry(struct multipath *mpp); + +-int adopt_paths (vector pathvec, struct multipath * mpp); ++int adopt_paths (vector pathvec, struct multipath *mpp, ++ const struct multipath *current_mpp); + void orphan_path (struct path * pp, const char *reason); + void set_path_removed(struct path *pp); + +@@ -28,7 +29,8 @@ void remove_maps (struct vectors * vecs); + + void sync_map_state (struct multipath *); + struct multipath * add_map_with_path (struct vectors * vecs, +- struct path * pp, int add_vec); ++ struct path * pp, int add_vec, ++ const struct multipath *current_mpp); + void update_queue_mode_del_path(struct multipath *mpp); + void update_queue_mode_add_path(struct multipath *mpp); + int update_multipath_table (struct multipath *mpp, vector pathvec, int flags); +diff --git a/multipathd/main.c b/multipathd/main.c +index dd17d5c3..d8518a92 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -636,7 +636,7 @@ update_map (struct multipath *mpp, struct vectors *vecs, int new_map) + + retry: + condlog(4, "%s: updating new map", mpp->alias); +- if (adopt_paths(vecs->pathvec, mpp)) { ++ if (adopt_paths(vecs->pathvec, mpp, NULL)) { + condlog(0, "%s: failed to adopt paths for new map update", + mpp->alias); + retries = -1; +@@ -1231,7 +1231,7 @@ rescan: + if (mpp) { + condlog(4,"%s: adopting all paths for path %s", + mpp->alias, pp->dev); +- if (adopt_paths(vecs->pathvec, mpp) || pp->mpp != mpp || ++ if (adopt_paths(vecs->pathvec, mpp, NULL) || pp->mpp != mpp || + find_slot(mpp->paths, pp) == -1) + goto fail; /* leave path added to pathvec */ + +@@ -1245,7 +1245,7 @@ rescan: + return 0; + } + condlog(4,"%s: creating new map", pp->dev); +- if ((mpp = add_map_with_path(vecs, pp, 1))) { ++ if ((mpp = add_map_with_path(vecs, pp, 1, NULL))) { + mpp->action = ACT_CREATE; + /* + * We don't depend on ACT_CREATE, as domap will +diff --git a/tests/Makefile b/tests/Makefile +index d1d52dde..4005204a 100644 +--- a/tests/Makefile ++++ b/tests/Makefile +@@ -45,7 +45,7 @@ dmevents-test_OBJDEPS = $(multipathdir)/devmapper.o + dmevents-test_LIBDEPS = -lpthread -ldevmapper -lurcu + hwtable-test_TESTDEPS := test-lib.o + hwtable-test_OBJDEPS := $(multipathdir)/discovery.o $(multipathdir)/blacklist.o \ +- $(multipathdir)/structs.o $(multipathdir)/propsel.o ++ $(multipathdir)/structs_vec.o $(multipathdir)/structs.o $(multipathdir)/propsel.o + hwtable-test_LIBDEPS := -ludev -lpthread -ldl + blacklist-test_TESTDEPS := test-log.o + blacklist-test_LIBDEPS := -ludev +diff --git a/tests/test-lib.c b/tests/test-lib.c +index cdb2780d..88f35e94 100644 +--- a/tests/test-lib.c ++++ b/tests/test-lib.c +@@ -152,6 +152,13 @@ int __wrap_sysfs_get_size(struct path *pp, unsigned long long *sz) + return 0; + } + ++int __wrap_sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, ++ const char * value, size_t value_len) ++{ ++ condlog(5, "%s: %s", __func__, value); ++ return value_len; ++} ++ + void *__wrap_udev_device_get_parent_with_subsystem_devtype( + struct udev_device *ud, const char *subsys, char *type) + { +@@ -400,7 +407,7 @@ struct multipath *__mock_multipath(struct vectors *vecs, struct path *pp) + /* pathinfo() call in adopt_paths */ + mock_pathinfo(DI_CHECKER|DI_PRIO, &mop); + +- mp = add_map_with_path(vecs, pp, 1); ++ mp = add_map_with_path(vecs, pp, 1, NULL); + assert_ptr_not_equal(mp, NULL); + + /* TBD: mock setup_map() ... */ diff --git a/0028-libmultipath-add-wildcard-k-for-printing-max_sectors.patch b/0028-libmultipath-add-wildcard-k-for-printing-max_sectors.patch new file mode 100644 index 0000000..9b66bbb --- /dev/null +++ b/0028-libmultipath-add-wildcard-k-for-printing-max_sectors.patch @@ -0,0 +1,89 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 17 Apr 2024 17:19:43 +0200 +Subject: [PATCH] libmultipath: add wildcard %k for printing max_sectors_kb + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/print.c | 38 ++++++++++++++++++++++++++++++++++++++ + 1 file changed, 38 insertions(+) + +diff --git a/libmultipath/print.c b/libmultipath/print.c +index 360308d2..efd5a16a 100644 +--- a/libmultipath/print.c ++++ b/libmultipath/print.c +@@ -32,6 +32,7 @@ + #include "util.h" + #include "foreign.h" + #include "strbuf.h" ++#include "sysfs.h" + + #define PRINT_PATH_LONG "%w %i %d %D %p %t %T %s %o" + #define PRINT_PATH_INDENT "%i %d %D %t %T %o" +@@ -431,6 +432,27 @@ snprint_multipath_vpd_data(struct strbuf *buff, + return append_strbuf_str(buff, "[undef]"); + } + ++static void cleanup_udev_device(struct udev_device **udd) ++{ ++ if (*udd) ++ udev_device_unref(*udd); ++} ++ ++static int ++snprint_multipath_max_sectors_kb(struct strbuf *buff, const struct multipath *mpp) ++{ ++ char buf[11]; ++ int max_sectors_kb; ++ struct udev_device *udd __attribute__((cleanup(cleanup_udev_device))) ++ = get_udev_for_mpp(mpp); ++ ++ if (!udd || ++ sysfs_attr_get_value(udd, "queue/max_sectors_kb", buf, sizeof(buf)) <= 0 || ++ sscanf(buf, "%d\n", &max_sectors_kb) != 1) ++ return print_strbuf(buff, "n/a"); ++ return print_strbuf(buff, "%d", max_sectors_kb); ++} ++ + /* + * path info printing functions + */ +@@ -790,6 +812,20 @@ snprint_alua_tpg(struct strbuf *buff, const struct path * pp) + return print_strbuf(buff, "0x%04x", pp->tpg_id); + } + ++static int ++snprint_path_max_sectors_kb(struct strbuf *buff, const struct path *pp) ++{ ++ char buf[11]; ++ int max_sectors_kb; ++ ++ if (!pp->udev || ++ sysfs_attr_get_value(pp->udev, "queue/max_sectors_kb", ++ buf, sizeof(buf)) <= 0 || ++ sscanf(buf, "%d\n", &max_sectors_kb) != 1) ++ return print_strbuf(buff, "n/a"); ++ return print_strbuf(buff, "%d", max_sectors_kb); ++} ++ + static const struct multipath_data mpd[] = { + {'n', "name", snprint_name}, + {'w', "uuid", snprint_multipath_uuid}, +@@ -815,6 +851,7 @@ static const struct multipath_data mpd[] = { + {'e', "rev", snprint_multipath_rev}, + {'G', "foreign", snprint_multipath_foreign}, + {'g', "vpd page data", snprint_multipath_vpd_data}, ++ {'k', "max_sectors_kb",snprint_multipath_max_sectors_kb}, + }; + + static const struct path_data pd[] = { +@@ -845,6 +882,7 @@ static const struct path_data pd[] = { + {'I', "init_st", snprint_initialized}, + {'L', "LUN hex", snprint_path_lunhex}, + {'A', "TPG", snprint_alua_tpg}, ++ {'k', "max_sectors_kb",snprint_path_max_sectors_kb}, + }; + + static const struct pathgroup_data pgd[] = { diff --git a/0029-multipath.conf-5-update-documentation-for-max_sector.patch b/0029-multipath.conf-5-update-documentation-for-max_sector.patch new file mode 100644 index 0000000..dcdf164 --- /dev/null +++ b/0029-multipath.conf-5-update-documentation-for-max_sector.patch @@ -0,0 +1,57 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 17 Apr 2024 18:59:04 +0200 +Subject: [PATCH] multipath.conf(5): update documentation for max_sectors_kb + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/multipath.conf.5.in | 33 +++++++++++++++++++++++++++++---- + 1 file changed, 29 insertions(+), 4 deletions(-) + +diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in +index c788c180..b29a75fe 100644 +--- a/multipath/multipath.conf.5.in ++++ b/multipath/multipath.conf.5.in +@@ -1311,11 +1311,36 @@ The default is: \fB0\fR + . + .TP + .B max_sectors_kb +-Sets the max_sectors_kb device parameter on all path devices and the multipath +-device to the specified value. ++Sets the \fImax_sectors_kb\fR device parameter on some path devices and the multipath ++device to the specified value. \fImax_sectors_kb\fR is the largest I/O size, in units ++of 1024 bytes, that the kernel allows for a single I/O request. For hardware devices ++like SCSI disks, this value is limited by the capabilities of the hardware. ++It is crucial that the value of a multipath map is never higher than the minimum value of ++of all its path devices. This is ensured by the kernel when a multipath map ++is loaded, but manipulating the values of a map or either of its paths while the ++map is live can cause race conditions and I/O errors. Therefore this value is only ++enforced by multipathd when a multipath map is first created, or when a path device ++is added to a map. In both cases, race conditions are avoided by the kernel. + .RS +-.TP +-The default is: in \fB/sys/block//queue/max_sectors_kb\fR ++.PP ++Setting \fImax_sectors_kb\fR does not guarantee that all path devices will have this ++value set. It is not an error if the value of a path device is higher than that of ++the containing multipath map. It is also not an error if the actual limit of a map is ++lower than the value in \fI@CONFIGFILE@\fR. This can happen if the hardware limits of one ++or more path devices are lower than the configured value. ++.PP ++Normally the kernel and its device drivers take care of the maximum ++I/O size, and administrators do not need to bother about \fImax_sectors_kb\fR. ++But some hardware devices may report incorrect I/O size limits, or other components ++in the environment (e.g. the fabric) may impose constraints that the kernel cannot ++detect. In such cases setting \fImax_sectors_kb\fR makes sense. It should be set when ++maps are first created, and not be changed thereafter. ++If the setting \fBmust\fR be changed for a live map, set the ++value in \fI@CONFIGFILE@\fR, run \fBmultipathd reconfigure\fR, and use ++\fBmultipathd del path \fR and \fBmultipathd add path \fR to ++delete and re-add the same path device. ++.LP ++The default is: \fBundefined\fR. + .RE + . + . diff --git a/0030-multipath-tools-simplify-comment-in-hwtable.patch b/0030-multipath-tools-simplify-comment-in-hwtable.patch new file mode 100644 index 0000000..59090a7 --- /dev/null +++ b/0030-multipath-tools-simplify-comment-in-hwtable.patch @@ -0,0 +1,34 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Sun, 28 Apr 2024 01:45:35 +0200 +Subject: [PATCH] multipath-tools: simplify comment in hwtable + +Instead of adding the new 5300 model, replace them with wildcards. + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/hwtable.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index 640bf347..7aac3f37 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -683,8 +683,8 @@ static struct hwentry default_hw[] = { + .pgfailback = -FAILBACK_IMMEDIATE, + }, + { +- // Storwize V5000/V7000 lines / SAN Volume Controller (SVC) / Flex System V7000 +- // FlashSystem V840/V9000/5000/5100/5200/7200/7300/9100/9200/9200R/9500 ++ // Storwize V5000/V7000 lines / SAN Volume Controller (SVC) ++ // Flex System V7000 / FlashSystem V840/V9000 and 5x00/7x00/9x00 + .vendor = "IBM", + .product = "^2145", + .no_path_retry = NO_PATH_RETRY_QUEUE, diff --git a/0031-multipath-tools-unify-text-in-multipath.conf.5.patch b/0031-multipath-tools-unify-text-in-multipath.conf.5.patch new file mode 100644 index 0000000..b6d9af3 --- /dev/null +++ b/0031-multipath-tools-unify-text-in-multipath.conf.5.patch @@ -0,0 +1,75 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Sun, 28 Apr 2024 01:45:36 +0200 +Subject: [PATCH] multipath-tools: unify text in multipath.conf.5 + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + multipath/multipath.conf.5.in | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in +index b29a75fe..c1a19ebb 100644 +--- a/multipath/multipath.conf.5.in ++++ b/multipath/multipath.conf.5.in +@@ -187,7 +187,7 @@ The default is: \fBno\fR + . + .TP + .B multipath_dir +-(Deprecated) This option is not supported anymore, and the value is ignored. ++(Deprecated) This option is not supported anymore, and will be ignored. + . + . + .TP +@@ -277,7 +277,7 @@ The default is: \fBno\fR + . + .TP + .B pg_timeout +-(Deprecated) This option is not supported anymore, and the value is ignored. ++(Deprecated) This option is not supported anymore, and will be ignored. + . + . + .TP +@@ -322,7 +322,7 @@ The default is: \fBID_WWN\fR, for NVMe devices + . + .TP + .B getuid_callout +-(Deprecated) This option is not supported anymore, and the value is ignored. ++(Deprecated) This option is not supported anymore, and will be ignored. + . + . + .TP +@@ -995,7 +995,7 @@ The default is: \fB\fR + . + .TP + .B config_dir +-(Deprecated) This option is not supported anymore, and the value is ignored. ++(Deprecated) This option is not supported anymore, and will be ignored. + .RS + .TP + The compiled-in value is: \fB@CONFIGDIR@\fR +@@ -1295,7 +1295,7 @@ The default is: \fBno\fR + . + .TP + .B disable_changed_wwids +-(Deprecated) This option is not supported anymore, and the value is ignored. ++(Deprecated) This option is not supported anymore, and will be ignored. + .RE + . + . +@@ -1340,7 +1340,7 @@ value in \fI@CONFIGFILE@\fR, run \fBmultipathd reconfigure\fR, and use + \fBmultipathd del path \fR and \fBmultipathd add path \fR to + delete and re-add the same path device. + .LP +-The default is: \fBundefined\fR. ++The default is: \fB\fR + .RE + . + . diff --git a/0032-multipath-tools-update-man-pages-dates.patch b/0032-multipath-tools-update-man-pages-dates.patch new file mode 100644 index 0000000..c011eac --- /dev/null +++ b/0032-multipath-tools-update-man-pages-dates.patch @@ -0,0 +1,86 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Sun, 28 Apr 2024 01:45:37 +0200 +Subject: [PATCH] multipath-tools: update man pages dates + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmpathpersist/mpath_persistent_reserve_in.3 | 2 +- + libmpathpersist/mpath_persistent_reserve_out.3 | 2 +- + multipath/multipath.8.in | 2 +- + multipath/multipath.conf.5.in | 2 +- + multipathd/multipathd.8.in | 2 +- + 5 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/libmpathpersist/mpath_persistent_reserve_in.3 b/libmpathpersist/mpath_persistent_reserve_in.3 +index 6cc35349..4ac43fa3 100644 +--- a/libmpathpersist/mpath_persistent_reserve_in.3 ++++ b/libmpathpersist/mpath_persistent_reserve_in.3 +@@ -6,7 +6,7 @@ + .\" Update the date below if you make any significant change. + .\" ---------------------------------------------------------------------------- + . +-.TH MPATH_PERSISTENT_RESERVE_IN 3 2018-06-15 Linux ++.TH MPATH_PERSISTENT_RESERVE_IN 3 2024-02-09 Linux + . + . + .\" ---------------------------------------------------------------------------- +diff --git a/libmpathpersist/mpath_persistent_reserve_out.3 b/libmpathpersist/mpath_persistent_reserve_out.3 +index 70e26028..3dbeae1f 100644 +--- a/libmpathpersist/mpath_persistent_reserve_out.3 ++++ b/libmpathpersist/mpath_persistent_reserve_out.3 +@@ -6,7 +6,7 @@ + .\" Update the date below if you make any significant change. + .\" ---------------------------------------------------------------------------- + . +-.TH MPATH_PERSISTENT_RESERVE_OUT 3 2018-06-15 Linux ++.TH MPATH_PERSISTENT_RESERVE_OUT 3 2024-02-09 Linux + . + . + .\" ---------------------------------------------------------------------------- +diff --git a/multipath/multipath.8.in b/multipath/multipath.8.in +index 348eb220..b88e9a4c 100644 +--- a/multipath/multipath.8.in ++++ b/multipath/multipath.8.in +@@ -6,7 +6,7 @@ + .\" Update the date below if you make any significant change. + .\" ---------------------------------------------------------------------------- + . +-.TH MULTIPATH 8 2021-11-12 Linux ++.TH MULTIPATH 8 2023-09-08 Linux + . + . + .\" ---------------------------------------------------------------------------- +diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in +index c1a19ebb..46d3685a 100644 +--- a/multipath/multipath.conf.5.in ++++ b/multipath/multipath.conf.5.in +@@ -6,7 +6,7 @@ + .\" Update the date below if you make any significant change. + .\" ---------------------------------------------------------------------------- + . +-.TH MULTIPATH.CONF 5 2023-06-15 Linux ++.TH MULTIPATH.CONF 5 2024-04-17 Linux + . + . + .\" ---------------------------------------------------------------------------- +diff --git a/multipathd/multipathd.8.in b/multipathd/multipathd.8.in +index f1cab3ff..12b77156 100644 +--- a/multipathd/multipathd.8.in ++++ b/multipathd/multipathd.8.in +@@ -6,7 +6,7 @@ + .\" Update the date below if you make any significant change. + .\" ---------------------------------------------------------------------------- + . +-.TH MULTIPATHD 8 2022-09-03 Linux ++.TH MULTIPATHD 8 2023-12-19 Linux + . + . + .\" ---------------------------------------------------------------------------- diff --git a/0033-libmultipath-export-partmap_in_use.patch b/0033-libmultipath-export-partmap_in_use.patch new file mode 100644 index 0000000..47a6772 --- /dev/null +++ b/0033-libmultipath-export-partmap_in_use.patch @@ -0,0 +1,53 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 25 Apr 2024 19:35:13 -0400 +Subject: [PATCH] libmultipath: export partmap_in_use + +A future commit will make use of this function + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +--- + libmultipath/devmapper.c | 2 +- + libmultipath/devmapper.h | 1 + + libmultipath/libmultipath.version | 1 + + 3 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index 4ce7e82f..a87abf7e 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -1043,7 +1043,7 @@ has_partmap(const char *name __attribute__((unused)), + return 1; + } + +-static int ++int + partmap_in_use(const char *name, void *data) + { + int part_count, *ret_count = (int *)data; +diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h +index a7d66604..93caa2aa 100644 +--- a/libmultipath/devmapper.h ++++ b/libmultipath/devmapper.h +@@ -57,6 +57,7 @@ enum { + DM_FLUSH_BUSY, + }; + ++int partmap_in_use(const char *name, void *data); + int _dm_flush_map (const char *, int, int, int, int); + int dm_flush_map_nopaths(const char * mapname, int deferred_remove); + #define dm_flush_map(mapname) _dm_flush_map(mapname, 1, 0, 0, 0) +diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version +index 724786d5..e070f296 100644 +--- a/libmultipath/libmultipath.version ++++ b/libmultipath/libmultipath.version +@@ -141,6 +141,7 @@ global: + need_io_err_check; + orphan_path; + parse_prkey_flags; ++ partmap_in_use; + pathcount; + path_discovery; + path_get_tpgs; diff --git a/0034-libmultipath-change-flush_on_last_del-to-fix-a-multi.patch b/0034-libmultipath-change-flush_on_last_del-to-fix-a-multi.patch new file mode 100644 index 0000000..7c36521 --- /dev/null +++ b/0034-libmultipath-change-flush_on_last_del-to-fix-a-multi.patch @@ -0,0 +1,346 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 25 Apr 2024 19:35:14 -0400 +Subject: [PATCH] libmultipath: change flush_on_last_del to fix a multipathd + hang + +Commit 9bd3482e ("multipathd: make flush_map() delete maps like the +multipath command") fixed an issue where deleting a queueing multipath +device through multipathd could hang because the multipath device had +outstanding IO, even though the only openers of it at the time of +deletion were the kpartx partition devices. However it is still possible +to hang multipathd, because autoremoving the device when all paths have +been deleted doesn't disable queueing. To reproduce this hang: + +1. create a multipath device with a kpartx partition on top of it and +no_path_retry set to either "queue" or something long enough to run all +the commands in the reproducer before it disables queueing. +2. disable all the paths to the device with something like: + # echo offline > /sys/block//device/state +3. Write directly to the multipath device with something like: + # dd if=/dev/zero of=/dev/mapper/ bs=4K count=1 +4. delete all the paths to the device with something like: + # echo 1 > /sys/block//device/delete + +Multipathd will hang trying to delete the kpartx device because, as the +last opener, it must flush the multipath device before closing it. +Because it hangs holding the vecs_lock, multipathd will never disable +queueing on the device, so it will hang forever, even if no_path_retry +is set to a number. + +This hang can occur, even if deferred_remove is set. Since nothing has +the kpartx device opened, device-mapper does an immediate remove, which +will still hang. This means that even if deferred_remove is set, +multipathd still cannot delete a map while queueing is enabled. It must +either disable queueing or skip the autoremove. + +Mulitpath can currently be configured to avoid this hang by setting + +flush_on_last_del yes + +However there are good reasons why users wouldn't want to set that. They +may need to be able to survive having all paths getting temporarily +deleted. I should note that this is a pretty rare corner case, since +multipath automatically sets dev_loss_tmo so that it should not trigger +before queueing is disabled. + +This commit avoids the hang by changing the possible values for +flush_on_last_del to "never", "unused", and "always", and sets the +default to "unused". "always" works like "yes" did, "never" will not +disable queueing, and "unused" will only disable queueing if nothing has +the kpartx devices or the multipath device open. In order to be safe, if +the device has queue_if_no_paths set (and in case of "unused", the +device is in-use) the autoremove will be skipped. Also, instead of just +trusting the lack of "queue_if_no_paths" in the current mpp->features, +multipathd will tell the kernel to disable queueing, just to be sure it +actually is. + +I chose "unused" as the default because this should generally only cause +multipathd to work differently from the users perspective when nothing +has the multipath device open but it is queueing and there is +outstanding IO. Without this change, it would have hung instead of +failing the outstanding IO. However, I do understand that an argument +could be made that "never" makes more sense as default, even though it +will cause multipathd to skip autoremoves in cases where it wouldn't +before. The change to the behavior of deffered_remove will be +noticeable, but skipping an autoremove is much better than hanging. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +--- + libmultipath/defaults.h | 2 +- + libmultipath/dict.c | 72 +++++++++++++++++++++++++++++++---- + libmultipath/dict.h | 1 + + libmultipath/hwtable.c | 6 +-- + libmultipath/propsel.c | 4 +- + libmultipath/structs.h | 7 ++-- + multipath/multipath.conf.5.in | 20 +++++++--- + multipathd/main.c | 39 +++++++++++++++---- + 8 files changed, 122 insertions(+), 29 deletions(-) + +diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h +index 64b633f2..ed08c251 100644 +--- a/libmultipath/defaults.h ++++ b/libmultipath/defaults.h +@@ -43,7 +43,7 @@ + #define DEFAULT_PRIO PRIO_CONST + #define DEFAULT_PRIO_ARGS "" + #define DEFAULT_CHECKER TUR +-#define DEFAULT_FLUSH FLUSH_DISABLED ++#define DEFAULT_FLUSH FLUSH_UNUSED + #define DEFAULT_USER_FRIENDLY_NAMES USER_FRIENDLY_NAMES_OFF + #define DEFAULT_FORCE_SYNC 0 + #define UNSET_PARTITION_DELIM "/UNSET/" +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index 5af036b7..546103f2 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -791,14 +791,70 @@ declare_def_snprint(checker_timeout, print_nonzero) + declare_def_handler(allow_usb_devices, set_yes_no) + declare_def_snprint(allow_usb_devices, print_yes_no) + +-declare_def_handler(flush_on_last_del, set_yes_no_undef) +-declare_def_snprint_defint(flush_on_last_del, print_yes_no_undef, DEFAULT_FLUSH) +-declare_ovr_handler(flush_on_last_del, set_yes_no_undef) +-declare_ovr_snprint(flush_on_last_del, print_yes_no_undef) +-declare_hw_handler(flush_on_last_del, set_yes_no_undef) +-declare_hw_snprint(flush_on_last_del, print_yes_no_undef) +-declare_mp_handler(flush_on_last_del, set_yes_no_undef) +-declare_mp_snprint(flush_on_last_del, print_yes_no_undef) ++ ++static const char * const flush_on_last_del_optvals[] = { ++ [FLUSH_NEVER] = "never", ++ [FLUSH_ALWAYS] = "always", ++ [FLUSH_UNUSED] = "unused", ++}; ++ ++static int ++set_flush_on_last_del(vector strvec, void *ptr, const char *file, int line_nr) ++{ ++ int i; ++ int *flush_val_ptr = (int *)ptr; ++ char *buff; ++ ++ buff = set_value(strvec); ++ if (!buff) ++ return 1; ++ ++ for (i = FLUSH_NEVER; i <= FLUSH_UNUSED; i++) { ++ if (flush_on_last_del_optvals[i] != NULL && ++ !strcmp(buff, flush_on_last_del_optvals[i])) { ++ *flush_val_ptr = i; ++ break; ++ } ++ } ++ ++ if (i > FLUSH_UNUSED) { ++ bool deprecated = true; ++ if (strcmp(buff, "no") == 0 || strcmp(buff, "0") == 0) ++ *flush_val_ptr = FLUSH_UNUSED; ++ else if (strcmp(buff, "yes") == 0 || strcmp(buff, "1") == 0) ++ *flush_val_ptr = FLUSH_ALWAYS; ++ else { ++ deprecated = false; ++ condlog(1, "%s line %d, invalid value for flush_on_last_del: \"%s\"", ++ file, line_nr, buff); ++ } ++ if (deprecated) ++ condlog(2, "%s line %d, \"%s\" is a deprecated value for flush_on_last_del and is treated as \"%s\"", ++ file, line_nr, buff, ++ flush_on_last_del_optvals[*flush_val_ptr]); ++ } ++ ++ free(buff); ++ return 0; ++} ++ ++int ++print_flush_on_last_del(struct strbuf *buff, long v) ++{ ++ if (v == FLUSH_UNDEF) ++ return 0; ++ return append_strbuf_quoted(buff, flush_on_last_del_optvals[(int)v]); ++} ++ ++declare_def_handler(flush_on_last_del, set_flush_on_last_del) ++declare_def_snprint_defint(flush_on_last_del, print_flush_on_last_del, ++ DEFAULT_FLUSH) ++declare_ovr_handler(flush_on_last_del, set_flush_on_last_del) ++declare_ovr_snprint(flush_on_last_del, print_flush_on_last_del) ++declare_hw_handler(flush_on_last_del, set_flush_on_last_del) ++declare_hw_snprint(flush_on_last_del, print_flush_on_last_del) ++declare_mp_handler(flush_on_last_del, set_flush_on_last_del) ++declare_mp_snprint(flush_on_last_del, print_flush_on_last_del) + + declare_def_handler(user_friendly_names, set_yes_no_undef) + declare_def_snprint_defint(user_friendly_names, print_yes_no_undef, +diff --git a/libmultipath/dict.h b/libmultipath/dict.h +index 7e2dfbe0..e1794537 100644 +--- a/libmultipath/dict.h ++++ b/libmultipath/dict.h +@@ -18,4 +18,5 @@ int print_undef_off_zero(struct strbuf *buff, long v); + int print_dev_loss(struct strbuf *buff, unsigned long v); + int print_off_int_undef(struct strbuf *buff, long v); + int print_auto_resize(struct strbuf *buff, long v); ++int print_flush_on_last_del(struct strbuf *buff, long v); + #endif /* _DICT_H */ +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index 7aac3f37..d1148de7 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -60,7 +60,7 @@ + .no_path_retry = NO_PATH_RETRY_UNDEF, + .minio = 1000, + .minio_rq = 1, +- .flush_on_last_del = FLUSH_DISABLED, ++ .flush_on_last_del = FLUSH_UNUSED, + .user_friendly_names = USER_FRIENDLY_NAMES_OFF, + .fast_io_fail = 5, + .dev_loss = 600, +@@ -829,7 +829,7 @@ static struct hwentry default_hw[] = { + .no_path_retry = NO_PATH_RETRY_QUEUE, + .pgpolicy = GROUP_BY_PRIO, + .pgfailback = -FAILBACK_IMMEDIATE, +- .flush_on_last_del = FLUSH_ENABLED, ++ .flush_on_last_del = FLUSH_ALWAYS, + .dev_loss = MAX_DEV_LOSS_TMO, + .prio_name = PRIO_ONTAP, + .user_friendly_names = USER_FRIENDLY_NAMES_OFF, +@@ -1160,7 +1160,7 @@ static struct hwentry default_hw[] = { + .no_path_retry = NO_PATH_RETRY_FAIL, + .minio = 1, + .minio_rq = 1, +- .flush_on_last_del = FLUSH_ENABLED, ++ .flush_on_last_del = FLUSH_ALWAYS, + .fast_io_fail = 15, + }, + /* +diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c +index 44241e2a..e2dcb316 100644 +--- a/libmultipath/propsel.c ++++ b/libmultipath/propsel.c +@@ -963,6 +963,7 @@ out: + int select_flush_on_last_del(struct config *conf, struct multipath *mp) + { + const char *origin; ++ STRBUF_ON_STACK(buff); + + mp_set_mpe(flush_on_last_del); + mp_set_ovr(flush_on_last_del); +@@ -970,8 +971,9 @@ int select_flush_on_last_del(struct config *conf, struct multipath *mp) + mp_set_conf(flush_on_last_del); + mp_set_default(flush_on_last_del, DEFAULT_FLUSH); + out: ++ print_flush_on_last_del(&buff, mp->flush_on_last_del); + condlog(3, "%s: flush_on_last_del = %s %s", mp->alias, +- (mp->flush_on_last_del == FLUSH_ENABLED)? "yes" : "no", origin); ++ get_strbuf_str(&buff), origin); + return 0; + } + +diff --git a/libmultipath/structs.h b/libmultipath/structs.h +index a25eb9d5..dbaf4d43 100644 +--- a/libmultipath/structs.h ++++ b/libmultipath/structs.h +@@ -109,9 +109,10 @@ enum marginal_pathgroups_mode { + }; + + enum flush_states { +- FLUSH_UNDEF = YNU_UNDEF, +- FLUSH_DISABLED = YNU_NO, +- FLUSH_ENABLED = YNU_YES, ++ FLUSH_UNDEF, ++ FLUSH_NEVER, ++ FLUSH_ALWAYS, ++ FLUSH_UNUSED, + }; + + enum log_checker_err_states { +diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in +index 46d3685a..1d3d53bb 100644 +--- a/multipath/multipath.conf.5.in ++++ b/multipath/multipath.conf.5.in +@@ -707,12 +707,22 @@ The default is: \fBno\fR + .TP + .B flush_on_last_del + If set to +-.I yes ++.I always + , multipathd will disable queueing when the last path to a device has been +-deleted. +-.RS +-.TP +-The default is: \fBno\fR ++deleted. If set to ++.I never ++, multipathd will not disable queueing when the last path to a device has ++been deleted. Since multipath cannot safely remove a device while queueing ++is enabled, setting this to \fInever\fR means that multipathd will not ++automatically remove an unused multipath device whose paths are all deleted if ++it is currently set to queue_if_no_path. If set to ++.I unused ++, multipathd will only disable queueing when the last path is removed if ++nothing currently has the multipath device or any of the kpartx partition ++devices on top of it open. ++.RS ++.TP ++The default is: \fBunused\fR + .RE + . + . +diff --git a/multipathd/main.c b/multipathd/main.c +index d8518a92..09286dd0 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -584,19 +584,42 @@ int update_multipath (struct vectors *vecs, char *mapname) + static bool + flush_map_nopaths(struct multipath *mpp, struct vectors *vecs) { + int r; ++ bool is_queueing = true; + ++ if (mpp->features) ++ is_queueing = strstr(mpp->features, "queue_if_no_path"); ++ ++ /* It's not safe to do a remove of a map that has "queue_if_no_path" ++ * set, since there could be outstanding IO which will cause ++ * multipathd to hang while attempting the remove */ ++ if (mpp->flush_on_last_del == FLUSH_NEVER && is_queueing) { ++ condlog(2, "%s: map is queueing, can't remove", mpp->alias); ++ return false; ++ } ++ if (mpp->flush_on_last_del == FLUSH_UNUSED && ++ partmap_in_use(mpp->alias, NULL) && is_queueing) { ++ condlog(2, "%s: map in use and queueing, can't remove", ++ mpp->alias); ++ return false; ++ } + /* +- * flush_map will fail if the device is open ++ * This will flush FLUSH_NEVER devices and FLUSH_UNUSED devices ++ * that are in use, but only if they are already marked as not ++ * queueing. That is just to make absolutely certain that they ++ * really are not queueing, like they claim. + */ +- if (mpp->flush_on_last_del == FLUSH_ENABLED) { +- condlog(2, "%s Last path deleted, disabling queueing", ++ condlog(is_queueing ? 2 : 3, "%s Last path deleted, disabling queueing", ++ mpp->alias); ++ mpp->retry_tick = 0; ++ mpp->no_path_retry = NO_PATH_RETRY_FAIL; ++ mpp->disable_queueing = 1; ++ mpp->stat_map_failures++; ++ if (dm_queue_if_no_path(mpp, 0) != 0) { ++ condlog(0, "%s: failed to disable queueing. Not removing", + mpp->alias); +- mpp->retry_tick = 0; +- mpp->no_path_retry = NO_PATH_RETRY_FAIL; +- mpp->disable_queueing = 1; +- mpp->stat_map_failures++; +- dm_queue_if_no_path(mpp, 0); ++ return false; + } ++ + r = dm_flush_map_nopaths(mpp->alias, mpp->deferred_remove); + if (r != DM_FLUSH_OK) { + if (r == DM_FLUSH_DEFERRED) { diff --git a/0035-libmultipath-remove-redundant-config-option-from-Inf.patch b/0035-libmultipath-remove-redundant-config-option-from-Inf.patch new file mode 100644 index 0000000..8de5639 --- /dev/null +++ b/0035-libmultipath-remove-redundant-config-option-from-Inf.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 25 Apr 2024 19:35:15 -0400 +Subject: [PATCH] libmultipath: remove redundant config option from InfiniBox + config + +The InfiniBox config already sets no_path_retry to "fail", so it won't +ever queue IO. That means setting flush_on_last_del to "always" is +redundant, since queueing is always disabled. Remove the +flush_on_last_del parameter, to make it easier for users to override the +default behavior if desired. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +--- + libmultipath/hwtable.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index d1148de7..9e008df6 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -1160,7 +1160,6 @@ static struct hwentry default_hw[] = { + .no_path_retry = NO_PATH_RETRY_FAIL, + .minio = 1, + .minio_rq = 1, +- .flush_on_last_del = FLUSH_ALWAYS, + .fast_io_fail = 15, + }, + /* diff --git a/0036-libmultipath-pad-dev_loss_tmo-to-avoid-race-with-no_.patch b/0036-libmultipath-pad-dev_loss_tmo-to-avoid-race-with-no_.patch new file mode 100644 index 0000000..f61f658 --- /dev/null +++ b/0036-libmultipath-pad-dev_loss_tmo-to-avoid-race-with-no_.patch @@ -0,0 +1,40 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 25 Apr 2024 19:35:16 -0400 +Subject: [PATCH] libmultipath: pad dev_loss_tmo to avoid race with + no_path_retry + +Currently multipath makes sure that dev_loss_tmo is at least as long as +the configured no path queueing time. The goal is to make sure that path +devices aren't removed while the multipath device is still queueing in +hopes that they will become usable again. + +This is racy. Multipathd may take longer to check the paths than +configured. If strict_timing isn't set, it will definitely take longer. +To account for this, pad the minimum dev_loss_tmo value by five seconds +(one default checker interval) plus one second per minute of no path +queueing time. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +--- + libmultipath/discovery.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index 6fd4dabb..e2052422 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -901,6 +901,11 @@ sysfs_set_scsi_tmo (struct config *conf, struct multipath *mpp) + uint64_t no_path_retry_tmo = + (uint64_t)mpp->no_path_retry * conf->checkint; + ++ /* pad no_path_retry_tmo by one standard check interval ++ * plus one second per minute to account for timing ++ * issues with the rechecks */ ++ no_path_retry_tmo += no_path_retry_tmo / 60 + DEFAULT_CHECKINT; ++ + if (no_path_retry_tmo > MAX_DEV_LOSS_TMO) + min_dev_loss = MAX_DEV_LOSS_TMO; + else diff --git a/0037-libmultipath-fix-deferred_remove-function-arguments.patch b/0037-libmultipath-fix-deferred_remove-function-arguments.patch new file mode 100644 index 0000000..507a056 --- /dev/null +++ b/0037-libmultipath-fix-deferred_remove-function-arguments.patch @@ -0,0 +1,107 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 25 Apr 2024 19:35:17 -0400 +Subject: [PATCH] libmultipath: fix deferred_remove function arguments + +Aside from one version of dm_flush_map_nopaths(), all the callers of +_dm_flush_map() and dm_simplecmd() set deferred_remove to 0. But these +functions, as well as some helper functions they called, all treated the +deferred_remove argument as an enum deferred_remove_states, and called +do_deferred() to see if the remove should be deferred. To simplify the +code, make these functions treat deferred_remove as a boolean value +signifying whether a remove is deferred, and make dm_flush_map_nopaths() +do the work of checking if the remove should be deferred. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +--- + libmultipath/devmapper.c | 19 +++++++++---------- + libmultipath/libmultipath.version | 2 +- + 2 files changed, 10 insertions(+), 11 deletions(-) + +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index a87abf7e..2e7b2c64 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -386,8 +386,6 @@ libmp_dm_task_create(int task) + return dm_task_create(task); + } + +-#define do_deferred(x) ((x) == DEFERRED_REMOVE_ON || (x) == DEFERRED_REMOVE_IN_PROGRESS) +- + static int + dm_simplecmd (int task, const char *name, int no_flush, int need_sync, + uint16_t udev_flags, int deferred_remove __DR_UNUSED__) { +@@ -411,7 +409,7 @@ dm_simplecmd (int task, const char *name, int no_flush, int need_sync, + dm_task_no_flush(dmt); /* for DM_DEVICE_SUSPEND/RESUME */ + #endif + #ifdef LIBDM_API_DEFERRED +- if (do_deferred(deferred_remove)) ++ if (deferred_remove) + dm_task_deferred_remove(dmt); + #endif + if (udev_wait_flag && +@@ -1082,7 +1080,7 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, + + /* If you aren't doing a deferred remove, make sure that no + * devices are in use */ +- if (!do_deferred(deferred_remove) && partmap_in_use(mapname, NULL)) ++ if (!deferred_remove && partmap_in_use(mapname, NULL)) + return DM_FLUSH_BUSY; + + if (need_suspend && +@@ -1100,7 +1098,7 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, + if ((r = dm_remove_partmaps(mapname, need_sync, deferred_remove))) + return r; + +- if (!do_deferred(deferred_remove) && dm_get_opencount(mapname)) { ++ if (!deferred_remove && dm_get_opencount(mapname)) { + condlog(2, "%s: map in use", mapname); + return DM_FLUSH_BUSY; + } +@@ -1112,8 +1110,7 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, + r = dm_device_remove(mapname, need_sync, deferred_remove); + + if (r) { +- if (do_deferred(deferred_remove) +- && dm_map_present(mapname)) { ++ if (deferred_remove && dm_map_present(mapname)) { + condlog(4, "multipath map %s remove deferred", + mapname); + return DM_FLUSH_DEFERRED; +@@ -1147,7 +1144,10 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, + int + dm_flush_map_nopaths(const char * mapname, int deferred_remove) + { +- return _dm_flush_map(mapname, 1, deferred_remove, 0, 0); ++ return _dm_flush_map(mapname, 1, ++ (deferred_remove == DEFERRED_REMOVE_ON || ++ deferred_remove == DEFERRED_REMOVE_IN_PROGRESS), ++ 0, 0); + } + + #else +@@ -1539,8 +1539,7 @@ remove_partmap(const char *name, void *data) + + if (dm_get_opencount(name)) { + dm_remove_partmaps(name, rd->need_sync, rd->deferred_remove); +- if (!do_deferred(rd->deferred_remove) && +- dm_get_opencount(name)) { ++ if (rd->deferred_remove && dm_get_opencount(name)) { + condlog(2, "%s: map in use", name); + return DM_FLUSH_BUSY; + } +diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version +index e070f296..eb511749 100644 +--- a/libmultipath/libmultipath.version ++++ b/libmultipath/libmultipath.version +@@ -43,7 +43,7 @@ LIBMPATHCOMMON_1.0.0 { + put_multipath_config; + }; + +-LIBMULTIPATH_23.0.0 { ++LIBMULTIPATH_24.0.0 { + global: + /* symbols referenced by multipath and multipathd */ + add_foreign; diff --git a/0038-libmultipath-use-bitwise-flags-for-map-flushing-API.patch b/0038-libmultipath-use-bitwise-flags-for-map-flushing-API.patch new file mode 100644 index 0000000..ef922ec --- /dev/null +++ b/0038-libmultipath-use-bitwise-flags-for-map-flushing-API.patch @@ -0,0 +1,212 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 2 May 2024 18:38:24 +0200 +Subject: [PATCH] libmultipath: use bitwise flags for map flushing API + +Rather than passing 3 separate bool variables to _dm_flush_map(), +define bitwise flags to modify the function's behavior, and pass +these flags to called functions accordingly. + +This improves the readability of the code, function calls are +more expressive. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/devmapper.c | 68 +++++++++++++++++----------------------- + libmultipath/devmapper.h | 18 ++++++++--- + 2 files changed, 41 insertions(+), 45 deletions(-) + +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index 2e7b2c64..a6a9c2b7 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -53,9 +53,8 @@ static int dm_cancel_remove_partmaps(const char * mapname); + #define __DR_UNUSED__ __attribute__((unused)) + #endif + +-static int dm_remove_partmaps (const char * mapname, int need_sync, +- int deferred_remove); +-static int do_foreach_partmaps(const char * mapname, ++static int dm_remove_partmaps (const char *mapname, int flags); ++static int do_foreach_partmaps(const char *mapname, + int (*partmap_func)(const char *, void *), + void *data); + static int _dm_queue_if_no_path(const char *mapname, int enable); +@@ -439,9 +438,9 @@ int dm_simplecmd_noflush (int task, const char *name, uint16_t udev_flags) + } + + static int +-dm_device_remove (const char *name, int needsync, int deferred_remove) { +- return dm_simplecmd(DM_DEVICE_REMOVE, name, 0, needsync, 0, +- deferred_remove); ++dm_device_remove (const char *name, int flags) { ++ return dm_simplecmd(DM_DEVICE_REMOVE, name, 0, flags & DMFL_NEED_SYNC, 0, ++ flags & DMFL_DEFERRED); + } + + static int +@@ -1061,8 +1060,7 @@ partmap_in_use(const char *name, void *data) + return 0; + } + +-int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, +- int need_suspend, int retries) ++int _dm_flush_map (const char *mapname, int flags, int retries) + { + int r; + int queue_if_no_path = 0; +@@ -1080,10 +1078,10 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, + + /* If you aren't doing a deferred remove, make sure that no + * devices are in use */ +- if (!deferred_remove && partmap_in_use(mapname, NULL)) ++ if (!(flags & DMFL_DEFERRED) && partmap_in_use(mapname, NULL)) + return DM_FLUSH_BUSY; + +- if (need_suspend && ++ if ((flags & DMFL_SUSPEND) && + dm_get_map(mapname, &mapsize, ¶ms) == DMP_OK && + strstr(params, "queue_if_no_path")) { + if (!_dm_queue_if_no_path(mapname, 0)) +@@ -1095,22 +1093,22 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, + free(params); + params = NULL; + +- if ((r = dm_remove_partmaps(mapname, need_sync, deferred_remove))) ++ if ((r = dm_remove_partmaps(mapname, flags))) + return r; + +- if (!deferred_remove && dm_get_opencount(mapname)) { ++ if (!(flags & DMFL_DEFERRED) && dm_get_opencount(mapname)) { + condlog(2, "%s: map in use", mapname); + return DM_FLUSH_BUSY; + } + + do { +- if (need_suspend && queue_if_no_path != -1) ++ if ((flags & DMFL_SUSPEND) && queue_if_no_path != -1) + dm_simplecmd_flush(DM_DEVICE_SUSPEND, mapname, 0); + +- r = dm_device_remove(mapname, need_sync, deferred_remove); ++ r = dm_device_remove(mapname, flags); + + if (r) { +- if (deferred_remove && dm_map_present(mapname)) { ++ if ((flags & DMFL_DEFERRED) && dm_map_present(mapname)) { + condlog(4, "multipath map %s remove deferred", + mapname); + return DM_FLUSH_DEFERRED; +@@ -1124,7 +1122,7 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, + } else { + condlog(2, "failed to remove multipath map %s", + mapname); +- if (need_suspend && queue_if_no_path != -1) { ++ if ((flags & DMFL_SUSPEND) && queue_if_no_path != -1) { + dm_simplecmd_noflush(DM_DEVICE_RESUME, + mapname, udev_flags); + } +@@ -1139,27 +1137,18 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, + return DM_FLUSH_FAIL; + } + +-#ifdef LIBDM_API_DEFERRED +- + int +-dm_flush_map_nopaths(const char * mapname, int deferred_remove) ++dm_flush_map_nopaths(const char *mapname, int deferred_remove __DR_UNUSED__) + { +- return _dm_flush_map(mapname, 1, +- (deferred_remove == DEFERRED_REMOVE_ON || +- deferred_remove == DEFERRED_REMOVE_IN_PROGRESS), +- 0, 0); +-} +- +-#else +- +-int +-dm_flush_map_nopaths(const char * mapname, +- int deferred_remove __attribute__((unused))) +-{ +- return _dm_flush_map(mapname, 1, 0, 0, 0); +-} ++ int flags = DMFL_NEED_SYNC; + ++#ifdef LIBDM_API_DEFERRED ++ flags |= ((deferred_remove == DEFERRED_REMOVE_ON || ++ deferred_remove == DEFERRED_REMOVE_IN_PROGRESS) ? ++ DMFL_DEFERRED : 0); + #endif ++ return _dm_flush_map(mapname, flags, 0); ++} + + int dm_flush_maps (int retries) + { +@@ -1528,8 +1517,7 @@ out: + } + + struct remove_data { +- int need_sync; +- int deferred_remove; ++ int flags; + }; + + static int +@@ -1538,21 +1526,21 @@ remove_partmap(const char *name, void *data) + struct remove_data *rd = (struct remove_data *)data; + + if (dm_get_opencount(name)) { +- dm_remove_partmaps(name, rd->need_sync, rd->deferred_remove); +- if (rd->deferred_remove && dm_get_opencount(name)) { ++ dm_remove_partmaps(name, rd->flags); ++ if ((rd->flags & DMFL_DEFERRED) && dm_get_opencount(name)) { + condlog(2, "%s: map in use", name); + return DM_FLUSH_BUSY; + } + } + condlog(4, "partition map %s removed", name); +- dm_device_remove(name, rd->need_sync, rd->deferred_remove); ++ dm_device_remove(name, rd->flags); + return DM_FLUSH_OK; + } + + static int +-dm_remove_partmaps (const char * mapname, int need_sync, int deferred_remove) ++dm_remove_partmaps (const char * mapname, int flags) + { +- struct remove_data rd = { need_sync, deferred_remove }; ++ struct remove_data rd = { flags }; + return do_foreach_partmaps(mapname, remove_partmap, &rd); + } + +diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h +index 93caa2aa..bb4a55a6 100644 +--- a/libmultipath/devmapper.h ++++ b/libmultipath/devmapper.h +@@ -58,12 +58,20 @@ enum { + }; + + int partmap_in_use(const char *name, void *data); +-int _dm_flush_map (const char *, int, int, int, int); +-int dm_flush_map_nopaths(const char * mapname, int deferred_remove); +-#define dm_flush_map(mapname) _dm_flush_map(mapname, 1, 0, 0, 0) +-#define dm_flush_map_nosync(mapname) _dm_flush_map(mapname, 0, 0, 0, 0) ++ ++enum { ++ DMFL_NONE = 0, ++ DMFL_NEED_SYNC = 1 << 0, ++ DMFL_DEFERRED = 1 << 1, ++ DMFL_SUSPEND = 1 << 2, ++}; ++ ++int _dm_flush_map (const char *mapname, int flags, int retries); ++#define dm_flush_map(mapname) _dm_flush_map(mapname, DMFL_NEED_SYNC, 0) ++#define dm_flush_map_nosync(mapname) _dm_flush_map(mapname, DMFL_NONE, 0) + #define dm_suspend_and_flush_map(mapname, retries) \ +- _dm_flush_map(mapname, 1, 0, 1, retries) ++ _dm_flush_map(mapname, DMFL_NEED_SYNC|DMFL_SUSPEND, retries) ++int dm_flush_map_nopaths(const char * mapname, int deferred_remove); + int dm_cancel_deferred_remove(struct multipath *mpp); + int dm_flush_maps (int retries); + int dm_fail_path(const char * mapname, char * path); diff --git a/0039-libmultipath-use-bitwise-flags-for-dm_simplecmd-API.patch b/0039-libmultipath-use-bitwise-flags-for-dm_simplecmd-API.patch new file mode 100644 index 0000000..1aee878 --- /dev/null +++ b/0039-libmultipath-use-bitwise-flags-for-dm_simplecmd-API.patch @@ -0,0 +1,117 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 2 May 2024 18:45:17 +0200 +Subject: [PATCH] libmultipath: use bitwise flags for dm_simplecmd API + +Also use bitwise flags for dm_simplecmd() and its relatives. Again, +this makes the code more expressive and more readable, while +simplifying the function calls. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/devmapper.c | 26 +++++++++++++------------- + libmultipath/devmapper.h | 5 +++-- + 2 files changed, 16 insertions(+), 15 deletions(-) + +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index a6a9c2b7..08bb3c51 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -386,10 +386,9 @@ libmp_dm_task_create(int task) + } + + static int +-dm_simplecmd (int task, const char *name, int no_flush, int need_sync, +- uint16_t udev_flags, int deferred_remove __DR_UNUSED__) { ++dm_simplecmd (int task, const char *name, int flags, uint16_t udev_flags) { + int r = 0; +- int udev_wait_flag = ((need_sync || udev_flags) && ++ int udev_wait_flag = (((flags & DMFL_NEED_SYNC) || udev_flags) && + (task == DM_DEVICE_RESUME || + task == DM_DEVICE_REMOVE)); + uint32_t cookie = 0; +@@ -404,11 +403,11 @@ dm_simplecmd (int task, const char *name, int no_flush, int need_sync, + dm_task_no_open_count(dmt); + dm_task_skip_lockfs(dmt); /* for DM_DEVICE_RESUME */ + #ifdef LIBDM_API_FLUSH +- if (no_flush) ++ if (flags & DMFL_NO_FLUSH) + dm_task_no_flush(dmt); /* for DM_DEVICE_SUSPEND/RESUME */ + #endif + #ifdef LIBDM_API_DEFERRED +- if (deferred_remove) ++ if (flags & DMFL_DEFERRED) + dm_task_deferred_remove(dmt); + #endif + if (udev_wait_flag && +@@ -429,18 +428,17 @@ out: + + int dm_simplecmd_flush (int task, const char *name, uint16_t udev_flags) + { +- return dm_simplecmd(task, name, 0, 1, udev_flags, 0); ++ return dm_simplecmd(task, name, DMFL_NEED_SYNC, udev_flags); + } + + int dm_simplecmd_noflush (int task, const char *name, uint16_t udev_flags) + { +- return dm_simplecmd(task, name, 1, 1, udev_flags, 0); ++ return dm_simplecmd(task, name, DMFL_NO_FLUSH|DMFL_NEED_SYNC, udev_flags); + } + + static int + dm_device_remove (const char *name, int flags) { +- return dm_simplecmd(DM_DEVICE_REMOVE, name, 0, flags & DMFL_NEED_SYNC, 0, +- flags & DMFL_DEFERRED); ++ return dm_simplecmd(DM_DEVICE_REMOVE, name, flags, 0); + } + + static int +@@ -594,8 +592,9 @@ int dm_addmap_reload(struct multipath *mpp, char *params, int flush) + params, ADDMAP_RO, 0); + } + if (r) +- r = dm_simplecmd(DM_DEVICE_RESUME, mpp->alias, !flush, +- 1, udev_flags, 0); ++ r = dm_simplecmd(DM_DEVICE_RESUME, mpp->alias, ++ DMFL_NEED_SYNC | (flush ? 0 : DMFL_NO_FLUSH), ++ udev_flags); + if (r) + return r; + +@@ -603,8 +602,9 @@ int dm_addmap_reload(struct multipath *mpp, char *params, int flush) + * drop the new table, so doing a second resume will try using + * the original table */ + if (dm_is_suspended(mpp->alias)) +- dm_simplecmd(DM_DEVICE_RESUME, mpp->alias, !flush, 1, +- udev_flags, 0); ++ dm_simplecmd(DM_DEVICE_RESUME, mpp->alias, ++ DMFL_NEED_SYNC | (flush ? 0 : DMFL_NO_FLUSH), ++ udev_flags); + return 0; + } + +diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h +index bb4a55a6..a242381e 100644 +--- a/libmultipath/devmapper.h ++++ b/libmultipath/devmapper.h +@@ -38,8 +38,8 @@ void skip_libmp_dm_init(void); + void libmp_dm_exit(void); + void libmp_udev_set_sync_support(int on); + struct dm_task *libmp_dm_task_create(int task); +-int dm_simplecmd_flush (int, const char *, uint16_t); +-int dm_simplecmd_noflush (int, const char *, uint16_t); ++int dm_simplecmd_flush (int task, const char *name, uint16_t udev_flags); ++int dm_simplecmd_noflush (int task, const char *name, uint16_t udev_flags); + int dm_addmap_create (struct multipath *mpp, char *params); + int dm_addmap_reload (struct multipath *mpp, char *params, int flush); + int dm_map_present (const char *); +@@ -64,6 +64,7 @@ enum { + DMFL_NEED_SYNC = 1 << 0, + DMFL_DEFERRED = 1 << 1, + DMFL_SUSPEND = 1 << 2, ++ DMFL_NO_FLUSH = 1 << 3, + }; + + int _dm_flush_map (const char *mapname, int flags, int retries); diff --git a/0040-libmultipath-add-argument-names-to-some-prototypes.patch b/0040-libmultipath-add-argument-names-to-some-prototypes.patch new file mode 100644 index 0000000..3244d55 --- /dev/null +++ b/0040-libmultipath-add-argument-names-to-some-prototypes.patch @@ -0,0 +1,34 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 2 May 2024 18:46:42 +0200 +Subject: [PATCH] libmultipath: add argument names to some prototypes + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/devmapper.h | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h +index a242381e..19b79c5b 100644 +--- a/libmultipath/devmapper.h ++++ b/libmultipath/devmapper.h +@@ -42,12 +42,12 @@ int dm_simplecmd_flush (int task, const char *name, uint16_t udev_flags); + int dm_simplecmd_noflush (int task, const char *name, uint16_t udev_flags); + int dm_addmap_create (struct multipath *mpp, char *params); + int dm_addmap_reload (struct multipath *mpp, char *params, int flush); +-int dm_map_present (const char *); ++int dm_map_present (const char *name); + int dm_map_present_by_uuid(const char *uuid); +-int dm_get_map(const char *, unsigned long long *, char **); +-int dm_get_status(const char *, char **); +-int dm_type(const char *, char *); +-int dm_is_mpath(const char *); ++int dm_get_map(const char *name, unsigned long long *size, char **outparams); ++int dm_get_status(const char *name, char **outstatus); ++int dm_type(const char *name, char *type); ++int dm_is_mpath(const char *name); + + enum { + DM_FLUSH_OK = 0, diff --git a/0041-libmultipath-bump-version-to-0.9.9.patch b/0041-libmultipath-bump-version-to-0.9.9.patch new file mode 100644 index 0000000..890b047 --- /dev/null +++ b/0041-libmultipath-bump-version-to-0.9.9.patch @@ -0,0 +1,27 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 3 May 2024 22:09:10 +0200 +Subject: [PATCH] libmultipath: bump version to 0.9.9 + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/version.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/version.h b/libmultipath/version.h +index e102975f..271d8e74 100644 +--- a/libmultipath/version.h ++++ b/libmultipath/version.h +@@ -20,9 +20,9 @@ + #ifndef _VERSION_H + #define _VERSION_H + +-#define VERSION_CODE 0x000908 ++#define VERSION_CODE 0x000909 + /* MMDDYY, in hex */ +-#define DATE_CODE 0x020F18 ++#define DATE_CODE 0x050318 + + #define PROG "multipath-tools" + diff --git a/0042-GitHub-Workflows-native.yaml-run-for-Fedora-40.patch b/0042-GitHub-Workflows-native.yaml-run-for-Fedora-40.patch new file mode 100644 index 0000000..47c3949 --- /dev/null +++ b/0042-GitHub-Workflows-native.yaml-run-for-Fedora-40.patch @@ -0,0 +1,24 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 3 May 2024 22:28:34 +0200 +Subject: [PATCH] GitHub Workflows: native.yaml: run for Fedora 40 + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/native.yaml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml +index 0ef9df94..a062845e 100644 +--- a/.github/workflows/native.yaml ++++ b/.github/workflows/native.yaml +@@ -33,7 +33,7 @@ jobs: + - debian-buster + - debian-bullseye + - debian-bookworm +- - fedora-39 ++ - fedora-40 + - opensuse-leap + container: ghcr.io/mwilck/multipath-build-${{ matrix.os }} + steps: diff --git a/0043-update-NEWS.md.patch b/0043-update-NEWS.md.patch new file mode 100644 index 0000000..4edc69d --- /dev/null +++ b/0043-update-NEWS.md.patch @@ -0,0 +1,134 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 3 May 2024 23:11:48 +0200 +Subject: [PATCH] update NEWS.md + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .github/actions/spelling/expect.txt | 3 ++ + .github/actions/spelling/patterns.txt | 3 +- + NEWS.md | 62 +++++++++++++++++++++++++++ + 3 files changed, 67 insertions(+), 1 deletion(-) + +diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt +index fc9f22f8..bdfce83a 100644 +--- a/.github/actions/spelling/expect.txt ++++ b/.github/actions/spelling/expect.txt +@@ -17,6 +17,7 @@ blkid + bmarzins + cciss + CFLAGS ++cgroups + christophe + clangd + clariion +@@ -67,6 +68,7 @@ fulldescr + gcc + getprkey + getprstatus ++getrlimit + getuid + github + GPT +@@ -170,6 +172,7 @@ rootprefixdir + rpmbuild + rport + rtpi ++rtprio + sas + sbp + scsi +diff --git a/.github/actions/spelling/patterns.txt b/.github/actions/spelling/patterns.txt +index 858faee6..aa361654 100644 +--- a/.github/actions/spelling/patterns.txt ++++ b/.github/actions/spelling/patterns.txt +@@ -22,7 +22,7 @@ + \bdmmp_pgs\b + \bdmmp_mpath_kdev_name_get\b + \bfast_io_fail_tmo\b +-\bLimitRTPRIO\b ++\bLimitRTPRIO=?\b + \bmax_fds\b + \bmissing_uev_wait_timeout\b + \bMPATH_MAX_PARAM_LEN\b +@@ -87,6 +87,7 @@ + \bprin_resvdescr\b + \bprout_param_descriptor\b + \brq_servact\b ++\bRLIMIT_RTPRIO\b + \bSCHED_RT_PRIO\b + \bssize_t\b + \btrnptid_list\b +diff --git a/NEWS.md b/NEWS.md +index 0b094b98..4c54afa0 100644 +--- a/NEWS.md ++++ b/NEWS.md +@@ -1,5 +1,67 @@ + # multipath-tools Release Notes + ++## multipath-tools 0.9.9, 2024/05 ++ ++### User-Visible Changes ++ ++* *Changed realtime scheduling:* multipathd used to run at the highest possible ++ realtime priority, 99. This has always been excessive, and on some ++ distributions (e.g. RHEL 8), it hasn't worked at all. It is now possible to ++ set multipathd's real time scheduling by setting the hard limit for ++ `RLIMIT_RTPRIO` (see getrlimit(2)), which corresponds to the `rtprio` ++ setting in limits.conf and to `LimitRTPRIO=` in the systemd unit file. The ++ default in the systemd unit file has been set to 10. If the limit is set to ++ 0, multipathd doesn't attempt to enable real-time scheduling. ++ Otherwise, it will try to set the scheduling priority to the given value. ++ Fixes [#82](https://github.com/opensvc/multipath-tools/issues/82). ++* *Changed normal scheduling:* In order to make sure that multipathd has ++ sufficient priority even if real time scheduling is switched off, the ++ `CPUWeight=` setting in the unit file is set to 1000. This is necessary ++ because regular nice(2) values have no effect in systems with cgroups enabled. ++* *Changed handling of `max_sectors_kb` configuration:* multipathd applies ++ the `max_sectors_kb` setting only during map creation, or when a new path is ++ added to an existing map. The kernel makes sure that the multipath device ++ never has a larger `max_sectors_kb` value than any of its configured path ++ devices. The reason for this change is that applying `max_sectors_kb` on ++ live maps can cause IO errors and data loss in rare situations. ++ It can now happen that some path devices have a higher `max_sectors_kb` ++ value than the map; this is not an error. It is not possible any more to ++ decrease `max_sectors_kb` in `multipath.conf` and run `multipathd ++ reconfigure` to "apply" this setting to the map and its paths. If decreasing ++ the IO size is necessary, either destroy and recreate the map, or remove one ++ path with `multipathd del path $PATH`, run `multipathd reconfigure`, and ++ re-add the path with `multipathd add path $PATH`. ++* *New wildcard %k:* The wildcard `%k` for `max_sectors_kb` has been added to ++ the `multipathd show paths format` and `multipathd show maps format` ++ commands. ++* *Changed semantics of flush_on_last_del:* The `flush_on_last_del` option ++ now takes the values `always` , `unused`, or `never`. `yes` and `no` ++ are still accepted as aliases for `always` and `unused`, respectively. ++ `always` means that when all paths for a multipath map have been removed, ++ *outstanding IO will be failed* and the map will be deleted. `unused` means ++ that this will only happen when the map is not mounted or otherwise opened. ++ `never` means the map will only be removed if the `queue_if_no_path` ++ feature is off. ++ This fixes a problem where multipathd could hang when the last path of ++ a queueing map was deleted. ++ ++### Other major changes ++ ++* Adapted the dm-mpath udev rules such that they will work with the modified ++ device mapper udev rules (`DM_UDEV_RULES_VSN==3`, lvm2 > 2.03.22). They are ++ still compatible with older versions of the device-mapper udev rules. ++ ++### Bug fixes ++ ++* Fixed misspelled DM_UDEV_DISABLE_OTHER_RULES_FLAG in 11-dm-mpath.rules ++* Always use `glibc_basename()` to avoid some issues with MUSL libc. ++ Fixes [#84](https://github.com/opensvc/multipath-tools/pull/84). ++ ++### Other ++ ++* Build: added `TGTDIR` option to simplify building for a different target ++ host (see README.md). ++ + ## multipath-tools 0.9.8, 2024/02 + + ### User-Visible Changes diff --git a/0044-multipath.conf.5.in-fix-man-page-date.patch b/0044-multipath.conf.5.in-fix-man-page-date.patch new file mode 100644 index 0000000..c9f2d5d --- /dev/null +++ b/0044-multipath.conf.5.in-fix-man-page-date.patch @@ -0,0 +1,24 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 3 May 2024 23:22:50 +0200 +Subject: [PATCH] multipath.conf.5.in: fix man page date + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + multipath/multipath.conf.5.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in +index 1d3d53bb..dacb9b0e 100644 +--- a/multipath/multipath.conf.5.in ++++ b/multipath/multipath.conf.5.in +@@ -6,7 +6,7 @@ + .\" Update the date below if you make any significant change. + .\" ---------------------------------------------------------------------------- + . +-.TH MULTIPATH.CONF 5 2024-04-17 Linux ++.TH MULTIPATH.CONF 5 2024-04-25 Linux + . + . + .\" ---------------------------------------------------------------------------- diff --git a/0001-RH-fixup-udev-rules-for-redhat.patch b/0045-RH-fixup-udev-rules-for-redhat.patch similarity index 86% rename from 0001-RH-fixup-udev-rules-for-redhat.patch rename to 0045-RH-fixup-udev-rules-for-redhat.patch index 02efadd..d78919e 100644 --- a/0001-RH-fixup-udev-rules-for-redhat.patch +++ b/0045-RH-fixup-udev-rules-for-redhat.patch @@ -15,7 +15,7 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 6b454303..0b0e3ad2 100644 +index 81b86cd8..33dbb99c 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -34,7 +34,7 @@ endif @@ -26,9 +26,9 @@ index 6b454303..0b0e3ad2 100644 +exec_prefix := $(prefix)/usr # Prefix for non-essential libraries (libdmmp) usr_prefix := $(if $(prefix),$(prefix),/usr) - # Prefix for configfuration files (multipath.conf) + # Prefix for configuration files (multipath.conf) diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules -index 1969dee0..d2b28233 100644 +index 8dd3369c..7c3c7524 100644 --- a/kpartx/kpartx.rules +++ b/kpartx/kpartx.rules @@ -39,6 +39,6 @@ LABEL="mpath_kpartx_end" @@ -40,20 +40,20 @@ index 1969dee0..d2b28233 100644 LABEL="kpartx_end" diff --git a/multipath/Makefile b/multipath/Makefile -index 0efb9b26..504d6892 100644 +index 67fb5e62..2ea9e528 100644 --- a/multipath/Makefile +++ b/multipath/Makefile -@@ -26,7 +26,7 @@ install: - $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ +@@ -27,7 +27,7 @@ install: $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) $(Q)$(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) + $(Q)$(INSTALL_PROGRAM) -m 644 99-z-dm-mpath-late.rules $(DESTDIR)$(udevrulesdir) - $(Q)$(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)$(udevrulesdir)/56-multipath.rules + $(Q)$(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)$(udevrulesdir)/62-multipath.rules $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(tmpfilesdir) $(Q)$(INSTALL_PROGRAM) -m 644 tmpfiles.conf $(DESTDIR)$(tmpfilesdir)/multipath.conf $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 -@@ -48,7 +48,7 @@ uninstall: - $(Q)$(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules +@@ -50,7 +50,7 @@ uninstall: + $(Q)$(RM) $(DESTDIR)$(udevrulesdir)/99-z-dm-mpath-late.rules $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf - $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules diff --git a/0002-RH-Remove-the-property-blacklist-exception-builtin.patch b/0046-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 96% rename from 0002-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0046-RH-Remove-the-property-blacklist-exception-builtin.patch index bc259d4..b039539 100644 --- a/0002-RH-Remove-the-property-blacklist-exception-builtin.patch +++ b/0046-RH-Remove-the-property-blacklist-exception-builtin.patch @@ -42,10 +42,10 @@ index 75100b20..0b212078 100644 udev_device_get_properties_list_entry(udev)) { diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in -index 683bdb72..87b3b2a5 100644 +index dacb9b0e..645e8f88 100644 --- a/multipath/multipath.conf.5.in +++ b/multipath/multipath.conf.5.in -@@ -1431,9 +1431,14 @@ keywords. Both are regular expressions. For a full description of these keywords +@@ -1468,9 +1468,14 @@ keywords. Both are regular expressions. For a full description of these keywords Regular expression for an udev property. All devices that have matching udev properties will be excluded/included. The handling of the \fIproperty\fR keyword is special, @@ -61,7 +61,7 @@ index 683bdb72..87b3b2a5 100644 . .RS .PP -@@ -1444,10 +1449,6 @@ Blacklisting by missing properties is only applied to devices which do have the +@@ -1481,10 +1486,6 @@ Blacklisting by missing properties is only applied to devices which do have the property specified by \fIuid_attribute\fR (e.g. \fIID_SERIAL\fR) set. Previously, it was applied to every device, possibly causing devices to be blacklisted because of temporary I/O error conditions. diff --git a/0003-RH-don-t-start-without-a-config-file.patch b/0047-RH-don-t-start-without-a-config-file.patch similarity index 92% rename from 0003-RH-don-t-start-without-a-config-file.patch rename to 0047-RH-don-t-start-without-a-config-file.patch index fa304dc..ad7962a 100644 --- a/0003-RH-don-t-start-without-a-config-file.patch +++ b/0047-RH-don-t-start-without-a-config-file.patch @@ -22,10 +22,10 @@ Signed-off-by: Benjamin Marzinski 7 files changed, 25 insertions(+) diff --git a/libmultipath/config.c b/libmultipath/config.c -index b7dbc6f5..3a374b3d 100644 +index 83fa7369..002027a7 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c -@@ -958,6 +958,19 @@ int _init_config (const char *file, struct config *conf) +@@ -959,6 +959,19 @@ int _init_config (const char *file, struct config *conf) } factorize_hwtable(conf->hwtable, builtin_hwtable_size, file); validate_pctable(conf->overrides, 0, file); @@ -58,12 +58,12 @@ index 384193ab..158cebf0 100644 enum devtypes { DEV_NONE, diff --git a/multipath/main.c b/multipath/main.c -index 9e1c5052..46944589 100644 +index ce702e7f..c21e3e0b 100644 --- a/multipath/main.c +++ b/multipath/main.c -@@ -829,11 +829,14 @@ main (int argc, char *argv[]) +@@ -842,11 +842,14 @@ main (int argc, char *argv[]) + char *dev = NULL; struct config *conf; - int retries = -1; bool enable_foreign = false; + bool have_config; + struct stat buf; @@ -76,7 +76,7 @@ index 9e1c5052..46944589 100644 if (init_config(DEFAULT_CONFIGFILE)) exit(RTVL_FAIL); if (atexit(uninit_config)) -@@ -1081,6 +1084,9 @@ main (int argc, char *argv[]) +@@ -1097,6 +1100,9 @@ main (int argc, char *argv[]) while ((r = configure(conf, cmd, dev_type, dev)) == RTVL_RETRY) condlog(3, "restart multipath configuration process"); @@ -87,7 +87,7 @@ index 9e1c5052..46944589 100644 put_multipath_config(conf); if (dev) diff --git a/multipath/multipath.rules.in b/multipath/multipath.rules.in -index 6f123760..70b69a06 100644 +index 780bf852..2c518378 100644 --- a/multipath/multipath.rules.in +++ b/multipath/multipath.rules.in @@ -9,6 +9,7 @@ IMPORT{cmdline}="nompath" @@ -99,7 +99,7 @@ index 6f123760..70b69a06 100644 ENV{DEVTYPE}!="partition", GOTO="test_dev" IMPORT{parent}="DM_MULTIPATH_DEVICE_PATH" diff --git a/multipathd/multipathd.8.in b/multipathd/multipathd.8.in -index e98c27fd..fd2061e5 100644 +index 12b77156..499557a0 100644 --- a/multipathd/multipathd.8.in +++ b/multipathd/multipathd.8.in @@ -49,6 +49,8 @@ map regains its maximum performance and redundancy. @@ -112,7 +112,7 @@ index e98c27fd..fd2061e5 100644 . .\" ---------------------------------------------------------------------------- diff --git a/multipathd/multipathd.service.in b/multipathd/multipathd.service.in -index 6d03ff71..0965d6f9 100644 +index a63ddd9a..01ceff7d 100644 --- a/multipathd/multipathd.service.in +++ b/multipathd/multipathd.service.in @@ -6,6 +6,7 @@ Wants=systemd-udevd-kernel.socket @MODPROBE_UNIT@ @@ -124,7 +124,7 @@ index 6d03ff71..0965d6f9 100644 Conflicts=shutdown.target Conflicts=initrd-cleanup.service diff --git a/multipathd/multipathd.socket b/multipathd/multipathd.socket -index c777e5e3..3c20a2ff 100644 +index 6a62f5fd..263b6b0c 100644 --- a/multipathd/multipathd.socket +++ b/multipathd/multipathd.socket @@ -1,6 +1,7 @@ diff --git a/0004-RH-Fix-nvme-function-missing-argument.patch b/0048-RH-Fix-nvme-function-missing-argument.patch similarity index 100% rename from 0004-RH-Fix-nvme-function-missing-argument.patch rename to 0048-RH-Fix-nvme-function-missing-argument.patch diff --git a/0005-RH-use-rpm-optflags-if-present.patch b/0049-RH-use-rpm-optflags-if-present.patch similarity index 87% rename from 0005-RH-use-rpm-optflags-if-present.patch rename to 0049-RH-use-rpm-optflags-if-present.patch index 6352c23..0f354e7 100644 --- a/0005-RH-use-rpm-optflags-if-present.patch +++ b/0049-RH-use-rpm-optflags-if-present.patch @@ -13,7 +13,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 0b0e3ad2..3d80d224 100644 +index 33dbb99c..94e0ec85 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -95,11 +95,23 @@ SYSTEMD_LIBDEPS := $(if $(SYSTEMD),$(if $(shell test $(SYSTEMD) -gt 209 && echo @@ -41,10 +41,10 @@ index 0b0e3ad2..3d80d224 100644 -CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) $(D_URCU_VERSION) \ + $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) $(W_URCU_TYPE_LIMITS) -Wstrict-prototypes +CPPFLAGS := $(CPPFLAGS) $(D_URCU_VERSION) \ - -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \ - -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(configdir)\" \ - -DDEFAULT_CONFIGFILE=\"$(configfile)\" -DSTATE_DIR=\"$(statedir)\" \ -@@ -108,7 +120,7 @@ CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe + -D_FILE_OFFSET_BITS=64 \ + -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(TGTDIR)$(plugindir)\" \ + -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(TGTDIR)$(configdir)\" \ +@@ -109,7 +121,7 @@ CFLAGS := -std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe BIN_CFLAGS := -fPIE -DPIE LIB_CFLAGS := -fPIC SHARED_FLAGS := -shared diff --git a/0006-RH-add-mpathconf.patch b/0050-RH-add-mpathconf.patch similarity index 98% rename from 0006-RH-add-mpathconf.patch rename to 0050-RH-add-mpathconf.patch index fd47a6c..fd65e34 100644 --- a/0006-RH-add-mpathconf.patch +++ b/0050-RH-add-mpathconf.patch @@ -22,10 +22,10 @@ Signed-off-by: Benjamin Marzinski create mode 100644 multipath/mpathconf.8 diff --git a/libmultipath/config.c b/libmultipath/config.c -index 3a374b3d..4544f484 100644 +index 002027a7..3d5943d3 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c -@@ -960,6 +960,8 @@ int _init_config (const char *file, struct config *conf) +@@ -961,6 +961,8 @@ int _init_config (const char *file, struct config *conf) validate_pctable(conf->overrides, 0, file); } else { condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices."); @@ -35,7 +35,7 @@ index 3a374b3d..4544f484 100644 conf->blist_devnode = vector_alloc(); if (!conf->blist_devnode) { diff --git a/multipath/Makefile b/multipath/Makefile -index 504d6892..9f14036c 100644 +index 2ea9e528..3dc241cc 100644 --- a/multipath/Makefile +++ b/multipath/Makefile @@ -24,6 +24,7 @@ $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so @@ -45,8 +45,8 @@ index 504d6892..9f14036c 100644 + $(Q)$(INSTALL_PROGRAM) -m 755 mpathconf $(DESTDIR)$(bindir)/ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) $(Q)$(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) - $(Q)$(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)$(udevrulesdir)/62-multipath.rules -@@ -31,6 +32,7 @@ install: + $(Q)$(INSTALL_PROGRAM) -m 644 99-z-dm-mpath-late.rules $(DESTDIR)$(udevrulesdir) +@@ -32,6 +33,7 @@ install: $(Q)$(INSTALL_PROGRAM) -m 644 tmpfiles.conf $(DESTDIR)$(tmpfilesdir)/multipath.conf $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 @@ -54,12 +54,13 @@ index 504d6892..9f14036c 100644 $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man5 $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5 $(DESTDIR)$(mandir)/man5 $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(modulesloaddir) -@@ -45,11 +47,13 @@ endif +@@ -46,12 +48,14 @@ endif uninstall: $(Q)$(RM) $(DESTDIR)$(bindir)/$(EXEC) + $(Q)$(RM) $(DESTDIR)$(bindir)/mpathconf $(Q)$(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules + $(Q)$(RM) $(DESTDIR)$(udevrulesdir)/99-z-dm-mpath-late.rules $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules diff --git a/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0051-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 96% rename from 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0051-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch index a3c4e9d..9884258 100644 --- a/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +++ b/0051-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch @@ -20,7 +20,7 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/multipath/main.c b/multipath/main.c -index 46944589..47f89a0a 100644 +index c21e3e0b..3f3ac9fb 100644 --- a/multipath/main.c +++ b/multipath/main.c @@ -120,7 +120,7 @@ usage (char * progname) @@ -92,7 +92,7 @@ index 46944589..47f89a0a 100644 static int configure (struct config *conf, enum mpath_cmds cmd, enum devtypes dev_type, char *devpath) -@@ -848,7 +894,7 @@ main (int argc, char *argv[]) +@@ -861,7 +907,7 @@ main (int argc, char *argv[]) condlog(1, "failed to register cleanup handler for vecs: %m"); if (atexit(cleanup_bindings)) condlog(1, "failed to register cleanup handler for bindings: %m"); @@ -101,7 +101,7 @@ index 46944589..47f89a0a 100644 switch(arg) { case 'v': if (!isdigit(optarg[0])) { -@@ -919,6 +965,10 @@ main (int argc, char *argv[]) +@@ -932,6 +978,10 @@ main (int argc, char *argv[]) case 'T': cmd = CMD_DUMP_CONFIG; break; @@ -113,7 +113,7 @@ index 46944589..47f89a0a 100644 usage(argv[0]); exit(RTVL_OK); diff --git a/multipath/multipath.8.in b/multipath/multipath.8.in -index 348eb220..82a7e68e 100644 +index b88e9a4c..edd742aa 100644 --- a/multipath/multipath.8.in +++ b/multipath/multipath.8.in @@ -64,7 +64,7 @@ multipath \- Device mapper target autoconfig. @@ -138,7 +138,7 @@ index 348eb220..82a7e68e 100644 Remove the WWID for the specified device from the WWIDs file. . diff --git a/multipathd/multipathd.service.in b/multipathd/multipathd.service.in -index 0965d6f9..c964eb1b 100644 +index 01ceff7d..e0c2011b 100644 --- a/multipathd/multipathd.service.in +++ b/multipathd/multipathd.service.in @@ -17,6 +17,7 @@ ConditionVirtualization=!container diff --git a/0008-RH-reset-default-find_mutipaths-value-to-off.patch b/0052-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 91% rename from 0008-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0052-RH-reset-default-find_mutipaths-value-to-off.patch index cf7317e..04ad52c 100644 --- a/0008-RH-reset-default-find_mutipaths-value-to-off.patch +++ b/0052-RH-reset-default-find_mutipaths-value-to-off.patch @@ -14,7 +14,7 @@ Signed-off-by: Benjamin Marzinski 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h -index 64b633f2..5bda9f93 100644 +index ed08c251..4b033ff9 100644 --- a/libmultipath/defaults.h +++ b/libmultipath/defaults.h @@ -23,7 +23,7 @@ @@ -27,10 +27,10 @@ index 64b633f2..5bda9f93 100644 #define DEFAULT_DEV_LOSS_TMO 600 #define DEFAULT_RETAIN_HWHANDLER RETAIN_HWHANDLER_ON diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in -index 87b3b2a5..8e246571 100644 +index 645e8f88..a7543939 100644 --- a/multipath/multipath.conf.5.in +++ b/multipath/multipath.conf.5.in -@@ -1213,7 +1213,7 @@ as non-multipath and passed on to upper layers. +@@ -1225,7 +1225,7 @@ as non-multipath and passed on to upper layers. \fBNote:\fR this may cause delays during device detection if there are single-path devices which aren\'t blacklisted. .TP diff --git a/0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0053-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 100% rename from 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0053-RH-attempt-to-get-ANA-info-via-sysfs-first.patch diff --git a/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch b/0054-RH-make-parse_vpd_pg83-match-scsi_id-output.patch similarity index 84% rename from 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch rename to 0054-RH-make-parse_vpd_pg83-match-scsi_id-output.patch index aa49d69..c090da0 100644 --- a/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +++ b/0054-RH-make-parse_vpd_pg83-match-scsi_id-output.patch @@ -14,10 +14,10 @@ Signed-off-by: Benjamin Marzinski 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 6fd4dabb..19692b1e 100644 +index e2052422..3bcd94ce 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c -@@ -1216,13 +1216,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, +@@ -1221,13 +1221,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, good_len = 8; break; case 2: @@ -33,7 +33,7 @@ index 6fd4dabb..19692b1e 100644 good_len = 8; break; default: -@@ -1240,10 +1236,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, +@@ -1245,10 +1241,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, break; case 0x8: /* SCSI Name: Prio 3 */ @@ -45,10 +45,10 @@ index 6fd4dabb..19692b1e 100644 case 0x1: /* T-10 Vendor ID: Prio 2 */ diff --git a/tests/vpd.c b/tests/vpd.c -index 1b2d62d6..7309b5c5 100644 +index e3212e61..cdb111bb 100644 --- a/tests/vpd.c +++ b/tests/vpd.c -@@ -231,11 +231,13 @@ static const char * const str_prefix[] = { +@@ -232,11 +232,13 @@ static const char * const str_prefix[] = { [STR_IQN] = "iqn.", }; @@ -62,7 +62,7 @@ index 1b2d62d6..7309b5c5 100644 /** * create_scsi_string_desc() - create a SCSI name string descriptor. -@@ -766,6 +768,7 @@ make_test_vpd_naa(2, 18); +@@ -767,6 +769,7 @@ make_test_vpd_naa(2, 18); make_test_vpd_naa(2, 17); make_test_vpd_naa(2, 16); @@ -70,7 +70,7 @@ index 1b2d62d6..7309b5c5 100644 /* SCSI Name string: EUI64, WWID size: 17 */ make_test_vpd_str(0, 20, 18) make_test_vpd_str(0, 20, 17) -@@ -801,6 +804,7 @@ make_test_vpd_str(18, 20, 18) +@@ -802,6 +805,7 @@ make_test_vpd_str(18, 20, 18) make_test_vpd_str(18, 20, 17) make_test_vpd_str(18, 20, 16) make_test_vpd_str(18, 20, 15) @@ -78,7 +78,7 @@ index 1b2d62d6..7309b5c5 100644 static int test_vpd(void) { -@@ -909,6 +913,7 @@ static int test_vpd(void) +@@ -910,6 +914,7 @@ static int test_vpd(void) cmocka_unit_test(test_vpd_naa_2_18), cmocka_unit_test(test_vpd_naa_2_17), cmocka_unit_test(test_vpd_naa_2_16), @@ -86,7 +86,7 @@ index 1b2d62d6..7309b5c5 100644 cmocka_unit_test(test_vpd_str_0_20_18), cmocka_unit_test(test_vpd_str_0_20_17), cmocka_unit_test(test_vpd_str_0_20_16), -@@ -933,6 +938,7 @@ static int test_vpd(void) +@@ -934,6 +939,7 @@ static int test_vpd(void) cmocka_unit_test(test_vpd_str_18_20_17), cmocka_unit_test(test_vpd_str_18_20_16), cmocka_unit_test(test_vpd_str_18_20_15), diff --git a/0011-RH-add-scsi-device-handlers-to-modules-load.d.patch b/0055-RH-add-scsi-device-handlers-to-modules-load.d.patch similarity index 96% rename from 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch rename to 0055-RH-add-scsi-device-handlers-to-modules-load.d.patch index 0059895..7624c5b 100644 --- a/0011-RH-add-scsi-device-handlers-to-modules-load.d.patch +++ b/0055-RH-add-scsi-device-handlers-to-modules-load.d.patch @@ -11,7 +11,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc -index 3d80d224..15e3bd3a 100644 +index 94e0ec85..49514b06 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -16,7 +16,7 @@ READLINE := diff --git a/0012-RH-compile-with-libreadline-support.patch b/0056-RH-compile-with-libreadline-support.patch similarity index 96% rename from 0012-RH-compile-with-libreadline-support.patch rename to 0056-RH-compile-with-libreadline-support.patch index b0c8749..eb0ab13 100644 --- a/0012-RH-compile-with-libreadline-support.patch +++ b/0056-RH-compile-with-libreadline-support.patch @@ -12,7 +12,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc -index 15e3bd3a..64384a72 100644 +index 49514b06..a3ed9f28 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -12,7 +12,7 @@ diff --git a/0013-RH-Add-mpathcleanup.patch b/0057-RH-Add-mpathcleanup.patch similarity index 96% rename from 0013-RH-Add-mpathcleanup.patch rename to 0057-RH-Add-mpathcleanup.patch index c15fb6d..bd2dcd6 100644 --- a/0013-RH-Add-mpathcleanup.patch +++ b/0057-RH-Add-mpathcleanup.patch @@ -14,7 +14,7 @@ Signed-off-by: Benjamin Marzinski create mode 100755 multipath/mpathcleanup diff --git a/multipath/Makefile b/multipath/Makefile -index 9f14036c..99ad81b0 100644 +index 3dc241cc..47e82234 100644 --- a/multipath/Makefile +++ b/multipath/Makefile @@ -25,6 +25,7 @@ install: @@ -24,15 +24,15 @@ index 9f14036c..99ad81b0 100644 + $(Q)$(INSTALL_PROGRAM) -m 755 mpathcleanup $(DESTDIR)$(bindir)/ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) $(Q)$(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) - $(Q)$(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)$(udevrulesdir)/62-multipath.rules -@@ -48,6 +49,7 @@ endif + $(Q)$(INSTALL_PROGRAM) -m 644 99-z-dm-mpath-late.rules $(DESTDIR)$(udevrulesdir) +@@ -49,6 +50,7 @@ endif uninstall: $(Q)$(RM) $(DESTDIR)$(bindir)/$(EXEC) $(Q)$(RM) $(DESTDIR)$(bindir)/mpathconf + $(Q)$(RM) $(DESTDIR)$(bindir)/mpathcleanup $(Q)$(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules + $(Q)$(RM) $(DESTDIR)$(udevrulesdir)/99-z-dm-mpath-late.rules $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf - $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf diff --git a/multipath/mpathcleanup b/multipath/mpathcleanup new file mode 100755 index 00000000..6fd921e4 diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 78bef5a..22e6ad7 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,30 +1,72 @@ Name: device-mapper-multipath -Version: 0.9.7 -Release: 7%{?dist} +Version: 0.9.8 +Release: 1%{?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 -L https://github.com/opensvc/multipath-tools/archive/0.9.7.tar.gz -o multipath-tools-0.9.7.tgz -Source0: multipath-tools-0.9.7.tgz +# curl -L https://github.com/opensvc/multipath-tools/archive/0.9.8.tar.gz -o multipath-tools-0.9.8.tgz +Source0: multipath-tools-0.9.8.tgz Source1: multipath.conf -Patch0001: 0001-RH-fixup-udev-rules-for-redhat.patch -Patch0002: 0002-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0003: 0003-RH-don-t-start-without-a-config-file.patch -Patch0004: 0004-RH-Fix-nvme-function-missing-argument.patch -Patch0005: 0005-RH-use-rpm-optflags-if-present.patch -Patch0006: 0006-RH-add-mpathconf.patch -Patch0007: 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0008: 0008-RH-reset-default-find_mutipaths-value-to-off.patch -Patch0009: 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch -Patch0010: 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch -Patch0011: 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch -Patch0012: 0012-RH-compile-with-libreadline-support.patch -Patch0013: 0013-RH-Add-mpathcleanup.patch -Patch0014: 0014-multipathd-fix-null-pointer-dereference-in-uev_updat.patch -Patch0015: 0015-multipathd-fix-auto-resize-configuration.patch +Patch0001: 0001-11-dm-mpath.rules-fix-misspelled-DM_UDEV_DISABLE_OTH.patch +Patch0002: 0002-multipathd-use-condlog-level-for-setscheduler-error-.patch +Patch0003: 0003-multipathd-make-multipathd-scheduling-configurable.patch +Patch0004: 0004-libmpathutil-really-always-use-glibc-basename.patch +Patch0005: 0005-multipathd-make-multipathd-set-priority-to-RLIMIT_RT.patch +Patch0006: 0006-multipathd-Set-CPUWeight-to-1000-and-LimitRTPRIO-to-.patch +Patch0007: 0007-11-dm-mpath.rules-explain-logic-for-device-becoming-.patch +Patch0008: 0008-11-dm-mpath.rules-don-t-import-DM_NOSCAN-from-udev-d.patch +Patch0009: 0009-11-dm-mpath.rules-don-t-import-ID_FS_VERSION-from-ud.patch +Patch0010: 0010-11-dm-mpath.rules-adapt-MPATH_DEVICE_READY-0-logic-t.patch +Patch0011: 0011-11-dm-mpath.rules-adapt-coldplug-event-handling-ro-1.patch +Patch0012: 0012-11-dm-mpath.rules-don-t-import-properties-with-new-1.patch +Patch0013: 0013-11-dm-mpath.rules-replace-DM_SUSPENDED-by-.DM_SUSPEN.patch +Patch0014: 0014-11-dm-mpath.rules-replace-DM_NOSCAN-by-.DM_NOSCAN.patch +Patch0015: 0015-11-dm-mpath.rules-simplify-PATH_FAILED-case.patch +Patch0016: 0016-11-dm-mpath.rules-make-label-names-more-intuitive.patch +Patch0017: 0017-kpartx.rules-ignore-DM_SUSPENDED.patch +Patch0018: 0018-multipath-tools-tests-fix-CI-failures-on-arm-v7-with.patch +Patch0019: 0019-multipath-tools-tests-fix-CI-failures-with-clang-on-.patch +Patch0020: 0020-GitHub-actions-fixes-for-spelling-CI.patch +Patch0021: 0021-GitHub-workflows-run-workflows-if-workflow-file-has-.patch +Patch0022: 0022-multipath-tools-add-TGTDIR-option.patch +Patch0023: 0023-libmultipath-move-get_udev_for_mpp-to-sysfs.c.patch +Patch0024: 0024-libmultipath-add-mp_find_path_by_devt.patch +Patch0025: 0025-Revert-libmultipath-fix-max_sectors_kb-on-adding-pat.patch +Patch0026: 0026-libmultipath-Only-set-max_sectors_kb-on-map-creation.patch +Patch0027: 0027-libmultipath-set-max_sectors_kb-in-adopt_paths.patch +Patch0028: 0028-libmultipath-add-wildcard-k-for-printing-max_sectors.patch +Patch0029: 0029-multipath.conf-5-update-documentation-for-max_sector.patch +Patch0030: 0030-multipath-tools-simplify-comment-in-hwtable.patch +Patch0031: 0031-multipath-tools-unify-text-in-multipath.conf.5.patch +Patch0032: 0032-multipath-tools-update-man-pages-dates.patch +Patch0033: 0033-libmultipath-export-partmap_in_use.patch +Patch0034: 0034-libmultipath-change-flush_on_last_del-to-fix-a-multi.patch +Patch0035: 0035-libmultipath-remove-redundant-config-option-from-Inf.patch +Patch0036: 0036-libmultipath-pad-dev_loss_tmo-to-avoid-race-with-no_.patch +Patch0037: 0037-libmultipath-fix-deferred_remove-function-arguments.patch +Patch0038: 0038-libmultipath-use-bitwise-flags-for-map-flushing-API.patch +Patch0039: 0039-libmultipath-use-bitwise-flags-for-dm_simplecmd-API.patch +Patch0040: 0040-libmultipath-add-argument-names-to-some-prototypes.patch +Patch0041: 0041-libmultipath-bump-version-to-0.9.9.patch +Patch0042: 0042-GitHub-Workflows-native.yaml-run-for-Fedora-40.patch +Patch0043: 0043-update-NEWS.md.patch +Patch0044: 0044-multipath.conf.5.in-fix-man-page-date.patch +Patch0045: 0045-RH-fixup-udev-rules-for-redhat.patch +Patch0046: 0046-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0047: 0047-RH-don-t-start-without-a-config-file.patch +Patch0048: 0048-RH-Fix-nvme-function-missing-argument.patch +Patch0049: 0049-RH-use-rpm-optflags-if-present.patch +Patch0050: 0050-RH-add-mpathconf.patch +Patch0051: 0051-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0052: 0052-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0053: 0053-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0054: 0054-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +Patch0055: 0055-RH-add-scsi-device-handlers-to-modules-load.d.patch +Patch0056: 0056-RH-compile-with-libreadline-support.patch +Patch0057: 0057-RH-Add-mpathcleanup.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -111,7 +153,7 @@ This package contains the files needed to develop applications that use device-mapper-multipath's libdmmp C API library %prep -%autosetup -n multipath-tools-0.9.7 -p1 +%autosetup -n multipath-tools-0.9.8 -p1 cp %{SOURCE1} . %build @@ -172,6 +214,7 @@ fi %{_mandir}/man8/mpathpersist.8* %config /usr/lib/udev/rules.d/62-multipath.rules %config /usr/lib/udev/rules.d/11-dm-mpath.rules +%config /usr/lib/udev/rules.d/99-z-dm-mpath-late.rules %dir %{_modulesloaddir} %{_modulesloaddir}/scsi_dh.conf %{_tmpfilesdir}/multipath.conf @@ -232,6 +275,14 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Mon May 20 2024 Benjamin Marzinski - 0.9.8-1 +- Update source to upstream version 0.9.8 plus latest staging branch + * Previous patches 0014 & 0015 are included in the source tarball + * patches 0001-0044 are from the upstream staging branch +- Rename redhat patches + * Previous patches 0001-0013 are now patches 0045-0057 +- Install /lib/udev/rules.d/99-z-dm-mpath-late.rules + * Wed Jan 24 2024 Fedora Release Engineering - 0.9.7-7 - Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild diff --git a/sources b/sources index 89f8f37..b0337e2 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (multipath-tools-0.9.7.tgz) = 0f4c97179a3de5a0c77893fec229eb183293fed8e5e01a9945b261845ccf5d13f8ef2c2ff0c17c9345217d236275caed4765422ec95aed80821f11658bf96e26 +SHA512 (multipath-tools-0.9.8.tgz) = 4d73bcf6bce769a829c306c609b206ddba65a708620f458106e406dd18d12f9a9d97f400662daa8e6a75c9fdf7decb6dcbda92cb807b6c53522c7b4b2795b627 SHA512 (multipath.conf) = 71953dce5a68adcf60a942305f5a66023e6f4c4baf53b1bfdb4edf65ed5b8e03db804363c36d1dcfd85591f4766f52b515269904c53b84d7b076da0b80b09942 From 59945a7f7ef24b659a0e3895f78f84a15384454a Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 13 Jun 2024 14:29:22 -0400 Subject: [PATCH 51/67] device-mapper-multipath-0.9.9-1 Update source to upstream version 0.9.9 * Previous patches 0001-0044 are included in the source tarball Rename redhat patches * Previous patches 0045-0057 are now patches 0001-0013 --- .gitignore | 1 + ...s-fix-misspelled-DM_UDEV_DISABLE_OTH.patch | 27 -- ... 0001-RH-fixup-udev-rules-for-redhat.patch | 0 ...property-blacklist-exception-builtin.patch | 0 ...ondlog-level-for-setscheduler-error-.patch | 27 -- ...RH-don-t-start-without-a-config-file.patch | 2 +- ...e-multipathd-scheduling-configurable.patch | 87 ----- ...H-Fix-nvme-function-missing-argument.patch | 0 ...til-really-always-use-glibc-basename.patch | 144 -------- ... 0005-RH-use-rpm-optflags-if-present.patch | 0 ...multipathd-set-priority-to-RLIMIT_RT.patch | 134 ------- ...hconf.patch => 0006-RH-add-mpathconf.patch | 0 ...PUWeight-to-1000-and-LimitRTPRIO-to-.patch | 33 -- ...s-explain-logic-for-device-becoming-.patch | 30 -- ...om-kernel-cmdline-mpath.wwids-with-A.patch | 0 ...s-don-t-import-DM_NOSCAN-from-udev-d.patch | 37 -- ...-default-find_mutipaths-value-to-off.patch | 0 ...s-don-t-import-ID_FS_VERSION-from-ud.patch | 27 -- ...empt-to-get-ANA-info-via-sysfs-first.patch | 0 ...s-adapt-MPATH_DEVICE_READY-0-logic-t.patch | 67 ---- ...-parse_vpd_pg83-match-scsi_id-output.patch | 0 ...s-adapt-coldplug-event-handling-ro-1.patch | 43 --- ...si-device-handlers-to-modules-load.d.patch | 0 ...s-don-t-import-properties-with-new-1.patch | 36 -- ...-RH-compile-with-libreadline-support.patch | 0 ...s-replace-DM_SUSPENDED-by-.DM_SUSPEN.patch | 75 ---- ...up.patch => 0013-RH-Add-mpathcleanup.patch | 0 ...ules-replace-DM_NOSCAN-by-.DM_NOSCAN.patch | 55 --- ...path.rules-simplify-PATH_FAILED-case.patch | 38 -- ...ules-make-label-names-more-intuitive.patch | 109 ------ 0017-kpartx.rules-ignore-DM_SUSPENDED.patch | 29 -- ...tests-fix-CI-failures-on-arm-v7-with.patch | 270 -------------- ...tests-fix-CI-failures-with-clang-on-.patch | 246 ------------- ...GitHub-actions-fixes-for-spelling-CI.patch | 31 -- ...-run-workflows-if-workflow-file-has-.patch | 146 -------- 0022-multipath-tools-add-TGTDIR-option.patch | 106 ------ ...ath-move-get_udev_for_mpp-to-sysfs.c.patch | 87 ----- ...ibmultipath-add-mp_find_path_by_devt.patch | 60 --- ...ath-fix-max_sectors_kb-on-adding-pat.patch | 33 -- ...y-set-max_sectors_kb-on-map-creation.patch | 122 ------ ...th-set-max_sectors_kb-in-adopt_paths.patch | 233 ------------ ...-wildcard-k-for-printing-max_sectors.patch | 89 ----- ...-update-documentation-for-max_sector.patch | 57 --- ...th-tools-simplify-comment-in-hwtable.patch | 34 -- ...tools-unify-text-in-multipath.conf.5.patch | 75 ---- ...ltipath-tools-update-man-pages-dates.patch | 86 ----- 0033-libmultipath-export-partmap_in_use.patch | 53 --- ...nge-flush_on_last_del-to-fix-a-multi.patch | 346 ------------------ ...ove-redundant-config-option-from-Inf.patch | 31 -- ...-dev_loss_tmo-to-avoid-race-with-no_.patch | 40 -- ...x-deferred_remove-function-arguments.patch | 107 ------ ...e-bitwise-flags-for-map-flushing-API.patch | 212 ----------- ...e-bitwise-flags-for-dm_simplecmd-API.patch | 117 ------ ...dd-argument-names-to-some-prototypes.patch | 34 -- 0041-libmultipath-bump-version-to-0.9.9.patch | 27 -- ...kflows-native.yaml-run-for-Fedora-40.patch | 24 -- 0043-update-NEWS.md.patch | 134 ------- ...ultipath.conf.5.in-fix-man-page-date.patch | 24 -- device-mapper-multipath.spec | 84 ++--- sources | 2 +- 60 files changed, 26 insertions(+), 3885 deletions(-) delete mode 100644 0001-11-dm-mpath.rules-fix-misspelled-DM_UDEV_DISABLE_OTH.patch rename 0045-RH-fixup-udev-rules-for-redhat.patch => 0001-RH-fixup-udev-rules-for-redhat.patch (100%) rename 0046-RH-Remove-the-property-blacklist-exception-builtin.patch => 0002-RH-Remove-the-property-blacklist-exception-builtin.patch (100%) delete mode 100644 0002-multipathd-use-condlog-level-for-setscheduler-error-.patch rename 0047-RH-don-t-start-without-a-config-file.patch => 0003-RH-don-t-start-without-a-config-file.patch (99%) delete mode 100644 0003-multipathd-make-multipathd-scheduling-configurable.patch rename 0048-RH-Fix-nvme-function-missing-argument.patch => 0004-RH-Fix-nvme-function-missing-argument.patch (100%) delete mode 100644 0004-libmpathutil-really-always-use-glibc-basename.patch rename 0049-RH-use-rpm-optflags-if-present.patch => 0005-RH-use-rpm-optflags-if-present.patch (100%) delete mode 100644 0005-multipathd-make-multipathd-set-priority-to-RLIMIT_RT.patch rename 0050-RH-add-mpathconf.patch => 0006-RH-add-mpathconf.patch (100%) delete mode 100644 0006-multipathd-Set-CPUWeight-to-1000-and-LimitRTPRIO-to-.patch delete mode 100644 0007-11-dm-mpath.rules-explain-logic-for-device-becoming-.patch rename 0051-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch => 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch (100%) delete mode 100644 0008-11-dm-mpath.rules-don-t-import-DM_NOSCAN-from-udev-d.patch rename 0052-RH-reset-default-find_mutipaths-value-to-off.patch => 0008-RH-reset-default-find_mutipaths-value-to-off.patch (100%) delete mode 100644 0009-11-dm-mpath.rules-don-t-import-ID_FS_VERSION-from-ud.patch rename 0053-RH-attempt-to-get-ANA-info-via-sysfs-first.patch => 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch (100%) delete mode 100644 0010-11-dm-mpath.rules-adapt-MPATH_DEVICE_READY-0-logic-t.patch rename 0054-RH-make-parse_vpd_pg83-match-scsi_id-output.patch => 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch (100%) delete mode 100644 0011-11-dm-mpath.rules-adapt-coldplug-event-handling-ro-1.patch rename 0055-RH-add-scsi-device-handlers-to-modules-load.d.patch => 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch (100%) delete mode 100644 0012-11-dm-mpath.rules-don-t-import-properties-with-new-1.patch rename 0056-RH-compile-with-libreadline-support.patch => 0012-RH-compile-with-libreadline-support.patch (100%) delete mode 100644 0013-11-dm-mpath.rules-replace-DM_SUSPENDED-by-.DM_SUSPEN.patch rename 0057-RH-Add-mpathcleanup.patch => 0013-RH-Add-mpathcleanup.patch (100%) delete mode 100644 0014-11-dm-mpath.rules-replace-DM_NOSCAN-by-.DM_NOSCAN.patch delete mode 100644 0015-11-dm-mpath.rules-simplify-PATH_FAILED-case.patch delete mode 100644 0016-11-dm-mpath.rules-make-label-names-more-intuitive.patch delete mode 100644 0017-kpartx.rules-ignore-DM_SUSPENDED.patch delete mode 100644 0018-multipath-tools-tests-fix-CI-failures-on-arm-v7-with.patch delete mode 100644 0019-multipath-tools-tests-fix-CI-failures-with-clang-on-.patch delete mode 100644 0020-GitHub-actions-fixes-for-spelling-CI.patch delete mode 100644 0021-GitHub-workflows-run-workflows-if-workflow-file-has-.patch delete mode 100644 0022-multipath-tools-add-TGTDIR-option.patch delete mode 100644 0023-libmultipath-move-get_udev_for_mpp-to-sysfs.c.patch delete mode 100644 0024-libmultipath-add-mp_find_path_by_devt.patch delete mode 100644 0025-Revert-libmultipath-fix-max_sectors_kb-on-adding-pat.patch delete mode 100644 0026-libmultipath-Only-set-max_sectors_kb-on-map-creation.patch delete mode 100644 0027-libmultipath-set-max_sectors_kb-in-adopt_paths.patch delete mode 100644 0028-libmultipath-add-wildcard-k-for-printing-max_sectors.patch delete mode 100644 0029-multipath.conf-5-update-documentation-for-max_sector.patch delete mode 100644 0030-multipath-tools-simplify-comment-in-hwtable.patch delete mode 100644 0031-multipath-tools-unify-text-in-multipath.conf.5.patch delete mode 100644 0032-multipath-tools-update-man-pages-dates.patch delete mode 100644 0033-libmultipath-export-partmap_in_use.patch delete mode 100644 0034-libmultipath-change-flush_on_last_del-to-fix-a-multi.patch delete mode 100644 0035-libmultipath-remove-redundant-config-option-from-Inf.patch delete mode 100644 0036-libmultipath-pad-dev_loss_tmo-to-avoid-race-with-no_.patch delete mode 100644 0037-libmultipath-fix-deferred_remove-function-arguments.patch delete mode 100644 0038-libmultipath-use-bitwise-flags-for-map-flushing-API.patch delete mode 100644 0039-libmultipath-use-bitwise-flags-for-dm_simplecmd-API.patch delete mode 100644 0040-libmultipath-add-argument-names-to-some-prototypes.patch delete mode 100644 0041-libmultipath-bump-version-to-0.9.9.patch delete mode 100644 0042-GitHub-Workflows-native.yaml-run-for-Fedora-40.patch delete mode 100644 0043-update-NEWS.md.patch delete mode 100644 0044-multipath.conf.5.in-fix-man-page-date.patch diff --git a/.gitignore b/.gitignore index 80e9936..3bea72e 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,4 @@ multipath-tools-091027.tar.gz /multipath-tools-0.9.6.tgz /multipath-tools-0.9.7.tgz /multipath-tools-0.9.8.tgz +/multipath-tools-0.9.9.tgz diff --git a/0001-11-dm-mpath.rules-fix-misspelled-DM_UDEV_DISABLE_OTH.patch b/0001-11-dm-mpath.rules-fix-misspelled-DM_UDEV_DISABLE_OTH.patch deleted file mode 100644 index 4b9d7fc..0000000 --- a/0001-11-dm-mpath.rules-fix-misspelled-DM_UDEV_DISABLE_OTH.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 1 Mar 2024 18:16:32 +0100 -Subject: [PATCH] 11-dm-mpath.rules: fix misspelled - DM_UDEV_DISABLE_OTHER_RULES_FLAG - -Fixes: b3582da ("11-dm-mpath.rules: use import logic like 13-dm-disk.rules") -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/11-dm-mpath.rules.in | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in -index d364f9bc..d9585abf 100644 ---- a/multipath/11-dm-mpath.rules.in -+++ b/multipath/11-dm-mpath.rules.in -@@ -116,7 +116,7 @@ LABEL="scan_import" - ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}!="1", GOTO="import_end" - - # Don't import the properties from db if we will run blkid later. --ENV{DM_NOSCAN}!="1", ENV{DM_DISABLE_OTHER_RULES_FLAG}!="1", GOTO="import_end" -+ENV{DM_NOSCAN}!="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}!="1", GOTO="import_end" - - IMPORT{db}="ID_FS_TYPE" - IMPORT{db}="ID_FS_USAGE" diff --git a/0045-RH-fixup-udev-rules-for-redhat.patch b/0001-RH-fixup-udev-rules-for-redhat.patch similarity index 100% rename from 0045-RH-fixup-udev-rules-for-redhat.patch rename to 0001-RH-fixup-udev-rules-for-redhat.patch diff --git a/0046-RH-Remove-the-property-blacklist-exception-builtin.patch b/0002-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 100% rename from 0046-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0002-RH-Remove-the-property-blacklist-exception-builtin.patch diff --git a/0002-multipathd-use-condlog-level-for-setscheduler-error-.patch b/0002-multipathd-use-condlog-level-for-setscheduler-error-.patch deleted file mode 100644 index 8a6ff99..0000000 --- a/0002-multipathd-use-condlog-level-for-setscheduler-error-.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 1 Mar 2024 19:37:29 -0500 -Subject: [PATCH] multipathd: use condlog level for setscheduler error message - -condlog uses its own log levels, so LOG_WARNING makes no sense. It -actually translates to a message sent at the LOG_DEBUG level. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - multipathd/main.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 6193e691..85ac540f 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -3178,7 +3178,7 @@ setscheduler (void) - res = sched_setscheduler (0, SCHED_RR, &sched_param); - - if (res == -1) -- condlog(LOG_WARNING, "Could not set SCHED_RR at priority 99"); -+ condlog(2, "Could not set SCHED_RR at priority 99"); - return; - } - diff --git a/0047-RH-don-t-start-without-a-config-file.patch b/0003-RH-don-t-start-without-a-config-file.patch similarity index 99% rename from 0047-RH-don-t-start-without-a-config-file.patch rename to 0003-RH-don-t-start-without-a-config-file.patch index ad7962a..267ffa7 100644 --- a/0047-RH-don-t-start-without-a-config-file.patch +++ b/0003-RH-don-t-start-without-a-config-file.patch @@ -99,7 +99,7 @@ index 780bf852..2c518378 100644 ENV{DEVTYPE}!="partition", GOTO="test_dev" IMPORT{parent}="DM_MULTIPATH_DEVICE_PATH" diff --git a/multipathd/multipathd.8.in b/multipathd/multipathd.8.in -index 12b77156..499557a0 100644 +index 7bc8806e..315884eb 100644 --- a/multipathd/multipathd.8.in +++ b/multipathd/multipathd.8.in @@ -49,6 +49,8 @@ map regains its maximum performance and redundancy. diff --git a/0003-multipathd-make-multipathd-scheduling-configurable.patch b/0003-multipathd-make-multipathd-scheduling-configurable.patch deleted file mode 100644 index 8529152..0000000 --- a/0003-multipathd-make-multipathd-scheduling-configurable.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 1 Mar 2024 19:37:30 -0500 -Subject: [PATCH] multipathd: make multipathd scheduling configurable - -Currently multipathd always tries to run as a realtime process with a -priority of 99. This is excessive. As a first step towards fixing this, -make it possible at compile time to lower the priority or keep -multipathd from making itself a realtime process. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - Makefile.inc | 6 ++++++ - README.md | 3 +++ - multipathd/Makefile | 3 +++ - multipathd/main.c | 5 +++-- - 4 files changed, 15 insertions(+), 2 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 5668e638..6d206281 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -18,6 +18,12 @@ READLINE := - # SCSI_DH_MODULES_PRELOAD := scsi_dh_alua scsi_dh_rdac - SCSI_DH_MODULES_PRELOAD := - -+# Multipathd scheduling priority. Set value from 1 to 99 to make multipathd -+# change its scheduling policy to SCHED_RR and its priority to the specified -+# value. set to 0 to stop multipathd from changing the scheduling policy and -+# priority it was started with. -+SCHED_RT_PRIO := 99 -+ - EXTRAVERSION := $(shell rev=$$(git rev-parse --short=7 HEAD 2>/dev/null); echo $${rev:+-g$$rev}) - - # PKG_CONFIG must be read from the environment to enable compilation -diff --git a/README.md b/README.md -index d4f35f57..bb41bf0e 100644 ---- a/README.md -+++ b/README.md -@@ -98,6 +98,9 @@ The following variables can be passed to the `make` command line: - By default, command line editing is disabled. - Note that using libreadline may - [make binary indistributable due to license incompatibility](https://github.com/opensvc/multipath-tools/issues/36). -+ * `SCHED_RT_PRIO={0-99}`: for values {1-99} set the realtime priority -+ multipathd will attempt to run with. for value 0, disable multipathd -+ changing itself to a realtime process. - * `ENABLE_LIBDMMP=0`: disable building libdmmp - * `ENABLE_DMEVENTS_POLL=0`: disable support for the device-mapper event - polling API. For use with pre-5.0 kernels that don't support dmevent polling -diff --git a/multipathd/Makefile b/multipathd/Makefile -index 997b40cf..7300f07a 100644 ---- a/multipathd/Makefile -+++ b/multipathd/Makefile -@@ -57,6 +57,9 @@ $(CLI): $(CLI_OBJS) - cli_handlers.o: cli_handlers.c - $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-parameter -c -o $@ $< - -+main.o: main.c -+ $(Q)$(CC) $(CPPFLAGS) -DSCHED_RT_PRIO=$(SCHED_RT_PRIO) $(CFLAGS) -c -o $@ $< -+ - install: - $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) - $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir) -diff --git a/multipathd/main.c b/multipathd/main.c -index 85ac540f..9486a8a3 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -3172,7 +3172,7 @@ setscheduler (void) - { - int res; - static struct sched_param sched_param = { -- .sched_priority = 99 -+ .sched_priority = SCHED_RT_PRIO - }; - - res = sched_setscheduler (0, SCHED_RR, &sched_param); -@@ -3471,7 +3471,8 @@ child (__attribute__((unused)) void *param) - if (!vecs) - goto failed; - -- setscheduler(); -+ if (SCHED_RT_PRIO) -+ setscheduler(); - set_oom_adj(); - #ifdef FPIN_EVENT_HANDLER - if (conf->marginal_pathgroups == MARGINAL_PATHGROUP_FPIN) diff --git a/0048-RH-Fix-nvme-function-missing-argument.patch b/0004-RH-Fix-nvme-function-missing-argument.patch similarity index 100% rename from 0048-RH-Fix-nvme-function-missing-argument.patch rename to 0004-RH-Fix-nvme-function-missing-argument.patch diff --git a/0004-libmpathutil-really-always-use-glibc-basename.patch b/0004-libmpathutil-really-always-use-glibc-basename.patch deleted file mode 100644 index 78f8859..0000000 --- a/0004-libmpathutil-really-always-use-glibc-basename.patch +++ /dev/null @@ -1,144 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 3 Apr 2024 18:55:54 +0200 -Subject: [PATCH] libmpathutil: really always use glibc basename() - -Despite 03a5456 ("libmultipath: always use glibc basename()"), we -still call the system library's basename() from libmultipath. -musl libc until 1.24 provided a prototype for basename() in string.h, -which was not correct and was resolved to the destructive POSIX -basename(). musl libc 1.25 removed this prototype. - -While the remaining code path doesn't strictly depend on the non-destructive -behavior of glibc's basename(), it's cleaner and safer to use the same -implementation everywhere. - -Fixes: 03a5456 ("libmultipath: always use glibc basename()") -Fixes: https://github.com/opensvc/multipath-tools/pull/84 - -Signed-off-by: Martin Wilck -Reviewed-by: Khem Raj -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmpathutil/libmpathutil.version | 4 ++++ - libmpathutil/util.c | 5 +---- - libmpathutil/util.h | 5 +++++ - tests/util.c | 31 +++++++++++++++++++++++++++++++ - 4 files changed, 41 insertions(+), 4 deletions(-) - -diff --git a/libmpathutil/libmpathutil.version b/libmpathutil/libmpathutil.version -index 80d64a3e..fee74a32 100644 ---- a/libmpathutil/libmpathutil.version -+++ b/libmpathutil/libmpathutil.version -@@ -129,3 +129,7 @@ LIBMPATHUTIL_2.0 { - vector_move_up; - vector_sort; - }; -+ -+LIBMPATHUTIL_2.1 { -+ libmp_basename; -+}; -diff --git a/libmpathutil/util.c b/libmpathutil/util.c -index 9d147fca..23d303f9 100644 ---- a/libmpathutil/util.c -+++ b/libmpathutil/util.c -@@ -32,18 +32,15 @@ strchop(char *str) - return i; - } - --#ifndef __GLIBC__ - /* - * glibc's non-destructive version of basename() - * License: LGPL-2.1-or-later - */ --static const char *__basename(const char *filename) -+const char *libmp_basename(const char *filename) - { - char *p = strrchr(filename, '/'); - return p ? p + 1 : filename; - } --#define basename(x) __basename(x) --#endif - - int - basenamecpy (const char *src, char *dst, size_t size) -diff --git a/libmpathutil/util.h b/libmpathutil/util.h -index de9fcfdd..4997fed6 100644 ---- a/libmpathutil/util.h -+++ b/libmpathutil/util.h -@@ -12,6 +12,11 @@ - #include - - size_t strchop(char *); -+ -+const char *libmp_basename(const char *filename); -+#ifndef __GLIBC__ -+#define basename(x) libmp_basename(x) -+#endif - int basenamecpy (const char *src, char *dst, size_t size); - int filepresent (const char *run); - char *get_next_string(char **temp, const char *split_char); -diff --git a/tests/util.c b/tests/util.c -index d6083dce..4850ddcb 100644 ---- a/tests/util.c -+++ b/tests/util.c -@@ -16,6 +16,7 @@ - * - */ - -+#define _GNU_SOURCE - #include - #include - #include -@@ -23,6 +24,7 @@ - #include - #include - #include -+#include - #include "util.h" - - #include "globals.c" -@@ -163,6 +165,34 @@ static int test_basenamecpy(void) - return cmocka_run_group_tests(tests, NULL, NULL); - } - -+static void test_basename_01(void **state) -+{ -+ const char *path = "/foo/bar"; -+ const char *base; -+ -+ base = basename(path); -+ assert_string_equal(base, "bar"); -+ assert_string_equal(path, "/foo/bar"); -+} -+ -+static void test_basename_02(void **state) -+{ -+ const char *path = "/foo/bar/"; -+ const char *base; -+ -+ base = basename(path); -+ assert_string_equal(base, ""); -+ assert_string_equal(path, "/foo/bar/"); -+} -+ -+static int test_basename(void) { -+ const struct CMUnitTest tests[] = { -+ cmocka_unit_test(test_basename_01), -+ cmocka_unit_test(test_basename_02), -+ }; -+ return cmocka_run_group_tests(tests, NULL, NULL); -+} -+ - /* - * On big endian systems, if bitfield_t is 32bit, we need - * to swap the two 32 bit parts of a 64bit value to make -@@ -946,6 +976,7 @@ int main(void) - - init_test_verbosity(-1); - ret += test_basenamecpy(); -+ ret += test_basename(); - ret += test_bitmasks(); - ret += test_strlcpy(); - ret += test_strlcat(); diff --git a/0049-RH-use-rpm-optflags-if-present.patch b/0005-RH-use-rpm-optflags-if-present.patch similarity index 100% rename from 0049-RH-use-rpm-optflags-if-present.patch rename to 0005-RH-use-rpm-optflags-if-present.patch diff --git a/0005-multipathd-make-multipathd-set-priority-to-RLIMIT_RT.patch b/0005-multipathd-make-multipathd-set-priority-to-RLIMIT_RT.patch deleted file mode 100644 index fd12767..0000000 --- a/0005-multipathd-make-multipathd-set-priority-to-RLIMIT_RT.patch +++ /dev/null @@ -1,134 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 9 Apr 2024 18:56:12 -0400 -Subject: [PATCH] multipathd: make multipathd set priority to RLIMIT_RTPRIO - -With this change, if the SCHED_RT_PRIO compiler flag has been removed. -Instead multipathd will call getrlimit(RLIMIT_RTPRIO, ...) and look at -the hard limit. It it's 0, multipath will do nothing. Otherwise it will -change its scheduling policy to SCHED_RR and its priority to the hard -limit. - -This allows users to change the priority of that multipathd runs with by -adding - -LimitRTPRIO= - -to the [Service] section of the multipathd.service unit file. Setting -LimitRTPRIO=0 will make multipathd run as a normal process, while -setting LimitRTPRIO=infinity will make it use the maximum SCHED_RR prio, -which is 99. - -To keep the existing behavior, multipathd.service now sets -LimitRTPRIO=infinity - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - Makefile.inc | 6 ------ - README.md | 3 --- - multipathd/Makefile | 3 --- - multipathd/main.c | 22 +++++++++++++++------- - multipathd/multipathd.service.in | 1 + - 5 files changed, 16 insertions(+), 19 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 6d206281..5668e638 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -18,12 +18,6 @@ READLINE := - # SCSI_DH_MODULES_PRELOAD := scsi_dh_alua scsi_dh_rdac - SCSI_DH_MODULES_PRELOAD := - --# Multipathd scheduling priority. Set value from 1 to 99 to make multipathd --# change its scheduling policy to SCHED_RR and its priority to the specified --# value. set to 0 to stop multipathd from changing the scheduling policy and --# priority it was started with. --SCHED_RT_PRIO := 99 -- - EXTRAVERSION := $(shell rev=$$(git rev-parse --short=7 HEAD 2>/dev/null); echo $${rev:+-g$$rev}) - - # PKG_CONFIG must be read from the environment to enable compilation -diff --git a/README.md b/README.md -index bb41bf0e..d4f35f57 100644 ---- a/README.md -+++ b/README.md -@@ -98,9 +98,6 @@ The following variables can be passed to the `make` command line: - By default, command line editing is disabled. - Note that using libreadline may - [make binary indistributable due to license incompatibility](https://github.com/opensvc/multipath-tools/issues/36). -- * `SCHED_RT_PRIO={0-99}`: for values {1-99} set the realtime priority -- multipathd will attempt to run with. for value 0, disable multipathd -- changing itself to a realtime process. - * `ENABLE_LIBDMMP=0`: disable building libdmmp - * `ENABLE_DMEVENTS_POLL=0`: disable support for the device-mapper event - polling API. For use with pre-5.0 kernels that don't support dmevent polling -diff --git a/multipathd/Makefile b/multipathd/Makefile -index 7300f07a..997b40cf 100644 ---- a/multipathd/Makefile -+++ b/multipathd/Makefile -@@ -57,9 +57,6 @@ $(CLI): $(CLI_OBJS) - cli_handlers.o: cli_handlers.c - $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-parameter -c -o $@ $< - --main.o: main.c -- $(Q)$(CC) $(CPPFLAGS) -DSCHED_RT_PRIO=$(SCHED_RT_PRIO) $(CFLAGS) -c -o $@ $< -- - install: - $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) - $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir) -diff --git a/multipathd/main.c b/multipathd/main.c -index 9486a8a3..dd17d5c3 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -3171,14 +3171,23 @@ static void - setscheduler (void) - { - int res; -- static struct sched_param sched_param = { -- .sched_priority = SCHED_RT_PRIO -- }; -+ static struct sched_param sched_param; -+ struct rlimit rlim; -+ -+ if (getrlimit(RLIMIT_RTPRIO, &rlim) < 0 || rlim.rlim_max == 0) -+ return; -+ -+ sched_param.sched_priority = rlim.rlim_max > INT_MAX ? INT_MAX : -+ rlim.rlim_max; -+ res = sched_get_priority_max(SCHED_RR); -+ if (res > 0 && res < sched_param.sched_priority) -+ sched_param.sched_priority = res; - -- res = sched_setscheduler (0, SCHED_RR, &sched_param); -+ res = sched_setscheduler(0, SCHED_RR, &sched_param); - - if (res == -1) -- condlog(2, "Could not set SCHED_RR at priority 99"); -+ condlog(2, "Could not set SCHED_RR at priority %d", -+ sched_param.sched_priority); - return; - } - -@@ -3471,8 +3480,7 @@ child (__attribute__((unused)) void *param) - if (!vecs) - goto failed; - -- if (SCHED_RT_PRIO) -- setscheduler(); -+ setscheduler(); - set_oom_adj(); - #ifdef FPIN_EVENT_HANDLER - if (conf->marginal_pathgroups == MARGINAL_PATHGROUP_FPIN) -diff --git a/multipathd/multipathd.service.in b/multipathd/multipathd.service.in -index 6d03ff71..18bb367e 100644 ---- a/multipathd/multipathd.service.in -+++ b/multipathd/multipathd.service.in -@@ -19,6 +19,7 @@ NotifyAccess=main - ExecStart=/sbin/multipathd -d -s - ExecReload=/sbin/multipathd reconfigure - TasksMax=infinity -+LimitRTPRIO=infinity - - [Install] - WantedBy=sysinit.target diff --git a/0050-RH-add-mpathconf.patch b/0006-RH-add-mpathconf.patch similarity index 100% rename from 0050-RH-add-mpathconf.patch rename to 0006-RH-add-mpathconf.patch diff --git a/0006-multipathd-Set-CPUWeight-to-1000-and-LimitRTPRIO-to-.patch b/0006-multipathd-Set-CPUWeight-to-1000-and-LimitRTPRIO-to-.patch deleted file mode 100644 index 0cbe997..0000000 --- a/0006-multipathd-Set-CPUWeight-to-1000-and-LimitRTPRIO-to-.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 15 Apr 2024 19:43:06 -0400 -Subject: [PATCH] multipathd: Set CPUWeight to 1000 and LimitRTPRIO to 10 - -If multipathd doesn't become a real time process, it was scheduled as a -normal process, without any priority increase. Bump up the CPUWeight so -that even as a normal process, it will still run with increased -priority. - -If multipathd did become a real time process, it set itself to the -highest priority, which is excessive. A priority of 10 is plenty. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - multipathd/multipathd.service.in | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/multipathd/multipathd.service.in b/multipathd/multipathd.service.in -index 18bb367e..a63ddd9a 100644 ---- a/multipathd/multipathd.service.in -+++ b/multipathd/multipathd.service.in -@@ -19,7 +19,8 @@ NotifyAccess=main - ExecStart=/sbin/multipathd -d -s - ExecReload=/sbin/multipathd reconfigure - TasksMax=infinity --LimitRTPRIO=infinity -+LimitRTPRIO=10 -+CPUWeight=1000 - - [Install] - WantedBy=sysinit.target diff --git a/0007-11-dm-mpath.rules-explain-logic-for-device-becoming-.patch b/0007-11-dm-mpath.rules-explain-logic-for-device-becoming-.patch deleted file mode 100644 index 6241459..0000000 --- a/0007-11-dm-mpath.rules-explain-logic-for-device-becoming-.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 1 Mar 2024 19:53:14 +0100 -Subject: [PATCH] 11-dm-mpath.rules: explain logic for device becoming ready - while suspended - -Add a comment to explain why we must set MPATH_DEVICE_READY=0 when -we see a device becoming ready (number of active paths 0 -> 1) while -the device is suspended. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/11-dm-mpath.rules.in | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in -index d9585abf..b8d19d01 100644 ---- a/multipath/11-dm-mpath.rules.in -+++ b/multipath/11-dm-mpath.rules.in -@@ -98,6 +98,8 @@ ENV{MPATH_DEVICE_READY}=="0", \ - # If the device comes back online, set DM_ACTIVATION so that - # upper layers do a rescan. If the device is currently suspended, - # we have to postpone the activation until the next event. -+# In this case, we have to set MPATH_DEVICE_READY=0; otherwise, the -+# MPATH_UNCHANGED logic will cause later rules to skipped in the next event. - ENV{MPATH_DEVICE_READY}=="0", GOTO="dont_activate" - ENV{.MPATH_DEVICE_READY_OLD}!="0", GOTO="dont_activate" - ENV{DM_SUSPENDED}=="1", ENV{MPATH_DEVICE_READY}="0", GOTO="dont_activate" diff --git a/0051-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 100% rename from 0051-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch diff --git a/0008-11-dm-mpath.rules-don-t-import-DM_NOSCAN-from-udev-d.patch b/0008-11-dm-mpath.rules-don-t-import-DM_NOSCAN-from-udev-d.patch deleted file mode 100644 index 3900b39..0000000 --- a/0008-11-dm-mpath.rules-don-t-import-DM_NOSCAN-from-udev-d.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 1 Mar 2024 19:57:59 +0100 -Subject: [PATCH] 11-dm-mpath.rules: don't import DM_NOSCAN from udev db - -DM_NOSCAN is our "output" flag for 13-dm-disk.rules, and it should -be treated the same way as DM_UDEV_DISABLE_OTHER_RULES_FLAG, which -isn't imported from the udev database. The state that we need to -remember is MPATH_DEVICE_READY, which we've already imported above, -and we will set the "output" flags accordingly in the "force_activation" -code path further down. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/11-dm-mpath.rules.in | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in -index b8d19d01..eb12b0c6 100644 ---- a/multipath/11-dm-mpath.rules.in -+++ b/multipath/11-dm-mpath.rules.in -@@ -18,9 +18,11 @@ ACTION=="add", ENV{DM_ACTIVATION}=="1", ENV{DM_SUSPENDED}!="1", ENV{DISK_RO}!="1 - - # If this uevent didn't come from dm, don't try to update the - # device state -+# Note that .MPATH_DEVICE_READY_OLD=="" here. Thus we won't activate the -+# device below at force_activation, which is correct. - ENV{DM_COOKIE}!="?*", ENV{DM_ACTION}!="PATH_*", \ -- IMPORT{db}="DM_NOSCAN", IMPORT{db}="DM_COLDPLUG_SUSPENDED", \ -- GOTO="scan_import" -+ IMPORT{db}="DM_COLDPLUG_SUSPENDED", \ -+ GOTO="force_activation" - - ENV{.MPATH_DEVICE_READY_OLD}="$env{MPATH_DEVICE_READY}" - diff --git a/0052-RH-reset-default-find_mutipaths-value-to-off.patch b/0008-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 100% rename from 0052-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0008-RH-reset-default-find_mutipaths-value-to-off.patch diff --git a/0009-11-dm-mpath.rules-don-t-import-ID_FS_VERSION-from-ud.patch b/0009-11-dm-mpath.rules-don-t-import-ID_FS_VERSION-from-ud.patch deleted file mode 100644 index 933a43a..0000000 --- a/0009-11-dm-mpath.rules-don-t-import-ID_FS_VERSION-from-ud.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 1 Mar 2024 21:02:49 +0100 -Subject: [PATCH] 11-dm-mpath.rules: don't import ID_FS_VERSION from udev db - -Use the same set of properties to import as 13-dm-disk.rules. -ID_FS_VERSION isn't used in any udev rule I am aware of. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/11-dm-mpath.rules.in | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in -index eb12b0c6..4386b6ca 100644 ---- a/multipath/11-dm-mpath.rules.in -+++ b/multipath/11-dm-mpath.rules.in -@@ -126,7 +126,6 @@ IMPORT{db}="ID_FS_TYPE" - IMPORT{db}="ID_FS_USAGE" - IMPORT{db}="ID_FS_UUID_ENC" - IMPORT{db}="ID_FS_LABEL_ENC" --IMPORT{db}="ID_FS_VERSION" - IMPORT{db}="ID_PART_ENTRY_NAME" - IMPORT{db}="ID_PART_ENTRY_UUID" - IMPORT{db}="ID_PART_ENTRY_SCHEME" diff --git a/0053-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 100% rename from 0053-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch diff --git a/0010-11-dm-mpath.rules-adapt-MPATH_DEVICE_READY-0-logic-t.patch b/0010-11-dm-mpath.rules-adapt-MPATH_DEVICE_READY-0-logic-t.patch deleted file mode 100644 index 97b3901..0000000 --- a/0010-11-dm-mpath.rules-adapt-MPATH_DEVICE_READY-0-logic-t.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 1 Mar 2024 20:53:50 +0100 -Subject: [PATCH] 11-dm-mpath.rules: adapt MPATH_DEVICE_READY=0 logic to - 10-dm.rules update - -With the late patches for 10-dm.rules, DM_UDEV_DISABLE_OTHER_RULES_FLAG isn't -restored from the udev database any more, so we don't need to restore -the flag to its original state before it is saved to the db. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/11-dm-mpath.rules.in | 22 ++++++++++++---------- - 1 file changed, 12 insertions(+), 10 deletions(-) - -diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in -index 4386b6ca..2f909c3a 100644 ---- a/multipath/11-dm-mpath.rules.in -+++ b/multipath/11-dm-mpath.rules.in -@@ -19,7 +19,7 @@ ACTION=="add", ENV{DM_ACTIVATION}=="1", ENV{DM_SUSPENDED}!="1", ENV{DISK_RO}!="1 - # If this uevent didn't come from dm, don't try to update the - # device state - # Note that .MPATH_DEVICE_READY_OLD=="" here. Thus we won't activate the --# device below at force_activation, which is correct. -+# device below at mpath_is_ready, which is correct. - ENV{DM_COOKIE}!="?*", ENV{DM_ACTION}!="PATH_*", \ - IMPORT{db}="DM_COLDPLUG_SUSPENDED", \ - GOTO="force_activation" -@@ -84,25 +84,27 @@ ENV{DM_ACTION}=="PATH_FAILED|PATH_REINSTATED", \ - - LABEL="force_activation" - -+ENV{MPATH_DEVICE_READY}!="0", GOTO="mpath_is_ready" - # Do not initiate scanning if no path is available, - # otherwise there would be a hang or IO error on access. - # We'd like to avoid this, especially within udev processing. --ENV{MPATH_DEVICE_READY}=="0", ENV{DM_NOSCAN}="1" -- --# Skip all foreign rules if no path is available. -+# This is communicated to later rules in DM_NOSCAN. -+# Likewise, skip all foreign rules if no path is available. - # Use DM_UDEV_DISABLE_OTHER_RULES_FLAG to communicate this --# to upper layers. The original value will be restored in a late --# udev rule. --ENV{MPATH_DEVICE_READY}=="0", \ -- ENV{.MPATH_SAVE_DISABLE_OTHER_RULES_FLAG}="$env{DM_UDEV_DISABLE_OTHER_RULES_FLAG}", \ -- ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1" -+# to upper layers. With dm rules < v3, save the original value here; -+# it will be restored in a late udev rule. -+ENV{DM_UDEV_RULES_VSN}=="1|2", \ -+ ENV{.MPATH_SAVE_DISABLE_OTHER_RULES_FLAG}="$env{DM_UDEV_DISABLE_OTHER_RULES_FLAG}" -+ENV{DM_NOSCAN}="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1" -+GOTO="dont_activate" -+ -+LABEL="mpath_is_ready" - - # If the device comes back online, set DM_ACTIVATION so that - # upper layers do a rescan. If the device is currently suspended, - # we have to postpone the activation until the next event. - # In this case, we have to set MPATH_DEVICE_READY=0; otherwise, the - # MPATH_UNCHANGED logic will cause later rules to skipped in the next event. --ENV{MPATH_DEVICE_READY}=="0", GOTO="dont_activate" - ENV{.MPATH_DEVICE_READY_OLD}!="0", GOTO="dont_activate" - ENV{DM_SUSPENDED}=="1", ENV{MPATH_DEVICE_READY}="0", GOTO="dont_activate" - diff --git a/0054-RH-make-parse_vpd_pg83-match-scsi_id-output.patch b/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch similarity index 100% rename from 0054-RH-make-parse_vpd_pg83-match-scsi_id-output.patch rename to 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch diff --git a/0011-11-dm-mpath.rules-adapt-coldplug-event-handling-ro-1.patch b/0011-11-dm-mpath.rules-adapt-coldplug-event-handling-ro-1.patch deleted file mode 100644 index 938a07f..0000000 --- a/0011-11-dm-mpath.rules-adapt-coldplug-event-handling-ro-1.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 1 Mar 2024 20:55:40 +0100 -Subject: [PATCH] 11-dm-mpath.rules: adapt coldplug event handling ro - 10-dm.rules update - -With late late patches for 10-dm.rules, DM_UDEV_DISABLE_OTHER_RULES_FLAG is -never restored from the udev db. Thus we don't need to clear it here -any more for coldplug events. Also, we must use .DM_SUSPENDED instead of -DM_SUSPENDED as input flag with the v3 rule set (other occurences of -DM_SUSPENDED will be replaced in a follow-up patch). - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/11-dm-mpath.rules.in | 9 +++++++-- - 1 file changed, 7 insertions(+), 2 deletions(-) - -diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in -index 2f909c3a..5f547cab 100644 ---- a/multipath/11-dm-mpath.rules.in -+++ b/multipath/11-dm-mpath.rules.in -@@ -9,12 +9,17 @@ ACTION=="add", ENV{DM_ACTIVATION}=="1", ENV{DM_SUSPENDED}=="1", \ - PROGRAM="/bin/logger -t 11-dm-mpath.rules -p daemon.warning \"Coldplug event for suspended device\"", \ - ENV{DM_COLDPLUG_SUSPENDED}="1", GOTO="scan_import" - --# Coldplug event. DM_UDEV_DISABLE_OTHER_RULES_FLAG has been restored -+# Coldplug event. Import previously set properties. -+ACTION!="add", GOTO="mpath_coldplug_end" -+ENV{DM_ACTIVATION}!="1", GOTO="mpath_coldplug_end" -+ENV{DM_UDEV_RULES_VSN}!="1|2", ENV{.DM_SUSPENDED}!="1", GOTO="scan_import" -+# With DM rules < v3, DM_UDEV_DISABLE_OTHER_RULES_FLAG has been restored - # from DB in 10-dm.rules. If the device is not suspended, clear the flag. - # This is safe for multipath where DM_UDEV_DISABLE_OTHER_RULES_FLAG is basically - # equivalent to DM_SUSPENDED==1 || DISK_RO==1 --ACTION=="add", ENV{DM_ACTIVATION}=="1", ENV{DM_SUSPENDED}!="1", ENV{DISK_RO}!="1", \ -+ENV{DM_UDEV_RULES_VSN}=="1|2", ENV{DM_SUSPENDED}!="1", ENV{DISK_RO}!="1", \ - ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="", GOTO="scan_import" -+LABEL="mpath_coldplug_end" - - # If this uevent didn't come from dm, don't try to update the - # device state diff --git a/0055-RH-add-scsi-device-handlers-to-modules-load.d.patch b/0011-RH-add-scsi-device-handlers-to-modules-load.d.patch similarity index 100% rename from 0055-RH-add-scsi-device-handlers-to-modules-load.d.patch rename to 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch diff --git a/0012-11-dm-mpath.rules-don-t-import-properties-with-new-1.patch b/0012-11-dm-mpath.rules-don-t-import-properties-with-new-1.patch deleted file mode 100644 index f4e69cf..0000000 --- a/0012-11-dm-mpath.rules-don-t-import-properties-with-new-1.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 1 Mar 2024 20:58:47 +0100 -Subject: [PATCH] 11-dm-mpath.rules: don't import properties with new - 13-dm-disk.rules - -With the late changes to 13-dm-disk.rules, we don't need to import any -blkid-generated properties from the udev database, because they will -be imported later. - -Except for ID_FS_TYPE, this actually holds since lvm2 commit 94f77a4 ("udev: -import previous results of blkid when in suspended state"), included in lvm2 -2.03.19, but we have no simple way to detect the version of the lvm2 rules. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/11-dm-mpath.rules.in | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in -index 5f547cab..95126bf2 100644 ---- a/multipath/11-dm-mpath.rules.in -+++ b/multipath/11-dm-mpath.rules.in -@@ -126,6 +126,10 @@ LABEL="scan_import" - # have never been properly set. Don't import them. - ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}!="1", GOTO="import_end" - -+# DM rules v3 will import missing properties on 13-dm-disk.rules. -+# No need to do it here. -+ENV{DM_UDEV_RULES_VSN}!="1|2", GOTO="import_end" -+ - # Don't import the properties from db if we will run blkid later. - ENV{DM_NOSCAN}!="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}!="1", GOTO="import_end" - diff --git a/0056-RH-compile-with-libreadline-support.patch b/0012-RH-compile-with-libreadline-support.patch similarity index 100% rename from 0056-RH-compile-with-libreadline-support.patch rename to 0012-RH-compile-with-libreadline-support.patch diff --git a/0013-11-dm-mpath.rules-replace-DM_SUSPENDED-by-.DM_SUSPEN.patch b/0013-11-dm-mpath.rules-replace-DM_SUSPENDED-by-.DM_SUSPEN.patch deleted file mode 100644 index e922427..0000000 --- a/0013-11-dm-mpath.rules-replace-DM_SUSPENDED-by-.DM_SUSPEN.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 1 Mar 2024 22:33:59 +0100 -Subject: [PATCH] 11-dm-mpath.rules: replace DM_SUSPENDED by .DM_SUSPENDED - -With the late changes to the device mapper rules, DM_SUSPENDED -is not exported any more. Use .DM_SUSPENDED instead. - -Note that although 11-dm-mpath.rules is not a part of lvm2, it -can be considered as part of the device-mapper layer (everything -before 13-dm-disk.rules can), and is thus allowed to use -.DM_SUSPENDED. In practice .DM_SUSPENDED is equivalent to -DM_UDEV_DISABLE_OTHER_RULES_FLAG for multipath devices, but -using .DM_SUSPENDED here makes the intention more obvious. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/11-dm-mpath.rules.in | 13 ++++++++----- - 1 file changed, 8 insertions(+), 5 deletions(-) - -diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in -index 95126bf2..efc6416f 100644 ---- a/multipath/11-dm-mpath.rules.in -+++ b/multipath/11-dm-mpath.rules.in -@@ -4,8 +4,11 @@ ENV{DM_UUID}!="mpath-?*", GOTO="mpath_end" - - IMPORT{db}="MPATH_DEVICE_READY" - -+# device-mapper rules v2 compatibility -+ENV{.DM_SUSPENDED}!="?*", ENV{.DM_SUSPENDED}="$env{DM_SUSPENDED}" -+ - # Coldplug event while device is suspended (e.g. during a reload) --ACTION=="add", ENV{DM_ACTIVATION}=="1", ENV{DM_SUSPENDED}=="1", \ -+ACTION=="add", ENV{DM_ACTIVATION}=="1", ENV{.DM_SUSPENDED}=="1", \ - PROGRAM="/bin/logger -t 11-dm-mpath.rules -p daemon.warning \"Coldplug event for suspended device\"", \ - ENV{DM_COLDPLUG_SUSPENDED}="1", GOTO="scan_import" - -@@ -17,7 +20,7 @@ ENV{DM_UDEV_RULES_VSN}!="1|2", ENV{.DM_SUSPENDED}!="1", GOTO="scan_import" - # from DB in 10-dm.rules. If the device is not suspended, clear the flag. - # This is safe for multipath where DM_UDEV_DISABLE_OTHER_RULES_FLAG is basically - # equivalent to DM_SUSPENDED==1 || DISK_RO==1 --ENV{DM_UDEV_RULES_VSN}=="1|2", ENV{DM_SUSPENDED}!="1", ENV{DISK_RO}!="1", \ -+ENV{DM_UDEV_RULES_VSN}=="1|2", ENV{.DM_SUSPENDED}!="1", ENV{DISK_RO}!="1", \ - ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="", GOTO="scan_import" - LABEL="mpath_coldplug_end" - -@@ -68,7 +71,7 @@ LABEL="mpath_action" - # Activation might have been partially skipped. Activate the device now, - # i.e. disable the MPATH_UNCHANGED logic and set DM_ACTIVATION=1. - IMPORT{db}="DM_COLDPLUG_SUSPENDED" --ENV{DM_COLDPLUG_SUSPENDED}=="1", ENV{DM_SUSPENDED}!="1", \ -+ENV{DM_COLDPLUG_SUSPENDED}=="1", ENV{.DM_SUSPENDED}!="1", \ - ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0", \ - PROGRAM="/bin/logger -t 11-dm-mpath.rules -p daemon.notice \"Forcing activation of previously suspended device\"", \ - GOTO="force_activation" -@@ -111,7 +114,7 @@ LABEL="mpath_is_ready" - # In this case, we have to set MPATH_DEVICE_READY=0; otherwise, the - # MPATH_UNCHANGED logic will cause later rules to skipped in the next event. - ENV{.MPATH_DEVICE_READY_OLD}!="0", GOTO="dont_activate" --ENV{DM_SUSPENDED}=="1", ENV{MPATH_DEVICE_READY}="0", GOTO="dont_activate" -+ENV{.DM_SUSPENDED}=="1", ENV{MPATH_DEVICE_READY}="0", GOTO="dont_activate" - - ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0" - LABEL="dont_activate" -@@ -145,7 +148,7 @@ IMPORT{db}="ID_PART_GPT_AUTO_ROOT" - LABEL="import_end" - - # Reset previous DM_COLDPLUG_SUSPENDED if activation happens now --ENV{DM_SUSPENDED}!="1", ENV{DM_ACTIVATION}=="1", ENV{DM_COLDPLUG_SUSPENDED}="" -+ENV{.DM_SUSPENDED}!="1", ENV{DM_ACTIVATION}=="1", ENV{DM_COLDPLUG_SUSPENDED}="" - - # Multipath maps should take precedence over their members. - ENV{DM_UDEV_LOW_PRIORITY_FLAG}!="1", OPTIONS+="link_priority=50" diff --git a/0057-RH-Add-mpathcleanup.patch b/0013-RH-Add-mpathcleanup.patch similarity index 100% rename from 0057-RH-Add-mpathcleanup.patch rename to 0013-RH-Add-mpathcleanup.patch diff --git a/0014-11-dm-mpath.rules-replace-DM_NOSCAN-by-.DM_NOSCAN.patch b/0014-11-dm-mpath.rules-replace-DM_NOSCAN-by-.DM_NOSCAN.patch deleted file mode 100644 index a5eecaf..0000000 --- a/0014-11-dm-mpath.rules-replace-DM_NOSCAN-by-.DM_NOSCAN.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 1 Mar 2024 23:23:53 +0100 -Subject: [PATCH] 11-dm-mpath.rules: replace DM_NOSCAN by .DM_NOSCAN - -We don't need to restore DM_NOSCAN from the db anymore, so we can rename -it to .DM_NOSCAN, making it a temporary property. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/11-dm-mpath.rules.in | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - -diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in -index efc6416f..3ae3c054 100644 ---- a/multipath/11-dm-mpath.rules.in -+++ b/multipath/11-dm-mpath.rules.in -@@ -96,14 +96,14 @@ ENV{MPATH_DEVICE_READY}!="0", GOTO="mpath_is_ready" - # Do not initiate scanning if no path is available, - # otherwise there would be a hang or IO error on access. - # We'd like to avoid this, especially within udev processing. --# This is communicated to later rules in DM_NOSCAN. -+# This is communicated to later rules in .DM_NOSCAN. - # Likewise, skip all foreign rules if no path is available. - # Use DM_UDEV_DISABLE_OTHER_RULES_FLAG to communicate this - # to upper layers. With dm rules < v3, save the original value here; - # it will be restored in a late udev rule. - ENV{DM_UDEV_RULES_VSN}=="1|2", \ - ENV{.MPATH_SAVE_DISABLE_OTHER_RULES_FLAG}="$env{DM_UDEV_DISABLE_OTHER_RULES_FLAG}" --ENV{DM_NOSCAN}="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1" -+ENV{.DM_NOSCAN}="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1" - GOTO="dont_activate" - - LABEL="mpath_is_ready" -@@ -134,7 +134,7 @@ ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}!="1", GOTO="import_end" - ENV{DM_UDEV_RULES_VSN}!="1|2", GOTO="import_end" - - # Don't import the properties from db if we will run blkid later. --ENV{DM_NOSCAN}!="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}!="1", GOTO="import_end" -+ENV{.DM_NOSCAN}!="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}!="1", GOTO="import_end" - - IMPORT{db}="ID_FS_TYPE" - IMPORT{db}="ID_FS_USAGE" -@@ -150,6 +150,9 @@ LABEL="import_end" - # Reset previous DM_COLDPLUG_SUSPENDED if activation happens now - ENV{.DM_SUSPENDED}!="1", ENV{DM_ACTIVATION}=="1", ENV{DM_COLDPLUG_SUSPENDED}="" - -+# device-mapper rules v2 compatibility for 13-dm-disk.rules -+ENV{DM_UDEV_RULES_VSN}=="1|2", ENV{DM_NOSCAN}="$env{.DM_NOSCAN}" -+ - # Multipath maps should take precedence over their members. - ENV{DM_UDEV_LOW_PRIORITY_FLAG}!="1", OPTIONS+="link_priority=50" - diff --git a/0015-11-dm-mpath.rules-simplify-PATH_FAILED-case.patch b/0015-11-dm-mpath.rules-simplify-PATH_FAILED-case.patch deleted file mode 100644 index ce393ae..0000000 --- a/0015-11-dm-mpath.rules-simplify-PATH_FAILED-case.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 6 Mar 2024 21:17:51 +0100 -Subject: [PATCH] 11-dm-mpath.rules: simplify PATH_FAILED case - -This combination of a GOTO and a simple rule can be combined -into a single rule. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/11-dm-mpath.rules.in | 12 ++++-------- - 1 file changed, 4 insertions(+), 8 deletions(-) - -diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in -index 3ae3c054..4777fbec 100644 ---- a/multipath/11-dm-mpath.rules.in -+++ b/multipath/11-dm-mpath.rules.in -@@ -56,14 +56,10 @@ PROGRAM=="@BINDIR@/multipath -U -v1 %k", GOTO="paths_ok" - ENV{MPATH_DEVICE_READY}="0", GOTO="mpath_action" - LABEL="paths_ok" - --# Don't mark a device ready on a PATH_FAILED event. even if --# DM_NR_VALID_PATHS is greater than 0. Just keep the existing --# value --ENV{DM_ACTION}=="PATH_FAILED", GOTO="mpath_action" -- --# This event is either a PATH_REINSTATED or a table reload where --# there are active paths. Mark the device ready --ENV{MPATH_DEVICE_READY}="1" -+# For PATH_FAILED events, keep the existing value of MPATH_DEVICE_READY. -+# If it's not PATH_FAILED, this event is either a PATH_REINSTATED or a -+# table reload where there are active paths. Mark the device ready. -+ENV{DM_ACTION}!="PATH_FAILED", ENV{MPATH_DEVICE_READY}="1" - - LABEL="mpath_action" - diff --git a/0016-11-dm-mpath.rules-make-label-names-more-intuitive.patch b/0016-11-dm-mpath.rules-make-label-names-more-intuitive.patch deleted file mode 100644 index e81f04f..0000000 --- a/0016-11-dm-mpath.rules-make-label-names-more-intuitive.patch +++ /dev/null @@ -1,109 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 1 Mar 2024 21:54:26 +0100 -Subject: [PATCH] 11-dm-mpath.rules: make label names more intuitive - -The labels "dont_activate" and "scan_import" denote the same code line. -Remove "dont_activate". Improve two misleading label names. - -Substitutions: - dont_activate -> scan_import - force_activation -> check_mpath_ready - mpath_action -> check_mpath_unchanged - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/11-dm-mpath.rules.in | 22 +++++++++++----------- - 1 file changed, 11 insertions(+), 11 deletions(-) - -diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in -index 4777fbec..0562eddf 100644 ---- a/multipath/11-dm-mpath.rules.in -+++ b/multipath/11-dm-mpath.rules.in -@@ -30,7 +30,7 @@ LABEL="mpath_coldplug_end" - # device below at mpath_is_ready, which is correct. - ENV{DM_COOKIE}!="?*", ENV{DM_ACTION}!="PATH_*", \ - IMPORT{db}="DM_COLDPLUG_SUSPENDED", \ -- GOTO="force_activation" -+ GOTO="check_mpath_ready" - - ENV{.MPATH_DEVICE_READY_OLD}="$env{MPATH_DEVICE_READY}" - -@@ -38,13 +38,13 @@ ENV{.MPATH_DEVICE_READY_OLD}="$env{MPATH_DEVICE_READY}" - # table with no active devices. If this happens, mark the - # device not ready - ENV{DM_SUBSYSTEM_UDEV_FLAG2}=="1", ENV{MPATH_DEVICE_READY}="0", \ -- GOTO="mpath_action" -+ GOTO="check_mpath_unchanged" - - # If the last path has failed mark the device not ready - # Note that DM_NR_VALID_PATHS is only set for PATH_FAILED|PATH_REINSTATED - # events. - # This may not be reliable, as events aren't necessarily received in order. --ENV{DM_NR_VALID_PATHS}=="0", ENV{MPATH_DEVICE_READY}="0", GOTO="mpath_action" -+ENV{DM_NR_VALID_PATHS}=="0", ENV{MPATH_DEVICE_READY}="0", GOTO="check_mpath_unchanged" - - # Don't run multipath -U during "coldplug" after switching root, - # because paths are just being added to the udev db. -@@ -53,7 +53,8 @@ ACTION=="add", ENV{.MPATH_DEVICE_READY_OLD}=="1", GOTO="paths_ok" - # Check the map state directly with multipath -U. - # This doesn't attempt I/O on the device. - PROGRAM=="@BINDIR@/multipath -U -v1 %k", GOTO="paths_ok" --ENV{MPATH_DEVICE_READY}="0", GOTO="mpath_action" -+ENV{MPATH_DEVICE_READY}="0", GOTO="check_mpath_unchanged" -+ - LABEL="paths_ok" - - # For PATH_FAILED events, keep the existing value of MPATH_DEVICE_READY. -@@ -61,7 +62,7 @@ LABEL="paths_ok" - # table reload where there are active paths. Mark the device ready. - ENV{DM_ACTION}!="PATH_FAILED", ENV{MPATH_DEVICE_READY}="1" - --LABEL="mpath_action" -+LABEL="check_mpath_unchanged" - - # A previous coldplug event occurred while the device was suspended. - # Activation might have been partially skipped. Activate the device now, -@@ -70,7 +71,7 @@ IMPORT{db}="DM_COLDPLUG_SUSPENDED" - ENV{DM_COLDPLUG_SUSPENDED}=="1", ENV{.DM_SUSPENDED}!="1", \ - ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0", \ - PROGRAM="/bin/logger -t 11-dm-mpath.rules -p daemon.notice \"Forcing activation of previously suspended device\"", \ -- GOTO="force_activation" -+ GOTO="check_mpath_ready" - - # DM_SUBSYSTEM_UDEV_FLAG0 is the "RELOAD" flag for multipath subsystem. - # Drop the DM_ACTIVATION flag here as mpath reloads tables if any of its -@@ -86,7 +87,7 @@ ENV{DM_SUBSYSTEM_UDEV_FLAG0}=="1", \ - ENV{DM_ACTION}=="PATH_FAILED|PATH_REINSTATED", \ - ENV{DM_ACTIVATION}="0", ENV{MPATH_UNCHANGED}="1" - --LABEL="force_activation" -+LABEL="check_mpath_ready" - - ENV{MPATH_DEVICE_READY}!="0", GOTO="mpath_is_ready" - # Do not initiate scanning if no path is available, -@@ -100,7 +101,7 @@ ENV{MPATH_DEVICE_READY}!="0", GOTO="mpath_is_ready" - ENV{DM_UDEV_RULES_VSN}=="1|2", \ - ENV{.MPATH_SAVE_DISABLE_OTHER_RULES_FLAG}="$env{DM_UDEV_DISABLE_OTHER_RULES_FLAG}" - ENV{.DM_NOSCAN}="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1" --GOTO="dont_activate" -+GOTO="scan_import" - - LABEL="mpath_is_ready" - -@@ -109,11 +110,10 @@ LABEL="mpath_is_ready" - # we have to postpone the activation until the next event. - # In this case, we have to set MPATH_DEVICE_READY=0; otherwise, the - # MPATH_UNCHANGED logic will cause later rules to skipped in the next event. --ENV{.MPATH_DEVICE_READY_OLD}!="0", GOTO="dont_activate" --ENV{.DM_SUSPENDED}=="1", ENV{MPATH_DEVICE_READY}="0", GOTO="dont_activate" -+ENV{.MPATH_DEVICE_READY_OLD}!="0", GOTO="scan_import" -+ENV{.DM_SUSPENDED}=="1", ENV{MPATH_DEVICE_READY}="0", GOTO="scan_import" - - ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0" --LABEL="dont_activate" - - # The code to check multipath state ends here. We need to set - # properties and symlinks regardless whether the map is usable or diff --git a/0017-kpartx.rules-ignore-DM_SUSPENDED.patch b/0017-kpartx.rules-ignore-DM_SUSPENDED.patch deleted file mode 100644 index 3b0ac76..0000000 --- a/0017-kpartx.rules-ignore-DM_SUSPENDED.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 1 Mar 2024 21:17:26 +0100 -Subject: [PATCH] kpartx.rules: ignore DM_SUSPENDED - -DM_SUSPENDED=1 implies DM_UDEV_DISABLE_OTHER_RULES_FLAG=1, no -need to check it again. The DM_NOSCAN check needs to remain in -order to keep compatibility with dm rules v2. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - kpartx/kpartx.rules | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules -index 1969dee0..8dd3369c 100644 ---- a/kpartx/kpartx.rules -+++ b/kpartx/kpartx.rules -@@ -27,7 +27,7 @@ ENV{DM_SUBSYSTEM_UDEV_FLAG1}=="1", GOTO="mpath_kpartx_end" - ENV{MPATH_UNCHANGED}=="1", GOTO="mpath_kpartx_end" - - # Don't run kpartx now if we know it will fail or hang. --ENV{DM_SUSPENDED}=="1", GOTO="mpath_kpartx_end" -+# This is required for device mapper rules v2 compatibility. - ENV{DM_NOSCAN}=="1", GOTO="mpath_kpartx_end" - - # Run kpartx diff --git a/0018-multipath-tools-tests-fix-CI-failures-on-arm-v7-with.patch b/0018-multipath-tools-tests-fix-CI-failures-on-arm-v7-with.patch deleted file mode 100644 index 2840cec..0000000 --- a/0018-multipath-tools-tests-fix-CI-failures-on-arm-v7-with.patch +++ /dev/null @@ -1,270 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 4 Apr 2024 23:23:28 +0200 -Subject: [PATCH] multipath-tools tests: fix CI failures on arm/v7 with glibc - 2.37 - -glibc 2.37 has added several new wrappers around the ioctl and -io_getevents system calls on 32 bit systems, to deal with 64bit -time_t. These aren't resolved with cmocka's wrapping technique. - -Fix this with C preprocessor trickery, similar to -7b217f8 ("multipath-tools: Makefile.inc: set _FILE_OFFSET_BITS=64"). - -Note: the directio test with DIO_TEST_DEV for fails under qemu-linux-user -with foreign-arch binfmt, because aio-related system calls are unsupported -by qemu-linux-user. See https://gitlab.com/qemu-project/qemu/-/issues/210. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - tests/directio.c | 28 ++++++++++++++-------------- - tests/vpd.c | 35 ++++++++++++++++++----------------- - tests/wrap64.h | 25 ++++++++++++++++++++++++- - 3 files changed, 56 insertions(+), 32 deletions(-) - -diff --git a/tests/directio.c b/tests/directio.c -index cbedcc9c..d5f84f10 100644 ---- a/tests/directio.c -+++ b/tests/directio.c -@@ -41,13 +41,13 @@ struct timespec full_timeout = { .tv_sec = -1 }; - #define ioctl_request_t int - #endif - --int __real_ioctl(int fd, ioctl_request_t request, void *argp); -+int REAL_IOCTL(int fd, ioctl_request_t request, void *argp); - --int __wrap_ioctl(int fd, ioctl_request_t request, void *argp) -+int WRAP_IOCTL(int fd, ioctl_request_t request, void *argp) - { - #ifdef DIO_TEST_DEV - mock_type(int); -- return __real_ioctl(fd, request, argp); -+ return REAL_IOCTL(fd, request, argp); - #else - int *blocksize = (int *)argp; - -@@ -148,10 +148,10 @@ int __wrap_io_cancel(io_context_t ctx, struct iocb *iocb, struct io_event *evt) - #endif - } - --int __real_io_getevents(io_context_t ctx, long min_nr, long nr, -+int REAL_IO_GETEVENTS(io_context_t ctx, long min_nr, long nr, - struct io_event *events, struct timespec *timeout); - --int __wrap_io_getevents(io_context_t ctx, long min_nr, long nr, -+int WRAP_IO_GETEVENTS(io_context_t ctx, long min_nr, long nr, - struct io_event *events, struct timespec *timeout) - { - int nr_evs; -@@ -169,8 +169,8 @@ int __wrap_io_getevents(io_context_t ctx, long min_nr, long nr, - #ifdef DIO_TEST_DEV - mock_ptr_type(struct timespec *); - mock_ptr_type(struct io_event *); -- assert_int_equal(nr_evs, __real_io_getevents(ctx, min_nr, nr_evs, -- events, timeout)); -+ assert_int_equal(nr_evs, REAL_IO_GETEVENTS(ctx, min_nr, nr_evs, -+ events, timeout)); - #else - sleep_tmo = mock_ptr_type(struct timespec *); - if (sleep_tmo) { -@@ -193,7 +193,7 @@ int __wrap_io_getevents(io_context_t ctx, long min_nr, long nr, - - static void return_io_getevents_none(void) - { -- will_return(__wrap_io_getevents, 0); -+ wrap_will_return(WRAP_IO_GETEVENTS, 0); - } - - static void return_io_getevents_nr(struct timespec *ts, int nr, -@@ -207,15 +207,15 @@ static void return_io_getevents_nr(struct timespec *ts, int nr, - mock_events[i + ev_off].res = reqs[i]->blksize; - } - while (nr > 0) { -- will_return(__wrap_io_getevents, (nr > 128)? 128 : nr); -- will_return(__wrap_io_getevents, ts); -- will_return(__wrap_io_getevents, &mock_events[off + ev_off]); -+ wrap_will_return(WRAP_IO_GETEVENTS, (nr > 128)? 128 : nr); -+ wrap_will_return(WRAP_IO_GETEVENTS, ts); -+ wrap_will_return(WRAP_IO_GETEVENTS, &mock_events[off + ev_off]); - ts = NULL; - off += 128; - nr -= 128; - } - if (nr == 0) -- will_return(__wrap_io_getevents, 0); -+ wrap_will_return(WRAP_IO_GETEVENTS, 0); - ev_off += i; - } - -@@ -251,7 +251,7 @@ static void do_libcheck_init(struct checker *c, int blocksize, - struct directio_context * ct; - - c->fd = test_fd; -- will_return(__wrap_ioctl, blocksize); -+ wrap_will_return(WRAP_IOCTL, blocksize); - assert_int_equal(libcheck_init(c), 0); - ct = (struct directio_context *)c->context; - assert_non_null(ct); -@@ -762,7 +762,7 @@ int main(void) - { - int ret = 0; - -- init_test_verbosity(2); -+ init_test_verbosity(5); - ret += test_directio(); - return ret; - } -diff --git a/tests/vpd.c b/tests/vpd.c -index 1b2d62d6..e3212e61 100644 ---- a/tests/vpd.c -+++ b/tests/vpd.c -@@ -20,6 +20,7 @@ - #include "vector.h" - #include "structs.h" - #include "discovery.h" -+#include "wrap64.h" - #include "globals.c" - - #define VPD_BUFSIZ 4096 -@@ -58,7 +59,7 @@ static const char vendor_id[] = "Linux"; - static const char test_id[] = - "A123456789AbcDefB123456789AbcDefC123456789AbcDefD123456789AbcDef"; - --int __wrap_ioctl(int fd, unsigned long request, void *param) -+int WRAP_IOCTL(int fd, unsigned long request, void *param) - { - int len; - struct sg_io_hdr *io_hdr; -@@ -428,8 +429,8 @@ static void test_vpd_vnd_ ## len ## _ ## wlen(void **state) \ - /* Replace spaces, like code under test */ \ - exp_subst = subst_spaces(exp_wwid); \ - free(exp_wwid); \ -- will_return(__wrap_ioctl, n); \ -- will_return(__wrap_ioctl, vt->vpdbuf); \ -+ wrap_will_return(WRAP_IOCTL, n); \ -+ wrap_will_return(WRAP_IOCTL, vt->vpdbuf); \ - ret = get_vpd_sgio(10, 0x83, 0, vt->wwid, wlen); \ - assert_correct_wwid("test_vpd_vnd_" #len "_" #wlen, \ - exp_len, ret, '1', 0, false, \ -@@ -458,8 +459,8 @@ static void test_vpd_str_ ## typ ## _ ## len ## _ ## wlen(void **state) \ - exp_len--; \ - if (exp_len >= wlen) \ - exp_len = wlen - 1; \ -- will_return(__wrap_ioctl, n); \ -- will_return(__wrap_ioctl, vt->vpdbuf); \ -+ wrap_will_return(WRAP_IOCTL, n); \ -+ wrap_will_return(WRAP_IOCTL, vt->vpdbuf); \ - ret = get_vpd_sgio(10, 0x83, 0, vt->wwid, wlen); \ - assert_correct_wwid("test_vpd_str_" #typ "_" #len "_" #wlen, \ - exp_len, ret, byte0[type], 0, \ -@@ -495,8 +496,8 @@ static void test_vpd_naa_ ## naa ## _ ## wlen(void **state) \ - \ - n = create_vpd83(vt->vpdbuf, sizeof(vt->vpdbuf), test_id, \ - 3, naa, 0); \ -- will_return(__wrap_ioctl, n); \ -- will_return(__wrap_ioctl, vt->vpdbuf); \ -+ wrap_will_return(WRAP_IOCTL, n); \ -+ wrap_will_return(WRAP_IOCTL, vt->vpdbuf); \ - ret = get_vpd_sgio(10, 0x83, 0, vt->wwid, wlen); \ - assert_correct_wwid("test_vpd_naa_" #naa "_" #wlen, \ - exp_len, ret, '3', '0' + naa, true, \ -@@ -518,8 +519,8 @@ static void test_vpd_naa_##NAA##_badlen_##BAD(void **state) \ - n = create_vpd83(vt->vpdbuf, sizeof(vt->vpdbuf), test_id, 3, NAA, 0); \ - \ - vt->vpdbuf[7] = BAD; \ -- will_return(__wrap_ioctl, n); \ -- will_return(__wrap_ioctl, vt->vpdbuf); \ -+ wrap_will_return(WRAP_IOCTL, n); \ -+ wrap_will_return(WRAP_IOCTL, vt->vpdbuf); \ - ret = get_vpd_sgio(10, 0x83, 0, vt->wwid, 40); \ - assert_int_equal(-ret, -ERR); \ - } -@@ -545,11 +546,11 @@ static void test_vpd_eui_ ## len ## _ ## wlen ## _ ## sml(void **state) \ - /* overwrite the page size to DEFAULT_SGIO_LEN + 1 */ \ - put_unaligned_be16(255, vt->vpdbuf + 2); \ - /* this causes get_vpd_sgio to do a second ioctl */ \ -- will_return(__wrap_ioctl, n); \ -- will_return(__wrap_ioctl, vt->vpdbuf); \ -+ wrap_will_return(WRAP_IOCTL, n); \ -+ wrap_will_return(WRAP_IOCTL, vt->vpdbuf); \ - } \ -- will_return(__wrap_ioctl, n); \ -- will_return(__wrap_ioctl, vt->vpdbuf); \ -+ wrap_will_return(WRAP_IOCTL, n); \ -+ wrap_will_return(WRAP_IOCTL, vt->vpdbuf); \ - ret = get_vpd_sgio(10, 0x83, 0, vt->wwid, wlen); \ - assert_correct_wwid("test_vpd_eui_" #len "_" #wlen "_" #sml, \ - exp_len, ret, '2', 0, true, \ -@@ -571,8 +572,8 @@ static void test_vpd_eui_badlen_##LEN##_##BAD(void **state) \ - n = create_vpd83(vt->vpdbuf, sizeof(vt->vpdbuf), test_id, 2, 0, LEN); \ - \ - vt->vpdbuf[7] = BAD; \ -- will_return(__wrap_ioctl, n); \ -- will_return(__wrap_ioctl, vt->vpdbuf); \ -+ wrap_will_return(WRAP_IOCTL, n); \ -+ wrap_will_return(WRAP_IOCTL, vt->vpdbuf); \ - ret = get_vpd_sgio(10, 0x83, 0, vt->wwid, 40); \ - assert_int_equal(ret, ERR); \ - if (ERR >= 0) \ -@@ -600,8 +601,8 @@ static void test_vpd80_ ## size ## _ ## len ## _ ## wlen(void **state) \ - exp_len = wlen - 1; \ - n = create_vpd80(vt->vpdbuf, sizeof(vt->vpdbuf), input, \ - size, len); \ -- will_return(__wrap_ioctl, n); \ -- will_return(__wrap_ioctl, vt->vpdbuf); \ -+ wrap_will_return(WRAP_IOCTL, n); \ -+ wrap_will_return(WRAP_IOCTL, vt->vpdbuf); \ - ret = get_vpd_sgio(10, 0x80, 0, vt->wwid, wlen); \ - assert_correct_wwid("test_vpd80_" #size "_" #len "_" #wlen, \ - exp_len, ret, 0, 0, false, \ -diff --git a/tests/wrap64.h b/tests/wrap64.h -index 8c91d279..b0a4d831 100644 ---- a/tests/wrap64.h -+++ b/tests/wrap64.h -@@ -1,5 +1,7 @@ - #ifndef _WRAP64_H - #define _WRAP64_H 1 -+#include -+#include - #include "util.h" - - /* -@@ -31,7 +33,9 @@ - * fcntl() needs special treatment; fcntl64() has been introduced in 2.28. - * https://savannah.gnu.org/forum/forum.php?forum_id=9205 - */ --#if defined(__GLIBC__) && __GLIBC_PREREQ(2, 28) -+#if defined(__GLIBC__) && __GLIBC_PREREQ(2, 37) && defined(__arm__) && __ARM_ARCH == 7 -+#define WRAP_FCNTL_NAME __fcntl_time64 -+#elif defined(__GLIBC__) && __GLIBC_PREREQ(2, 28) - #define WRAP_FCNTL_NAME WRAP_NAME(fcntl) - #else - #define WRAP_FCNTL_NAME fcntl -@@ -39,6 +43,25 @@ - #define WRAP_FCNTL CONCAT2(__wrap_, WRAP_FCNTL_NAME) - #define REAL_FCNTL CONCAT2(__real_, WRAP_FCNTL_NAME) - -+/* -+ * glibc 2.37 uses __ioctl_time64 for ioctl -+ */ -+#if defined(__GLIBC__) && __GLIBC_PREREQ(2, 37) && defined(__arm__) && __ARM_ARCH == 7 -+#define WRAP_IOCTL_NAME __ioctl_time64 -+#else -+#define WRAP_IOCTL_NAME ioctl -+#endif -+#define WRAP_IOCTL CONCAT2(__wrap_, WRAP_IOCTL_NAME) -+#define REAL_IOCTL CONCAT2(__real_, WRAP_IOCTL_NAME) -+ -+#if defined(__NR_io_pgetevents) && __BITS_PER_LONG == 32 && defined(_TIME_BITS) && _TIME_BITS == 64 -+#define WRAP_IO_GETEVENTS_NAME io_getevents_time64 -+#else -+#define WRAP_IO_GETEVENTS_NAME io_getevents -+#endif -+#define WRAP_IO_GETEVENTS CONCAT2(__wrap_, WRAP_IO_GETEVENTS_NAME) -+#define REAL_IO_GETEVENTS CONCAT2(__real_, WRAP_IO_GETEVENTS_NAME) -+ - /* - * will_return() is itself a macro that uses CPP "stringizing". We need a - * macro indirection to make sure the *value* of WRAP_FUNC() is stringized diff --git a/0019-multipath-tools-tests-fix-CI-failures-with-clang-on-.patch b/0019-multipath-tools-tests-fix-CI-failures-with-clang-on-.patch deleted file mode 100644 index d1dedac..0000000 --- a/0019-multipath-tools-tests-fix-CI-failures-with-clang-on-.patch +++ /dev/null @@ -1,246 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 5 Apr 2024 22:21:43 +0200 -Subject: [PATCH] multipath-tools tests: fix CI failures with clang on Fedora - Rawhide - -Fedora's glibc 2.39 includes the following patch: - -https://patches.linaro.org/project/libc-alpha/patch/20240208184622.332678-10-adhemerval.zanella@linaro.org/ - -It causes open("file", O_RDONLY) to resolve to __open64_2(), -whereas it resolves to open64() with gcc, causing CI failures because of -wrong wrapper substitutions. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - tests/dmevents.c | 6 ++--- - tests/sysfs.c | 58 ++++++++++++++++++++++++------------------------ - tests/test-lib.c | 6 ++--- - tests/wrap64.h | 14 ++++++++++++ - 4 files changed, 49 insertions(+), 35 deletions(-) - -diff --git a/tests/dmevents.c b/tests/dmevents.c -index 540bf0d3..395b16d7 100644 ---- a/tests/dmevents.c -+++ b/tests/dmevents.c -@@ -207,7 +207,7 @@ static int teardown(void **state) - return 0; - } - --int WRAP_FUNC(open)(const char *pathname, int flags) -+int WRAP_OPEN(const char *pathname, int flags) - { - assert_ptr_equal(pathname, "/dev/mapper/control"); - assert_int_equal(flags, O_RDWR); -@@ -389,7 +389,7 @@ static void test_init_waiter_bad1(void **state) - struct test_data *datap = (struct test_data *)(*state); - if (datap == NULL) - skip(); -- wrap_will_return(WRAP_FUNC(open), -1); -+ wrap_will_return(WRAP_OPEN, -1); - assert_int_equal(init_dmevent_waiter(&datap->vecs), -1); - assert_ptr_equal(waiter, NULL); - } -@@ -400,7 +400,7 @@ static void test_init_waiter_good0(void **state) - struct test_data *datap = (struct test_data *)(*state); - if (datap == NULL) - skip(); -- wrap_will_return(WRAP_FUNC(open), 2); -+ wrap_will_return(WRAP_OPEN, 2); - assert_int_equal(init_dmevent_waiter(&datap->vecs), 0); - assert_ptr_not_equal(waiter, NULL); - } -diff --git a/tests/sysfs.c b/tests/sysfs.c -index fc256d87..c623d1bb 100644 ---- a/tests/sysfs.c -+++ b/tests/sysfs.c -@@ -29,7 +29,7 @@ char *__wrap_udev_device_get_syspath(struct udev_device *ud) - return val; - } - --int WRAP_FUNC(open)(const char *pathname, int flags) -+int WRAP_OPEN(const char *pathname, int flags) - { - int ret; - -@@ -167,10 +167,10 @@ static void test_sagv_open_fail(void **state) - - will_return(__wrap_udev_device_get_syspath, "/foo"); - expect_condlog(4, "open '/foo/bar'"); -- expect_string(WRAP_FUNC(open), pathname, "/foo/bar"); -- expect_value(WRAP_FUNC(open), flags, O_RDONLY); -+ expect_string(WRAP_OPEN, pathname, "/foo/bar"); -+ expect_value(WRAP_OPEN, flags, O_RDONLY); - errno = ENOENT; -- wrap_will_return(WRAP_FUNC(open), -1); -+ wrap_will_return(WRAP_OPEN, -1); - expect_condlog(3, "__sysfs_attr_get_value: attribute '/foo/bar' cannot be opened"); - assert_int_equal(sysfs_attr_get_value((void *)state, "bar", - buf, sizeof(buf)), -ENOENT); -@@ -182,9 +182,9 @@ static void test_sagv_read_fail(void **state) - - will_return(__wrap_udev_device_get_syspath, "/foo"); - expect_condlog(4, "open '/foo/bar'"); -- expect_string(WRAP_FUNC(open), pathname, "/foo/bar"); -- expect_value(WRAP_FUNC(open), flags, O_RDONLY); -- wrap_will_return(WRAP_FUNC(open), TEST_FD); -+ expect_string(WRAP_OPEN, pathname, "/foo/bar"); -+ expect_value(WRAP_OPEN, flags, O_RDONLY); -+ wrap_will_return(WRAP_OPEN, TEST_FD); - expect_value(__wrap_read, fd, TEST_FD); - expect_value(__wrap_read, count, sizeof(buf)); - errno = EISDIR; -@@ -197,9 +197,9 @@ static void test_sagv_read_fail(void **state) - - will_return(__wrap_udev_device_get_syspath, "/foo"); - expect_condlog(4, "open '/foo/baz'"); -- expect_string(WRAP_FUNC(open), pathname, "/foo/baz"); -- expect_value(WRAP_FUNC(open), flags, O_RDONLY); -- wrap_will_return(WRAP_FUNC(open), TEST_FD); -+ expect_string(WRAP_OPEN, pathname, "/foo/baz"); -+ expect_value(WRAP_OPEN, flags, O_RDONLY); -+ wrap_will_return(WRAP_OPEN, TEST_FD); - expect_value(__wrap_read, fd, TEST_FD); - expect_value(__wrap_read, count, sizeof(buf)); - errno = EPERM; -@@ -223,9 +223,9 @@ static void _test_sagv_read(void **state, unsigned int bufsz) - memset(buf, '.', sizeof(buf)); - will_return(__wrap_udev_device_get_syspath, "/foo"); - expect_condlog(4, "open '/foo/bar'"); -- expect_string(WRAP_FUNC(open), pathname, "/foo/bar"); -- expect_value(WRAP_FUNC(open), flags, O_RDONLY); -- wrap_will_return(WRAP_FUNC(open), TEST_FD); -+ expect_string(WRAP_OPEN, pathname, "/foo/bar"); -+ expect_value(WRAP_OPEN, flags, O_RDONLY); -+ wrap_will_return(WRAP_OPEN, TEST_FD); - expect_value(__wrap_read, fd, TEST_FD); - expect_value(__wrap_read, count, bufsz); - will_return(__wrap_read, sizeof(input) - 1); -@@ -250,9 +250,9 @@ static void _test_sagv_read(void **state, unsigned int bufsz) - memset(buf, '.', sizeof(buf)); - will_return(__wrap_udev_device_get_syspath, "/foo"); - expect_condlog(4, "open '/foo/baz'"); -- expect_string(WRAP_FUNC(open), pathname, "/foo/baz"); -- expect_value(WRAP_FUNC(open), flags, O_RDONLY); -- wrap_will_return(WRAP_FUNC(open), TEST_FD); -+ expect_string(WRAP_OPEN, pathname, "/foo/baz"); -+ expect_value(WRAP_OPEN, flags, O_RDONLY); -+ wrap_will_return(WRAP_OPEN, TEST_FD); - expect_value(__wrap_read, fd, TEST_FD); - expect_value(__wrap_read, count, bufsz); - will_return(__wrap_read, sizeof(input) - 1); -@@ -301,9 +301,9 @@ static void _test_sagv_read_zeroes(void **state, unsigned int bufsz) - memset(buf, '.', sizeof(buf)); - will_return(__wrap_udev_device_get_syspath, "/foo"); - expect_condlog(4, "open '/foo/bar'"); -- expect_string(WRAP_FUNC(open), pathname, "/foo/bar"); -- expect_value(WRAP_FUNC(open), flags, O_RDONLY); -- wrap_will_return(WRAP_FUNC(open), TEST_FD); -+ expect_string(WRAP_OPEN, pathname, "/foo/bar"); -+ expect_value(WRAP_OPEN, flags, O_RDONLY); -+ wrap_will_return(WRAP_OPEN, TEST_FD); - expect_value(__wrap_read, fd, TEST_FD); - expect_value(__wrap_read, count, bufsz); - will_return(__wrap_read, sizeof(input) - 1); -@@ -386,10 +386,10 @@ static void test_sasv_open_fail(void **state) - - will_return(__wrap_udev_device_get_syspath, "/foo"); - expect_condlog(4, "open '/foo/bar'"); -- expect_string(WRAP_FUNC(open), pathname, "/foo/bar"); -- expect_value(WRAP_FUNC(open), flags, O_WRONLY); -+ expect_string(WRAP_OPEN, pathname, "/foo/bar"); -+ expect_value(WRAP_OPEN, flags, O_WRONLY); - errno = EPERM; -- wrap_will_return(WRAP_FUNC(open), -1); -+ wrap_will_return(WRAP_OPEN, -1); - expect_condlog(3, "sysfs_attr_set_value: attribute '/foo/bar' cannot be opened"); - assert_int_equal(sysfs_attr_set_value((void *)state, "bar", - buf, sizeof(buf)), -EPERM); -@@ -401,9 +401,9 @@ static void test_sasv_write_fail(void **state) - - will_return(__wrap_udev_device_get_syspath, "/foo"); - expect_condlog(4, "open '/foo/bar'"); -- expect_string(WRAP_FUNC(open), pathname, "/foo/bar"); -- expect_value(WRAP_FUNC(open), flags, O_WRONLY); -- wrap_will_return(WRAP_FUNC(open), TEST_FD); -+ expect_string(WRAP_OPEN, pathname, "/foo/bar"); -+ expect_value(WRAP_OPEN, flags, O_WRONLY); -+ wrap_will_return(WRAP_OPEN, TEST_FD); - expect_value(__wrap_write, fd, TEST_FD); - expect_value(__wrap_write, count, sizeof(buf)); - errno = EISDIR; -@@ -422,9 +422,9 @@ static void _test_sasv_write(void **state, unsigned int n_written) - assert_in_range(n_written, 0, sizeof(buf)); - will_return(__wrap_udev_device_get_syspath, "/foo"); - expect_condlog(4, "open '/foo/bar'"); -- expect_string(WRAP_FUNC(open), pathname, "/foo/bar"); -- expect_value(WRAP_FUNC(open), flags, O_WRONLY); -- wrap_will_return(WRAP_FUNC(open), TEST_FD); -+ expect_string(WRAP_OPEN, pathname, "/foo/bar"); -+ expect_value(WRAP_OPEN, flags, O_WRONLY); -+ wrap_will_return(WRAP_OPEN, TEST_FD); - expect_value(__wrap_write, fd, TEST_FD); - expect_value(__wrap_write, count, sizeof(buf)); - will_return(__wrap_write, n_written); -@@ -489,7 +489,7 @@ int main(void) - { - int ret = 0; - -- init_test_verbosity(4); -+ init_test_verbosity(5); - ret += test_sysfs(); - return ret; - } -diff --git a/tests/test-lib.c b/tests/test-lib.c -index 665d438e..cdb2780d 100644 ---- a/tests/test-lib.c -+++ b/tests/test-lib.c -@@ -40,17 +40,17 @@ const char default_wwid_1[] = "TEST-WWID-1"; - */ - - --int REAL_FUNC(open)(const char *path, int flags, int mode); -+int REAL_OPEN(const char *path, int flags, int mode); - - static const char _mocked_filename[] = "mocked_path"; - --int WRAP_FUNC(open)(const char *path, int flags, int mode) -+int WRAP_OPEN(const char *path, int flags, int mode) - { - condlog(4, "%s: %s", __func__, path); - - if (!strcmp(path, _mocked_filename)) - return 111; -- return REAL_FUNC(open)(path, flags, mode); -+ return REAL_OPEN(path, flags, mode); - } - - int __wrap_libmp_get_version(int which, unsigned int version[3]) -diff --git a/tests/wrap64.h b/tests/wrap64.h -index b0a4d831..7e434206 100644 ---- a/tests/wrap64.h -+++ b/tests/wrap64.h -@@ -29,6 +29,20 @@ - #define WRAP_FUNC(x) CONCAT2(__wrap_, WRAP_NAME(x)) - #define REAL_FUNC(x) CONCAT2(__real_, WRAP_NAME(x)) - -+/* -+ * With clang, glibc 2.39, and _FILE_OFFSET_BITS==64, -+ * open() resolves to __open64_2(). -+ */ -+#if defined(__GLIBC__) && __GLIBC_PREREQ(2, 39) && \ -+ defined(__clang__) && __clang__ == 1 && \ -+ defined(__fortify_use_clang) && __fortify_use_clang == 1 -+#define WRAP_OPEN_NAME __open64_2 -+#else -+#define WRAP_OPEN_NAME WRAP_NAME(open) -+#endif -+#define WRAP_OPEN CONCAT2(__wrap_, WRAP_OPEN_NAME) -+#define REAL_OPEN CONCAT2(__real_, WRAP_OPEN_NAME) -+ - /* - * fcntl() needs special treatment; fcntl64() has been introduced in 2.28. - * https://savannah.gnu.org/forum/forum.php?forum_id=9205 diff --git a/0020-GitHub-actions-fixes-for-spelling-CI.patch b/0020-GitHub-actions-fixes-for-spelling-CI.patch deleted file mode 100644 index 21b74ff..0000000 --- a/0020-GitHub-actions-fixes-for-spelling-CI.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 8 Mar 2024 10:04:39 +0100 -Subject: [PATCH] GitHub actions: fixes for spelling CI - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .github/actions/spelling/patterns.txt | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/.github/actions/spelling/patterns.txt b/.github/actions/spelling/patterns.txt -index 57767ea1..858faee6 100644 ---- a/.github/actions/spelling/patterns.txt -+++ b/.github/actions/spelling/patterns.txt -@@ -22,6 +22,7 @@ - \bdmmp_pgs\b - \bdmmp_mpath_kdev_name_get\b - \bfast_io_fail_tmo\b -+\bLimitRTPRIO\b - \bmax_fds\b - \bmissing_uev_wait_timeout\b - \bMPATH_MAX_PARAM_LEN\b -@@ -86,6 +87,7 @@ - \bprin_resvdescr\b - \bprout_param_descriptor\b - \brq_servact\b -+\bSCHED_RT_PRIO\b - \bssize_t\b - \btrnptid_list\b - \buxsock_timeout\b diff --git a/0021-GitHub-workflows-run-workflows-if-workflow-file-has-.patch b/0021-GitHub-workflows-run-workflows-if-workflow-file-has-.patch deleted file mode 100644 index 59cdd0e..0000000 --- a/0021-GitHub-workflows-run-workflows-if-workflow-file-has-.patch +++ /dev/null @@ -1,146 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 27 Feb 2024 09:57:47 +0100 -Subject: [PATCH] GitHub workflows: run workflows if workflow file has changed - -We want to run workflows if the workflow file itself has changed. - -Fixes: 2cbe81a ("GitHub Workflows: run expensive workflows only on relevant changes") -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/abi.yaml | 1 + - .github/workflows/foreign.yaml | 2 ++ - .github/workflows/multiarch-stable.yaml | 2 ++ - .github/workflows/multiarch.yaml | 2 ++ - .github/workflows/native.yaml | 2 ++ - .github/workflows/rolling.yaml | 2 ++ - .github/workflows/spelling.yml | 2 ++ - 7 files changed, 13 insertions(+) - -diff --git a/.github/workflows/abi.yaml b/.github/workflows/abi.yaml -index 53382420..393322e5 100644 ---- a/.github/workflows/abi.yaml -+++ b/.github/workflows/abi.yaml -@@ -5,6 +5,7 @@ on: - - queue - - abi - paths: -+ - '.github/workflows/abi.yaml' - - '**.h' - - '**.c' - pull_request: -diff --git a/.github/workflows/foreign.yaml b/.github/workflows/foreign.yaml -index 92f6d17a..a62ae009 100644 ---- a/.github/workflows/foreign.yaml -+++ b/.github/workflows/foreign.yaml -@@ -6,6 +6,7 @@ on: - - queue - - tip - paths: -+ - '.github/workflows/foreign.yaml' - - '**.h' - - '**.c' - - '**Makefile*' -@@ -15,6 +16,7 @@ on: - - master - - queue - paths: -+ - '.github/workflows/foreign.yaml' - - '**.h' - - '**.c' - - '**Makefile*' -diff --git a/.github/workflows/multiarch-stable.yaml b/.github/workflows/multiarch-stable.yaml -index 45b74c51..e51d383c 100644 ---- a/.github/workflows/multiarch-stable.yaml -+++ b/.github/workflows/multiarch-stable.yaml -@@ -6,6 +6,7 @@ on: - - queue - - tip - paths: -+ - '.github/workflows/multiarch-stable.yaml' - - '**.h' - - '**.c' - - '**Makefile*' -@@ -15,6 +16,7 @@ on: - - master - - queue - paths: -+ - '.github/workflows/multiarch-stable.yaml' - - '**.h' - - '**.c' - - '**Makefile*' -diff --git a/.github/workflows/multiarch.yaml b/.github/workflows/multiarch.yaml -index b4dec9c7..7b762e5c 100644 ---- a/.github/workflows/multiarch.yaml -+++ b/.github/workflows/multiarch.yaml -@@ -6,6 +6,7 @@ on: - - queue - - tip - paths: -+ - '.github/workflows/multiarch.yaml' - - '**.h' - - '**.c' - - '**Makefile*' -@@ -15,6 +16,7 @@ on: - - master - - queue - paths: -+ - '.github/workflows/multiarch.yaml' - - '**.h' - - '**.c' - - '**Makefile*' -diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml -index 09133c1e..0ef9df94 100644 ---- a/.github/workflows/native.yaml -+++ b/.github/workflows/native.yaml -@@ -6,6 +6,7 @@ on: - - queue - - tip - paths: -+ - '.github/workflows/native.yaml' - - '**.h' - - '**.c' - - '**Makefile*' -@@ -15,6 +16,7 @@ on: - - master - - queue - paths: -+ - '.github/workflows/native.yaml' - - '**.h' - - '**.c' - - '**Makefile*' -diff --git a/.github/workflows/rolling.yaml b/.github/workflows/rolling.yaml -index 1f1507ee..3536b944 100644 ---- a/.github/workflows/rolling.yaml -+++ b/.github/workflows/rolling.yaml -@@ -6,6 +6,7 @@ on: - - queue - - tip - paths: -+ - '.github/workflows/rolling.yaml' - - '**.h' - - '**.c' - - '**Makefile*' -@@ -15,6 +16,7 @@ on: - - master - - queue - paths: -+ - '.github/workflows/rolling.yaml' - - '**.h' - - '**.c' - - '**Makefile*' -diff --git a/.github/workflows/spelling.yml b/.github/workflows/spelling.yml -index 0416fa9e..7943ebb8 100644 ---- a/.github/workflows/spelling.yml -+++ b/.github/workflows/spelling.yml -@@ -63,7 +63,9 @@ on: - tags-ignore: - - "**" - paths: -+ - '.github/workflows/spelling.yml' - - 'README*' -+ - 'NEWS.md' - - '**.3' - - '**.5' - - '**.8' diff --git a/0022-multipath-tools-add-TGTDIR-option.patch b/0022-multipath-tools-add-TGTDIR-option.patch deleted file mode 100644 index d26fb18..0000000 --- a/0022-multipath-tools-add-TGTDIR-option.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 17 Apr 2024 14:44:45 +0200 -Subject: [PATCH] multipath-tools: add TGTDIR option - -TGTDIR is a convenience option for developers for building multipath-tools such -that compiled-in paths of the plugins, config files, etc. match an -installation under some optional path. See README.md for instructions and -examples. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - .github/actions/spelling/expect.txt | 2 ++ - Makefile.inc | 8 +++---- - README.md | 33 +++++++++++++++++++++++++++++ - 3 files changed, 39 insertions(+), 4 deletions(-) - -diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt -index 5906403d..fc9f22f8 100644 ---- a/.github/actions/spelling/expect.txt -+++ b/.github/actions/spelling/expect.txt -@@ -167,6 +167,7 @@ retrigger - rhabarber - rootprefix - rootprefixdir -+rpmbuild - rport - rtpi - sas -@@ -200,6 +201,7 @@ tcp - TESTDEPS - testname - tgill -+TGTDIR - TIDS - tmo - tpg -diff --git a/Makefile.inc b/Makefile.inc -index 5668e638..81b86cd8 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -101,9 +101,9 @@ WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implici - $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) $(W_URCU_TYPE_LIMITS) - CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) $(D_URCU_VERSION) \ - -D_FILE_OFFSET_BITS=64 \ -- -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \ -- -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(configdir)\" \ -- -DDEFAULT_CONFIGFILE=\"$(configfile)\" -DSTATE_DIR=\"$(statedir)\" \ -+ -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(TGTDIR)$(plugindir)\" \ -+ -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(TGTDIR)$(configdir)\" \ -+ -DDEFAULT_CONFIGFILE=\"$(TGTDIR)$(configfile)\" -DSTATE_DIR=\"$(TGTDIR)$(statedir)\" \ - -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP - CFLAGS := -std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe - BIN_CFLAGS := -fPIE -DPIE -@@ -149,4 +149,4 @@ NV_VERSION_SCRIPT = $(DEVLIB:%.so=%-nv.version) - - %: %.in - @echo creating $@ -- $(Q)sed 's:@CONFIGFILE@:'$(configfile)':g;s:@CONFIGDIR@:'$(configdir)':g;s:@STATE_DIR@:'$(statedir)':g;s:@RUNTIME_DIR@:'$(runtimedir)':g;s/@MODPROBE_UNIT@/'$(MODPROBE_UNIT)'/g;s:@BINDIR@:'$(bindir)':g' $< >$@ -+ $(Q)sed 's:@CONFIGFILE@:'$(TGTDIR)$(configfile)':g;s:@CONFIGDIR@:'$(TGTDIR)$(configdir)':g;s:@STATE_DIR@:'$(TGTDIR)$(statedir)':g;s:@RUNTIME_DIR@:'$(runtimedir)':g;s/@MODPROBE_UNIT@/'$(MODPROBE_UNIT)'/g;s:@BINDIR@:'$(bindir)':g' $< >$@ -diff --git a/README.md b/README.md -index d4f35f57..7207b14c 100644 ---- a/README.md -+++ b/README.md -@@ -151,6 +151,39 @@ sufficient control. See `Makefile.inc` for even more fine-grained control. - On such distributions, override `unitdir` and `libudevdir` to use systemd's - `rootprefix`: `make libudevdir=/lib/udev unitdir=/lib/systemd/system` - -+### prefix, DESTDIR and TGTDIR -+ -+`prefix` and related variables are included in compiled-in paths like -+`plugindir` and are used by `make install`. Using `prefix` is useful if -+multipath-tools is built locally on the same host where it's supposed to be -+installed. -+ -+By convention, the `DESTDIR` variable is prepended to all paths by `make -+install`, but not to any compiled-in paths. -+It is useful if the software is built on one system (build host) but intended -+to be run on another system (installation host). This is typically used in build -+systems like *rpmbuild* to set a root directory for all the installed -+files. -+ -+On the contrary, the `TGTDIR` variable is used for compiled-in paths only, and -+ignored by `make install`. It is useful for running multipath-tools in a separate -+subdirectory in the installation host, mostly for testing / development -+purposes. -+ -+For example, -+ -+ make prefix=/opt DESTDIR=/build TGTDIR=/test install -+ -+will install plugins into `/build/opt/lib64/multipath` on the build -+host. On the installation host, the plugins will be expected to be found under -+`/test/opt/lib64/multipath`. If the developer runs -+ -+ rsync -a $BUILD_HOST:$DESTDIR/ $INSTALL_HOST:$TGTDIR/ -+ -+and adds `$TGTDIR/lib64` to `LD_LIBRARY_PATH` on the installation host, the -+multipath binaries installed under `$TGTDIR` will find their plugins and -+configuration files in the expected compiled-in paths. -+ - ### Compiler Options - - Use `OPTFLAGS` to change optimization-related compiler options; diff --git a/0023-libmultipath-move-get_udev_for_mpp-to-sysfs.c.patch b/0023-libmultipath-move-get_udev_for_mpp-to-sysfs.c.patch deleted file mode 100644 index b59f879..0000000 --- a/0023-libmultipath-move-get_udev_for_mpp-to-sysfs.c.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 17 Apr 2024 17:18:18 +0200 -Subject: [PATCH] libmultipath: move get_udev_for_mpp to sysfs.c - -No functional changes, just code movement. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 20 -------------------- - libmultipath/sysfs.c | 19 +++++++++++++++++++ - libmultipath/sysfs.h | 4 ++++ - 3 files changed, 23 insertions(+), 20 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 4ecf6ba4..89ac03d5 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -453,26 +453,6 @@ pgcmp (struct multipath * mpp, struct multipath * cmpp) - return r; - } - --static struct udev_device * --get_udev_for_mpp(const struct multipath *mpp) --{ -- dev_t devnum; -- struct udev_device *udd; -- -- if (!mpp || !has_dm_info(mpp)) { -- condlog(1, "%s called with empty mpp", __func__); -- return NULL; -- } -- -- devnum = makedev(mpp->dmi.major, mpp->dmi.minor); -- udd = udev_device_new_from_devnum(udev, 'b', devnum); -- if (!udd) { -- condlog(1, "failed to get udev device for %s", mpp->alias); -- return NULL; -- } -- return udd; --} -- - void trigger_partitions_udev_change(struct udev_device *dev, - const char *action, int len) - { -diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c -index 328951ed..afe9de91 100644 ---- a/libmultipath/sysfs.c -+++ b/libmultipath/sysfs.c -@@ -339,3 +339,22 @@ bool sysfs_is_multipathed(struct path *pp, bool set_wwid) - - return found; - } -+ -+struct udev_device *get_udev_for_mpp(const struct multipath *mpp) -+{ -+ dev_t devnum; -+ struct udev_device *udd; -+ -+ if (!mpp || !has_dm_info(mpp)) { -+ condlog(1, "%s called with empty mpp", __func__); -+ return NULL; -+ } -+ -+ devnum = makedev(mpp->dmi.major, mpp->dmi.minor); -+ udd = udev_device_new_from_devnum(udev, 'b', devnum); -+ if (!udd) { -+ condlog(1, "failed to get udev device for %s", mpp->alias); -+ return NULL; -+ } -+ return udd; -+} -diff --git a/libmultipath/sysfs.h b/libmultipath/sysfs.h -index 2db86bd6..3be3f665 100644 ---- a/libmultipath/sysfs.h -+++ b/libmultipath/sysfs.h -@@ -39,4 +39,8 @@ do { \ - int sysfs_get_size (struct path *pp, unsigned long long * size); - int sysfs_check_holders(char * check_devt, char * new_devt); - bool sysfs_is_multipathed(struct path *pp, bool set_wwid); -+ -+struct multipath; -+struct udev_device *get_udev_for_mpp(const struct multipath *mpp); -+ - #endif diff --git a/0024-libmultipath-add-mp_find_path_by_devt.patch b/0024-libmultipath-add-mp_find_path_by_devt.patch deleted file mode 100644 index 8a85be2..0000000 --- a/0024-libmultipath-add-mp_find_path_by_devt.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 17 Apr 2024 14:57:33 +0200 -Subject: [PATCH] libmultipath: add mp_find_path_by_devt() - -A helper function that searches a struct multipath by dev_t, and -works whether or not mpp->paths is currently available. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/structs.c | 19 +++++++++++++++++++ - libmultipath/structs.h | 3 +++ - 2 files changed, 22 insertions(+) - -diff --git a/libmultipath/structs.c b/libmultipath/structs.c -index 74e31a13..e248fb51 100644 ---- a/libmultipath/structs.c -+++ b/libmultipath/structs.c -@@ -526,6 +526,25 @@ find_path_by_devt (const struct _vector *pathvec, const char * dev_t) - return NULL; - } - -+struct path *mp_find_path_by_devt(const struct multipath *mpp, const char *devt) -+{ -+ struct path *pp; -+ struct pathgroup *pgp; -+ unsigned int i, j; -+ -+ pp = find_path_by_devt(mpp->paths, devt); -+ if (pp) -+ return pp; -+ -+ vector_foreach_slot (mpp->pg, pgp, i){ -+ vector_foreach_slot (pgp->paths, pp, j){ -+ if (!strcmp(pp->dev_t, devt)) -+ return pp; -+ } -+ } -+ return NULL; -+} -+ - static int do_pathcount(const struct multipath *mpp, const int *states, - unsigned int nr_states) - { -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index 734905e2..a25eb9d5 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -568,6 +568,9 @@ struct path * find_path_by_devt (const struct _vector *pathvec, const char *devt - struct path * find_path_by_dev (const struct _vector *pathvec, const char *dev); - struct path * first_path (const struct multipath *mpp); - -+struct path *mp_find_path_by_devt(const struct multipath *mpp, const char *devt); -+ -+ - int pathcount (const struct multipath *, int); - int count_active_paths(const struct multipath *); - int count_active_pending_paths(const struct multipath *); diff --git a/0025-Revert-libmultipath-fix-max_sectors_kb-on-adding-pat.patch b/0025-Revert-libmultipath-fix-max_sectors_kb-on-adding-pat.patch deleted file mode 100644 index aaa0e9f..0000000 --- a/0025-Revert-libmultipath-fix-max_sectors_kb-on-adding-pat.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 11 Apr 2024 17:20:14 +0200 -Subject: [PATCH] Revert "libmultipath: fix max_sectors_kb on adding path" - -This reverts commit bbb77f318ee483292f50a7782aecaecc7e60f727. -Reviewed-by: Benjamin Marzinski - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 89ac03d5..13602f3f 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -575,12 +575,11 @@ sysfs_set_max_sectors_kb(struct multipath *mpp, int is_reload) - ssize_t len; - int i, j, ret, err = 0; - struct udev_device *udd; -- int max_sectors_kb = mpp->max_sectors_kb; -+ int max_sectors_kb; - -- /* by default, do not initialize max_sectors_kb on the device */ -- if (max_sectors_kb == MAX_SECTORS_KB_UNDEF && !is_reload) -+ if (mpp->max_sectors_kb == MAX_SECTORS_KB_UNDEF) - return 0; -- /* on reload, re-apply the user tuning on all the path devices */ -+ max_sectors_kb = mpp->max_sectors_kb; - if (is_reload) { - if (!has_dm_info(mpp) && - dm_get_info(mpp->alias, &mpp->dmi) != 0) { diff --git a/0026-libmultipath-Only-set-max_sectors_kb-on-map-creation.patch b/0026-libmultipath-Only-set-max_sectors_kb-on-map-creation.patch deleted file mode 100644 index c82cfe7..0000000 --- a/0026-libmultipath-Only-set-max_sectors_kb-on-map-creation.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 16 Apr 2024 22:20:46 +0200 -Subject: [PATCH] libmultipath: Only set max_sectors_kb on map creation - -Changing max_sectors_kb on a live map is dangerous. When I/O occurs while the -max_sectors_kb value of a map is larger than that of any of its paths, I/O -errors like this may result: - - blk_insert_cloned_request: over max size limit. (127 > 126) - -This situation must be strictly avoided. The kernel makes sure that the -map's limits match those of the paths when the map is created. But setting -max_sectors_kb on path devices before reloading is dangerous, even if we -read the value from the map's max_sectors_kb beforehand. The reason for -this is that the sysfs value max_sectors_kb is the kernel's max_sectors -divided by 2, and user space has no way to figure out if the kernel-internal -value is odd or even. Thus by writing back the value just read to -max_sectors_kb, one might actually decrease the kernel value by one. - -The only safe way to set max_sectors_kb on a live map would be to suspend -it, flushing all outstanding IO, then the path max_sectors_kb, reload, -and resume. - -Since commit 8fd4868 ("libmultipath: don't set max_sectors_kb on reloads"), -we don't set the configured max_sectors_kb any more. But as shown above, -this is not safe. So really only set max_sectors_kb when creating a map. - -Users who have stacked block devices on top of multipath, as described in the -commit message of 8fd4868 must make sure that the max_sectors_kb setting is -correct when the multipath map is first created. Decreasing the map's -max_sectors_kb value (without touching the paths) should actually be possible -in this situation, because stacked block devices are usually bio-based, and -bio-based IO (in contrast to request-based) can be split if the lower-level -device has can't handle the size of the I/O. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 38 ++++---------------------------------- - 1 file changed, 4 insertions(+), 34 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 13602f3f..8cbb2a88 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -566,46 +566,18 @@ trigger_paths_udev_change(struct multipath *mpp, bool is_mpath) - mpp->needs_paths_uevent = 0; - } - --static int --sysfs_set_max_sectors_kb(struct multipath *mpp, int is_reload) -+static int sysfs_set_max_sectors_kb(struct multipath *mpp) - { - struct pathgroup * pgp; - struct path *pp; - char buff[11]; - ssize_t len; - int i, j, ret, err = 0; -- struct udev_device *udd; -- int max_sectors_kb; - - if (mpp->max_sectors_kb == MAX_SECTORS_KB_UNDEF) - return 0; -- max_sectors_kb = mpp->max_sectors_kb; -- if (is_reload) { -- if (!has_dm_info(mpp) && -- dm_get_info(mpp->alias, &mpp->dmi) != 0) { -- condlog(1, "failed to get dm info for %s", mpp->alias); -- return 1; -- } -- udd = get_udev_for_mpp(mpp); -- if (!udd) { -- condlog(1, "failed to get udev device to set max_sectors_kb for %s", mpp->alias); -- return 1; -- } -- ret = sysfs_attr_get_value(udd, "queue/max_sectors_kb", buff, -- sizeof(buff)); -- udev_device_unref(udd); -- if (!sysfs_attr_value_ok(ret, sizeof(buff))) { -- condlog(1, "failed to get current max_sectors_kb from %s", mpp->alias); -- return 1; -- } -- if (sscanf(buff, "%u\n", &max_sectors_kb) != 1) { -- condlog(1, "can't parse current max_sectors_kb from %s", -- mpp->alias); -- return 1; -- } -- } -- snprintf(buff, 11, "%d", max_sectors_kb); -- len = strlen(buff); -+ -+ len = snprintf(buff, sizeof(buff), "%d", mpp->max_sectors_kb); - - vector_foreach_slot (mpp->pg, pgp, i) { - vector_foreach_slot(pgp->paths, pp, j) { -@@ -923,7 +895,7 @@ int domap(struct multipath *mpp, char *params, int is_daemon) - return DOMAP_RETRY; - } - -- sysfs_set_max_sectors_kb(mpp, 0); -+ sysfs_set_max_sectors_kb(mpp); - if (is_daemon && mpp->ghost_delay > 0 && count_active_paths(mpp) && - pathcount(mpp, PATH_UP) == 0) - mpp->ghost_delay_tick = mpp->ghost_delay; -@@ -934,7 +906,6 @@ int domap(struct multipath *mpp, char *params, int is_daemon) - - case ACT_RELOAD: - case ACT_RELOAD_RENAME: -- sysfs_set_max_sectors_kb(mpp, 1); - if (mpp->ghost_delay_tick > 0 && pathcount(mpp, PATH_UP)) - mpp->ghost_delay_tick = 0; - r = dm_addmap_reload(mpp, params, 0); -@@ -942,7 +913,6 @@ int domap(struct multipath *mpp, char *params, int is_daemon) - - case ACT_RESIZE: - case ACT_RESIZE_RENAME: -- sysfs_set_max_sectors_kb(mpp, 1); - if (mpp->ghost_delay_tick > 0 && pathcount(mpp, PATH_UP)) - mpp->ghost_delay_tick = 0; - r = dm_addmap_reload(mpp, params, 1); diff --git a/0027-libmultipath-set-max_sectors_kb-in-adopt_paths.patch b/0027-libmultipath-set-max_sectors_kb-in-adopt_paths.patch deleted file mode 100644 index a4389df..0000000 --- a/0027-libmultipath-set-max_sectors_kb-in-adopt_paths.patch +++ /dev/null @@ -1,233 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 16 Apr 2024 23:59:03 +0200 -Subject: [PATCH] libmultipath: set max_sectors_kb in adopt_paths() - -As explained in the previous commit, setting max_sectors_kb for -paths that are members of a live map is dangerous. But as long as -a path is not a member of a map, setting max_sectors_kb poses no risk. -Set the parameter in adopt_paths(), for paths that aren't members -of the map yet. In order to determine whether or not a path is currently -member of the map, adopt_paths() needs to passed the current member list. If -(and only if) it's called from coalesce_paths(), the passed struct multipath -doesn not represent the current state of the map; adopt_paths() must therefore -get a new argument current_mpp that represents the kernel state. - -We must still call sysfs_set_max_sectors_kb() from domap() in the ACT_CREATE -case, because when adopt_paths is called from coalesce_paths() for a map that -doesn't exist yet, mpp->max_sectors_kb is not set. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 2 +- - libmultipath/structs_vec.c | 62 ++++++++++++++++++++++++++++++++++---- - libmultipath/structs_vec.h | 6 ++-- - multipathd/main.c | 6 ++-- - tests/Makefile | 2 +- - tests/test-lib.c | 9 +++++- - 6 files changed, 73 insertions(+), 14 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 8cbb2a88..b5c701fa 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -1105,7 +1105,7 @@ int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid, - /* - * at this point, we know we really got a new mp - */ -- mpp = add_map_with_path(vecs, pp1, 0); -+ mpp = add_map_with_path(vecs, pp1, 0, cmpp); - if (!mpp) { - orphan_path(pp1, "failed to create multipath device"); - continue; -diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c -index 0fc608c2..c0c5cc90 100644 ---- a/libmultipath/structs_vec.c -+++ b/libmultipath/structs_vec.c -@@ -242,7 +242,38 @@ static bool update_pathvec_from_dm(vector pathvec, struct multipath *mpp, - return must_reload; - } - --int adopt_paths(vector pathvec, struct multipath *mpp) -+static bool set_path_max_sectors_kb(const struct path *pp, int max_sectors_kb) -+{ -+ char buf[11]; -+ ssize_t len; -+ int ret, current; -+ bool rc = false; -+ -+ if (max_sectors_kb == MAX_SECTORS_KB_UNDEF) -+ return rc; -+ -+ if (sysfs_attr_get_value(pp->udev, "queue/max_sectors_kb", buf, sizeof(buf)) <= 0 -+ || sscanf(buf, "%d\n", ¤t) != 1) -+ current = MAX_SECTORS_KB_UNDEF; -+ if (current == max_sectors_kb) -+ return rc; -+ -+ len = snprintf(buf, sizeof(buf), "%d", max_sectors_kb); -+ ret = sysfs_attr_set_value(pp->udev, "queue/max_sectors_kb", buf, len); -+ if (ret != len) -+ log_sysfs_attr_set_value(3, ret, -+ "failed setting max_sectors_kb on %s", -+ pp->dev); -+ else { -+ condlog(3, "%s: set max_sectors_kb to %d for %s", __func__, -+ max_sectors_kb, pp->dev); -+ rc = true; -+ } -+ return rc; -+} -+ -+int adopt_paths(vector pathvec, struct multipath *mpp, -+ const struct multipath *current_mpp) - { - int i, ret; - struct path * pp; -@@ -285,9 +316,28 @@ int adopt_paths(vector pathvec, struct multipath *mpp) - continue; - } - -- if (!find_path_by_devt(mpp->paths, pp->dev_t) && -- store_path(mpp->paths, pp)) -- goto err; -+ if (!find_path_by_devt(mpp->paths, pp->dev_t)) { -+ -+ if (store_path(mpp->paths, pp)) -+ goto err; -+ /* -+ * Setting max_sectors_kb on live paths is dangerous. -+ * But we can do it here on a path that isn't yet part -+ * of the map. If this value is lower than the current -+ * max_sectors_kb and the map is reloaded, the map's -+ * max_sectors_kb will be safely adjusted by the kernel. -+ * -+ * We must make sure that the path is not part of the -+ * map yet. Normally we can check this in mpp->paths. -+ * But if adopt_paths is called from coalesce_paths, -+ * we need to check the separate struct multipath that -+ * has been obtained from map_discovery(). -+ */ -+ if (!current_mpp || -+ !mp_find_path_by_devt(current_mpp, pp->dev_t)) -+ mpp->need_reload = mpp->need_reload || -+ set_path_max_sectors_kb(pp, mpp->max_sectors_kb); -+ } - - pp->mpp = mpp; - condlog(3, "%s: ownership set to %s", -@@ -693,7 +743,7 @@ find_existing_alias (struct multipath * mpp, - } - - struct multipath *add_map_with_path(struct vectors *vecs, struct path *pp, -- int add_vec) -+ int add_vec, const struct multipath *current_mpp) - { - struct multipath * mpp; - struct config *conf = NULL; -@@ -721,7 +771,7 @@ struct multipath *add_map_with_path(struct vectors *vecs, struct path *pp, - goto out; - mpp->size = pp->size; - -- if (adopt_paths(vecs->pathvec, mpp) || pp->mpp != mpp || -+ if (adopt_paths(vecs->pathvec, mpp, current_mpp) || pp->mpp != mpp || - find_slot(mpp->paths, pp) == -1) - goto out; - -diff --git a/libmultipath/structs_vec.h b/libmultipath/structs_vec.h -index 3253f1bb..dbc43058 100644 ---- a/libmultipath/structs_vec.h -+++ b/libmultipath/structs_vec.h -@@ -13,7 +13,8 @@ struct vectors { - - void set_no_path_retry(struct multipath *mpp); - --int adopt_paths (vector pathvec, struct multipath * mpp); -+int adopt_paths (vector pathvec, struct multipath *mpp, -+ const struct multipath *current_mpp); - void orphan_path (struct path * pp, const char *reason); - void set_path_removed(struct path *pp); - -@@ -28,7 +29,8 @@ void remove_maps (struct vectors * vecs); - - void sync_map_state (struct multipath *); - struct multipath * add_map_with_path (struct vectors * vecs, -- struct path * pp, int add_vec); -+ struct path * pp, int add_vec, -+ const struct multipath *current_mpp); - void update_queue_mode_del_path(struct multipath *mpp); - void update_queue_mode_add_path(struct multipath *mpp); - int update_multipath_table (struct multipath *mpp, vector pathvec, int flags); -diff --git a/multipathd/main.c b/multipathd/main.c -index dd17d5c3..d8518a92 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -636,7 +636,7 @@ update_map (struct multipath *mpp, struct vectors *vecs, int new_map) - - retry: - condlog(4, "%s: updating new map", mpp->alias); -- if (adopt_paths(vecs->pathvec, mpp)) { -+ if (adopt_paths(vecs->pathvec, mpp, NULL)) { - condlog(0, "%s: failed to adopt paths for new map update", - mpp->alias); - retries = -1; -@@ -1231,7 +1231,7 @@ rescan: - if (mpp) { - condlog(4,"%s: adopting all paths for path %s", - mpp->alias, pp->dev); -- if (adopt_paths(vecs->pathvec, mpp) || pp->mpp != mpp || -+ if (adopt_paths(vecs->pathvec, mpp, NULL) || pp->mpp != mpp || - find_slot(mpp->paths, pp) == -1) - goto fail; /* leave path added to pathvec */ - -@@ -1245,7 +1245,7 @@ rescan: - return 0; - } - condlog(4,"%s: creating new map", pp->dev); -- if ((mpp = add_map_with_path(vecs, pp, 1))) { -+ if ((mpp = add_map_with_path(vecs, pp, 1, NULL))) { - mpp->action = ACT_CREATE; - /* - * We don't depend on ACT_CREATE, as domap will -diff --git a/tests/Makefile b/tests/Makefile -index d1d52dde..4005204a 100644 ---- a/tests/Makefile -+++ b/tests/Makefile -@@ -45,7 +45,7 @@ dmevents-test_OBJDEPS = $(multipathdir)/devmapper.o - dmevents-test_LIBDEPS = -lpthread -ldevmapper -lurcu - hwtable-test_TESTDEPS := test-lib.o - hwtable-test_OBJDEPS := $(multipathdir)/discovery.o $(multipathdir)/blacklist.o \ -- $(multipathdir)/structs.o $(multipathdir)/propsel.o -+ $(multipathdir)/structs_vec.o $(multipathdir)/structs.o $(multipathdir)/propsel.o - hwtable-test_LIBDEPS := -ludev -lpthread -ldl - blacklist-test_TESTDEPS := test-log.o - blacklist-test_LIBDEPS := -ludev -diff --git a/tests/test-lib.c b/tests/test-lib.c -index cdb2780d..88f35e94 100644 ---- a/tests/test-lib.c -+++ b/tests/test-lib.c -@@ -152,6 +152,13 @@ int __wrap_sysfs_get_size(struct path *pp, unsigned long long *sz) - return 0; - } - -+int __wrap_sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, -+ const char * value, size_t value_len) -+{ -+ condlog(5, "%s: %s", __func__, value); -+ return value_len; -+} -+ - void *__wrap_udev_device_get_parent_with_subsystem_devtype( - struct udev_device *ud, const char *subsys, char *type) - { -@@ -400,7 +407,7 @@ struct multipath *__mock_multipath(struct vectors *vecs, struct path *pp) - /* pathinfo() call in adopt_paths */ - mock_pathinfo(DI_CHECKER|DI_PRIO, &mop); - -- mp = add_map_with_path(vecs, pp, 1); -+ mp = add_map_with_path(vecs, pp, 1, NULL); - assert_ptr_not_equal(mp, NULL); - - /* TBD: mock setup_map() ... */ diff --git a/0028-libmultipath-add-wildcard-k-for-printing-max_sectors.patch b/0028-libmultipath-add-wildcard-k-for-printing-max_sectors.patch deleted file mode 100644 index 9b66bbb..0000000 --- a/0028-libmultipath-add-wildcard-k-for-printing-max_sectors.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 17 Apr 2024 17:19:43 +0200 -Subject: [PATCH] libmultipath: add wildcard %k for printing max_sectors_kb - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/print.c | 38 ++++++++++++++++++++++++++++++++++++++ - 1 file changed, 38 insertions(+) - -diff --git a/libmultipath/print.c b/libmultipath/print.c -index 360308d2..efd5a16a 100644 ---- a/libmultipath/print.c -+++ b/libmultipath/print.c -@@ -32,6 +32,7 @@ - #include "util.h" - #include "foreign.h" - #include "strbuf.h" -+#include "sysfs.h" - - #define PRINT_PATH_LONG "%w %i %d %D %p %t %T %s %o" - #define PRINT_PATH_INDENT "%i %d %D %t %T %o" -@@ -431,6 +432,27 @@ snprint_multipath_vpd_data(struct strbuf *buff, - return append_strbuf_str(buff, "[undef]"); - } - -+static void cleanup_udev_device(struct udev_device **udd) -+{ -+ if (*udd) -+ udev_device_unref(*udd); -+} -+ -+static int -+snprint_multipath_max_sectors_kb(struct strbuf *buff, const struct multipath *mpp) -+{ -+ char buf[11]; -+ int max_sectors_kb; -+ struct udev_device *udd __attribute__((cleanup(cleanup_udev_device))) -+ = get_udev_for_mpp(mpp); -+ -+ if (!udd || -+ sysfs_attr_get_value(udd, "queue/max_sectors_kb", buf, sizeof(buf)) <= 0 || -+ sscanf(buf, "%d\n", &max_sectors_kb) != 1) -+ return print_strbuf(buff, "n/a"); -+ return print_strbuf(buff, "%d", max_sectors_kb); -+} -+ - /* - * path info printing functions - */ -@@ -790,6 +812,20 @@ snprint_alua_tpg(struct strbuf *buff, const struct path * pp) - return print_strbuf(buff, "0x%04x", pp->tpg_id); - } - -+static int -+snprint_path_max_sectors_kb(struct strbuf *buff, const struct path *pp) -+{ -+ char buf[11]; -+ int max_sectors_kb; -+ -+ if (!pp->udev || -+ sysfs_attr_get_value(pp->udev, "queue/max_sectors_kb", -+ buf, sizeof(buf)) <= 0 || -+ sscanf(buf, "%d\n", &max_sectors_kb) != 1) -+ return print_strbuf(buff, "n/a"); -+ return print_strbuf(buff, "%d", max_sectors_kb); -+} -+ - static const struct multipath_data mpd[] = { - {'n', "name", snprint_name}, - {'w', "uuid", snprint_multipath_uuid}, -@@ -815,6 +851,7 @@ static const struct multipath_data mpd[] = { - {'e', "rev", snprint_multipath_rev}, - {'G', "foreign", snprint_multipath_foreign}, - {'g', "vpd page data", snprint_multipath_vpd_data}, -+ {'k', "max_sectors_kb",snprint_multipath_max_sectors_kb}, - }; - - static const struct path_data pd[] = { -@@ -845,6 +882,7 @@ static const struct path_data pd[] = { - {'I', "init_st", snprint_initialized}, - {'L', "LUN hex", snprint_path_lunhex}, - {'A', "TPG", snprint_alua_tpg}, -+ {'k', "max_sectors_kb",snprint_path_max_sectors_kb}, - }; - - static const struct pathgroup_data pgd[] = { diff --git a/0029-multipath.conf-5-update-documentation-for-max_sector.patch b/0029-multipath.conf-5-update-documentation-for-max_sector.patch deleted file mode 100644 index dcdf164..0000000 --- a/0029-multipath.conf-5-update-documentation-for-max_sector.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 17 Apr 2024 18:59:04 +0200 -Subject: [PATCH] multipath.conf(5): update documentation for max_sectors_kb - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/multipath.conf.5.in | 33 +++++++++++++++++++++++++++++---- - 1 file changed, 29 insertions(+), 4 deletions(-) - -diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in -index c788c180..b29a75fe 100644 ---- a/multipath/multipath.conf.5.in -+++ b/multipath/multipath.conf.5.in -@@ -1311,11 +1311,36 @@ The default is: \fB0\fR - . - .TP - .B max_sectors_kb --Sets the max_sectors_kb device parameter on all path devices and the multipath --device to the specified value. -+Sets the \fImax_sectors_kb\fR device parameter on some path devices and the multipath -+device to the specified value. \fImax_sectors_kb\fR is the largest I/O size, in units -+of 1024 bytes, that the kernel allows for a single I/O request. For hardware devices -+like SCSI disks, this value is limited by the capabilities of the hardware. -+It is crucial that the value of a multipath map is never higher than the minimum value of -+of all its path devices. This is ensured by the kernel when a multipath map -+is loaded, but manipulating the values of a map or either of its paths while the -+map is live can cause race conditions and I/O errors. Therefore this value is only -+enforced by multipathd when a multipath map is first created, or when a path device -+is added to a map. In both cases, race conditions are avoided by the kernel. - .RS --.TP --The default is: in \fB/sys/block//queue/max_sectors_kb\fR -+.PP -+Setting \fImax_sectors_kb\fR does not guarantee that all path devices will have this -+value set. It is not an error if the value of a path device is higher than that of -+the containing multipath map. It is also not an error if the actual limit of a map is -+lower than the value in \fI@CONFIGFILE@\fR. This can happen if the hardware limits of one -+or more path devices are lower than the configured value. -+.PP -+Normally the kernel and its device drivers take care of the maximum -+I/O size, and administrators do not need to bother about \fImax_sectors_kb\fR. -+But some hardware devices may report incorrect I/O size limits, or other components -+in the environment (e.g. the fabric) may impose constraints that the kernel cannot -+detect. In such cases setting \fImax_sectors_kb\fR makes sense. It should be set when -+maps are first created, and not be changed thereafter. -+If the setting \fBmust\fR be changed for a live map, set the -+value in \fI@CONFIGFILE@\fR, run \fBmultipathd reconfigure\fR, and use -+\fBmultipathd del path \fR and \fBmultipathd add path \fR to -+delete and re-add the same path device. -+.LP -+The default is: \fBundefined\fR. - .RE - . - . diff --git a/0030-multipath-tools-simplify-comment-in-hwtable.patch b/0030-multipath-tools-simplify-comment-in-hwtable.patch deleted file mode 100644 index 59090a7..0000000 --- a/0030-multipath-tools-simplify-comment-in-hwtable.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Sun, 28 Apr 2024 01:45:35 +0200 -Subject: [PATCH] multipath-tools: simplify comment in hwtable - -Instead of adding the new 5300 model, replace them with wildcards. - -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez -Reviewed-by: Benjamin Marzinski -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/hwtable.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index 640bf347..7aac3f37 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -683,8 +683,8 @@ static struct hwentry default_hw[] = { - .pgfailback = -FAILBACK_IMMEDIATE, - }, - { -- // Storwize V5000/V7000 lines / SAN Volume Controller (SVC) / Flex System V7000 -- // FlashSystem V840/V9000/5000/5100/5200/7200/7300/9100/9200/9200R/9500 -+ // Storwize V5000/V7000 lines / SAN Volume Controller (SVC) -+ // Flex System V7000 / FlashSystem V840/V9000 and 5x00/7x00/9x00 - .vendor = "IBM", - .product = "^2145", - .no_path_retry = NO_PATH_RETRY_QUEUE, diff --git a/0031-multipath-tools-unify-text-in-multipath.conf.5.patch b/0031-multipath-tools-unify-text-in-multipath.conf.5.patch deleted file mode 100644 index b6d9af3..0000000 --- a/0031-multipath-tools-unify-text-in-multipath.conf.5.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Sun, 28 Apr 2024 01:45:36 +0200 -Subject: [PATCH] multipath-tools: unify text in multipath.conf.5 - -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez -Reviewed-by: Benjamin Marzinski -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - multipath/multipath.conf.5.in | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - -diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in -index b29a75fe..c1a19ebb 100644 ---- a/multipath/multipath.conf.5.in -+++ b/multipath/multipath.conf.5.in -@@ -187,7 +187,7 @@ The default is: \fBno\fR - . - .TP - .B multipath_dir --(Deprecated) This option is not supported anymore, and the value is ignored. -+(Deprecated) This option is not supported anymore, and will be ignored. - . - . - .TP -@@ -277,7 +277,7 @@ The default is: \fBno\fR - . - .TP - .B pg_timeout --(Deprecated) This option is not supported anymore, and the value is ignored. -+(Deprecated) This option is not supported anymore, and will be ignored. - . - . - .TP -@@ -322,7 +322,7 @@ The default is: \fBID_WWN\fR, for NVMe devices - . - .TP - .B getuid_callout --(Deprecated) This option is not supported anymore, and the value is ignored. -+(Deprecated) This option is not supported anymore, and will be ignored. - . - . - .TP -@@ -995,7 +995,7 @@ The default is: \fB\fR - . - .TP - .B config_dir --(Deprecated) This option is not supported anymore, and the value is ignored. -+(Deprecated) This option is not supported anymore, and will be ignored. - .RS - .TP - The compiled-in value is: \fB@CONFIGDIR@\fR -@@ -1295,7 +1295,7 @@ The default is: \fBno\fR - . - .TP - .B disable_changed_wwids --(Deprecated) This option is not supported anymore, and the value is ignored. -+(Deprecated) This option is not supported anymore, and will be ignored. - .RE - . - . -@@ -1340,7 +1340,7 @@ value in \fI@CONFIGFILE@\fR, run \fBmultipathd reconfigure\fR, and use - \fBmultipathd del path \fR and \fBmultipathd add path \fR to - delete and re-add the same path device. - .LP --The default is: \fBundefined\fR. -+The default is: \fB\fR - .RE - . - . diff --git a/0032-multipath-tools-update-man-pages-dates.patch b/0032-multipath-tools-update-man-pages-dates.patch deleted file mode 100644 index c011eac..0000000 --- a/0032-multipath-tools-update-man-pages-dates.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Sun, 28 Apr 2024 01:45:37 +0200 -Subject: [PATCH] multipath-tools: update man pages dates - -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez -Reviewed-by: Benjamin Marzinski -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmpathpersist/mpath_persistent_reserve_in.3 | 2 +- - libmpathpersist/mpath_persistent_reserve_out.3 | 2 +- - multipath/multipath.8.in | 2 +- - multipath/multipath.conf.5.in | 2 +- - multipathd/multipathd.8.in | 2 +- - 5 files changed, 5 insertions(+), 5 deletions(-) - -diff --git a/libmpathpersist/mpath_persistent_reserve_in.3 b/libmpathpersist/mpath_persistent_reserve_in.3 -index 6cc35349..4ac43fa3 100644 ---- a/libmpathpersist/mpath_persistent_reserve_in.3 -+++ b/libmpathpersist/mpath_persistent_reserve_in.3 -@@ -6,7 +6,7 @@ - .\" Update the date below if you make any significant change. - .\" ---------------------------------------------------------------------------- - . --.TH MPATH_PERSISTENT_RESERVE_IN 3 2018-06-15 Linux -+.TH MPATH_PERSISTENT_RESERVE_IN 3 2024-02-09 Linux - . - . - .\" ---------------------------------------------------------------------------- -diff --git a/libmpathpersist/mpath_persistent_reserve_out.3 b/libmpathpersist/mpath_persistent_reserve_out.3 -index 70e26028..3dbeae1f 100644 ---- a/libmpathpersist/mpath_persistent_reserve_out.3 -+++ b/libmpathpersist/mpath_persistent_reserve_out.3 -@@ -6,7 +6,7 @@ - .\" Update the date below if you make any significant change. - .\" ---------------------------------------------------------------------------- - . --.TH MPATH_PERSISTENT_RESERVE_OUT 3 2018-06-15 Linux -+.TH MPATH_PERSISTENT_RESERVE_OUT 3 2024-02-09 Linux - . - . - .\" ---------------------------------------------------------------------------- -diff --git a/multipath/multipath.8.in b/multipath/multipath.8.in -index 348eb220..b88e9a4c 100644 ---- a/multipath/multipath.8.in -+++ b/multipath/multipath.8.in -@@ -6,7 +6,7 @@ - .\" Update the date below if you make any significant change. - .\" ---------------------------------------------------------------------------- - . --.TH MULTIPATH 8 2021-11-12 Linux -+.TH MULTIPATH 8 2023-09-08 Linux - . - . - .\" ---------------------------------------------------------------------------- -diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in -index c1a19ebb..46d3685a 100644 ---- a/multipath/multipath.conf.5.in -+++ b/multipath/multipath.conf.5.in -@@ -6,7 +6,7 @@ - .\" Update the date below if you make any significant change. - .\" ---------------------------------------------------------------------------- - . --.TH MULTIPATH.CONF 5 2023-06-15 Linux -+.TH MULTIPATH.CONF 5 2024-04-17 Linux - . - . - .\" ---------------------------------------------------------------------------- -diff --git a/multipathd/multipathd.8.in b/multipathd/multipathd.8.in -index f1cab3ff..12b77156 100644 ---- a/multipathd/multipathd.8.in -+++ b/multipathd/multipathd.8.in -@@ -6,7 +6,7 @@ - .\" Update the date below if you make any significant change. - .\" ---------------------------------------------------------------------------- - . --.TH MULTIPATHD 8 2022-09-03 Linux -+.TH MULTIPATHD 8 2023-12-19 Linux - . - . - .\" ---------------------------------------------------------------------------- diff --git a/0033-libmultipath-export-partmap_in_use.patch b/0033-libmultipath-export-partmap_in_use.patch deleted file mode 100644 index 47a6772..0000000 --- a/0033-libmultipath-export-partmap_in_use.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 25 Apr 2024 19:35:13 -0400 -Subject: [PATCH] libmultipath: export partmap_in_use - -A future commit will make use of this function - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck -Reviewed-by: Benjamin Marzinski ---- - libmultipath/devmapper.c | 2 +- - libmultipath/devmapper.h | 1 + - libmultipath/libmultipath.version | 1 + - 3 files changed, 3 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index 4ce7e82f..a87abf7e 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -1043,7 +1043,7 @@ has_partmap(const char *name __attribute__((unused)), - return 1; - } - --static int -+int - partmap_in_use(const char *name, void *data) - { - int part_count, *ret_count = (int *)data; -diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h -index a7d66604..93caa2aa 100644 ---- a/libmultipath/devmapper.h -+++ b/libmultipath/devmapper.h -@@ -57,6 +57,7 @@ enum { - DM_FLUSH_BUSY, - }; - -+int partmap_in_use(const char *name, void *data); - int _dm_flush_map (const char *, int, int, int, int); - int dm_flush_map_nopaths(const char * mapname, int deferred_remove); - #define dm_flush_map(mapname) _dm_flush_map(mapname, 1, 0, 0, 0) -diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version -index 724786d5..e070f296 100644 ---- a/libmultipath/libmultipath.version -+++ b/libmultipath/libmultipath.version -@@ -141,6 +141,7 @@ global: - need_io_err_check; - orphan_path; - parse_prkey_flags; -+ partmap_in_use; - pathcount; - path_discovery; - path_get_tpgs; diff --git a/0034-libmultipath-change-flush_on_last_del-to-fix-a-multi.patch b/0034-libmultipath-change-flush_on_last_del-to-fix-a-multi.patch deleted file mode 100644 index 7c36521..0000000 --- a/0034-libmultipath-change-flush_on_last_del-to-fix-a-multi.patch +++ /dev/null @@ -1,346 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 25 Apr 2024 19:35:14 -0400 -Subject: [PATCH] libmultipath: change flush_on_last_del to fix a multipathd - hang - -Commit 9bd3482e ("multipathd: make flush_map() delete maps like the -multipath command") fixed an issue where deleting a queueing multipath -device through multipathd could hang because the multipath device had -outstanding IO, even though the only openers of it at the time of -deletion were the kpartx partition devices. However it is still possible -to hang multipathd, because autoremoving the device when all paths have -been deleted doesn't disable queueing. To reproduce this hang: - -1. create a multipath device with a kpartx partition on top of it and -no_path_retry set to either "queue" or something long enough to run all -the commands in the reproducer before it disables queueing. -2. disable all the paths to the device with something like: - # echo offline > /sys/block//device/state -3. Write directly to the multipath device with something like: - # dd if=/dev/zero of=/dev/mapper/ bs=4K count=1 -4. delete all the paths to the device with something like: - # echo 1 > /sys/block//device/delete - -Multipathd will hang trying to delete the kpartx device because, as the -last opener, it must flush the multipath device before closing it. -Because it hangs holding the vecs_lock, multipathd will never disable -queueing on the device, so it will hang forever, even if no_path_retry -is set to a number. - -This hang can occur, even if deferred_remove is set. Since nothing has -the kpartx device opened, device-mapper does an immediate remove, which -will still hang. This means that even if deferred_remove is set, -multipathd still cannot delete a map while queueing is enabled. It must -either disable queueing or skip the autoremove. - -Mulitpath can currently be configured to avoid this hang by setting - -flush_on_last_del yes - -However there are good reasons why users wouldn't want to set that. They -may need to be able to survive having all paths getting temporarily -deleted. I should note that this is a pretty rare corner case, since -multipath automatically sets dev_loss_tmo so that it should not trigger -before queueing is disabled. - -This commit avoids the hang by changing the possible values for -flush_on_last_del to "never", "unused", and "always", and sets the -default to "unused". "always" works like "yes" did, "never" will not -disable queueing, and "unused" will only disable queueing if nothing has -the kpartx devices or the multipath device open. In order to be safe, if -the device has queue_if_no_paths set (and in case of "unused", the -device is in-use) the autoremove will be skipped. Also, instead of just -trusting the lack of "queue_if_no_paths" in the current mpp->features, -multipathd will tell the kernel to disable queueing, just to be sure it -actually is. - -I chose "unused" as the default because this should generally only cause -multipathd to work differently from the users perspective when nothing -has the multipath device open but it is queueing and there is -outstanding IO. Without this change, it would have hung instead of -failing the outstanding IO. However, I do understand that an argument -could be made that "never" makes more sense as default, even though it -will cause multipathd to skip autoremoves in cases where it wouldn't -before. The change to the behavior of deffered_remove will be -noticeable, but skipping an autoremove is much better than hanging. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck -Reviewed-by: Benjamin Marzinski ---- - libmultipath/defaults.h | 2 +- - libmultipath/dict.c | 72 +++++++++++++++++++++++++++++++---- - libmultipath/dict.h | 1 + - libmultipath/hwtable.c | 6 +-- - libmultipath/propsel.c | 4 +- - libmultipath/structs.h | 7 ++-- - multipath/multipath.conf.5.in | 20 +++++++--- - multipathd/main.c | 39 +++++++++++++++---- - 8 files changed, 122 insertions(+), 29 deletions(-) - -diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h -index 64b633f2..ed08c251 100644 ---- a/libmultipath/defaults.h -+++ b/libmultipath/defaults.h -@@ -43,7 +43,7 @@ - #define DEFAULT_PRIO PRIO_CONST - #define DEFAULT_PRIO_ARGS "" - #define DEFAULT_CHECKER TUR --#define DEFAULT_FLUSH FLUSH_DISABLED -+#define DEFAULT_FLUSH FLUSH_UNUSED - #define DEFAULT_USER_FRIENDLY_NAMES USER_FRIENDLY_NAMES_OFF - #define DEFAULT_FORCE_SYNC 0 - #define UNSET_PARTITION_DELIM "/UNSET/" -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index 5af036b7..546103f2 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -791,14 +791,70 @@ declare_def_snprint(checker_timeout, print_nonzero) - declare_def_handler(allow_usb_devices, set_yes_no) - declare_def_snprint(allow_usb_devices, print_yes_no) - --declare_def_handler(flush_on_last_del, set_yes_no_undef) --declare_def_snprint_defint(flush_on_last_del, print_yes_no_undef, DEFAULT_FLUSH) --declare_ovr_handler(flush_on_last_del, set_yes_no_undef) --declare_ovr_snprint(flush_on_last_del, print_yes_no_undef) --declare_hw_handler(flush_on_last_del, set_yes_no_undef) --declare_hw_snprint(flush_on_last_del, print_yes_no_undef) --declare_mp_handler(flush_on_last_del, set_yes_no_undef) --declare_mp_snprint(flush_on_last_del, print_yes_no_undef) -+ -+static const char * const flush_on_last_del_optvals[] = { -+ [FLUSH_NEVER] = "never", -+ [FLUSH_ALWAYS] = "always", -+ [FLUSH_UNUSED] = "unused", -+}; -+ -+static int -+set_flush_on_last_del(vector strvec, void *ptr, const char *file, int line_nr) -+{ -+ int i; -+ int *flush_val_ptr = (int *)ptr; -+ char *buff; -+ -+ buff = set_value(strvec); -+ if (!buff) -+ return 1; -+ -+ for (i = FLUSH_NEVER; i <= FLUSH_UNUSED; i++) { -+ if (flush_on_last_del_optvals[i] != NULL && -+ !strcmp(buff, flush_on_last_del_optvals[i])) { -+ *flush_val_ptr = i; -+ break; -+ } -+ } -+ -+ if (i > FLUSH_UNUSED) { -+ bool deprecated = true; -+ if (strcmp(buff, "no") == 0 || strcmp(buff, "0") == 0) -+ *flush_val_ptr = FLUSH_UNUSED; -+ else if (strcmp(buff, "yes") == 0 || strcmp(buff, "1") == 0) -+ *flush_val_ptr = FLUSH_ALWAYS; -+ else { -+ deprecated = false; -+ condlog(1, "%s line %d, invalid value for flush_on_last_del: \"%s\"", -+ file, line_nr, buff); -+ } -+ if (deprecated) -+ condlog(2, "%s line %d, \"%s\" is a deprecated value for flush_on_last_del and is treated as \"%s\"", -+ file, line_nr, buff, -+ flush_on_last_del_optvals[*flush_val_ptr]); -+ } -+ -+ free(buff); -+ return 0; -+} -+ -+int -+print_flush_on_last_del(struct strbuf *buff, long v) -+{ -+ if (v == FLUSH_UNDEF) -+ return 0; -+ return append_strbuf_quoted(buff, flush_on_last_del_optvals[(int)v]); -+} -+ -+declare_def_handler(flush_on_last_del, set_flush_on_last_del) -+declare_def_snprint_defint(flush_on_last_del, print_flush_on_last_del, -+ DEFAULT_FLUSH) -+declare_ovr_handler(flush_on_last_del, set_flush_on_last_del) -+declare_ovr_snprint(flush_on_last_del, print_flush_on_last_del) -+declare_hw_handler(flush_on_last_del, set_flush_on_last_del) -+declare_hw_snprint(flush_on_last_del, print_flush_on_last_del) -+declare_mp_handler(flush_on_last_del, set_flush_on_last_del) -+declare_mp_snprint(flush_on_last_del, print_flush_on_last_del) - - declare_def_handler(user_friendly_names, set_yes_no_undef) - declare_def_snprint_defint(user_friendly_names, print_yes_no_undef, -diff --git a/libmultipath/dict.h b/libmultipath/dict.h -index 7e2dfbe0..e1794537 100644 ---- a/libmultipath/dict.h -+++ b/libmultipath/dict.h -@@ -18,4 +18,5 @@ int print_undef_off_zero(struct strbuf *buff, long v); - int print_dev_loss(struct strbuf *buff, unsigned long v); - int print_off_int_undef(struct strbuf *buff, long v); - int print_auto_resize(struct strbuf *buff, long v); -+int print_flush_on_last_del(struct strbuf *buff, long v); - #endif /* _DICT_H */ -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index 7aac3f37..d1148de7 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -60,7 +60,7 @@ - .no_path_retry = NO_PATH_RETRY_UNDEF, - .minio = 1000, - .minio_rq = 1, -- .flush_on_last_del = FLUSH_DISABLED, -+ .flush_on_last_del = FLUSH_UNUSED, - .user_friendly_names = USER_FRIENDLY_NAMES_OFF, - .fast_io_fail = 5, - .dev_loss = 600, -@@ -829,7 +829,7 @@ static struct hwentry default_hw[] = { - .no_path_retry = NO_PATH_RETRY_QUEUE, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, -- .flush_on_last_del = FLUSH_ENABLED, -+ .flush_on_last_del = FLUSH_ALWAYS, - .dev_loss = MAX_DEV_LOSS_TMO, - .prio_name = PRIO_ONTAP, - .user_friendly_names = USER_FRIENDLY_NAMES_OFF, -@@ -1160,7 +1160,7 @@ static struct hwentry default_hw[] = { - .no_path_retry = NO_PATH_RETRY_FAIL, - .minio = 1, - .minio_rq = 1, -- .flush_on_last_del = FLUSH_ENABLED, -+ .flush_on_last_del = FLUSH_ALWAYS, - .fast_io_fail = 15, - }, - /* -diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c -index 44241e2a..e2dcb316 100644 ---- a/libmultipath/propsel.c -+++ b/libmultipath/propsel.c -@@ -963,6 +963,7 @@ out: - int select_flush_on_last_del(struct config *conf, struct multipath *mp) - { - const char *origin; -+ STRBUF_ON_STACK(buff); - - mp_set_mpe(flush_on_last_del); - mp_set_ovr(flush_on_last_del); -@@ -970,8 +971,9 @@ int select_flush_on_last_del(struct config *conf, struct multipath *mp) - mp_set_conf(flush_on_last_del); - mp_set_default(flush_on_last_del, DEFAULT_FLUSH); - out: -+ print_flush_on_last_del(&buff, mp->flush_on_last_del); - condlog(3, "%s: flush_on_last_del = %s %s", mp->alias, -- (mp->flush_on_last_del == FLUSH_ENABLED)? "yes" : "no", origin); -+ get_strbuf_str(&buff), origin); - return 0; - } - -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index a25eb9d5..dbaf4d43 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -109,9 +109,10 @@ enum marginal_pathgroups_mode { - }; - - enum flush_states { -- FLUSH_UNDEF = YNU_UNDEF, -- FLUSH_DISABLED = YNU_NO, -- FLUSH_ENABLED = YNU_YES, -+ FLUSH_UNDEF, -+ FLUSH_NEVER, -+ FLUSH_ALWAYS, -+ FLUSH_UNUSED, - }; - - enum log_checker_err_states { -diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in -index 46d3685a..1d3d53bb 100644 ---- a/multipath/multipath.conf.5.in -+++ b/multipath/multipath.conf.5.in -@@ -707,12 +707,22 @@ The default is: \fBno\fR - .TP - .B flush_on_last_del - If set to --.I yes -+.I always - , multipathd will disable queueing when the last path to a device has been --deleted. --.RS --.TP --The default is: \fBno\fR -+deleted. If set to -+.I never -+, multipathd will not disable queueing when the last path to a device has -+been deleted. Since multipath cannot safely remove a device while queueing -+is enabled, setting this to \fInever\fR means that multipathd will not -+automatically remove an unused multipath device whose paths are all deleted if -+it is currently set to queue_if_no_path. If set to -+.I unused -+, multipathd will only disable queueing when the last path is removed if -+nothing currently has the multipath device or any of the kpartx partition -+devices on top of it open. -+.RS -+.TP -+The default is: \fBunused\fR - .RE - . - . -diff --git a/multipathd/main.c b/multipathd/main.c -index d8518a92..09286dd0 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -584,19 +584,42 @@ int update_multipath (struct vectors *vecs, char *mapname) - static bool - flush_map_nopaths(struct multipath *mpp, struct vectors *vecs) { - int r; -+ bool is_queueing = true; - -+ if (mpp->features) -+ is_queueing = strstr(mpp->features, "queue_if_no_path"); -+ -+ /* It's not safe to do a remove of a map that has "queue_if_no_path" -+ * set, since there could be outstanding IO which will cause -+ * multipathd to hang while attempting the remove */ -+ if (mpp->flush_on_last_del == FLUSH_NEVER && is_queueing) { -+ condlog(2, "%s: map is queueing, can't remove", mpp->alias); -+ return false; -+ } -+ if (mpp->flush_on_last_del == FLUSH_UNUSED && -+ partmap_in_use(mpp->alias, NULL) && is_queueing) { -+ condlog(2, "%s: map in use and queueing, can't remove", -+ mpp->alias); -+ return false; -+ } - /* -- * flush_map will fail if the device is open -+ * This will flush FLUSH_NEVER devices and FLUSH_UNUSED devices -+ * that are in use, but only if they are already marked as not -+ * queueing. That is just to make absolutely certain that they -+ * really are not queueing, like they claim. - */ -- if (mpp->flush_on_last_del == FLUSH_ENABLED) { -- condlog(2, "%s Last path deleted, disabling queueing", -+ condlog(is_queueing ? 2 : 3, "%s Last path deleted, disabling queueing", -+ mpp->alias); -+ mpp->retry_tick = 0; -+ mpp->no_path_retry = NO_PATH_RETRY_FAIL; -+ mpp->disable_queueing = 1; -+ mpp->stat_map_failures++; -+ if (dm_queue_if_no_path(mpp, 0) != 0) { -+ condlog(0, "%s: failed to disable queueing. Not removing", - mpp->alias); -- mpp->retry_tick = 0; -- mpp->no_path_retry = NO_PATH_RETRY_FAIL; -- mpp->disable_queueing = 1; -- mpp->stat_map_failures++; -- dm_queue_if_no_path(mpp, 0); -+ return false; - } -+ - r = dm_flush_map_nopaths(mpp->alias, mpp->deferred_remove); - if (r != DM_FLUSH_OK) { - if (r == DM_FLUSH_DEFERRED) { diff --git a/0035-libmultipath-remove-redundant-config-option-from-Inf.patch b/0035-libmultipath-remove-redundant-config-option-from-Inf.patch deleted file mode 100644 index 8de5639..0000000 --- a/0035-libmultipath-remove-redundant-config-option-from-Inf.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 25 Apr 2024 19:35:15 -0400 -Subject: [PATCH] libmultipath: remove redundant config option from InfiniBox - config - -The InfiniBox config already sets no_path_retry to "fail", so it won't -ever queue IO. That means setting flush_on_last_del to "always" is -redundant, since queueing is always disabled. Remove the -flush_on_last_del parameter, to make it easier for users to override the -default behavior if desired. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck -Reviewed-by: Benjamin Marzinski ---- - libmultipath/hwtable.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index d1148de7..9e008df6 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -1160,7 +1160,6 @@ static struct hwentry default_hw[] = { - .no_path_retry = NO_PATH_RETRY_FAIL, - .minio = 1, - .minio_rq = 1, -- .flush_on_last_del = FLUSH_ALWAYS, - .fast_io_fail = 15, - }, - /* diff --git a/0036-libmultipath-pad-dev_loss_tmo-to-avoid-race-with-no_.patch b/0036-libmultipath-pad-dev_loss_tmo-to-avoid-race-with-no_.patch deleted file mode 100644 index f61f658..0000000 --- a/0036-libmultipath-pad-dev_loss_tmo-to-avoid-race-with-no_.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 25 Apr 2024 19:35:16 -0400 -Subject: [PATCH] libmultipath: pad dev_loss_tmo to avoid race with - no_path_retry - -Currently multipath makes sure that dev_loss_tmo is at least as long as -the configured no path queueing time. The goal is to make sure that path -devices aren't removed while the multipath device is still queueing in -hopes that they will become usable again. - -This is racy. Multipathd may take longer to check the paths than -configured. If strict_timing isn't set, it will definitely take longer. -To account for this, pad the minimum dev_loss_tmo value by five seconds -(one default checker interval) plus one second per minute of no path -queueing time. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck -Reviewed-by: Benjamin Marzinski ---- - libmultipath/discovery.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 6fd4dabb..e2052422 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -901,6 +901,11 @@ sysfs_set_scsi_tmo (struct config *conf, struct multipath *mpp) - uint64_t no_path_retry_tmo = - (uint64_t)mpp->no_path_retry * conf->checkint; - -+ /* pad no_path_retry_tmo by one standard check interval -+ * plus one second per minute to account for timing -+ * issues with the rechecks */ -+ no_path_retry_tmo += no_path_retry_tmo / 60 + DEFAULT_CHECKINT; -+ - if (no_path_retry_tmo > MAX_DEV_LOSS_TMO) - min_dev_loss = MAX_DEV_LOSS_TMO; - else diff --git a/0037-libmultipath-fix-deferred_remove-function-arguments.patch b/0037-libmultipath-fix-deferred_remove-function-arguments.patch deleted file mode 100644 index 507a056..0000000 --- a/0037-libmultipath-fix-deferred_remove-function-arguments.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 25 Apr 2024 19:35:17 -0400 -Subject: [PATCH] libmultipath: fix deferred_remove function arguments - -Aside from one version of dm_flush_map_nopaths(), all the callers of -_dm_flush_map() and dm_simplecmd() set deferred_remove to 0. But these -functions, as well as some helper functions they called, all treated the -deferred_remove argument as an enum deferred_remove_states, and called -do_deferred() to see if the remove should be deferred. To simplify the -code, make these functions treat deferred_remove as a boolean value -signifying whether a remove is deferred, and make dm_flush_map_nopaths() -do the work of checking if the remove should be deferred. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck -Reviewed-by: Benjamin Marzinski ---- - libmultipath/devmapper.c | 19 +++++++++---------- - libmultipath/libmultipath.version | 2 +- - 2 files changed, 10 insertions(+), 11 deletions(-) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index a87abf7e..2e7b2c64 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -386,8 +386,6 @@ libmp_dm_task_create(int task) - return dm_task_create(task); - } - --#define do_deferred(x) ((x) == DEFERRED_REMOVE_ON || (x) == DEFERRED_REMOVE_IN_PROGRESS) -- - static int - dm_simplecmd (int task, const char *name, int no_flush, int need_sync, - uint16_t udev_flags, int deferred_remove __DR_UNUSED__) { -@@ -411,7 +409,7 @@ dm_simplecmd (int task, const char *name, int no_flush, int need_sync, - dm_task_no_flush(dmt); /* for DM_DEVICE_SUSPEND/RESUME */ - #endif - #ifdef LIBDM_API_DEFERRED -- if (do_deferred(deferred_remove)) -+ if (deferred_remove) - dm_task_deferred_remove(dmt); - #endif - if (udev_wait_flag && -@@ -1082,7 +1080,7 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, - - /* If you aren't doing a deferred remove, make sure that no - * devices are in use */ -- if (!do_deferred(deferred_remove) && partmap_in_use(mapname, NULL)) -+ if (!deferred_remove && partmap_in_use(mapname, NULL)) - return DM_FLUSH_BUSY; - - if (need_suspend && -@@ -1100,7 +1098,7 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, - if ((r = dm_remove_partmaps(mapname, need_sync, deferred_remove))) - return r; - -- if (!do_deferred(deferred_remove) && dm_get_opencount(mapname)) { -+ if (!deferred_remove && dm_get_opencount(mapname)) { - condlog(2, "%s: map in use", mapname); - return DM_FLUSH_BUSY; - } -@@ -1112,8 +1110,7 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, - r = dm_device_remove(mapname, need_sync, deferred_remove); - - if (r) { -- if (do_deferred(deferred_remove) -- && dm_map_present(mapname)) { -+ if (deferred_remove && dm_map_present(mapname)) { - condlog(4, "multipath map %s remove deferred", - mapname); - return DM_FLUSH_DEFERRED; -@@ -1147,7 +1144,10 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, - int - dm_flush_map_nopaths(const char * mapname, int deferred_remove) - { -- return _dm_flush_map(mapname, 1, deferred_remove, 0, 0); -+ return _dm_flush_map(mapname, 1, -+ (deferred_remove == DEFERRED_REMOVE_ON || -+ deferred_remove == DEFERRED_REMOVE_IN_PROGRESS), -+ 0, 0); - } - - #else -@@ -1539,8 +1539,7 @@ remove_partmap(const char *name, void *data) - - if (dm_get_opencount(name)) { - dm_remove_partmaps(name, rd->need_sync, rd->deferred_remove); -- if (!do_deferred(rd->deferred_remove) && -- dm_get_opencount(name)) { -+ if (rd->deferred_remove && dm_get_opencount(name)) { - condlog(2, "%s: map in use", name); - return DM_FLUSH_BUSY; - } -diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version -index e070f296..eb511749 100644 ---- a/libmultipath/libmultipath.version -+++ b/libmultipath/libmultipath.version -@@ -43,7 +43,7 @@ LIBMPATHCOMMON_1.0.0 { - put_multipath_config; - }; - --LIBMULTIPATH_23.0.0 { -+LIBMULTIPATH_24.0.0 { - global: - /* symbols referenced by multipath and multipathd */ - add_foreign; diff --git a/0038-libmultipath-use-bitwise-flags-for-map-flushing-API.patch b/0038-libmultipath-use-bitwise-flags-for-map-flushing-API.patch deleted file mode 100644 index ef922ec..0000000 --- a/0038-libmultipath-use-bitwise-flags-for-map-flushing-API.patch +++ /dev/null @@ -1,212 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 2 May 2024 18:38:24 +0200 -Subject: [PATCH] libmultipath: use bitwise flags for map flushing API - -Rather than passing 3 separate bool variables to _dm_flush_map(), -define bitwise flags to modify the function's behavior, and pass -these flags to called functions accordingly. - -This improves the readability of the code, function calls are -more expressive. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/devmapper.c | 68 +++++++++++++++++----------------------- - libmultipath/devmapper.h | 18 ++++++++--- - 2 files changed, 41 insertions(+), 45 deletions(-) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index 2e7b2c64..a6a9c2b7 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -53,9 +53,8 @@ static int dm_cancel_remove_partmaps(const char * mapname); - #define __DR_UNUSED__ __attribute__((unused)) - #endif - --static int dm_remove_partmaps (const char * mapname, int need_sync, -- int deferred_remove); --static int do_foreach_partmaps(const char * mapname, -+static int dm_remove_partmaps (const char *mapname, int flags); -+static int do_foreach_partmaps(const char *mapname, - int (*partmap_func)(const char *, void *), - void *data); - static int _dm_queue_if_no_path(const char *mapname, int enable); -@@ -439,9 +438,9 @@ int dm_simplecmd_noflush (int task, const char *name, uint16_t udev_flags) - } - - static int --dm_device_remove (const char *name, int needsync, int deferred_remove) { -- return dm_simplecmd(DM_DEVICE_REMOVE, name, 0, needsync, 0, -- deferred_remove); -+dm_device_remove (const char *name, int flags) { -+ return dm_simplecmd(DM_DEVICE_REMOVE, name, 0, flags & DMFL_NEED_SYNC, 0, -+ flags & DMFL_DEFERRED); - } - - static int -@@ -1061,8 +1060,7 @@ partmap_in_use(const char *name, void *data) - return 0; - } - --int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, -- int need_suspend, int retries) -+int _dm_flush_map (const char *mapname, int flags, int retries) - { - int r; - int queue_if_no_path = 0; -@@ -1080,10 +1078,10 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, - - /* If you aren't doing a deferred remove, make sure that no - * devices are in use */ -- if (!deferred_remove && partmap_in_use(mapname, NULL)) -+ if (!(flags & DMFL_DEFERRED) && partmap_in_use(mapname, NULL)) - return DM_FLUSH_BUSY; - -- if (need_suspend && -+ if ((flags & DMFL_SUSPEND) && - dm_get_map(mapname, &mapsize, ¶ms) == DMP_OK && - strstr(params, "queue_if_no_path")) { - if (!_dm_queue_if_no_path(mapname, 0)) -@@ -1095,22 +1093,22 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, - free(params); - params = NULL; - -- if ((r = dm_remove_partmaps(mapname, need_sync, deferred_remove))) -+ if ((r = dm_remove_partmaps(mapname, flags))) - return r; - -- if (!deferred_remove && dm_get_opencount(mapname)) { -+ if (!(flags & DMFL_DEFERRED) && dm_get_opencount(mapname)) { - condlog(2, "%s: map in use", mapname); - return DM_FLUSH_BUSY; - } - - do { -- if (need_suspend && queue_if_no_path != -1) -+ if ((flags & DMFL_SUSPEND) && queue_if_no_path != -1) - dm_simplecmd_flush(DM_DEVICE_SUSPEND, mapname, 0); - -- r = dm_device_remove(mapname, need_sync, deferred_remove); -+ r = dm_device_remove(mapname, flags); - - if (r) { -- if (deferred_remove && dm_map_present(mapname)) { -+ if ((flags & DMFL_DEFERRED) && dm_map_present(mapname)) { - condlog(4, "multipath map %s remove deferred", - mapname); - return DM_FLUSH_DEFERRED; -@@ -1124,7 +1122,7 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, - } else { - condlog(2, "failed to remove multipath map %s", - mapname); -- if (need_suspend && queue_if_no_path != -1) { -+ if ((flags & DMFL_SUSPEND) && queue_if_no_path != -1) { - dm_simplecmd_noflush(DM_DEVICE_RESUME, - mapname, udev_flags); - } -@@ -1139,27 +1137,18 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, - return DM_FLUSH_FAIL; - } - --#ifdef LIBDM_API_DEFERRED -- - int --dm_flush_map_nopaths(const char * mapname, int deferred_remove) -+dm_flush_map_nopaths(const char *mapname, int deferred_remove __DR_UNUSED__) - { -- return _dm_flush_map(mapname, 1, -- (deferred_remove == DEFERRED_REMOVE_ON || -- deferred_remove == DEFERRED_REMOVE_IN_PROGRESS), -- 0, 0); --} -- --#else -- --int --dm_flush_map_nopaths(const char * mapname, -- int deferred_remove __attribute__((unused))) --{ -- return _dm_flush_map(mapname, 1, 0, 0, 0); --} -+ int flags = DMFL_NEED_SYNC; - -+#ifdef LIBDM_API_DEFERRED -+ flags |= ((deferred_remove == DEFERRED_REMOVE_ON || -+ deferred_remove == DEFERRED_REMOVE_IN_PROGRESS) ? -+ DMFL_DEFERRED : 0); - #endif -+ return _dm_flush_map(mapname, flags, 0); -+} - - int dm_flush_maps (int retries) - { -@@ -1528,8 +1517,7 @@ out: - } - - struct remove_data { -- int need_sync; -- int deferred_remove; -+ int flags; - }; - - static int -@@ -1538,21 +1526,21 @@ remove_partmap(const char *name, void *data) - struct remove_data *rd = (struct remove_data *)data; - - if (dm_get_opencount(name)) { -- dm_remove_partmaps(name, rd->need_sync, rd->deferred_remove); -- if (rd->deferred_remove && dm_get_opencount(name)) { -+ dm_remove_partmaps(name, rd->flags); -+ if ((rd->flags & DMFL_DEFERRED) && dm_get_opencount(name)) { - condlog(2, "%s: map in use", name); - return DM_FLUSH_BUSY; - } - } - condlog(4, "partition map %s removed", name); -- dm_device_remove(name, rd->need_sync, rd->deferred_remove); -+ dm_device_remove(name, rd->flags); - return DM_FLUSH_OK; - } - - static int --dm_remove_partmaps (const char * mapname, int need_sync, int deferred_remove) -+dm_remove_partmaps (const char * mapname, int flags) - { -- struct remove_data rd = { need_sync, deferred_remove }; -+ struct remove_data rd = { flags }; - return do_foreach_partmaps(mapname, remove_partmap, &rd); - } - -diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h -index 93caa2aa..bb4a55a6 100644 ---- a/libmultipath/devmapper.h -+++ b/libmultipath/devmapper.h -@@ -58,12 +58,20 @@ enum { - }; - - int partmap_in_use(const char *name, void *data); --int _dm_flush_map (const char *, int, int, int, int); --int dm_flush_map_nopaths(const char * mapname, int deferred_remove); --#define dm_flush_map(mapname) _dm_flush_map(mapname, 1, 0, 0, 0) --#define dm_flush_map_nosync(mapname) _dm_flush_map(mapname, 0, 0, 0, 0) -+ -+enum { -+ DMFL_NONE = 0, -+ DMFL_NEED_SYNC = 1 << 0, -+ DMFL_DEFERRED = 1 << 1, -+ DMFL_SUSPEND = 1 << 2, -+}; -+ -+int _dm_flush_map (const char *mapname, int flags, int retries); -+#define dm_flush_map(mapname) _dm_flush_map(mapname, DMFL_NEED_SYNC, 0) -+#define dm_flush_map_nosync(mapname) _dm_flush_map(mapname, DMFL_NONE, 0) - #define dm_suspend_and_flush_map(mapname, retries) \ -- _dm_flush_map(mapname, 1, 0, 1, retries) -+ _dm_flush_map(mapname, DMFL_NEED_SYNC|DMFL_SUSPEND, retries) -+int dm_flush_map_nopaths(const char * mapname, int deferred_remove); - int dm_cancel_deferred_remove(struct multipath *mpp); - int dm_flush_maps (int retries); - int dm_fail_path(const char * mapname, char * path); diff --git a/0039-libmultipath-use-bitwise-flags-for-dm_simplecmd-API.patch b/0039-libmultipath-use-bitwise-flags-for-dm_simplecmd-API.patch deleted file mode 100644 index 1aee878..0000000 --- a/0039-libmultipath-use-bitwise-flags-for-dm_simplecmd-API.patch +++ /dev/null @@ -1,117 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 2 May 2024 18:45:17 +0200 -Subject: [PATCH] libmultipath: use bitwise flags for dm_simplecmd API - -Also use bitwise flags for dm_simplecmd() and its relatives. Again, -this makes the code more expressive and more readable, while -simplifying the function calls. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/devmapper.c | 26 +++++++++++++------------- - libmultipath/devmapper.h | 5 +++-- - 2 files changed, 16 insertions(+), 15 deletions(-) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index a6a9c2b7..08bb3c51 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -386,10 +386,9 @@ libmp_dm_task_create(int task) - } - - static int --dm_simplecmd (int task, const char *name, int no_flush, int need_sync, -- uint16_t udev_flags, int deferred_remove __DR_UNUSED__) { -+dm_simplecmd (int task, const char *name, int flags, uint16_t udev_flags) { - int r = 0; -- int udev_wait_flag = ((need_sync || udev_flags) && -+ int udev_wait_flag = (((flags & DMFL_NEED_SYNC) || udev_flags) && - (task == DM_DEVICE_RESUME || - task == DM_DEVICE_REMOVE)); - uint32_t cookie = 0; -@@ -404,11 +403,11 @@ dm_simplecmd (int task, const char *name, int no_flush, int need_sync, - dm_task_no_open_count(dmt); - dm_task_skip_lockfs(dmt); /* for DM_DEVICE_RESUME */ - #ifdef LIBDM_API_FLUSH -- if (no_flush) -+ if (flags & DMFL_NO_FLUSH) - dm_task_no_flush(dmt); /* for DM_DEVICE_SUSPEND/RESUME */ - #endif - #ifdef LIBDM_API_DEFERRED -- if (deferred_remove) -+ if (flags & DMFL_DEFERRED) - dm_task_deferred_remove(dmt); - #endif - if (udev_wait_flag && -@@ -429,18 +428,17 @@ out: - - int dm_simplecmd_flush (int task, const char *name, uint16_t udev_flags) - { -- return dm_simplecmd(task, name, 0, 1, udev_flags, 0); -+ return dm_simplecmd(task, name, DMFL_NEED_SYNC, udev_flags); - } - - int dm_simplecmd_noflush (int task, const char *name, uint16_t udev_flags) - { -- return dm_simplecmd(task, name, 1, 1, udev_flags, 0); -+ return dm_simplecmd(task, name, DMFL_NO_FLUSH|DMFL_NEED_SYNC, udev_flags); - } - - static int - dm_device_remove (const char *name, int flags) { -- return dm_simplecmd(DM_DEVICE_REMOVE, name, 0, flags & DMFL_NEED_SYNC, 0, -- flags & DMFL_DEFERRED); -+ return dm_simplecmd(DM_DEVICE_REMOVE, name, flags, 0); - } - - static int -@@ -594,8 +592,9 @@ int dm_addmap_reload(struct multipath *mpp, char *params, int flush) - params, ADDMAP_RO, 0); - } - if (r) -- r = dm_simplecmd(DM_DEVICE_RESUME, mpp->alias, !flush, -- 1, udev_flags, 0); -+ r = dm_simplecmd(DM_DEVICE_RESUME, mpp->alias, -+ DMFL_NEED_SYNC | (flush ? 0 : DMFL_NO_FLUSH), -+ udev_flags); - if (r) - return r; - -@@ -603,8 +602,9 @@ int dm_addmap_reload(struct multipath *mpp, char *params, int flush) - * drop the new table, so doing a second resume will try using - * the original table */ - if (dm_is_suspended(mpp->alias)) -- dm_simplecmd(DM_DEVICE_RESUME, mpp->alias, !flush, 1, -- udev_flags, 0); -+ dm_simplecmd(DM_DEVICE_RESUME, mpp->alias, -+ DMFL_NEED_SYNC | (flush ? 0 : DMFL_NO_FLUSH), -+ udev_flags); - return 0; - } - -diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h -index bb4a55a6..a242381e 100644 ---- a/libmultipath/devmapper.h -+++ b/libmultipath/devmapper.h -@@ -38,8 +38,8 @@ void skip_libmp_dm_init(void); - void libmp_dm_exit(void); - void libmp_udev_set_sync_support(int on); - struct dm_task *libmp_dm_task_create(int task); --int dm_simplecmd_flush (int, const char *, uint16_t); --int dm_simplecmd_noflush (int, const char *, uint16_t); -+int dm_simplecmd_flush (int task, const char *name, uint16_t udev_flags); -+int dm_simplecmd_noflush (int task, const char *name, uint16_t udev_flags); - int dm_addmap_create (struct multipath *mpp, char *params); - int dm_addmap_reload (struct multipath *mpp, char *params, int flush); - int dm_map_present (const char *); -@@ -64,6 +64,7 @@ enum { - DMFL_NEED_SYNC = 1 << 0, - DMFL_DEFERRED = 1 << 1, - DMFL_SUSPEND = 1 << 2, -+ DMFL_NO_FLUSH = 1 << 3, - }; - - int _dm_flush_map (const char *mapname, int flags, int retries); diff --git a/0040-libmultipath-add-argument-names-to-some-prototypes.patch b/0040-libmultipath-add-argument-names-to-some-prototypes.patch deleted file mode 100644 index 3244d55..0000000 --- a/0040-libmultipath-add-argument-names-to-some-prototypes.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 2 May 2024 18:46:42 +0200 -Subject: [PATCH] libmultipath: add argument names to some prototypes - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/devmapper.h | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h -index a242381e..19b79c5b 100644 ---- a/libmultipath/devmapper.h -+++ b/libmultipath/devmapper.h -@@ -42,12 +42,12 @@ int dm_simplecmd_flush (int task, const char *name, uint16_t udev_flags); - int dm_simplecmd_noflush (int task, const char *name, uint16_t udev_flags); - int dm_addmap_create (struct multipath *mpp, char *params); - int dm_addmap_reload (struct multipath *mpp, char *params, int flush); --int dm_map_present (const char *); -+int dm_map_present (const char *name); - int dm_map_present_by_uuid(const char *uuid); --int dm_get_map(const char *, unsigned long long *, char **); --int dm_get_status(const char *, char **); --int dm_type(const char *, char *); --int dm_is_mpath(const char *); -+int dm_get_map(const char *name, unsigned long long *size, char **outparams); -+int dm_get_status(const char *name, char **outstatus); -+int dm_type(const char *name, char *type); -+int dm_is_mpath(const char *name); - - enum { - DM_FLUSH_OK = 0, diff --git a/0041-libmultipath-bump-version-to-0.9.9.patch b/0041-libmultipath-bump-version-to-0.9.9.patch deleted file mode 100644 index 890b047..0000000 --- a/0041-libmultipath-bump-version-to-0.9.9.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 3 May 2024 22:09:10 +0200 -Subject: [PATCH] libmultipath: bump version to 0.9.9 - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/version.h | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/version.h b/libmultipath/version.h -index e102975f..271d8e74 100644 ---- a/libmultipath/version.h -+++ b/libmultipath/version.h -@@ -20,9 +20,9 @@ - #ifndef _VERSION_H - #define _VERSION_H - --#define VERSION_CODE 0x000908 -+#define VERSION_CODE 0x000909 - /* MMDDYY, in hex */ --#define DATE_CODE 0x020F18 -+#define DATE_CODE 0x050318 - - #define PROG "multipath-tools" - diff --git a/0042-GitHub-Workflows-native.yaml-run-for-Fedora-40.patch b/0042-GitHub-Workflows-native.yaml-run-for-Fedora-40.patch deleted file mode 100644 index 47c3949..0000000 --- a/0042-GitHub-Workflows-native.yaml-run-for-Fedora-40.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 3 May 2024 22:28:34 +0200 -Subject: [PATCH] GitHub Workflows: native.yaml: run for Fedora 40 - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/native.yaml | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml -index 0ef9df94..a062845e 100644 ---- a/.github/workflows/native.yaml -+++ b/.github/workflows/native.yaml -@@ -33,7 +33,7 @@ jobs: - - debian-buster - - debian-bullseye - - debian-bookworm -- - fedora-39 -+ - fedora-40 - - opensuse-leap - container: ghcr.io/mwilck/multipath-build-${{ matrix.os }} - steps: diff --git a/0043-update-NEWS.md.patch b/0043-update-NEWS.md.patch deleted file mode 100644 index 4edc69d..0000000 --- a/0043-update-NEWS.md.patch +++ /dev/null @@ -1,134 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 3 May 2024 23:11:48 +0200 -Subject: [PATCH] update NEWS.md - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .github/actions/spelling/expect.txt | 3 ++ - .github/actions/spelling/patterns.txt | 3 +- - NEWS.md | 62 +++++++++++++++++++++++++++ - 3 files changed, 67 insertions(+), 1 deletion(-) - -diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt -index fc9f22f8..bdfce83a 100644 ---- a/.github/actions/spelling/expect.txt -+++ b/.github/actions/spelling/expect.txt -@@ -17,6 +17,7 @@ blkid - bmarzins - cciss - CFLAGS -+cgroups - christophe - clangd - clariion -@@ -67,6 +68,7 @@ fulldescr - gcc - getprkey - getprstatus -+getrlimit - getuid - github - GPT -@@ -170,6 +172,7 @@ rootprefixdir - rpmbuild - rport - rtpi -+rtprio - sas - sbp - scsi -diff --git a/.github/actions/spelling/patterns.txt b/.github/actions/spelling/patterns.txt -index 858faee6..aa361654 100644 ---- a/.github/actions/spelling/patterns.txt -+++ b/.github/actions/spelling/patterns.txt -@@ -22,7 +22,7 @@ - \bdmmp_pgs\b - \bdmmp_mpath_kdev_name_get\b - \bfast_io_fail_tmo\b --\bLimitRTPRIO\b -+\bLimitRTPRIO=?\b - \bmax_fds\b - \bmissing_uev_wait_timeout\b - \bMPATH_MAX_PARAM_LEN\b -@@ -87,6 +87,7 @@ - \bprin_resvdescr\b - \bprout_param_descriptor\b - \brq_servact\b -+\bRLIMIT_RTPRIO\b - \bSCHED_RT_PRIO\b - \bssize_t\b - \btrnptid_list\b -diff --git a/NEWS.md b/NEWS.md -index 0b094b98..4c54afa0 100644 ---- a/NEWS.md -+++ b/NEWS.md -@@ -1,5 +1,67 @@ - # multipath-tools Release Notes - -+## multipath-tools 0.9.9, 2024/05 -+ -+### User-Visible Changes -+ -+* *Changed realtime scheduling:* multipathd used to run at the highest possible -+ realtime priority, 99. This has always been excessive, and on some -+ distributions (e.g. RHEL 8), it hasn't worked at all. It is now possible to -+ set multipathd's real time scheduling by setting the hard limit for -+ `RLIMIT_RTPRIO` (see getrlimit(2)), which corresponds to the `rtprio` -+ setting in limits.conf and to `LimitRTPRIO=` in the systemd unit file. The -+ default in the systemd unit file has been set to 10. If the limit is set to -+ 0, multipathd doesn't attempt to enable real-time scheduling. -+ Otherwise, it will try to set the scheduling priority to the given value. -+ Fixes [#82](https://github.com/opensvc/multipath-tools/issues/82). -+* *Changed normal scheduling:* In order to make sure that multipathd has -+ sufficient priority even if real time scheduling is switched off, the -+ `CPUWeight=` setting in the unit file is set to 1000. This is necessary -+ because regular nice(2) values have no effect in systems with cgroups enabled. -+* *Changed handling of `max_sectors_kb` configuration:* multipathd applies -+ the `max_sectors_kb` setting only during map creation, or when a new path is -+ added to an existing map. The kernel makes sure that the multipath device -+ never has a larger `max_sectors_kb` value than any of its configured path -+ devices. The reason for this change is that applying `max_sectors_kb` on -+ live maps can cause IO errors and data loss in rare situations. -+ It can now happen that some path devices have a higher `max_sectors_kb` -+ value than the map; this is not an error. It is not possible any more to -+ decrease `max_sectors_kb` in `multipath.conf` and run `multipathd -+ reconfigure` to "apply" this setting to the map and its paths. If decreasing -+ the IO size is necessary, either destroy and recreate the map, or remove one -+ path with `multipathd del path $PATH`, run `multipathd reconfigure`, and -+ re-add the path with `multipathd add path $PATH`. -+* *New wildcard %k:* The wildcard `%k` for `max_sectors_kb` has been added to -+ the `multipathd show paths format` and `multipathd show maps format` -+ commands. -+* *Changed semantics of flush_on_last_del:* The `flush_on_last_del` option -+ now takes the values `always` , `unused`, or `never`. `yes` and `no` -+ are still accepted as aliases for `always` and `unused`, respectively. -+ `always` means that when all paths for a multipath map have been removed, -+ *outstanding IO will be failed* and the map will be deleted. `unused` means -+ that this will only happen when the map is not mounted or otherwise opened. -+ `never` means the map will only be removed if the `queue_if_no_path` -+ feature is off. -+ This fixes a problem where multipathd could hang when the last path of -+ a queueing map was deleted. -+ -+### Other major changes -+ -+* Adapted the dm-mpath udev rules such that they will work with the modified -+ device mapper udev rules (`DM_UDEV_RULES_VSN==3`, lvm2 > 2.03.22). They are -+ still compatible with older versions of the device-mapper udev rules. -+ -+### Bug fixes -+ -+* Fixed misspelled DM_UDEV_DISABLE_OTHER_RULES_FLAG in 11-dm-mpath.rules -+* Always use `glibc_basename()` to avoid some issues with MUSL libc. -+ Fixes [#84](https://github.com/opensvc/multipath-tools/pull/84). -+ -+### Other -+ -+* Build: added `TGTDIR` option to simplify building for a different target -+ host (see README.md). -+ - ## multipath-tools 0.9.8, 2024/02 - - ### User-Visible Changes diff --git a/0044-multipath.conf.5.in-fix-man-page-date.patch b/0044-multipath.conf.5.in-fix-man-page-date.patch deleted file mode 100644 index c9f2d5d..0000000 --- a/0044-multipath.conf.5.in-fix-man-page-date.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 3 May 2024 23:22:50 +0200 -Subject: [PATCH] multipath.conf.5.in: fix man page date - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - multipath/multipath.conf.5.in | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in -index 1d3d53bb..dacb9b0e 100644 ---- a/multipath/multipath.conf.5.in -+++ b/multipath/multipath.conf.5.in -@@ -6,7 +6,7 @@ - .\" Update the date below if you make any significant change. - .\" ---------------------------------------------------------------------------- - . --.TH MULTIPATH.CONF 5 2024-04-17 Linux -+.TH MULTIPATH.CONF 5 2024-04-25 Linux - . - . - .\" ---------------------------------------------------------------------------- diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 22e6ad7..b898339 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,5 +1,5 @@ Name: device-mapper-multipath -Version: 0.9.8 +Version: 0.9.9 Release: 1%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 @@ -7,66 +7,22 @@ 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 -L https://github.com/opensvc/multipath-tools/archive/0.9.8.tar.gz -o multipath-tools-0.9.8.tgz -Source0: multipath-tools-0.9.8.tgz +# curl -L https://github.com/opensvc/multipath-tools/archive/0.9.9.tar.gz -o multipath-tools-0.9.9.tgz +Source0: multipath-tools-0.9.9.tgz Source1: multipath.conf -Patch0001: 0001-11-dm-mpath.rules-fix-misspelled-DM_UDEV_DISABLE_OTH.patch -Patch0002: 0002-multipathd-use-condlog-level-for-setscheduler-error-.patch -Patch0003: 0003-multipathd-make-multipathd-scheduling-configurable.patch -Patch0004: 0004-libmpathutil-really-always-use-glibc-basename.patch -Patch0005: 0005-multipathd-make-multipathd-set-priority-to-RLIMIT_RT.patch -Patch0006: 0006-multipathd-Set-CPUWeight-to-1000-and-LimitRTPRIO-to-.patch -Patch0007: 0007-11-dm-mpath.rules-explain-logic-for-device-becoming-.patch -Patch0008: 0008-11-dm-mpath.rules-don-t-import-DM_NOSCAN-from-udev-d.patch -Patch0009: 0009-11-dm-mpath.rules-don-t-import-ID_FS_VERSION-from-ud.patch -Patch0010: 0010-11-dm-mpath.rules-adapt-MPATH_DEVICE_READY-0-logic-t.patch -Patch0011: 0011-11-dm-mpath.rules-adapt-coldplug-event-handling-ro-1.patch -Patch0012: 0012-11-dm-mpath.rules-don-t-import-properties-with-new-1.patch -Patch0013: 0013-11-dm-mpath.rules-replace-DM_SUSPENDED-by-.DM_SUSPEN.patch -Patch0014: 0014-11-dm-mpath.rules-replace-DM_NOSCAN-by-.DM_NOSCAN.patch -Patch0015: 0015-11-dm-mpath.rules-simplify-PATH_FAILED-case.patch -Patch0016: 0016-11-dm-mpath.rules-make-label-names-more-intuitive.patch -Patch0017: 0017-kpartx.rules-ignore-DM_SUSPENDED.patch -Patch0018: 0018-multipath-tools-tests-fix-CI-failures-on-arm-v7-with.patch -Patch0019: 0019-multipath-tools-tests-fix-CI-failures-with-clang-on-.patch -Patch0020: 0020-GitHub-actions-fixes-for-spelling-CI.patch -Patch0021: 0021-GitHub-workflows-run-workflows-if-workflow-file-has-.patch -Patch0022: 0022-multipath-tools-add-TGTDIR-option.patch -Patch0023: 0023-libmultipath-move-get_udev_for_mpp-to-sysfs.c.patch -Patch0024: 0024-libmultipath-add-mp_find_path_by_devt.patch -Patch0025: 0025-Revert-libmultipath-fix-max_sectors_kb-on-adding-pat.patch -Patch0026: 0026-libmultipath-Only-set-max_sectors_kb-on-map-creation.patch -Patch0027: 0027-libmultipath-set-max_sectors_kb-in-adopt_paths.patch -Patch0028: 0028-libmultipath-add-wildcard-k-for-printing-max_sectors.patch -Patch0029: 0029-multipath.conf-5-update-documentation-for-max_sector.patch -Patch0030: 0030-multipath-tools-simplify-comment-in-hwtable.patch -Patch0031: 0031-multipath-tools-unify-text-in-multipath.conf.5.patch -Patch0032: 0032-multipath-tools-update-man-pages-dates.patch -Patch0033: 0033-libmultipath-export-partmap_in_use.patch -Patch0034: 0034-libmultipath-change-flush_on_last_del-to-fix-a-multi.patch -Patch0035: 0035-libmultipath-remove-redundant-config-option-from-Inf.patch -Patch0036: 0036-libmultipath-pad-dev_loss_tmo-to-avoid-race-with-no_.patch -Patch0037: 0037-libmultipath-fix-deferred_remove-function-arguments.patch -Patch0038: 0038-libmultipath-use-bitwise-flags-for-map-flushing-API.patch -Patch0039: 0039-libmultipath-use-bitwise-flags-for-dm_simplecmd-API.patch -Patch0040: 0040-libmultipath-add-argument-names-to-some-prototypes.patch -Patch0041: 0041-libmultipath-bump-version-to-0.9.9.patch -Patch0042: 0042-GitHub-Workflows-native.yaml-run-for-Fedora-40.patch -Patch0043: 0043-update-NEWS.md.patch -Patch0044: 0044-multipath.conf.5.in-fix-man-page-date.patch -Patch0045: 0045-RH-fixup-udev-rules-for-redhat.patch -Patch0046: 0046-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0047: 0047-RH-don-t-start-without-a-config-file.patch -Patch0048: 0048-RH-Fix-nvme-function-missing-argument.patch -Patch0049: 0049-RH-use-rpm-optflags-if-present.patch -Patch0050: 0050-RH-add-mpathconf.patch -Patch0051: 0051-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0052: 0052-RH-reset-default-find_mutipaths-value-to-off.patch -Patch0053: 0053-RH-attempt-to-get-ANA-info-via-sysfs-first.patch -Patch0054: 0054-RH-make-parse_vpd_pg83-match-scsi_id-output.patch -Patch0055: 0055-RH-add-scsi-device-handlers-to-modules-load.d.patch -Patch0056: 0056-RH-compile-with-libreadline-support.patch -Patch0057: 0057-RH-Add-mpathcleanup.patch +Patch0001: 0001-RH-fixup-udev-rules-for-redhat.patch +Patch0002: 0002-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0003: 0003-RH-don-t-start-without-a-config-file.patch +Patch0004: 0004-RH-Fix-nvme-function-missing-argument.patch +Patch0005: 0005-RH-use-rpm-optflags-if-present.patch +Patch0006: 0006-RH-add-mpathconf.patch +Patch0007: 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0008: 0008-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0009: 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0010: 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +Patch0011: 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch +Patch0012: 0012-RH-compile-with-libreadline-support.patch +Patch0013: 0013-RH-Add-mpathcleanup.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -153,7 +109,7 @@ This package contains the files needed to develop applications that use device-mapper-multipath's libdmmp C API library %prep -%autosetup -n multipath-tools-0.9.8 -p1 +%autosetup -n multipath-tools-0.9.9 -p1 cp %{SOURCE1} . %build @@ -275,6 +231,12 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Thu Jun 13 2024 Benjamin Marzinski - 0.9.9-1 +- Update source to upstream version 0.9.9 + * Previous patches 0001-0044 are included in the source tarball +- Rename redhat patches + * Previous patches 0045-0057 are now patches 0001-0013 + * Mon May 20 2024 Benjamin Marzinski - 0.9.8-1 - Update source to upstream version 0.9.8 plus latest staging branch * Previous patches 0014 & 0015 are included in the source tarball diff --git a/sources b/sources index b0337e2..f098bc9 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (multipath-tools-0.9.8.tgz) = 4d73bcf6bce769a829c306c609b206ddba65a708620f458106e406dd18d12f9a9d97f400662daa8e6a75c9fdf7decb6dcbda92cb807b6c53522c7b4b2795b627 +SHA512 (multipath-tools-0.9.9.tgz) = 65b5d5c48792f6041d700968c87675bc349ede475fe178a203814dbb0325f69895782a22c5c35f6c0157f694951714de9e83cc1464a6c062d911a58faed8960a SHA512 (multipath.conf) = 71953dce5a68adcf60a942305f5a66023e6f4c4baf53b1bfdb4edf65ed5b8e03db804363c36d1dcfd85591f4766f52b515269904c53b84d7b076da0b80b09942 From 4e4233829d041b14b0773e59b57ed1aca0de9b7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 9 Jul 2024 12:58:25 +0200 Subject: [PATCH 52/67] Rebuilt for the bin-sbin merge https://fedoraproject.org/wiki/Changes/Unify_bin_and_sbin --- device-mapper-multipath.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index b898339..2897380 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.9.9 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -231,6 +231,9 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Tue Jul 09 2024 Zbigniew Jędrzejewski-Szmek - 0.9.9-2 +- Rebuilt for the bin-sbin merge + * Thu Jun 13 2024 Benjamin Marzinski - 0.9.9-1 - Update source to upstream version 0.9.9 * Previous patches 0001-0044 are included in the source tarball From 3cde646adee765e1e8dca298f73db057039f317d Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 17 Jul 2024 20:51:42 +0000 Subject: [PATCH 53/67] Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild --- device-mapper-multipath.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 2897380..247501d 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.9.9 -Release: 2%{?dist} +Release: 3%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -231,6 +231,9 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Wed Jul 17 2024 Fedora Release Engineering - 0.9.9-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild + * Tue Jul 09 2024 Zbigniew Jędrzejewski-Szmek - 0.9.9-2 - Rebuilt for the bin-sbin merge From 519bd15b4dd30fadd1310fae97d8189ea061cae8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20Such=C3=BD?= Date: Thu, 25 Jul 2024 11:35:35 +0200 Subject: [PATCH 54/67] convert GPLv3+ license to SPDX This is part of https://fedoraproject.org/wiki/Changes/SPDX_Licenses_Phase_4 --- device-mapper-multipath.spec | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 247501d..fb448ed 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.9.9 -Release: 3%{?dist} +Release: 4%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -90,7 +90,8 @@ kpartx manages partition creation and removal for device-mapper devices. %package -n libdmmp Summary: device-mapper-multipath C API library -License: GPLv3+ +# Automatically converted from old format: GPLv3+ - review is highly recommended. +License: GPL-3.0-or-later Requires: json-c Requires: %{name} = %{version}-%{release} Requires: %{name}-libs = %{version}-%{release} @@ -231,6 +232,9 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Thu Jul 25 2024 Miroslav Suchý - 0.9.9-4 +- convert license to SPDX + * Wed Jul 17 2024 Fedora Release Engineering - 0.9.9-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild From 354f1e7cfbad435492ff429f5a3e98e713a2530b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20Such=C3=BD?= Date: Mon, 29 Jul 2024 10:25:45 +0200 Subject: [PATCH 55/67] convert GPLv2 license to SPDX This is part of https://fedoraproject.org/wiki/Changes/SPDX_Licenses_Phase_4 --- device-mapper-multipath.spec | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index fb448ed..6cd8a6d 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,8 +1,9 @@ Name: device-mapper-multipath Version: 0.9.9 -Release: 4%{?dist} +Release: 5%{?dist} Summary: Tools to manage multipath devices using device-mapper -License: GPLv2 +# Automatically converted from old format: GPLv2 - review is highly recommended. +License: GPL-2.0-only URL: http://christophe.varoqui.free.fr/ # The source for this package was pulled from upstream's git repo. Use the @@ -232,6 +233,9 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Mon Jul 29 2024 Miroslav Suchý - 0.9.9-5 +- convert license to SPDX + * Thu Jul 25 2024 Miroslav Suchý - 0.9.9-4 - convert license to SPDX From 0c6649fa32544f07677c7495c8269bd0d95cc62b Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Fri, 9 Aug 2024 16:00:03 -0400 Subject: [PATCH 56/67] device-mapper-multipath-0.9.9-6 Add 0014-multipathd-fix-null-pointer-dereference-in-uev_updat.patch * multipath features tracking on failed removes --- ...tipathd-fix-flush-check-in-flush_map.patch | 28 +++++++++++++++++++ device-mapper-multipath.spec | 7 ++++- 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 0014-multipathd-fix-flush-check-in-flush_map.patch diff --git a/0014-multipathd-fix-flush-check-in-flush_map.patch b/0014-multipathd-fix-flush-check-in-flush_map.patch new file mode 100644 index 0000000..3ff957d --- /dev/null +++ b/0014-multipathd-fix-flush-check-in-flush_map.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 5 Jun 2024 19:22:48 -0400 +Subject: [PATCH] multipathd: fix flush check in flush_map() + +Forgot the comparison in the "if" statement. + +Fixes 8a3898339 ("multipathd: sync features on flush_map failure corner case") + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + multipathd/main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 09286dd0..58afe14a 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -813,7 +813,7 @@ flush_map(struct multipath * mpp, struct vectors * vecs) + { + int r = dm_suspend_and_flush_map(mpp->alias, 0); + if (r != DM_FLUSH_OK) { +- if (DM_FLUSH_FAIL_CANT_RESTORE) ++ if (r == DM_FLUSH_FAIL_CANT_RESTORE) + remove_feature(&mpp->features, "queue_if_no_path"); + condlog(0, "%s: can't flush", mpp->alias); + return r; diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 6cd8a6d..9e74d46 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.9.9 -Release: 5%{?dist} +Release: 6%{?dist} Summary: Tools to manage multipath devices using device-mapper # Automatically converted from old format: GPLv2 - review is highly recommended. License: GPL-2.0-only @@ -24,6 +24,7 @@ Patch0010: 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch Patch0011: 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch Patch0012: 0012-RH-compile-with-libreadline-support.patch Patch0013: 0013-RH-Add-mpathcleanup.patch +Patch0014: 0014-multipathd-fix-flush-check-in-flush_map.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -233,6 +234,10 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Fri Aug 9 2024 Benjamin Marzinski - 0.9.9-6 +- Add 0014-multipathd-fix-null-pointer-dereference-in-uev_updat.patch + * multipath features tracking on failed removes + * Mon Jul 29 2024 Miroslav Suchý - 0.9.9-5 - convert license to SPDX From 94144d9276e41dd879043596114d248db042dbc5 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 29 Aug 2024 15:20:13 -0400 Subject: [PATCH 57/67] device-mapper-multipath-0.10.0-1 Update source to upstream version 0.9.9 * Previous patch 0014-multipathd-fix-flush-check-in-flush_map.patch is included in the source tarball Rebase redhat patches --- .gitignore | 1 + 0001-RH-fixup-udev-rules-for-redhat.patch | 20 ++++----- ...property-blacklist-exception-builtin.patch | 8 ++-- ...RH-don-t-start-without-a-config-file.patch | 16 +++---- ...H-Fix-nvme-function-missing-argument.patch | 2 +- 0005-RH-use-rpm-optflags-if-present.patch | 30 ++++++++----- 0006-RH-add-mpathconf.patch | 43 +++++++++++++++---- ...om-kernel-cmdline-mpath.wwids-with-A.patch | 16 +++---- ...-default-find_mutipaths-value-to-off.patch | 8 ++-- ...-parse_vpd_pg83-match-scsi_id-output.patch | 2 +- ...si-device-handlers-to-modules-load.d.patch | 2 +- ...-RH-compile-with-libreadline-support.patch | 2 +- ...tipathd-fix-flush-check-in-flush_map.patch | 28 ------------ device-mapper-multipath.spec | 17 +++++--- sources | 2 +- 15 files changed, 105 insertions(+), 92 deletions(-) delete mode 100644 0014-multipathd-fix-flush-check-in-flush_map.patch diff --git a/.gitignore b/.gitignore index 3bea72e..908094d 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,4 @@ multipath-tools-091027.tar.gz /multipath-tools-0.9.7.tgz /multipath-tools-0.9.8.tgz /multipath-tools-0.9.9.tgz +/multipath-tools-0.10.0.tgz diff --git a/0001-RH-fixup-udev-rules-for-redhat.patch b/0001-RH-fixup-udev-rules-for-redhat.patch index d78919e..0645240 100644 --- a/0001-RH-fixup-udev-rules-for-redhat.patch +++ b/0001-RH-fixup-udev-rules-for-redhat.patch @@ -9,13 +9,13 @@ different naming scheme for partitions than SuSE. Signed-off-by: Benjamin Marzinski --- - Makefile.inc | 2 +- - kpartx/kpartx.rules | 2 +- - multipath/Makefile | 4 ++-- + Makefile.inc | 2 +- + kpartx/kpartx.rules.in | 2 +- + multipath/Makefile | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 81b86cd8..33dbb99c 100644 +index 729618bd..81cb61d2 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -34,7 +34,7 @@ endif @@ -27,16 +27,16 @@ index 81b86cd8..33dbb99c 100644 # Prefix for non-essential libraries (libdmmp) usr_prefix := $(if $(prefix),$(prefix),/usr) # Prefix for configuration files (multipath.conf) -diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules -index 8dd3369c..7c3c7524 100644 ---- a/kpartx/kpartx.rules -+++ b/kpartx/kpartx.rules +diff --git a/kpartx/kpartx.rules.in b/kpartx/kpartx.rules.in +index 9d879609..2049eb8f 100644 +--- a/kpartx/kpartx.rules.in ++++ b/kpartx/kpartx.rules.in @@ -39,6 +39,6 @@ LABEL="mpath_kpartx_end" GOTO="kpartx_end" LABEL="run_kpartx" --RUN+="/sbin/kpartx -un -p -part /dev/$name" -+RUN+="/sbin/kpartx -un /dev/$name" +-RUN+="@BINDIR@/kpartx -un -p -part /dev/$name" ++RUN+="@BINDIR@/kpartx -un /dev/$name" LABEL="kpartx_end" diff --git a/multipath/Makefile b/multipath/Makefile diff --git a/0002-RH-Remove-the-property-blacklist-exception-builtin.patch b/0002-RH-Remove-the-property-blacklist-exception-builtin.patch index b039539..a74e6c2 100644 --- a/0002-RH-Remove-the-property-blacklist-exception-builtin.patch +++ b/0002-RH-Remove-the-property-blacklist-exception-builtin.patch @@ -19,7 +19,7 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c -index 75100b20..0b212078 100644 +index 17e1b54a..10d13e98 100644 --- a/libmultipath/blacklist.c +++ b/libmultipath/blacklist.c @@ -230,8 +230,6 @@ setup_default_blist (struct config * conf) @@ -42,10 +42,10 @@ index 75100b20..0b212078 100644 udev_device_get_properties_list_entry(udev)) { diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in -index dacb9b0e..645e8f88 100644 +index 4388baad..af9fbb96 100644 --- a/multipath/multipath.conf.5.in +++ b/multipath/multipath.conf.5.in -@@ -1468,9 +1468,14 @@ keywords. Both are regular expressions. For a full description of these keywords +@@ -1469,9 +1469,14 @@ keywords. Both are regular expressions. For a full description of these keywords Regular expression for an udev property. All devices that have matching udev properties will be excluded/included. The handling of the \fIproperty\fR keyword is special, @@ -61,7 +61,7 @@ index dacb9b0e..645e8f88 100644 . .RS .PP -@@ -1481,10 +1486,6 @@ Blacklisting by missing properties is only applied to devices which do have the +@@ -1482,10 +1487,6 @@ Blacklisting by missing properties is only applied to devices which do have the property specified by \fIuid_attribute\fR (e.g. \fIID_SERIAL\fR) set. Previously, it was applied to every device, possibly causing devices to be blacklisted because of temporary I/O error conditions. diff --git a/0003-RH-don-t-start-without-a-config-file.patch b/0003-RH-don-t-start-without-a-config-file.patch index 267ffa7..02827df 100644 --- a/0003-RH-don-t-start-without-a-config-file.patch +++ b/0003-RH-don-t-start-without-a-config-file.patch @@ -22,10 +22,10 @@ Signed-off-by: Benjamin Marzinski 7 files changed, 25 insertions(+) diff --git a/libmultipath/config.c b/libmultipath/config.c -index 83fa7369..002027a7 100644 +index 0e3a5cc1..80f61914 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c -@@ -959,6 +959,19 @@ int _init_config (const char *file, struct config *conf) +@@ -959,6 +959,19 @@ int init_config__ (const char *file, struct config *conf) } factorize_hwtable(conf->hwtable, builtin_hwtable_size, file); validate_pctable(conf->overrides, 0, file); @@ -46,7 +46,7 @@ index 83fa7369..002027a7 100644 conf->processed_main_config = 1; diff --git a/libmultipath/config.h b/libmultipath/config.h -index 384193ab..158cebf0 100644 +index 94cdf252..534b6142 100644 --- a/libmultipath/config.h +++ b/libmultipath/config.h @@ -10,6 +10,7 @@ @@ -58,10 +58,10 @@ index 384193ab..158cebf0 100644 enum devtypes { DEV_NONE, diff --git a/multipath/main.c b/multipath/main.c -index ce702e7f..c21e3e0b 100644 +index 28e3a055..346acb61 100644 --- a/multipath/main.c +++ b/multipath/main.c -@@ -842,11 +842,14 @@ main (int argc, char *argv[]) +@@ -843,11 +843,14 @@ main (int argc, char *argv[]) char *dev = NULL; struct config *conf; bool enable_foreign = false; @@ -76,7 +76,7 @@ index ce702e7f..c21e3e0b 100644 if (init_config(DEFAULT_CONFIGFILE)) exit(RTVL_FAIL); if (atexit(uninit_config)) -@@ -1097,6 +1100,9 @@ main (int argc, char *argv[]) +@@ -1101,6 +1104,9 @@ main (int argc, char *argv[]) while ((r = configure(conf, cmd, dev_type, dev)) == RTVL_RETRY) condlog(3, "restart multipath configuration process"); @@ -87,7 +87,7 @@ index ce702e7f..c21e3e0b 100644 put_multipath_config(conf); if (dev) diff --git a/multipath/multipath.rules.in b/multipath/multipath.rules.in -index 780bf852..2c518378 100644 +index 2ac1972f..cc248231 100644 --- a/multipath/multipath.rules.in +++ b/multipath/multipath.rules.in @@ -9,6 +9,7 @@ IMPORT{cmdline}="nompath" @@ -112,7 +112,7 @@ index 7bc8806e..315884eb 100644 . .\" ---------------------------------------------------------------------------- diff --git a/multipathd/multipathd.service.in b/multipathd/multipathd.service.in -index a63ddd9a..01ceff7d 100644 +index 646001e6..72e44849 100644 --- a/multipathd/multipathd.service.in +++ b/multipathd/multipathd.service.in @@ -6,6 +6,7 @@ Wants=systemd-udevd-kernel.socket @MODPROBE_UNIT@ diff --git a/0004-RH-Fix-nvme-function-missing-argument.patch b/0004-RH-Fix-nvme-function-missing-argument.patch index ced7159..74b7b53 100644 --- a/0004-RH-Fix-nvme-function-missing-argument.patch +++ b/0004-RH-Fix-nvme-function-missing-argument.patch @@ -12,7 +12,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmultipath/nvme/argconfig.h b/libmultipath/nvme/argconfig.h -index adb192b6..bfd10ef8 100644 +index e6c54453..0c6c9439 100644 --- a/libmultipath/nvme/argconfig.h +++ b/libmultipath/nvme/argconfig.h @@ -76,7 +76,7 @@ struct argconfig_commandline_options { diff --git a/0005-RH-use-rpm-optflags-if-present.patch b/0005-RH-use-rpm-optflags-if-present.patch index 0f354e7..3f115c1 100644 --- a/0005-RH-use-rpm-optflags-if-present.patch +++ b/0005-RH-use-rpm-optflags-if-present.patch @@ -9,19 +9,18 @@ still being generic. Signed-off-by: Benjamin Marzinski --- - Makefile.inc | 22 +++++++++++++++++----- - 1 file changed, 17 insertions(+), 5 deletions(-) + Makefile.inc | 25 ++++++++++++++++++------- + 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 33dbb99c..94e0ec85 100644 +index 81cb61d2..35334a0c 100644 --- a/Makefile.inc +++ b/Makefile.inc -@@ -95,11 +95,23 @@ SYSTEMD_LIBDEPS := $(if $(SYSTEMD),$(if $(shell test $(SYSTEMD) -gt 209 && echo +@@ -99,28 +99,39 @@ SYSTEMD_LIBDEPS := $(if $(SYSTEMD),$(if $(shell test $(SYSTEMD) -gt 209 && echo MODPROBE_UNIT := $(shell test "0$(SYSTEMD)" -lt 245 2>/dev/null || \ echo "modprobe@dm_multipath.service") -OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 --WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int \ +ifndef RPM_OPT_FLAGS + OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 \ + -Wall $(FORTIFY_OPT) -fexceptions -grecord-gcc-switches \ @@ -35,16 +34,27 @@ index 33dbb99c..94e0ec85 100644 +else + OPTFLAGS := $(RPM_OPT_FLAGS) --param=ssp-buffer-size=4 +endif -+WARNFLAGS := -Werror -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int \ - -Werror=implicit-function-declaration -Werror=format-security \ -- $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) $(W_URCU_TYPE_LIMITS) + + # Set WARN_ONLY=1 to avoid compilation erroring out due to warnings. Useful during development. + WARN_ONLY := + ERROR := $(if $(WARN_ONLY),,error=) + WERROR := $(if $(WARN_ONLY),,-Werror) +-WARNFLAGS := $(WERROR) -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -W$(ERROR)implicit-int \ ++WARNFLAGS := $(WERROR) -Wextra -Wformat=2 $(WFORMATOVERFLOW) -W$(ERROR)implicit-int \ + -W$(ERROR)implicit-function-declaration -W$(ERROR)format-security \ +- $(WNOCLOBBERED) -W$(ERROR)cast-qual $(ERROR_DISCARDED_QUALIFIERS) $(W_URCU_TYPE_LIMITS) ++ $(WNOCLOBBERED) -W$(ERROR)cast-qual $(ERROR_DISCARDED_QUALIFIERS) $(W_URCU_TYPE_LIMITS) -Wstrict-prototypes + -CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) $(D_URCU_VERSION) \ -+ $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) $(W_URCU_TYPE_LIMITS) -Wstrict-prototypes +CPPFLAGS := $(CPPFLAGS) $(D_URCU_VERSION) \ -D_FILE_OFFSET_BITS=64 \ -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(TGTDIR)$(plugindir)\" \ -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(TGTDIR)$(configdir)\" \ -@@ -109,7 +121,7 @@ CFLAGS := -std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe + -DDEFAULT_CONFIGFILE=\"$(TGTDIR)$(configfile)\" -DSTATE_DIR=\"$(TGTDIR)$(statedir)\" \ + -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP +-CFLAGS := -std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ +- -fexceptions ++CFLAGS := -std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe BIN_CFLAGS := -fPIE -DPIE LIB_CFLAGS := -fPIC SHARED_FLAGS := -shared diff --git a/0006-RH-add-mpathconf.patch b/0006-RH-add-mpathconf.patch index fd65e34..2ae48f3 100644 --- a/0006-RH-add-mpathconf.patch +++ b/0006-RH-add-mpathconf.patch @@ -13,19 +13,44 @@ a single command. Co-authored-by: Paul Donohue Signed-off-by: Benjamin Marzinski --- - libmultipath/config.c | 2 + - multipath/Makefile | 4 + - multipath/mpathconf | 658 ++++++++++++++++++++++++++++++++++++++++++ - multipath/mpathconf.8 | 151 ++++++++++ - 4 files changed, 815 insertions(+) + .github/actions/spelling/expect.txt | 3 + + libmultipath/config.c | 2 + + multipath/Makefile | 4 + + multipath/mpathconf | 658 ++++++++++++++++++++++++++++ + multipath/mpathconf.8 | 151 +++++++ + 5 files changed, 818 insertions(+) create mode 100644 multipath/mpathconf create mode 100644 multipath/mpathconf.8 +diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt +index 934f582e..61351583 100644 +--- a/.github/actions/spelling/expect.txt ++++ b/.github/actions/spelling/expect.txt +@@ -124,9 +124,11 @@ lvmteam + Marzinski + mpath + mpathb ++mpathconf + mpathpersist + mpathvalid + msecs ++multipathable + multipathc + multipathd + multipathed +@@ -144,6 +146,7 @@ ontap + OOM + opensvc + OPTFLAGS ++outfile + paramp + partx + pathgroup diff --git a/libmultipath/config.c b/libmultipath/config.c -index 002027a7..3d5943d3 100644 +index 80f61914..1373f15b 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c -@@ -961,6 +961,8 @@ int _init_config (const char *file, struct config *conf) +@@ -961,6 +961,8 @@ int init_config__ (const char *file, struct config *conf) validate_pctable(conf->overrides, 0, file); } else { condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices."); @@ -735,7 +760,7 @@ index 00000000..ce430075 +fi diff --git a/multipath/mpathconf.8 b/multipath/mpathconf.8 new file mode 100644 -index 00000000..ea025f31 +index 00000000..ec4e5c56 --- /dev/null +++ b/multipath/mpathconf.8 @@ -0,0 +1,151 @@ @@ -877,7 +902,7 @@ index 00000000..ea025f31 +.B service multipathd stop +to stop the multipathd daemon on \fB--disable\fP, and +.B service multipathd reload -+to reconfigure multipathd on \fB--user_frindly_names\fP and ++to reconfigure multipathd on \fB--user_friendly_names\fP and +\fB--find_multipaths\fP. +This option is set to \fBn\fP by default. +.SH FILES diff --git a/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch index 9884258..4e781fa 100644 --- a/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +++ b/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch @@ -20,7 +20,7 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/multipath/main.c b/multipath/main.c -index c21e3e0b..3f3ac9fb 100644 +index 346acb61..adc50d69 100644 --- a/multipath/main.c +++ b/multipath/main.c @@ -120,7 +120,7 @@ usage (char * progname) @@ -41,7 +41,7 @@ index c21e3e0b..3f3ac9fb 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" -@@ -448,6 +450,50 @@ static void cleanup_vecs(void) +@@ -449,6 +451,50 @@ static void cleanup_vecs(void) free_pathvec(vecs.pathvec, FREE_PATHS); } @@ -92,7 +92,7 @@ index c21e3e0b..3f3ac9fb 100644 static int configure (struct config *conf, enum mpath_cmds cmd, enum devtypes dev_type, char *devpath) -@@ -861,7 +907,7 @@ main (int argc, char *argv[]) +@@ -860,7 +906,7 @@ main (int argc, char *argv[]) condlog(1, "failed to register cleanup handler for vecs: %m"); if (atexit(cleanup_bindings)) condlog(1, "failed to register cleanup handler for bindings: %m"); @@ -101,7 +101,7 @@ index c21e3e0b..3f3ac9fb 100644 switch(arg) { case 'v': if (!isdigit(optarg[0])) { -@@ -932,6 +978,10 @@ main (int argc, char *argv[]) +@@ -931,6 +977,10 @@ main (int argc, char *argv[]) case 'T': cmd = CMD_DUMP_CONFIG; break; @@ -138,14 +138,14 @@ index b88e9a4c..edd742aa 100644 Remove the WWID for the specified device from the WWIDs file. . diff --git a/multipathd/multipathd.service.in b/multipathd/multipathd.service.in -index 01ceff7d..e0c2011b 100644 +index 72e44849..69a6c39d 100644 --- a/multipathd/multipathd.service.in +++ b/multipathd/multipathd.service.in @@ -17,6 +17,7 @@ ConditionVirtualization=!container [Service] Type=notify NotifyAccess=main -+ExecStartPre=-/sbin/multipath -A - ExecStart=/sbin/multipathd -d -s - ExecReload=/sbin/multipathd reconfigure ++ExecStartPre=-@BINDIR@/multipath -A + ExecStart=@BINDIR@/multipathd -d -s + ExecReload=@BINDIR@/multipathd reconfigure TasksMax=infinity diff --git a/0008-RH-reset-default-find_mutipaths-value-to-off.patch b/0008-RH-reset-default-find_mutipaths-value-to-off.patch index 04ad52c..5789916 100644 --- a/0008-RH-reset-default-find_mutipaths-value-to-off.patch +++ b/0008-RH-reset-default-find_mutipaths-value-to-off.patch @@ -14,10 +14,10 @@ Signed-off-by: Benjamin Marzinski 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h -index ed08c251..4b033ff9 100644 +index 02f7e57c..cd03fd1a 100644 --- a/libmultipath/defaults.h +++ b/libmultipath/defaults.h -@@ -23,7 +23,7 @@ +@@ -24,7 +24,7 @@ #define DEFAULT_NO_PATH_RETRY NO_PATH_RETRY_UNDEF #define DEFAULT_VERBOSITY 2 #define DEFAULT_REASSIGN_MAPS 0 @@ -27,10 +27,10 @@ index ed08c251..4b033ff9 100644 #define DEFAULT_DEV_LOSS_TMO 600 #define DEFAULT_RETAIN_HWHANDLER RETAIN_HWHANDLER_ON diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in -index 645e8f88..a7543939 100644 +index af9fbb96..0c1eff40 100644 --- a/multipath/multipath.conf.5.in +++ b/multipath/multipath.conf.5.in -@@ -1225,7 +1225,7 @@ as non-multipath and passed on to upper layers. +@@ -1226,7 +1226,7 @@ as non-multipath and passed on to upper layers. \fBNote:\fR this may cause delays during device detection if there are single-path devices which aren\'t blacklisted. .TP diff --git a/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch b/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch index c090da0..06194f6 100644 --- a/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +++ b/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch @@ -14,7 +14,7 @@ Signed-off-by: Benjamin Marzinski 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index e2052422..3bcd94ce 100644 +index e94705bf..61ac27ef 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c @@ -1221,13 +1221,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, diff --git a/0011-RH-add-scsi-device-handlers-to-modules-load.d.patch b/0011-RH-add-scsi-device-handlers-to-modules-load.d.patch index 7624c5b..3debe8a 100644 --- a/0011-RH-add-scsi-device-handlers-to-modules-load.d.patch +++ b/0011-RH-add-scsi-device-handlers-to-modules-load.d.patch @@ -11,7 +11,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc -index 94e0ec85..49514b06 100644 +index 35334a0c..377125b6 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -16,7 +16,7 @@ READLINE := diff --git a/0012-RH-compile-with-libreadline-support.patch b/0012-RH-compile-with-libreadline-support.patch index eb0ab13..db04640 100644 --- a/0012-RH-compile-with-libreadline-support.patch +++ b/0012-RH-compile-with-libreadline-support.patch @@ -12,7 +12,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc -index 49514b06..a3ed9f28 100644 +index 377125b6..4a6528a9 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -12,7 +12,7 @@ diff --git a/0014-multipathd-fix-flush-check-in-flush_map.patch b/0014-multipathd-fix-flush-check-in-flush_map.patch deleted file mode 100644 index 3ff957d..0000000 --- a/0014-multipathd-fix-flush-check-in-flush_map.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 5 Jun 2024 19:22:48 -0400 -Subject: [PATCH] multipathd: fix flush check in flush_map() - -Forgot the comparison in the "if" statement. - -Fixes 8a3898339 ("multipathd: sync features on flush_map failure corner case") - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - multipathd/main.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 09286dd0..58afe14a 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -813,7 +813,7 @@ flush_map(struct multipath * mpp, struct vectors * vecs) - { - int r = dm_suspend_and_flush_map(mpp->alias, 0); - if (r != DM_FLUSH_OK) { -- if (DM_FLUSH_FAIL_CANT_RESTORE) -+ if (r == DM_FLUSH_FAIL_CANT_RESTORE) - remove_feature(&mpp->features, "queue_if_no_path"); - condlog(0, "%s: can't flush", mpp->alias); - return r; diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 9e74d46..da97503 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath -Version: 0.9.9 -Release: 6%{?dist} +Version: 0.10.0 +Release: 1%{?dist} Summary: Tools to manage multipath devices using device-mapper # Automatically converted from old format: GPLv2 - review is highly recommended. License: GPL-2.0-only @@ -8,8 +8,8 @@ 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 -L https://github.com/opensvc/multipath-tools/archive/0.9.9.tar.gz -o multipath-tools-0.9.9.tgz -Source0: multipath-tools-0.9.9.tgz +# curl -L https://github.com/opensvc/multipath-tools/archive/0.10.0.tar.gz -o multipath-tools-0.10.0.tgz +Source0: multipath-tools-0.10.0.tgz Source1: multipath.conf Patch0001: 0001-RH-fixup-udev-rules-for-redhat.patch Patch0002: 0002-RH-Remove-the-property-blacklist-exception-builtin.patch @@ -24,7 +24,6 @@ Patch0010: 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch Patch0011: 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch Patch0012: 0012-RH-compile-with-libreadline-support.patch Patch0013: 0013-RH-Add-mpathcleanup.patch -Patch0014: 0014-multipathd-fix-flush-check-in-flush_map.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -112,7 +111,7 @@ This package contains the files needed to develop applications that use device-mapper-multipath's libdmmp C API library %prep -%autosetup -n multipath-tools-0.9.9 -p1 +%autosetup -n multipath-tools-0.10.0 -p1 cp %{SOURCE1} . %build @@ -234,6 +233,12 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Thu Aug 29 2024 Benjamin Marzinski - 0.10.0-1 +- Update source to upstream version 0.9.9 + * Previous patch 0014-multipathd-fix-flush-check-in-flush_map.patch is + included in the source tarball +- Rebase redhat patches + * Fri Aug 9 2024 Benjamin Marzinski - 0.9.9-6 - Add 0014-multipathd-fix-null-pointer-dereference-in-uev_updat.patch * multipath features tracking on failed removes diff --git a/sources b/sources index f098bc9..da06e16 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (multipath-tools-0.9.9.tgz) = 65b5d5c48792f6041d700968c87675bc349ede475fe178a203814dbb0325f69895782a22c5c35f6c0157f694951714de9e83cc1464a6c062d911a58faed8960a +SHA512 (multipath-tools-0.10.0.tgz) = 8f545609fa20df7547428f2929571dc0df87c17d9f61f11aad3559446c2e94755e18b1c4b3780b3de92ec2cbc450939ca15a9d6c95551eee4084064d83874b2d SHA512 (multipath.conf) = 71953dce5a68adcf60a942305f5a66023e6f4c4baf53b1bfdb4edf65ed5b8e03db804363c36d1dcfd85591f4766f52b515269904c53b84d7b076da0b80b09942 From 75d5c0c70a04b7033f662e60c47f6634298a067e Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 29 Aug 2024 18:11:38 -0400 Subject: [PATCH 58/67] device-mapper-multipath-0.10.0-2 Update CI tests. --- device-mapper-multipath.spec | 5 +- tests/bindings/main.sh | 126 ++++++++--- tests/find_multipaths/Makefile | 49 ----- tests/find_multipaths/main.sh | 208 ++++++++++++------- tests/include/ec.sh | 14 +- tests/medium_error_scsi_debug/main.sh | 66 +++--- tests/restate_module/main.sh | 6 +- tests/user_friendly_names/main.sh | 151 ++++++++++---- tests/user_friendly_names/multipath.conf.no | 3 - tests/user_friendly_names/multipath.conf.yes | 11 - 10 files changed, 395 insertions(+), 244 deletions(-) delete mode 100644 tests/find_multipaths/Makefile delete mode 100644 tests/user_friendly_names/multipath.conf.no delete mode 100644 tests/user_friendly_names/multipath.conf.yes diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index da97503..4363b49 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.10.0 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Tools to manage multipath devices using device-mapper # Automatically converted from old format: GPLv2 - review is highly recommended. License: GPL-2.0-only @@ -233,6 +233,9 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Thu Aug 29 2024 Benjamin Marzinski - 0.10.0-2 +- update CI tests. + * Thu Aug 29 2024 Benjamin Marzinski - 0.10.0-1 - Update source to upstream version 0.9.9 * Previous patch 0014-multipathd-fix-flush-check-in-flush_map.patch is diff --git a/tests/bindings/main.sh b/tests/bindings/main.sh index 2d6f284..76292e4 100755 --- a/tests/bindings/main.sh +++ b/tests/bindings/main.sh @@ -18,40 +18,110 @@ # Author: Lin Li #set -x -source ../include/ec.sh || exit 200 - +source ../include/tc.sh || exit 200 tlog "running $0" -trun "service multipathd stop" -rpm -q device-mapper-multipath || yum install -y device-mapper-multipath -trun "mpathconf --enable --with_multipathd y --user_friendly_names y" -trun "service multipathd status" -sleep 5 +cleanup () +{ + local retries + if pidof multipathd; then + tlog "stopping multipathd" + trun "systemctl stop multipathd.service || pkill multipathd" + sleep 1 + fi + retries=10 + while pidof multipathd; do + ((retries--)) + if [[ $retries -le 0 ]]; then + tfail_ "failed to stop multipath" + tend + fi + tlog "waiting for multipathd to stop" + sleep 2 + pidof multipathd && pkill multipathd + done + trun "multipath -l -v1" + retries=10 + while [[ -n `multipath -l -v1` ]]; do + ((retries--)) + if [[ $retries -le 0 ]]; then + tfail_ "failed to remove deviece" + tend + fi + tlog "removing multipath device" + trun "udevadm settle" + trun "multipath -DF" + sleep 2 + done + if lsmod | grep -q "^scsi_debug"; then + tlog "removing scsi_debug module" + tok "rmmod scsi_debug" + fi + trun "rm -f /etc/multipath.conf" +} -trun "multipath -F" -sleep 5 -terr "modprobe -r scsi_debug" -terr "modprobe scsi_debug num_tgts=1 vpd_use_hostno=0 add_host=2 delay=20 \ -max_luns=2 no_lun_0=1" -sleep 60 +assert () +{ + local cmd="$*" + _trun_ "$cmd" 0 + if test $? -eq 0; then + tpass_ "$cmd" ; + else + tfail_ "$cmd" ; + cleanup ; + tend ; + fi +} -disk_path=$(get_scsi_debug_devices) -disk=$(basename $disk_path) -mpath_name=$(get_mpath_disk_by_scsi_device $disk) +setup_config () +{ + trun "mpathconf --enable --user_friendly_names y" + sed -i '/^blacklist[[:space:]]*{/ a\ + device {\ + vendor ".*"\ + product ".*"\ + } +' /etc/multipath.conf + cat << _EOF_ >> /etc/multipath.conf + +blacklist_exceptions { + device { + vendor Linux + product scsi_debug + } +} +_EOF_ + trun "cat /etc/multipath.conf" +} + +do_reconfigure () +{ + tok "multipathd reconfigure" + sleep 5 +} + +rpm -q device-mapper-multipath || dnf install -y device-mapper-multipath +cleanup +setup_config +trun "rm -r /etc/multipath/bindings" +trun "modprobe scsi_debug vpd_use_hostno=0 add_host=2" +sleep 5 +trun "systemctl start multipathd.service" +while multipathd show daemon | grep -qv idle; do + tlog "waiting for multipathd to start" + sleep 1 +done + +trun 'multipathd show maps raw format "%n"' +mpath_name=`multipathd show maps raw format "%n" | head -1` +assert "[[ -n $mpath_name ]] && [[ $mpath_name != ok ]]" new_alias="mpath_test_$$" trun "sed -i 's/$mpath_name/$new_alias/' /etc/multipath/bindings" -trun "multipath -r" -sleep 5 -tok "[[ -b /dev/mapper/$new_alias ]]" -tok is_mpath $new_alias -sleep 5 +do_reconfigure +trun 'multipathd show maps raw format "%n"' +mpath_name=`multipathd show maps raw format "%n" | head -1` +assert "[[ $mpath_name = $new_alias ]]" -trun "multipath -F" -sleep 5 -trun "modprobe -r scsi_debug" -trun "service multipathd stop" -sleep 3 -trun "multipath -W" -trun "rm /etc/multipath/bindings" +cleanup tend diff --git a/tests/find_multipaths/Makefile b/tests/find_multipaths/Makefile deleted file mode 100644 index b78dc57..0000000 --- a/tests/find_multipaths/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/bash - -# Copyright (c) 2016 Red Hat, Inc. -# # -# # 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 3 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 . -# -# # Author: Lin Li - -.PHONY: all install download clean - -BUILT_FILES= - -FILES=$(METADATA) Makefile PURPOSE main.sh - -run: $(FILES) build - ./main.sh - -build: $(BUILT_FILES) - chmod a+x ./main.sh - -clean: - rm -f *~ *.rpm $(BUILT_FILES) - -include /usr/share/rhts/lib/rhts-make.include - -$(METADATA): Makefile - @touch $(METADATA) - @echo "Owner: LiLin " > $(METADATA) - @echo "Name: $(TEST)" >> $(METADATA) - @echo "Path: $(TEST_DIR)" >> $(METADATA) - @echo "License: GPLv3" >> $(METADATA) - @echo "TestVersion: $(TESTVERSION)" >> $(METADATA) - @echo "Description: find_multipaths" >> $(METADATA) - @echo "TestTime: 15m" >> $(METADATA) - @echo "RunFor: device-mapper-multipath" >> $(METADATA) - @echo "Requires: device-mapper-multipath" >> $(METADATA) - - rhts-lint $(METADATA) diff --git a/tests/find_multipaths/main.sh b/tests/find_multipaths/main.sh index 4d94c87..28c325c 100755 --- a/tests/find_multipaths/main.sh +++ b/tests/find_multipaths/main.sh @@ -18,39 +18,92 @@ # Author: Lin Li #set -x -source ../include/ec.sh || exit 200 +source ../include/tc.sh || exit 200 +tlog "running $0" + +remove_devices () +{ + local retries + retries=10 + while [[ -n `multipath -l -v1` ]]; do + ((retries--)) + if [[ $retries -le 0 ]]; then + tfail_ "failed to remove devices" + cleanup + tend + fi + tlog "removing multipath devices" + trun "udevadm settle" + trun "multipath -F" + sleep 2 + done +} cleanup () { - trun "multipathd disablequeueing maps" - trun "service multipathd stop" - sleep 5 - trun "udevadm settle" - trun "multipath -F" - sleep 5 - trun "modprobe -r scsi_debug" + local retries + if pidof multipathd; then + tlog "stopping multipathd" + trun "systemctl stop multipathd.service || pkill multipathd" + sleep 1 + fi + retries=10 + while pidof multipathd; do + ((retries--)) + if [[ $retries -le 0 ]]; then + tfail_ "failed to stop multipath" + tend + fi + tlog "waiting for multipathd to stop" + sleep 2 + pidof multipathd && pkill multipathd + done + trun "multipath -l -v1" + retries=10 + while [[ -n `multipath -l -v1` ]]; do + ((retries--)) + if [[ $retries -le 0 ]]; then + tfail_ "failed to remove devices" + tend + fi + tlog "removing multipath devices" + trun "udevadm settle" + trun "multipath -DF" + sleep 2 + done + if lsmod | grep -q "^scsi_debug"; then + tlog "removing scsi_debug module" + tok "rmmod scsi_debug" + fi + trun "rm -f /etc/multipath.conf" + trun "rm -f /etc/multipath/wwids" + trun "rm -r /etc/multipath/bindings" } -tlog "running $0" +assert () +{ + local cmd="$*" + _trun_ "$cmd" 0 + if test $? -eq 0; then + tpass_ "$cmd" ; + else + tfail_ "$cmd" ; + cleanup ; + tend ; + fi +} -# which not set find_multipaths yes, so multipath always create a multipath device for single device -# so stop service and reconfig with --find_multipaths y, and reload/start the service again. -rpm -q device-mapper-multipath || yum install -y device-mapper-multipath +setup_config () +{ + trun "mpathconf --enable --user_friendly_names y --find_multipaths y" + sed -i '/^blacklist[[:space:]]*{/ a\ + device {\ + vendor ".*"\ + product ".*"\ + } +' /etc/multipath.conf + cat << _EOF_ >> /etc/multipath.conf -# test with find_multipath=y, will not multipath for the single device; reload/start the service to enable the config -cleanup -trun "rm -f /etc/multipath.conf" -trun "rm -f /etc/multipath/wwids" -trun "mpathconf --enable --user_friendly_names y --find_multipaths y --with_multipathd n" -sed -i '/^blacklist[[:space:]]*{/ a\ - device {\n vendor ".*"\n product ".*"\n } -' /etc/multipath.conf -if grep -qw blacklist_exceptions /etc/multipath.conf ; then - sed -i '/^blacklist_exceptions[[:space:]]*{/ a\ - device {\n vendor Linux\n product scsi_debug\n } -' /etc/multipath.conf -else - cat << _EOF_ >> /etc/multipath.conf blacklist_exceptions { device { vendor Linux @@ -58,56 +111,69 @@ blacklist_exceptions { } } _EOF_ -fi -trun "service multipathd start" + trun "cat /etc/multipath.conf" +} + +do_reconfigure () +{ + trun "cat /etc/multipath.conf" + tok "multipathd reconfigure" + sleep 5 +} + +trun "rpm -q device-mapper-multipath || dnf install -y device-mapper-multipath" +cleanup +setup_config + +# test with find_multipath=y, will not multipath the single device trun "modprobe scsi_debug" sleep 5 +trun "systemctl start multipathd.service" +while multipathd show daemon | grep -qv idle; do + tlog "waiting for multipathd to start" + sleep 1 +done +trun 'multipathd show paths raw format "%d %m"' +trun 'cat /etc/multipath/wwids' +mpath_name=`multipathd show paths raw format "%m" | head -1` +tok "[[ $mpath_name = '[orphan]' ]]" +remove_devices + +# test with find_multipath=n, will multipath the single device +trun 'mpathconf --find_multipaths n' +do_reconfigure +trun 'multipathd show paths raw format "%d %m"' +trun 'cat /etc/multipath/wwids' +mpath_name=`multipathd show paths raw format "%m" | head -1` +tok "[[ -n $mpath_name ]] && [[ $mpath_name != '[orphan]' ]]" +remove_devices + +# test with find_multipath=y, with multipath single device with known WWID +trun 'mpathconf --find_multipaths y' +do_reconfigure +trun 'multipathd show paths raw format "%d %m"' +trun 'cat /etc/multipath/wwids' +mpath_name=`multipathd show paths raw format "%m" | head -1` +tok "[[ -n $mpath_name ]] && [[ $mpath_name != '[orphan]' ]]" +remove_devices + +# Clear WWID, test with find_multipath=y, will not multipath single device trun "multipath -W" -cat /etc/multipath/wwids -trun "multipath" -disk_path=$(get_scsi_debug_devices) -disk_node=$(basename $disk_path) -mpath_name=$(get_mpath_disk_by_scsi_device $disk_node) -tok '[[ $mpath_name = "[orphan]" ]]' - -# test with find_multipath=n, will multipath for the single device -trun "mpathconf --user_friendly_names y --find_multipaths n --with_multipathd y" -sleep 5 -mpath_name=$(get_mpath_disk_by_scsi_device $disk_node) -tok "is_mpath $mpath_name" - -# flush new created path -trun "multipath -F" -sleep 1 - -# test with find_multipath=y, A path has the same WWID as a multipath device that was previously created -trun "mpathconf --user_friendly_names y --find_multipaths y --with_multipathd y" -sleep 5 -mpath_name=$(get_mpath_disk_by_scsi_device $disk_node) -tok "is_mpath $mpath_name" -trun "multipath -F" -sleep 1 - -# Clear wwid, test with find_multipath=y, will not multipath for the single device -trun "multipath -W" -trun "service multipathd reload" -sleep 5 -mpath_name=$(get_mpath_disk_by_scsi_device $disk_node) -tok '[[ $mpath_name = "[orphan]" ]]' - -trun "multipath -F" -sleep 5 -trun "modprobe -r scsi_debug" +do_reconfigure +trun 'multipathd show paths raw format "%d %m"' +trun 'cat /etc/multipath/wwids' +mpath_name=`multipathd show paths raw format "%m" | head -1` +tok "[[ $mpath_name = '[orphan]' ]]" +remove_devices +assert 'rmmod scsi_debug' # test find_multipaths=y create device for paths have same wwid -tok "modprobe scsi_debug num_tgts=1 vpd_use_hostno=0 add_host=2 delay=20 max_luns=2 no_lun_0=1" -sleep 10 -disk_paths=$(get_scsi_debug_devices) -disk_node=$(basename $disk_paths) -mpath_name=$(get_mpath_disk_by_scsi_device $disk_node) -tok "is_mpath $mpath_name" +trun "modprobe scsi_debug vpd_use_hostno=0 add_host=2" +sleep 5 +trun 'multipathd show paths raw format "%d %m"' +trun 'cat /etc/multipath/wwids' +mpath_name=`multipathd show paths raw format "%m" | head -1` +tok "[[ -n $mpath_name ]] && [[ $mpath_name != '[orphan]' ]]" cleanup -trun "multipath -W" -cat /etc/multipath/wwids tend diff --git a/tests/include/ec.sh b/tests/include/ec.sh index 22dfc40..4b0aba9 100755 --- a/tests/include/ec.sh +++ b/tests/include/ec.sh @@ -44,9 +44,12 @@ function _init (){ } function _destroy (){ - sleep 10 - Cmd "multipath -F" + Cmd "multipathd disablequeueing maps" sleep 5 + Cmd "multipath -DF -R2" + Cmd "service multipathd stop" + sleep 5 + Cmd "udevadm settle" Cmd "modprobe -r scsi_debug" } @@ -174,10 +177,7 @@ AA fi #setup scsi_debug echo "INFO: Loading scsi_debug module for simulation of mpath" - modprobe scsi_debug \ - num_tgts=1 vpd_use_hostno=0 \ - add_host=4 delay=20 \ - max_luns=2 no_lun_0=1 2>&1 1>/dev/null + modprobe scsi_debug vpd_use_hostno=0 add_host=2 echo "INFO: Waiting for udev to create /dev/sdX" sleep 15s #wait for udev to create /dev/sdX @@ -189,8 +189,6 @@ AA #enable multipath for scsi_debug. cat << AA > /etc/multipath.conf defaults { -#Enable multibus is for mutlbus testing - path_grouping_policy multibus user_friendly_names yes } blacklist { diff --git a/tests/medium_error_scsi_debug/main.sh b/tests/medium_error_scsi_debug/main.sh index db2f008..35c6e6f 100755 --- a/tests/medium_error_scsi_debug/main.sh +++ b/tests/medium_error_scsi_debug/main.sh @@ -16,47 +16,51 @@ # along with this program. If not, see . # Author: LiLin +source ../include/tc.sh || exit 200 -function cleanup() +cleanup() { sleep 5 udevadm settle - multipath -F + trun "multipath -DF" sleep 5 - modprobe -r scsi_debug - - return 0 + trun "modprobe -r scsi_debug" } -yum -y install device-mapper device-mapper-multipath -mpathconf --enable -service multipathd stop -modprobe scsi_debug num_tgts=1 vpd_use_hostno=0 add_host=2 delay=20 max_luns=2 no_lun_0=1 opts=2 +assert () +{ + local cmd="$*" + _trun_ "$cmd" 0 + if test $? -eq 0; then + tpass_ "$cmd" ; + else + tfail_ "$cmd" ; + cleanup ; + tend ; + fi +} + +tlog "running $0" +rpm -q device-mapper-multipath || dnf install -y device-mapper-multipath +trun "multipathd disablequeueing maps" +cleanup +trun "service multipathd stop" +trun "rm -f /etc/multipath.conf" +trun "mpathconf --enable" +trun "modprobe scsi_debug vpd_use_hostno=0 add_host=2 opts=2" sleep 5 -multipath > /dev/null +trun "multipath" sleep 5 +trun "multipath -l" mpathdev=`multipath -l | grep scsi_debug | awk '{print $1}' | head -1` -if [ -z "$mpathdev" ]; then - echo "------- FAIL, no multipath device created -----" - cleanup - exit 1 -fi +assert "[[ -n \"$mpathdev\" ]]" before_active=`multipath -l $mpathdev | grep "active undef" | wc -l` +tlog "before active = ${before_active}" IO_error=`dd if=/dev/zero of=/dev/mapper/$mpathdev bs=1024 seek=2330 count=10 2>&1 | grep -o "Input/output error" ` -if [ -n "$IO_error" ];then - after_active=`multipath -l $mpathdev | grep "active undef" | wc -l` - if [ "$before_active" -eq "$after_active" ]; then - echo "------- PASS, a medium error, correctly generated an I/O error and did not fail paths -----" - cleanup - exit 0 - else - echo "------- FAIL, paths failed -----" - cleanup - exit 1 - fi -else - echo "------- FAIL, did not generate an I/O error -----" - cleanup - exit 1 -fi +assert "[[ -n \"$IO_error\" ]]" +after_active=`multipath -l $mpathdev | grep "active undef" | wc -l` +tlog "after active = ${after_active}" +assert "[[ \"$before_active\" -eq \"$after_active\" ]]" +cleanup +tend diff --git a/tests/restate_module/main.sh b/tests/restate_module/main.sh index 565e59c..be60eba 100755 --- a/tests/restate_module/main.sh +++ b/tests/restate_module/main.sh @@ -48,10 +48,8 @@ rpm -q device-mapper-multipath || yum install -y device-mapper-multipath tlog "device-mapper-multipath is installed" # cleanup existing devices trun "rm /etc/multipath.conf" -trun "mpathconf --enable --with_module y" -sed -i '/^defaults[[:space:]]*{/ a\ - max_polling_interval 10 -' /etc/multipath.conf +trun "mpathconf --enable --with_module y --option max_polling_interval:10" +trun "mpathconf --option detect_pgpolicy_use_tpg:yes" trun "service multipathd stop" trun "multipath -F" sleep 5 diff --git a/tests/user_friendly_names/main.sh b/tests/user_friendly_names/main.sh index 56082fd..1d48801 100755 --- a/tests/user_friendly_names/main.sh +++ b/tests/user_friendly_names/main.sh @@ -17,50 +17,125 @@ # Author: Lin Li -source ../include/ec.sh || exit 200 - +source ../include/tc.sh || exit 200 tlog "running $0" -trun "rpm -q device-mapper-multipath || yum install -y device-mapper-multipath" -trun "mpathconf --enable --with_multipathd y --user_friendly_names y" +cleanup () +{ + local retries + if pidof multipathd; then + tlog "stopping multipathd" + trun "systemctl stop multipathd.service || pkill multipathd" + sleep 1 + fi + retries=10 + while pidof multipathd; do + ((retries--)) + if [[ $retries -le 0 ]]; then + tfail_ "failed to stop multipath" + tend + fi + tlog "waiting for multipathd to stop" + sleep 2 + pidof multipathd && pkill multipathd + done + trun "multipath -l -v1" + retries=10 + while [[ -n `multipath -l -v1` ]]; do + ((retries--)) + if [[ $retries -le 0 ]]; then + tfail_ "failed to remove deviece" + tend + fi + tlog "removing multipath device" + trun "udevadm settle" + trun "multipath -DF" + sleep 2 + done + if lsmod | grep -q "^scsi_debug"; then + tlog "removing scsi_debug module" + tok "rmmod scsi_debug" + fi + trun "rm -f /etc/multipath.conf" +} -# backup the /etc/multipath.conf -trun "cp /etc/multipath.conf /etc/multipath.conf.$$" -trun "multipath -F" +assert () +{ + local cmd="$*" + _trun_ "$cmd" 0 + if test $? -eq 0; then + tpass_ "$cmd" ; + else + tfail_ "$cmd" ; + cleanup ; + tend ; + fi +} -trun "modprobe scsi_debug num_tgts=1 vpd_use_hostno=0 add_host=2 delay=20 \ -max_luns=2 no_lun_0=1" -trun "multipath" -# wwid shown slowly on s390x by the script framework, but normally when run by multipath command directly -# so extend sleep time -sleep 20 +setup_config () +{ + trun "mpathconf --enable --user_friendly_names y" + sed -i '/^blacklist[[:space:]]*{/ a\ + device {\ + vendor ".*"\ + product ".*"\ + } +' /etc/multipath.conf + cat << _EOF_ >> /etc/multipath.conf -disk=$(get_scsi_debug_devices) -disk=$(basename $disk) -wwid=$(get_wwid_of_disk $disk) -mpath=$(get_mpath_disk_by_scsi_device $disk) +blacklist_exceptions { + device { + vendor Linux + product scsi_debug + } +} -# user_friendly_names = yes and mpath=test -#cur_dir=/mnt/tests/kernel/storage/multipath/user_friendly_names/ -#cur_dir=/home/test/scratch/device-mapper-multipath/user_friendly_names -trun "cat multipath.conf.yes | sed "s/your_wwid/$wwid/g" > /etc/multipath.conf" -trun "cat -n /etc/multipath.conf" -trun "multipath -r" -echo ">>> Verify 'test ($wwid)' is present ..." -trun "multipath -ll" -tok "multipath -ll | egrep \"^test\"" +multipaths { + multipath { + wwid TEST_WWID + alias test + } +} +_EOF_ + trun "cat /etc/multipath.conf" +} -# user_friendly_names = no -trun "cat multipath.conf.no > /etc/multipath.conf" -trun "multipath -r" -echo ">>> Verify 'test' is gone but '$wwid' present ..." -trun "multipath -ll" -tok "multipath -ll | egrep \"^$wwid\"" -sleep 10 -tok "multipath -F $wwid" -sleep 10 -trun "modprobe -r scsi_debug" +do_reconfigure () +{ + trun "cat /etc/multipath.conf" + tok "multipathd reconfigure" + sleep 5 +} -trun "cp /etc/multipath.conf.$$ /etc/multipath.conf" -trun "multipath -F; multipath" +trun "rpm -q device-mapper-multipath || dnf install -y device-mapper-multipath" +cleanup +setup_config +trun "rm -r /etc/multipath/bindings" +trun "modprobe scsi_debug vpd_use_hostno=0 add_host=2" +sleep 5 +trun "systemctl start multipathd.service" +while multipathd show daemon | grep -qv idle; do + tlog "waiting for multipathd to start" + sleep 1 +done +trun 'multipathd show maps raw format "%n %w"' +# verify user_friendly_name +tok 'multipathd show maps raw format "%n" | head -1 | grep -q mpath' +wwid=`multipathd show maps raw format "%w" | head -1` +assert "[[ -n $wwid ]] && [[ $wwid != ok ]]" +sed -i 's/TEST_WWID/'"$wwid"'/' /etc/multipath.conf +do_reconfigure +trun 'multipathd show maps raw format "%n %w"' +# verify configured alias takes precedence over user_friendly_name +tok 'multipathd show maps raw format "%n" | head -1 | grep -q test' +trun "mpathconf --user_friendly_names n" +do_reconfigure +trun 'multipathd show maps raw format "%n %w"' +# verify configured alias takes precedence over wwid name +tok 'multipathd show maps raw format "%n" | head -1 | grep -q test' +sed -i 's/'"$wwid"'/TEST_WWID/' /etc/multipath.conf +do_reconfigure +trun 'multipathd show maps raw format "%n %w"' +tok 'multipathd show maps raw format "%n" | head -1 | grep -q '"$wwid" +cleanup tend diff --git a/tests/user_friendly_names/multipath.conf.no b/tests/user_friendly_names/multipath.conf.no deleted file mode 100644 index b916bfb..0000000 --- a/tests/user_friendly_names/multipath.conf.no +++ /dev/null @@ -1,3 +0,0 @@ -defaults { - user_friendly_names no -} diff --git a/tests/user_friendly_names/multipath.conf.yes b/tests/user_friendly_names/multipath.conf.yes deleted file mode 100644 index ffc21bb..0000000 --- a/tests/user_friendly_names/multipath.conf.yes +++ /dev/null @@ -1,11 +0,0 @@ -defaults { - user_friendly_names yes -} - -multipaths { - multipath { - wwid your_wwid - alias test - } -} - From 4ec4661deede93f7134c87624f89a07ac166e3f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 12 Jan 2025 14:25:51 +0100 Subject: [PATCH 59/67] Rebuilt for the bin-sbin merge (2nd attempt) https://fedoraproject.org/wiki/Changes/Unify_bin_and_sbin --- device-mapper-multipath.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 4363b49..2eebd2f 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.10.0 -Release: 2%{?dist} +Release: 3%{?dist} Summary: Tools to manage multipath devices using device-mapper # Automatically converted from old format: GPLv2 - review is highly recommended. License: GPL-2.0-only @@ -233,6 +233,9 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Sun Jan 12 2025 Zbigniew Jędrzejewski-Szmek - 0.10.0-3 +- Rebuilt for the bin-sbin merge (2nd attempt) + * Thu Aug 29 2024 Benjamin Marzinski - 0.10.0-2 - update CI tests. From 61847c90be2f7afa60de098651ff5c92cd0f1374 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 16 Jan 2025 15:37:12 +0000 Subject: [PATCH 60/67] Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild --- device-mapper-multipath.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 2eebd2f..8ff030a 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.10.0 -Release: 3%{?dist} +Release: 4%{?dist} Summary: Tools to manage multipath devices using device-mapper # Automatically converted from old format: GPLv2 - review is highly recommended. License: GPL-2.0-only @@ -233,6 +233,9 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Thu Jan 16 2025 Fedora Release Engineering - 0.10.0-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild + * Sun Jan 12 2025 Zbigniew Jędrzejewski-Szmek - 0.10.0-3 - Rebuilt for the bin-sbin merge (2nd attempt) From 05ecb26e7c73e0563c5b4096bf6288324b753cea Mon Sep 17 00:00:00 2001 From: Yaakov Selkowitz Date: Tue, 28 Jan 2025 23:12:39 -0500 Subject: [PATCH 61/67] Fix build with userspace-rcu 0.15.0 C11 (or C++11) are now required for atomics in userspace-rcu: https://github.com/urcu/userspace-rcu/commit/89280d020bf064d1055c360fb9974f128051043f --- 0005-RH-use-rpm-optflags-if-present.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/0005-RH-use-rpm-optflags-if-present.patch b/0005-RH-use-rpm-optflags-if-present.patch index 3f115c1..266e224 100644 --- a/0005-RH-use-rpm-optflags-if-present.patch +++ b/0005-RH-use-rpm-optflags-if-present.patch @@ -54,7 +54,7 @@ index 81cb61d2..35334a0c 100644 -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP -CFLAGS := -std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ - -fexceptions -+CFLAGS := -std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe ++CFLAGS := -std=gnu11 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe BIN_CFLAGS := -fPIE -DPIE LIB_CFLAGS := -fPIC SHARED_FLAGS := -shared From 3c2eb3f84ecbc2fd6790437dc83955ab4fd6cc33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20Such=C3=BD?= Date: Mon, 20 Jan 2025 08:06:30 +0000 Subject: [PATCH 62/67] Migrate to SPDX license This is part of https://fedoraproject.org/wiki/Changes/SPDX_Licenses_Phase_4 --- device-mapper-multipath.spec | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 8ff030a..d2c3cc6 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -2,8 +2,8 @@ Name: device-mapper-multipath Version: 0.10.0 Release: 4%{?dist} Summary: Tools to manage multipath devices using device-mapper -# Automatically converted from old format: GPLv2 - review is highly recommended. -License: GPL-2.0-only +# readline uses GPL-3.0-only +License: GPL-2.0-only AND GPL-3.0-only URL: http://christophe.varoqui.free.fr/ # The source for this package was pulled from upstream's git repo. Use the @@ -65,8 +65,8 @@ The tools are : %package libs Summary: The %{name} modules and shared library -# only libmpathcmd is LGPLv2+ -License: GPLv2 and LGPLv2+ +# only libmpathcmd is LGPL-2.1-or-later AND LGPL-2.0-or-later +License: GPL-2.0-or-later AND LGPL-2.1-or-later AND LGPL-2.0-or-later %description libs The %{name}-libs provides the path checker From f2377371e3fef1c096acab223bd842dbd755f5d0 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Sun, 2 Feb 2025 01:54:16 -0500 Subject: [PATCH 63/67] device-mapper-multipath-0.10.0-5 - Update source to upstream staging branch for 0.10.y (will be 0.10.2 when merged). - Rebase redhat patches --- ...lows-use-upload-download-artifact-v4.patch | 122 ++++++++++++++++ ...-update-dawidd6-action-download-arti.patch | 24 +++ ...-native.yml-use-mosteo-actions-docke.patch | 98 +++++++++++++ ...s-native.yml-use-extra-job-for-clang.patch | 43 ++++++ ...-native.yaml-make-test-and-archive-s.patch | 51 +++++++ ...-enable-unit-tests-for-stable-branch.patch | 133 +++++++++++++++++ ...ws-add-abi-check-for-stable-branches.patch | 110 ++++++++++++++ ...get_maps-don-t-bail-out-for-single-m.patch | 32 ++++ ...s.in-import-DM_COLDPLUG_SUSPENDED-on.patch | 42 ++++++ ...s.in-handle-inactive-suspended-devic.patch | 66 +++++++++ ...rules.in-clarify-DM_ACTIVATION-logic.patch | 78 ++++++++++ ...h-rules.in-skip-one-.DM_NOSCAN-check.patch | 28 ++++ ...s.in-set-.DM_NOSCAN-if-MPATH_UNCHANG.patch | 44 ++++++ ...-t-set-dev_loss_tmo-to-0-for-NO_PATH.patch | 31 ++++ ...eferred_failback_tick-for-reload-rem.patch | 35 +++++ ...ipathd-fix-an-unsigned-int-ovwerflow.patch | 28 ++++ ...id-Wcast-function-type-mismatch-erro.patch | 36 +++++ 0018-Update-NEWS.md-for-0.10.1.patch | 44 ++++++ ...-t-print-error-message-if-WATCHDOG_U.patch | 30 ++++ ...uce-log-level-of-map-X-has-multiple-.patch | 38 +++++ ...eign-fix-memory-leak-in-nvme-foreign.patch | 54 +++++++ ...-condition-for-enqueueing-path-to-io.patch | 41 ++++++ ...dditional-NEWS.md-updates-for-0.10.1.patch | 63 ++++++++ ...multipath-fix-handling-of-pp-pgindex.patch | 138 ++++++++++++++++++ ...e-pgcmp-detect-if-map-is-missing-a-p.patch | 70 +++++++++ ...gger-uevents-upon-map-creation-in-do.patch | 94 ++++++++++++ ...er-uevents-upon-map-removal-in-coale.patch | 41 ++++++ ...h-Don-t-skip-set_path_max_sectors_kb.patch | 31 ++++ ...p-static-analyzer-complaint-in-init_.patch | 27 ++++ ...lenient-in-allowing-the-alua-based-p.patch | 44 ++++++ 0031-Update-NEWS.md-for-0.10.2.patch | 64 ++++++++ ...-fix-abi-stable.yaml-for-pull-reques.patch | 61 ++++++++ ... 0033-RH-fixup-udev-rules-for-redhat.patch | 0 ...property-blacklist-exception-builtin.patch | 0 ...RH-don-t-start-without-a-config-file.patch | 4 +- ...H-Fix-nvme-function-missing-argument.patch | 0 ... 0037-RH-use-rpm-optflags-if-present.patch | 3 +- ...hconf.patch => 0038-RH-add-mpathconf.patch | 12 +- ...om-kernel-cmdline-mpath.wwids-with-A.patch | 0 ...-default-find_mutipaths-value-to-off.patch | 0 ...empt-to-get-ANA-info-via-sysfs-first.patch | 0 ...-parse_vpd_pg83-match-scsi_id-output.patch | 2 +- ...si-device-handlers-to-modules-load.d.patch | 2 +- ...-RH-compile-with-libreadline-support.patch | 2 +- ...up.patch => 0045-RH-Add-mpathcleanup.patch | 0 device-mapper-multipath.spec | 65 +++++++-- 46 files changed, 1905 insertions(+), 26 deletions(-) create mode 100644 0001-GitHub-workflows-use-upload-download-artifact-v4.patch create mode 100644 0002-GitHub-workflows-update-dawidd6-action-download-arti.patch create mode 100644 0003-Github-workflows-native.yml-use-mosteo-actions-docke.patch create mode 100644 0004-GitHub-workflows-native.yml-use-extra-job-for-clang.patch create mode 100644 0005-GitHub-workflows-native.yaml-make-test-and-archive-s.patch create mode 100644 0006-GitHub-workflows-enable-unit-tests-for-stable-branch.patch create mode 100644 0007-GitHub-Workflows-add-abi-check-for-stable-branches.patch create mode 100644 0008-libmultipath-dm_get_maps-don-t-bail-out-for-single-m.patch create mode 100644 0009-11-dm-mpath.rules.in-import-DM_COLDPLUG_SUSPENDED-on.patch create mode 100644 0010-11-dm-mpath.rules.in-handle-inactive-suspended-devic.patch create mode 100644 0011-11-dm-mpath.rules.in-clarify-DM_ACTIVATION-logic.patch create mode 100644 0012-11-dm-mpath-rules.in-skip-one-.DM_NOSCAN-check.patch create mode 100644 0013-11-dm-mpath.rules.in-set-.DM_NOSCAN-if-MPATH_UNCHANG.patch create mode 100644 0014-libmultipath-don-t-set-dev_loss_tmo-to-0-for-NO_PATH.patch create mode 100644 0015-multipathd-fix-deferred_failback_tick-for-reload-rem.patch create mode 100644 0016-multipathd-fix-an-unsigned-int-ovwerflow.patch create mode 100644 0017-libmpathutil-avoid-Wcast-function-type-mismatch-erro.patch create mode 100644 0018-Update-NEWS.md-for-0.10.1.patch create mode 100644 0019-libmultipath-don-t-print-error-message-if-WATCHDOG_U.patch create mode 100644 0020-libmultipath-reduce-log-level-of-map-X-has-multiple-.patch create mode 100644 0021-libmultipath-foreign-fix-memory-leak-in-nvme-foreign.patch create mode 100644 0022-libmultipath-add-condition-for-enqueueing-path-to-io.patch create mode 100644 0023-Additional-NEWS.md-updates-for-0.10.1.patch create mode 100644 0024-libmultipath-fix-handling-of-pp-pgindex.patch create mode 100644 0025-libmultipath-make-pgcmp-detect-if-map-is-missing-a-p.patch create mode 100644 0026-libmultipath-trigger-uevents-upon-map-creation-in-do.patch create mode 100644 0027-multipathd-trigger-uevents-upon-map-removal-in-coale.patch create mode 100644 0028-libmultipath-Don-t-skip-set_path_max_sectors_kb.patch create mode 100644 0029-libmultipath-stop-static-analyzer-complaint-in-init_.patch create mode 100644 0030-libmultipath-be-lenient-in-allowing-the-alua-based-p.patch create mode 100644 0031-Update-NEWS.md-for-0.10.2.patch create mode 100644 0032-GitHub-Workflows-fix-abi-stable.yaml-for-pull-reques.patch rename 0001-RH-fixup-udev-rules-for-redhat.patch => 0033-RH-fixup-udev-rules-for-redhat.patch (100%) rename 0002-RH-Remove-the-property-blacklist-exception-builtin.patch => 0034-RH-Remove-the-property-blacklist-exception-builtin.patch (100%) rename 0003-RH-don-t-start-without-a-config-file.patch => 0035-RH-don-t-start-without-a-config-file.patch (98%) rename 0004-RH-Fix-nvme-function-missing-argument.patch => 0036-RH-Fix-nvme-function-missing-argument.patch (100%) rename 0005-RH-use-rpm-optflags-if-present.patch => 0037-RH-use-rpm-optflags-if-present.patch (97%) rename 0006-RH-add-mpathconf.patch => 0038-RH-add-mpathconf.patch (99%) rename 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch => 0039-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch (100%) rename 0008-RH-reset-default-find_mutipaths-value-to-off.patch => 0040-RH-reset-default-find_mutipaths-value-to-off.patch (100%) rename 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch => 0041-RH-attempt-to-get-ANA-info-via-sysfs-first.patch (100%) rename 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch => 0042-RH-make-parse_vpd_pg83-match-scsi_id-output.patch (98%) rename 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch => 0043-RH-add-scsi-device-handlers-to-modules-load.d.patch (96%) rename 0012-RH-compile-with-libreadline-support.patch => 0044-RH-compile-with-libreadline-support.patch (96%) rename 0013-RH-Add-mpathcleanup.patch => 0045-RH-Add-mpathcleanup.patch (100%) diff --git a/0001-GitHub-workflows-use-upload-download-artifact-v4.patch b/0001-GitHub-workflows-use-upload-download-artifact-v4.patch new file mode 100644 index 0000000..c8247ca --- /dev/null +++ b/0001-GitHub-workflows-use-upload-download-artifact-v4.patch @@ -0,0 +1,122 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 13 Sep 2024 09:09:19 +0200 +Subject: [PATCH] GitHub workflows: use {upload,download}-artifact@v4 + +The @v1 releases are deprecated. +https://github.blog/changelog/2024-02-13-deprecation-notice-v1-and-v2-of-the-artifact-actions/ + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/abi.yaml | 6 ++++-- + .github/workflows/foreign.yaml | 15 +++++++-------- + .github/workflows/native.yaml | 5 +++-- + 3 files changed, 14 insertions(+), 12 deletions(-) + +diff --git a/.github/workflows/abi.yaml b/.github/workflows/abi.yaml +index 393322e5..dce09f5c 100644 +--- a/.github/workflows/abi.yaml ++++ b/.github/workflows/abi.yaml +@@ -45,10 +45,11 @@ jobs: + - name: create ABI + run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) abi.tar.gz + - name: save ABI +- uses: actions/upload-artifact@v1 ++ uses: actions/upload-artifact@v4 + with: + name: abi + path: abi ++ overwrite: true + - name: compare ABI against reference + id: compare + continue-on-error: true +@@ -56,10 +57,11 @@ jobs: + run: make abi-test + - name: save differences + if: ${{ steps.compare.outcome == 'failure' }} +- uses: actions/upload-artifact@v1 ++ uses: actions/upload-artifact@v4 + with: + name: abi-test + path: abi-test ++ overwrite: true + + - name: fail + # MUST use >- here, otherwise the condition always evaluates to true +diff --git a/.github/workflows/foreign.yaml b/.github/workflows/foreign.yaml +index 9e4d35e0..d68650df 100644 +--- a/.github/workflows/foreign.yaml ++++ b/.github/workflows/foreign.yaml +@@ -36,14 +36,13 @@ jobs: + - name: checkout + uses: actions/checkout@v1 + - name: build +- run: make -j8 -Orecurse test-progs +- - name: create binary archive +- run: make test-progs.tar ++ run: make -j -Orecurse test-progs.tar + - name: upload binary archive +- uses: actions/upload-artifact@v1 ++ uses: actions/upload-artifact@v4 + with: + name: cross-${{ matrix.os }}-${{ matrix.arch }} + path: test-progs.tar ++ overwrite: true + + test: + runs-on: ubuntu-22.04 +@@ -61,11 +60,11 @@ jobs: + run: echo CONTAINER_ARCH="arm/v7" >> $GITHUB_ENV + if: ${{ matrix.arch == 'armhf' }} + - name: download binary archive +- uses: actions/download-artifact@v1 ++ uses: actions/download-artifact@v4 + with: + name: cross-${{ matrix.os }}-${{ matrix.arch }} + - name: unpack binary archive +- run: tar xfv cross-${{ matrix.os }}-${{ matrix.arch }}/test-progs.tar ++ run: tar xfv test-progs.tar + - name: enable foreign arch + uses: dbhi/qus/action@main + - name: run tests +@@ -100,11 +99,11 @@ jobs: + run: echo CONTAINER_ARCH="arm/v7" >> $GITHUB_ENV + if: ${{ matrix.arch == 'armhf' }} + - name: download binary archive +- uses: actions/download-artifact@v1 ++ uses: actions/download-artifact@v4 + with: + name: cross-${{ matrix.os }}-${{ matrix.arch }} + - name: unpack binary archive +- run: tar xfv cross-${{ matrix.os }}-${{ matrix.arch }}/test-progs.tar ++ run: tar xfv test-progs.tar + - name: enable foreign arch + uses: dbhi/qus/action@main + - name: run tests +diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml +index 80ff6df5..500becaa 100644 +--- a/.github/workflows/native.yaml ++++ b/.github/workflows/native.yaml +@@ -57,10 +57,11 @@ jobs: + - name: create binary archive + run: make ${{ env.ARCHIVE_TGT }} + - name: upload binary archive +- uses: actions/upload-artifact@v1 ++ uses: actions/upload-artifact@v4 + with: + name: native-${{ matrix.os }} + path: ${{ env.ARCHIVE_TGT }} ++ overwrite: true + + - name: clean + run: make clean +@@ -98,7 +99,7 @@ jobs: + uses: actions/checkout@v1 + + - name: download binary archive +- uses: actions/download-artifact@v1 ++ uses: actions/download-artifact@v4 + with: + name: native-${{ matrix.os }} + - name: unpack binary archive diff --git a/0002-GitHub-workflows-update-dawidd6-action-download-arti.patch b/0002-GitHub-workflows-update-dawidd6-action-download-arti.patch new file mode 100644 index 0000000..423bf56 --- /dev/null +++ b/0002-GitHub-workflows-update-dawidd6-action-download-arti.patch @@ -0,0 +1,24 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 13 Sep 2024 09:10:38 +0200 +Subject: [PATCH] GitHub workflows: update dawidd6/action-download-artifact + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/abi.yaml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/.github/workflows/abi.yaml b/.github/workflows/abi.yaml +index dce09f5c..d5f8b477 100644 +--- a/.github/workflows/abi.yaml ++++ b/.github/workflows/abi.yaml +@@ -28,7 +28,7 @@ jobs: + - name: get reference ABI + id: reference + continue-on-error: true +- uses: dawidd6/action-download-artifact@v2 ++ uses: dawidd6/action-download-artifact@v6 + with: + workflow: abi.yaml + branch: ${{ env.ABI_BRANCH }} diff --git a/0003-Github-workflows-native.yml-use-mosteo-actions-docke.patch b/0003-Github-workflows-native.yml-use-mosteo-actions-docke.patch new file mode 100644 index 0000000..63aa273 --- /dev/null +++ b/0003-Github-workflows-native.yml-use-mosteo-actions-docke.patch @@ -0,0 +1,98 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 13 Sep 2024 09:45:25 +0200 +Subject: [PATCH] Github workflows: native.yml: use mosteo-actions/docker-run + +We can't use "container:" any more because upload-artifact@v4 doesn't +work on Debian Jessie. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/native.yaml | 45 +++++++++++++++++++++-------------- + 1 file changed, 27 insertions(+), 18 deletions(-) + +diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml +index 500becaa..70d01c55 100644 +--- a/.github/workflows/native.yaml ++++ b/.github/workflows/native.yaml +@@ -35,17 +35,9 @@ jobs: + - debian-bookworm + - fedora-40 + - opensuse-leap +- container: ghcr.io/mwilck/multipath-build-${{ matrix.os }} + steps: + - name: checkout + uses: actions/checkout@v1 +- - name: build and test +- if: ${{ matrix.os != 'debian-jessie' }} +- run: make -j -Orecurse test +- - name: build and test (jessie) +- # On jessie, we use libreadline 5 (no licensing issue) +- if: ${{ matrix.os == 'debian-jessie' }} +- run: make -j -Orecurse READLINE=libreadline test + + - name: set archive name + # Leap containers have cpio but not tar +@@ -54,8 +46,21 @@ jobs: + - name: set archive name + run: echo ARCHIVE_TGT=test-progs.tar >> $GITHUB_ENV + if: ${{ matrix.os != 'opensuse-leap' }} +- - name: create binary archive +- run: make ${{ env.ARCHIVE_TGT }} ++ ++ - name: build and test ++ if: ${{ matrix.os != 'debian-jessie' }} ++ uses: mosteo-actions/docker-run@v1 ++ with: ++ image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} ++ command: -j -Orecurse ${{ env.ARCHIVE_TGT }} test ++ - name: build and test (jessie) ++ # On jessie, we use libreadline 5 (no licensing issue) ++ if: ${{ matrix.os == 'debian-jessie' }} ++ uses: mosteo-actions/docker-run@v1 ++ with: ++ image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} ++ command: -j -Orecurse READLINE=libreadline ${{ env.ARCHIVE_TGT }} test ++ + - name: upload binary archive + uses: actions/upload-artifact@v4 + with: +@@ -67,14 +72,18 @@ jobs: + run: make clean + - name: clang + if: ${{ matrix.os != 'debian-jessie' }} +- env: +- CC: clang +- run: make -j -Orecurse test ++ uses: mosteo-actions/docker-run@v1 ++ with: ++ image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} ++ params: -e CC=clang ++ command: -j -Orecurse test + - name: clang (jessie) + if: ${{ matrix.os == 'debian-jessie' }} +- env: +- CC: clang +- run: make READLINE=libreadline test ++ uses: mosteo-actions/docker-run@v1 ++ with: ++ image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} ++ params: -e CC=clang ++ command: -j -Orecurse READLINE=libreadline test + + root-test: + runs-on: ubuntu-22.04 +@@ -103,10 +112,10 @@ jobs: + with: + name: native-${{ matrix.os }} + - name: unpack binary archive +- run: cpio -idv < native-${{ matrix.os }}/test-progs.cpio ++ run: cpio -idv < test-progs.cpio + if: ${{ matrix.os == 'opensuse-leap' }} + - name: unpack binary archive +- run: tar xfmv native-${{ matrix.os }}/test-progs.tar ++ run: tar xfmv test-progs.tar + if: ${{ matrix.os != 'opensuse-leap' }} + + - name: run root tests diff --git a/0004-GitHub-workflows-native.yml-use-extra-job-for-clang.patch b/0004-GitHub-workflows-native.yml-use-extra-job-for-clang.patch new file mode 100644 index 0000000..e6d618c --- /dev/null +++ b/0004-GitHub-workflows-native.yml-use-extra-job-for-clang.patch @@ -0,0 +1,43 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 13 Sep 2024 10:17:17 +0200 +Subject: [PATCH] GitHub workflows: native.yml: use extra job for clang + +Running "make" in a container and "make clean" outside doesn't +work (access right issues). So just use separate jobs. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/native.yaml | 18 ++++++++++++++++-- + 1 file changed, 16 insertions(+), 2 deletions(-) + +diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml +index 70d01c55..95b53b87 100644 +--- a/.github/workflows/native.yaml ++++ b/.github/workflows/native.yaml +@@ -68,8 +68,22 @@ jobs: + path: ${{ env.ARCHIVE_TGT }} + overwrite: true + +- - name: clean +- run: make clean ++ clang: ++ runs-on: ubuntu-22.04 ++ strategy: ++ fail-fast: false ++ matrix: ++ os: ++ - debian-jessie ++ - debian-buster ++ - debian-bullseye ++ - debian-bookworm ++ - fedora-40 ++ - opensuse-leap ++ steps: ++ - name: checkout ++ uses: actions/checkout@v1 ++ + - name: clang + if: ${{ matrix.os != 'debian-jessie' }} + uses: mosteo-actions/docker-run@v1 diff --git a/0005-GitHub-workflows-native.yaml-make-test-and-archive-s.patch b/0005-GitHub-workflows-native.yaml-make-test-and-archive-s.patch new file mode 100644 index 0000000..cabfbcf --- /dev/null +++ b/0005-GitHub-workflows-native.yaml-make-test-and-archive-s.patch @@ -0,0 +1,51 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 13 Sep 2024 10:30:47 +0200 +Subject: [PATCH] GitHub workflows: native.yaml: make test and archive + separately + +Avoid "text file busy" error on GitHub. + +dmevents-test: Text file busy +Makefile:74: recipe for target 'dmevents.out' failed + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/native.yaml | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml +index 95b53b87..f06b09df 100644 +--- a/.github/workflows/native.yaml ++++ b/.github/workflows/native.yaml +@@ -52,14 +52,27 @@ jobs: + uses: mosteo-actions/docker-run@v1 + with: + image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} +- command: -j -Orecurse ${{ env.ARCHIVE_TGT }} test ++ command: -j -Orecurse test + - name: build and test (jessie) + # On jessie, we use libreadline 5 (no licensing issue) + if: ${{ matrix.os == 'debian-jessie' }} + uses: mosteo-actions/docker-run@v1 + with: + image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} +- command: -j -Orecurse READLINE=libreadline ${{ env.ARCHIVE_TGT }} test ++ command: -j -Orecurse READLINE=libreadline test ++ ++ - name: create ${{ env.ARCHIVE_TGT }} ++ if: ${{ matrix.os != 'debian-jessie' }} ++ uses: mosteo-actions/docker-run@v1 ++ with: ++ image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} ++ command: ${{ env.ARCHIVE_TGT }} ++ - name: create ${{ env.ARCHIVE_TGT }} (jessie) ++ if: ${{ matrix.os == 'debian-jessie' }} ++ uses: mosteo-actions/docker-run@v1 ++ with: ++ image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} ++ command: READLINE=libreadline ${{ env.ARCHIVE_TGT }} + + - name: upload binary archive + uses: actions/upload-artifact@v4 diff --git a/0006-GitHub-workflows-enable-unit-tests-for-stable-branch.patch b/0006-GitHub-workflows-enable-unit-tests-for-stable-branch.patch new file mode 100644 index 0000000..4a9b254 --- /dev/null +++ b/0006-GitHub-workflows-enable-unit-tests-for-stable-branch.patch @@ -0,0 +1,133 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 14 Nov 2024 16:02:38 +0100 +Subject: [PATCH] GitHub workflows: enable unit tests for stable branches + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/build-and-unittest.yaml | 2 ++ + .github/workflows/foreign.yaml | 2 ++ + .github/workflows/multiarch-stable.yaml | 2 ++ + .github/workflows/multiarch.yaml | 2 ++ + .github/workflows/native.yaml | 2 ++ + .github/workflows/rolling.yaml | 2 ++ + 6 files changed, 12 insertions(+) + +diff --git a/.github/workflows/build-and-unittest.yaml b/.github/workflows/build-and-unittest.yaml +index a838f9a2..1a727e14 100644 +--- a/.github/workflows/build-and-unittest.yaml ++++ b/.github/workflows/build-and-unittest.yaml +@@ -5,10 +5,12 @@ on: + - master + - queue + - tip ++ - 'stable-*' + pull_request: + branches: + - master + - queue ++ - 'stable-*' + jobs: + jammy: + runs-on: ubuntu-22.04 +diff --git a/.github/workflows/foreign.yaml b/.github/workflows/foreign.yaml +index d68650df..0f80957b 100644 +--- a/.github/workflows/foreign.yaml ++++ b/.github/workflows/foreign.yaml +@@ -5,6 +5,7 @@ on: + - master + - queue + - tip ++ - 'stable-*' + paths: + - '.github/workflows/foreign.yaml' + - '**.h' +@@ -15,6 +16,7 @@ on: + branches: + - master + - queue ++ - 'stable-*' + paths: + - '.github/workflows/foreign.yaml' + - '**.h' +diff --git a/.github/workflows/multiarch-stable.yaml b/.github/workflows/multiarch-stable.yaml +index e51d383c..ffede53d 100644 +--- a/.github/workflows/multiarch-stable.yaml ++++ b/.github/workflows/multiarch-stable.yaml +@@ -5,6 +5,7 @@ on: + - master + - queue + - tip ++ - 'stable-*' + paths: + - '.github/workflows/multiarch-stable.yaml' + - '**.h' +@@ -15,6 +16,7 @@ on: + branches: + - master + - queue ++ - 'stable-*' + paths: + - '.github/workflows/multiarch-stable.yaml' + - '**.h' +diff --git a/.github/workflows/multiarch.yaml b/.github/workflows/multiarch.yaml +index df95a02f..d2b833a4 100644 +--- a/.github/workflows/multiarch.yaml ++++ b/.github/workflows/multiarch.yaml +@@ -5,6 +5,7 @@ on: + - master + - queue + - tip ++ - 'stable-*' + paths: + - '.github/workflows/multiarch.yaml' + - '**.h' +@@ -15,6 +16,7 @@ on: + branches: + - master + - queue ++ - 'stable-*' + paths: + - '.github/workflows/multiarch.yaml' + - '**.h' +diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml +index f06b09df..c9d9df9e 100644 +--- a/.github/workflows/native.yaml ++++ b/.github/workflows/native.yaml +@@ -5,6 +5,7 @@ on: + - master + - queue + - tip ++ - 'stable-*' + paths: + - '.github/workflows/native.yaml' + - '**.h' +@@ -15,6 +16,7 @@ on: + branches: + - master + - queue ++ - 'stable-*' + paths: + - '.github/workflows/native.yaml' + - '**.h' +diff --git a/.github/workflows/rolling.yaml b/.github/workflows/rolling.yaml +index 3536b944..66af7a44 100644 +--- a/.github/workflows/rolling.yaml ++++ b/.github/workflows/rolling.yaml +@@ -5,6 +5,7 @@ on: + - master + - queue + - tip ++ - 'stable-*' + paths: + - '.github/workflows/rolling.yaml' + - '**.h' +@@ -15,6 +16,7 @@ on: + branches: + - master + - queue ++ - 'stable-*' + paths: + - '.github/workflows/rolling.yaml' + - '**.h' diff --git a/0007-GitHub-Workflows-add-abi-check-for-stable-branches.patch b/0007-GitHub-Workflows-add-abi-check-for-stable-branches.patch new file mode 100644 index 0000000..c19980f --- /dev/null +++ b/0007-GitHub-Workflows-add-abi-check-for-stable-branches.patch @@ -0,0 +1,110 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 14 Nov 2024 16:51:05 +0100 +Subject: [PATCH] GitHub Workflows: add abi check for stable branches + +The ABI should never change on a stable branch. This workflow +asserts that. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/abi-stable.yaml | 89 +++++++++++++++++++++++++++++++ + 1 file changed, 89 insertions(+) + create mode 100644 .github/workflows/abi-stable.yaml + +diff --git a/.github/workflows/abi-stable.yaml b/.github/workflows/abi-stable.yaml +new file mode 100644 +index 00000000..a6746f23 +--- /dev/null ++++ b/.github/workflows/abi-stable.yaml +@@ -0,0 +1,89 @@ ++name: check-abi for stable branch ++on: ++ push: ++ branches: ++ - 'stable-*' ++ paths: ++ - '.github/workflows/abi-stable.yaml' ++ - '**.h' ++ - '**.c' ++ - '**.version' ++ pull_request: ++ branches: ++ - 'stable-*' ++ workflow_dispatch: ++ ++jobs: ++ reference-abi: ++ runs-on: ubuntu-20.04 ++ steps: ++ - name: get parent tag ++ run: > ++ echo ${{ github.ref }} | ++ sed -E 's,refs/heads/stable-([0-9]\.[0-9]*)\.y,PARENT_TAG=\1.0,' >> $GITHUB_ENV ++ - name: assert parent tag ++ run: /bin/false ++ if: ${{ env.PARENT_TAG == '' }} ++ - name: update ++ run: sudo apt-get update ++ - name: dependencies ++ run: > ++ sudo apt-get install --yes gcc ++ gcc make pkg-config abigail-tools ++ libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev ++ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev ++ - name: checkout ${{ env.PARENT_TAG }} ++ uses: actions/checkout@v4 ++ with: ++ ref: ${{ env.PARENT_TAG }} ++ - name: build ABI for ${{ env.PARENT_TAG }} ++ run: make -j$(grep -c ^processor /proc/cpuinfo) -Orecurse abi ++ - name: save ABI ++ uses: actions/upload-artifact@v4 ++ with: ++ name: multipath-abi-${{ env.PARENT_TAG }} ++ path: abi ++ ++ check-abi: ++ runs-on: ubuntu-20.04 ++ needs: reference-abi ++ steps: ++ - name: get parent tag ++ run: > ++ echo ${{ github.ref }} | ++ sed -E 's,refs/heads/stable-([0-9]\.[0-9]*)\.y,PARENT_TAG=\1.0,' >> $GITHUB_ENV ++ - name: assert parent tag ++ run: /bin/false ++ if: ${{ env.PARENT_TAG == '' }} ++ - name: checkout ${{ env.PARENT_TAG }} ++ uses: actions/checkout@v4 ++ with: ++ ref: ${{ env.PARENT_TAG }} ++ - name: download ABI for ${{ env.PARENT_TAG }} ++ id: download_abi ++ uses: actions/download-artifact@v4 ++ with: ++ name: multipath-abi-${{ env.PARENT_TAG }} ++ path: reference-abi ++ - name: update ++ run: sudo apt-get update ++ if: steps.download_abi.outcome != 'success' ++ - name: dependencies ++ run: > ++ sudo apt-get install --yes gcc ++ gcc make pkg-config abigail-tools ++ libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev ++ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev ++ - name: check ABI of ${{ github.ref }} against ${{ env.PARENT_TAG }} ++ id: check_abi ++ run: make -j$(grep -c ^processor /proc/cpuinfo) -Orecurse abi-test ++ continue-on-error: true ++ - name: save differences ++ if: ${{ steps.check_abi.outcome != 'success' }} ++ uses: actions/upload-artifact@v4 ++ with: ++ name: abi-test ++ path: abi-test ++ - name: fail ++ run: /bin/false ++ if: steps.check_abi.outcome != 'success' diff --git a/0008-libmultipath-dm_get_maps-don-t-bail-out-for-single-m.patch b/0008-libmultipath-dm_get_maps-don-t-bail-out-for-single-m.patch new file mode 100644 index 0000000..88122b0 --- /dev/null +++ b/0008-libmultipath-dm_get_maps-don-t-bail-out-for-single-m.patch @@ -0,0 +1,32 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 12 Nov 2024 13:06:10 +0100 +Subject: [PATCH] libmultipath: dm_get_maps(): don't bail out for single-map + failures + +dm_get_maps() traverses the entire list of dm maps. We shouldn't +give up just because probing a single map failed. + +Fixes: bf3a4ad ("libmultipath: simplify dm_get_maps()") +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/devmapper.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index c497c225..52bfe9ce 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -1262,10 +1262,8 @@ int dm_get_maps(vector mp) + } + vector_set_slot(mp, mpp); + break; +- case DMP_NO_MATCH: +- break; + default: +- return 1; ++ break; + } + next = names->next; + names = (void *) names + next; diff --git a/0009-11-dm-mpath.rules.in-import-DM_COLDPLUG_SUSPENDED-on.patch b/0009-11-dm-mpath.rules.in-import-DM_COLDPLUG_SUSPENDED-on.patch new file mode 100644 index 0000000..b380f75 --- /dev/null +++ b/0009-11-dm-mpath.rules.in-import-DM_COLDPLUG_SUSPENDED-on.patch @@ -0,0 +1,42 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 31 Oct 2024 12:08:08 +0100 +Subject: [PATCH] 11-dm-mpath.rules.in: import DM_COLDPLUG_SUSPENDED only once + +We import DM_COLDPLUG_SUSPENDED in all code flows below mpath_coldplug_end. +Clarify this in the code. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/11-dm-mpath.rules.in | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in +index 30647b99..67838261 100644 +--- a/multipath/11-dm-mpath.rules.in ++++ b/multipath/11-dm-mpath.rules.in +@@ -24,12 +24,13 @@ ENV{DM_UDEV_RULES_VSN}=="1|2", ENV{.DM_SUSPENDED}!="1", ENV{DISK_RO}!="1", \ + ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="", GOTO="scan_import" + LABEL="mpath_coldplug_end" + ++IMPORT{db}="DM_COLDPLUG_SUSPENDED" ++ + # If this uevent didn't come from dm, don't try to update the + # device state + # Note that .MPATH_DEVICE_READY_OLD=="" here. Thus we won't activate the + # device below at mpath_is_ready, which is correct. + ENV{DM_COOKIE}!="?*", ENV{DM_ACTION}!="PATH_*", \ +- IMPORT{db}="DM_COLDPLUG_SUSPENDED", \ + GOTO="check_mpath_ready" + + ENV{.MPATH_DEVICE_READY_OLD}="$env{MPATH_DEVICE_READY}" +@@ -67,7 +68,6 @@ LABEL="check_mpath_unchanged" + # A previous coldplug event occurred while the device was suspended. + # Activation might have been partially skipped. Activate the device now, + # i.e. disable the MPATH_UNCHANGED logic and set DM_ACTIVATION=1. +-IMPORT{db}="DM_COLDPLUG_SUSPENDED" + ENV{DM_COLDPLUG_SUSPENDED}=="1", ENV{.DM_SUSPENDED}!="1", \ + ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0", \ + PROGRAM="@SYSDIR_BIN@/logger -t 11-dm-mpath.rules -p daemon.notice \"Forcing activation of previously suspended device\"", \ diff --git a/0010-11-dm-mpath.rules.in-handle-inactive-suspended-devic.patch b/0010-11-dm-mpath.rules.in-handle-inactive-suspended-devic.patch new file mode 100644 index 0000000..f34e699 --- /dev/null +++ b/0010-11-dm-mpath.rules.in-handle-inactive-suspended-devic.patch @@ -0,0 +1,66 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 31 Oct 2024 12:59:03 +0100 +Subject: [PATCH] 11-dm-mpath.rules.in: handle inactive suspended devices + correctly + +Since b22c273 ("11-dm-mpath.rules: Don't force activation while device is +suspended"), we've handled the case where a device is suspended while +an uevent is processed (e.g. because multipathd is reloading the +map again at the same time). But we were missing the case where +The device had never been initialized before. If .MPATH_DEVICE_READY_OLD +was empty, we'd jump to scan_import without setting MPATH_DEVICE_READY +to 0. This can cause a device not to be fully activated at boot time, +because in follow-up uevents we'd assume that the device had already +been set up. + +Treat the case in which an uevent is processed for a previously not +fully set-up, suspended device like other situations where we set +MPATH_DEVICE_READY to 0. + +Fixes: b22c273 ("11-dm-mpath.rules: Don't force activation while device is +suspended") +Reviewed-by: Benjamin Marzinski + +Signed-off-by: Benjamin Marzinski +--- + multipath/11-dm-mpath.rules.in | 19 +++++++++++-------- + 1 file changed, 11 insertions(+), 8 deletions(-) + +diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in +index 67838261..20f8c6ac 100644 +--- a/multipath/11-dm-mpath.rules.in ++++ b/multipath/11-dm-mpath.rules.in +@@ -35,6 +35,13 @@ ENV{DM_COOKIE}!="?*", ENV{DM_ACTION}!="PATH_*", \ + + ENV{.MPATH_DEVICE_READY_OLD}="$env{MPATH_DEVICE_READY}" + ++# If the device wasn't ready previously and is currently suspended, ++# we have to postpone the activation until the next event. ++# In this case, we have to set MPATH_DEVICE_READY=0; otherwise, the ++# MPATH_UNCHANGED logic will cause later rules to skipped in the next event. ++ENV{.MPATH_DEVICE_READY_OLD}!="1", ENV{.DM_SUSPENDED}=="1", \ ++ ENV{MPATH_DEVICE_READY}="0", GOTO="check_mpath_unchanged" ++ + # multipath sets DM_SUBSYSTEM_UDEV_FLAG2 when it reloads a + # table with no active devices. If this happens, mark the + # device not ready +@@ -106,14 +113,10 @@ GOTO="scan_import" + LABEL="mpath_is_ready" + + # If the device comes back online, set DM_ACTIVATION so that +-# upper layers do a rescan. If the device is currently suspended, +-# we have to postpone the activation until the next event. +-# In this case, we have to set MPATH_DEVICE_READY=0; otherwise, the +-# MPATH_UNCHANGED logic will cause later rules to skipped in the next event. +-ENV{.MPATH_DEVICE_READY_OLD}!="0", GOTO="scan_import" +-ENV{.DM_SUSPENDED}=="1", ENV{MPATH_DEVICE_READY}="0", GOTO="scan_import" +- +-ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0" ++# upper layers will do a rescan. Don't do this if .MPATH_DEVICE_READY_OLD ++# is just empty (see comment above the DM_COOKIE test above). ++ENV{.MPATH_DEVICE_READY_OLD}=="0", \ ++ ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0" + + # The code to check multipath state ends here. We need to set + # properties and symlinks regardless whether the map is usable or diff --git a/0011-11-dm-mpath.rules.in-clarify-DM_ACTIVATION-logic.patch b/0011-11-dm-mpath.rules.in-clarify-DM_ACTIVATION-logic.patch new file mode 100644 index 0000000..cb129bf --- /dev/null +++ b/0011-11-dm-mpath.rules.in-clarify-DM_ACTIVATION-logic.patch @@ -0,0 +1,78 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 31 Oct 2024 13:11:21 +0100 +Subject: [PATCH] 11-dm-mpath.rules.in: clarify DM_ACTIVATION logic + +Our code is always setting MPATH_UNCHANGED and DM_ACTIVATION in +pairs. While DM_ACTIVATION is a global DM property, MPATH_UNCHANGED +is owned by us. Just set MPATH_UNCHANGED, and adapt DM_ACTIVATION +when necessary just in one place. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/11-dm-mpath.rules.in | 21 ++++++++++++--------- + 1 file changed, 12 insertions(+), 9 deletions(-) + +diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in +index 20f8c6ac..a2655cb2 100644 +--- a/multipath/11-dm-mpath.rules.in ++++ b/multipath/11-dm-mpath.rules.in +@@ -74,25 +74,25 @@ LABEL="check_mpath_unchanged" + + # A previous coldplug event occurred while the device was suspended. + # Activation might have been partially skipped. Activate the device now, +-# i.e. disable the MPATH_UNCHANGED logic and set DM_ACTIVATION=1. ++# i.e. disable the MPATH_UNCHANGED logic. + ENV{DM_COLDPLUG_SUSPENDED}=="1", ENV{.DM_SUSPENDED}!="1", \ +- ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0", \ ++ ENV{MPATH_UNCHANGED}="0", \ + PROGRAM="@SYSDIR_BIN@/logger -t 11-dm-mpath.rules -p daemon.notice \"Forcing activation of previously suspended device\"", \ + GOTO="check_mpath_ready" + + # DM_SUBSYSTEM_UDEV_FLAG0 is the "RELOAD" flag for multipath subsystem. +-# Drop the DM_ACTIVATION flag here as mpath reloads tables if any of its ++# Set the MPATH_UNCHANGED flag here as mpath reloads tables if any of its + # paths are lost/recovered. For any stack above the mpath device, this is not + # something that should be reacted upon since it would be useless extra work. + # It's exactly mpath's job to provide *seamless* device access to any of the + # paths that are available underneath. + ENV{DM_SUBSYSTEM_UDEV_FLAG0}=="1", \ +- ENV{DM_ACTIVATION}="0", ENV{MPATH_UNCHANGED}="1" ++ ENV{MPATH_UNCHANGED}="1" + +-# For path failed or reinstated events, unset DM_ACTIVATION. ++# For path failed or reinstated events, set MPATH_UNCHANGED. + # This is similar to the DM_SUBSYSTEM_UDEV_FLAG0 case above. + ENV{DM_ACTION}=="PATH_FAILED|PATH_REINSTATED", \ +- ENV{DM_ACTIVATION}="0", ENV{MPATH_UNCHANGED}="1" ++ ENV{MPATH_UNCHANGED}="1" + + LABEL="check_mpath_ready" + +@@ -112,11 +112,10 @@ GOTO="scan_import" + + LABEL="mpath_is_ready" + +-# If the device comes back online, set DM_ACTIVATION so that ++# If the device comes back online, clear MPATH_UNCHANGED so that + # upper layers will do a rescan. Don't do this if .MPATH_DEVICE_READY_OLD + # is just empty (see comment above the DM_COOKIE test above). +-ENV{.MPATH_DEVICE_READY_OLD}=="0", \ +- ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0" ++ENV{.MPATH_DEVICE_READY_OLD}=="0", ENV{MPATH_UNCHANGED}="0" + + # The code to check multipath state ends here. We need to set + # properties and symlinks regardless whether the map is usable or +@@ -146,6 +145,10 @@ IMPORT{db}="ID_PART_GPT_AUTO_ROOT" + + LABEL="import_end" + ++# If MPATH_UNCHANGED is set, adapt DM_ACTIVATION. ++ENV{MPATH_UNCHANGED}=="0", ENV{DM_ACTIVATION}="1" ++ENV{MPATH_UNCHANGED}=="1", ENV{DM_ACTIVATION}="0" ++ + # Reset previous DM_COLDPLUG_SUSPENDED if activation happens now + ENV{.DM_SUSPENDED}!="1", ENV{DM_ACTIVATION}=="1", ENV{DM_COLDPLUG_SUSPENDED}="" + diff --git a/0012-11-dm-mpath-rules.in-skip-one-.DM_NOSCAN-check.patch b/0012-11-dm-mpath-rules.in-skip-one-.DM_NOSCAN-check.patch new file mode 100644 index 0000000..cb1620a --- /dev/null +++ b/0012-11-dm-mpath-rules.in-skip-one-.DM_NOSCAN-check.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Sun, 3 Nov 2024 23:04:08 +0100 +Subject: [PATCH] 11-dm-mpath-rules.in: skip one .DM_NOSCAN check + +We set .DM_NOSCAN above where we set DM_UDEV_DISABLE_OTHER_RULES_FLAG, too. If +the latter isn't set, .DM_NOSCAN can't be set. Skip the redundant test. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/11-dm-mpath.rules.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in +index a2655cb2..79227bec 100644 +--- a/multipath/11-dm-mpath.rules.in ++++ b/multipath/11-dm-mpath.rules.in +@@ -132,7 +132,7 @@ ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}!="1", GOTO="import_end" + ENV{DM_UDEV_RULES_VSN}!="1|2", GOTO="import_end" + + # Don't import the properties from db if we will run blkid later. +-ENV{.DM_NOSCAN}!="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}!="1", GOTO="import_end" ++ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}!="1", GOTO="import_end" + + IMPORT{db}="ID_FS_TYPE" + IMPORT{db}="ID_FS_USAGE" diff --git a/0013-11-dm-mpath.rules.in-set-.DM_NOSCAN-if-MPATH_UNCHANG.patch b/0013-11-dm-mpath.rules.in-set-.DM_NOSCAN-if-MPATH_UNCHANG.patch new file mode 100644 index 0000000..36cd91d --- /dev/null +++ b/0013-11-dm-mpath.rules.in-set-.DM_NOSCAN-if-MPATH_UNCHANG.patch @@ -0,0 +1,44 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Sun, 3 Nov 2024 23:07:23 +0100 +Subject: [PATCH] 11-dm-mpath.rules.in: set .DM_NOSCAN if MPATH_UNCHANGED is + set + +When multipath reloads a device or fails or restores a path, the udev +rules disable LVM scanning, but since .DM_NOSCAN isn't set, blkid is +still run on the device. When multipath devices that are set to +queue_if_no_path lose all their paths at close to the same time, udev +workers can hang trying to run blkid. The blkid results shouldn't +change when multipathd is adding, removing, failing or reinstating +paths, aside from avoiding hanging udev processes, we're skipping +unnecessary work. + +Hence, set .DM_NOSCAN if MPATH_UNCHANGED is set, to avoid blkid from +being called in 13-dm.rules. + +Suggested-by: Benjamin Marzinski +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/11-dm-mpath.rules.in | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in +index 79227bec..a816edbf 100644 +--- a/multipath/11-dm-mpath.rules.in ++++ b/multipath/11-dm-mpath.rules.in +@@ -145,9 +145,11 @@ IMPORT{db}="ID_PART_GPT_AUTO_ROOT" + + LABEL="import_end" + +-# If MPATH_UNCHANGED is set, adapt DM_ACTIVATION. ++# If MPATH_UNCHANGED is set, adapt DM_ACTIVATION and DM_NOSCAN. ++# .DM_NOSCAN controls whether blkid will be run in 13-dm-disk.rules; ++# we don't want to do that if MPATH_UNCHANGED is 1. + ENV{MPATH_UNCHANGED}=="0", ENV{DM_ACTIVATION}="1" +-ENV{MPATH_UNCHANGED}=="1", ENV{DM_ACTIVATION}="0" ++ENV{MPATH_UNCHANGED}=="1", ENV{DM_ACTIVATION}="0", ENV{.DM_NOSCAN}="1" + + # Reset previous DM_COLDPLUG_SUSPENDED if activation happens now + ENV{.DM_SUSPENDED}!="1", ENV{DM_ACTIVATION}=="1", ENV{DM_COLDPLUG_SUSPENDED}="" diff --git a/0014-libmultipath-don-t-set-dev_loss_tmo-to-0-for-NO_PATH.patch b/0014-libmultipath-don-t-set-dev_loss_tmo-to-0-for-NO_PATH.patch new file mode 100644 index 0000000..b7ae3c4 --- /dev/null +++ b/0014-libmultipath-don-t-set-dev_loss_tmo-to-0-for-NO_PATH.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 7 Nov 2024 22:07:03 +0100 +Subject: [PATCH] libmultipath: don't set dev_loss_tmo to 0 for + NO_PATH_RETRY_FAIL + +If pp->dev_loss is DEV_LOSS_TMO_UNSET and min_dev_loss is 0 (which is +the case if no_path_retry is NO_PATH_RETRY_FAIL or NO_PATH_RETRY_UNDEF), +we will set pp->dev_loss to 0, which is wrong. Fix it. + +Fixes: 058b5f5 ("libmultipath: fix dev_loss_tmo even if not set in configuration") +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/discovery.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index e94705bf..5043330c 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -942,7 +942,7 @@ sysfs_set_scsi_tmo (struct config *conf, struct multipath *mpp) + continue; + } + +- if (pp->dev_loss == DEV_LOSS_TMO_UNSET) ++ if (pp->dev_loss == DEV_LOSS_TMO_UNSET && min_dev_loss != 0) + pp->dev_loss = min_dev_loss; + else if (pp->dev_loss < min_dev_loss) { + pp->dev_loss = min_dev_loss; diff --git a/0015-multipathd-fix-deferred_failback_tick-for-reload-rem.patch b/0015-multipathd-fix-deferred_failback_tick-for-reload-rem.patch new file mode 100644 index 0000000..f775e85 --- /dev/null +++ b/0015-multipathd-fix-deferred_failback_tick-for-reload-rem.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 14 Oct 2024 23:28:30 -0400 +Subject: [PATCH] multipathd: fix deferred_failback_tick for reload removes + +If reload_and_sync_map() removes the multipath device, +deferred_failback_tick() needs to decrement the counter so that it +doesn't skip the following device. + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 1b7fd04f..e4ef9a1d 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -2080,9 +2080,12 @@ deferred_failback_tick (struct vectors *vecs) + + if (!mpp->failback_tick && + need_switch_pathgroup(mpp, &need_reload)) { +- if (need_reload) +- reload_and_sync_map(mpp, vecs); +- else ++ if (need_reload) { ++ if (reload_and_sync_map(mpp, vecs) == 2) { ++ /* multipath device removed */ ++ i--; ++ } ++ } else + switch_pathgroup(mpp); + } + } diff --git a/0016-multipathd-fix-an-unsigned-int-ovwerflow.patch b/0016-multipathd-fix-an-unsigned-int-ovwerflow.patch new file mode 100644 index 0000000..12c9a51 --- /dev/null +++ b/0016-multipathd-fix-an-unsigned-int-ovwerflow.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 13 Nov 2024 16:19:49 +0100 +Subject: [PATCH] multipathd: fix an unsigned int ovwerflow + +Reported by coverity: "i--" may cause an underflow, which will again +cause an overflow when the loop continues. Use a signed int for +loops like this to make coverity happy. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index e4ef9a1d..3fb623fd 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -2068,7 +2068,7 @@ static void + deferred_failback_tick (struct vectors *vecs) + { + struct multipath * mpp; +- unsigned int i; ++ int i; + bool need_reload; + + vector_foreach_slot (vecs->mpvec, mpp, i) { diff --git a/0017-libmpathutil-avoid-Wcast-function-type-mismatch-erro.patch b/0017-libmpathutil-avoid-Wcast-function-type-mismatch-erro.patch new file mode 100644 index 0000000..64b90d7 --- /dev/null +++ b/0017-libmpathutil-avoid-Wcast-function-type-mismatch-erro.patch @@ -0,0 +1,36 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 6 Nov 2024 22:17:16 +0100 +Subject: [PATCH] libmpathutil: avoid -Wcast-function-type-mismatch error with + clang 19 + +Avoid the following error with clang 19: + +msort.c:268:27: error: cast from '__compar_fn_t' (aka 'int (*)(const void *, const void *)') to '__compar_d_fn_t' (aka 'int (*)(const void *, const void *, void *)') converts to incompatible function type [-Werror,-Wcast-function-type-mismatch] + 268 | return msort_r (b, n, s, (__compar_d_fn_t)cmp, NULL); + | ^~~~~~~~~~~~~~~~~~~~ + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmpathutil/msort.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/libmpathutil/msort.c b/libmpathutil/msort.c +index 50f799d9..9df7b267 100644 +--- a/libmpathutil/msort.c ++++ b/libmpathutil/msort.c +@@ -259,9 +259,12 @@ msort_r (void *b, size_t n, size_t s, __compar_d_fn_t cmp, void *arg) + * If this is safe for them, it should be for us, too. + */ + #pragma GCC diagnostic push +-#if __GNUC__ >= 8 ++#if __GNUC__ >= 8 || __clang_major__ >= 19 + #pragma GCC diagnostic ignored "-Wcast-function-type" + #endif ++#if __clang_major__ >= 19 ++#pragma GCC diagnostic ignored "-Wcast-function-type-mismatch" ++#endif + void + msort (void *b, size_t n, size_t s, __compar_fn_t cmp) + { diff --git a/0018-Update-NEWS.md-for-0.10.1.patch b/0018-Update-NEWS.md-for-0.10.1.patch new file mode 100644 index 0000000..601b6e5 --- /dev/null +++ b/0018-Update-NEWS.md-for-0.10.1.patch @@ -0,0 +1,44 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 14 Nov 2024 17:59:14 +0100 +Subject: [PATCH] Update NEWS.md for 0.10.1 + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + NEWS.md | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +diff --git a/NEWS.md b/NEWS.md +index 69acda47..b740efb1 100644 +--- a/NEWS.md ++++ b/NEWS.md +@@ -1,5 +1,28 @@ + # multipath-tools Release Notes + ++## multipath-tools 0.10.1, 2024/11 ++ ++This is the first bug fix release on the `stable-0.10.y` branch. It contains ++bug fixes from 0.11.0, and some CI-related fixes. ++ ++### Bug fixes ++ ++* Fixed the problem that multipathd wouldn't start on systems with certain types ++ of device mapper devices, in particular devices with multiple DM targets. ++ The problem was introduced in 0.10.0. ++ Fixes [#102](https://github.com/opensvc/multipath-tools/issues/102). ++* Fixed a corner case in the udev rules which could cause a device not to be ++ activated during boot if a cold plug uevent is processed for a previously ++ not configured multipath map while this map was suspended. This problem existed ++ since 0.9.8. ++* Fixed the problem that devices with `no_path_retry fail` and no setting ++ for `dev_loss_tmo` might get the `dev_loss_tmo` set to 0, causing the ++ device to be deleted immediately in the event of a transport disruption. ++ This bug was introduced in 0.9.6. ++* Fixed the problem that, if there were multiple maps with deferred failback ++ (`failback` value > 0 in `multipath.conf`), some maps might fail back later ++ than configured. The problem existed since 0.9.6. ++ + ## multipath-tools 0.10.0, 2024/08 + + ### User-Visible Changes diff --git a/0019-libmultipath-don-t-print-error-message-if-WATCHDOG_U.patch b/0019-libmultipath-don-t-print-error-message-if-WATCHDOG_U.patch new file mode 100644 index 0000000..18fb614 --- /dev/null +++ b/0019-libmultipath-don-t-print-error-message-if-WATCHDOG_U.patch @@ -0,0 +1,30 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 14 Nov 2024 15:20:24 +0100 +Subject: [PATCH] libmultipath: don't print error message if WATCHDOG_USEC is 0 + +WATCHDOG_USEC may be set to 0, which means that the watchdog +is disabled in systemd. + +Fixes: 9366cfb ("multipathd: Implement systemd watchdog integration") +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/config.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/libmultipath/config.c b/libmultipath/config.c +index 0e3a5cc1..226ddecb 100644 +--- a/libmultipath/config.c ++++ b/libmultipath/config.c +@@ -865,6 +865,9 @@ static void set_max_checkint_from_watchdog(struct config *conf) + unsigned long checkint; + + if (envp && sscanf(envp, "%lu", &checkint) == 1) { ++ if (checkint == 0) ++ /* watchdog disabled */ ++ return; + /* Value is in microseconds */ + checkint /= 1000000; + if (checkint < 1 || checkint > UINT_MAX) { diff --git a/0020-libmultipath-reduce-log-level-of-map-X-has-multiple-.patch b/0020-libmultipath-reduce-log-level-of-map-X-has-multiple-.patch new file mode 100644 index 0000000..7467627 --- /dev/null +++ b/0020-libmultipath-reduce-log-level-of-map-X-has-multiple-.patch @@ -0,0 +1,38 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 25 Nov 2024 18:01:32 +0100 +Subject: [PATCH] libmultipath: reduce log level of "map X has multiple + targets" + +On systems with LVM volumes, "multipath -ll" will spit out lots of messages +like + + libmp_mapinfo: map vg-lv0 has multiple targets + +which is irritating. Reduce the log level of these messages to 3, as they +are harmless most of the time. + +This is a backport of e8949c2 ("libmultipath: reduce log level of +libmp_mapinfo() messages") from the master branch. We can't apply exactly +the same fix because the stable branch is missing 8c772d3 ("libmultipath: +check DM UUID earlier in libmp_mapinfo__"). + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/devmapper.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index 52bfe9ce..fe5637b3 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -718,7 +718,7 @@ static int libmp_mapinfo__(int flags, mapid_t id, mapinfo_t info, const char *ma + if (info.target || info.status || info.size || flags & MAPINFO_TGT_TYPE__) { + if (dm_get_next_target(dmt, NULL, &start, &length, + &target_type, ¶ms) != NULL) { +- condlog(2, "%s: map %s has multiple targets", fname__, map_id); ++ condlog(3, "%s: map %s has multiple targets", fname__, map_id); + return DMP_NOT_FOUND; + } + if (!params) { diff --git a/0021-libmultipath-foreign-fix-memory-leak-in-nvme-foreign.patch b/0021-libmultipath-foreign-fix-memory-leak-in-nvme-foreign.patch new file mode 100644 index 0000000..2610c6d --- /dev/null +++ b/0021-libmultipath-foreign-fix-memory-leak-in-nvme-foreign.patch @@ -0,0 +1,54 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 8 Jan 2025 19:06:53 -0500 +Subject: [PATCH] libmultipath/foreign: fix memory leak in nvme foreign handler + +_find_controllers() needs to free the udev device if it doesn't get +added to a path. Otherwise it can leak memory whenever check_foreign() +is called, causing multipathd's memory usage to continually grow. + +Fixes: 7b47762 ("libmultipath: nvme: fix path detection for kernel 4.16") +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +(cherry picked from commit 5a3d334e416a4a35ee88d7b8f1433ff7f57923ad) +--- + libmultipath/foreign/nvme.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/libmultipath/foreign/nvme.c b/libmultipath/foreign/nvme.c +index 0b7f4eab..cde660ce 100644 +--- a/libmultipath/foreign/nvme.c ++++ b/libmultipath/foreign/nvme.c +@@ -675,7 +675,8 @@ static void _find_controllers(struct context *ctx, struct nvme_map *map) + pthread_cleanup_push_cast(free_scandir_result, &sr); + for (i = 0; i < r; i++) { + char *fn = di[i]->d_name; +- struct udev_device *ctrl, *udev; ++ struct udev_device *ctrl; ++ struct udev_device *udev __attribute__((cleanup(cleanup_udev_device))) = NULL; + + if (safe_snprintf(pathbuf + n, sizeof(pathbuf) - n, "/%s", fn)) + continue; +@@ -719,11 +720,11 @@ static void _find_controllers(struct context *ctx, struct nvme_map *map) + continue; + + path->gen.ops = &nvme_path_ops; +- path->udev = udev; ++ path->udev = steal_ptr(udev); + path->seen = true; + path->map = map; + path->ctl = udev_device_get_parent_with_subsystem_devtype +- (udev, "nvme", NULL); ++ (path->udev, "nvme", NULL); + if (path->ctl == NULL) { + condlog(1, "%s: %s: failed to get controller for %s", + __func__, THIS, fn); +@@ -744,7 +745,7 @@ static void _find_controllers(struct context *ctx, struct nvme_map *map) + } + vector_set_slot(&map->pgvec, &path->pg); + condlog(3, "%s: %s: new path %s added to %s", +- __func__, THIS, udev_device_get_sysname(udev), ++ __func__, THIS, udev_device_get_sysname(path->udev), + udev_device_get_sysname(map->udev)); + } + pthread_cleanup_pop(1); diff --git a/0022-libmultipath-add-condition-for-enqueueing-path-to-io.patch b/0022-libmultipath-add-condition-for-enqueueing-path-to-io.patch new file mode 100644 index 0000000..cf8d80a --- /dev/null +++ b/0022-libmultipath-add-condition-for-enqueueing-path-to-io.patch @@ -0,0 +1,41 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: chenrenhui +Date: Fri, 10 Jan 2025 14:38:16 +0800 +Subject: [PATCH] libmultipath: add condition for enqueueing path to io error + check + +In function io_err_stat_handle_pathfail(), path->io_err_dis_reinstate_time +is set to 0 to enqueue path to io error check as soon as possible. But +multipathd can not do it within marginal_path_err_recheck_gap_time seconds +after power-on, because curr_time is less than +marginal_path_err_recheck_gap_time. + +To handle the early marginal path, we can enqueue path when +io_err_dis_reinstate_time is 0. + +Signed-off-by: chenrenhui +Reviewed-by: Benjamin Marzinski +Reviewed-by: Martin Wilck + +> + +(cherry picked from commit a1e3cf2d42cc4bab10753e466c8adb7efa83c99e) +Signed-off-by: Benjamin Marzinski +--- + libmultipath/io_err_stat.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/io_err_stat.c b/libmultipath/io_err_stat.c +index 4996c0b0..879c310a 100644 +--- a/libmultipath/io_err_stat.c ++++ b/libmultipath/io_err_stat.c +@@ -367,7 +367,8 @@ int need_io_err_check(struct path *pp) + return 1; + get_monotonic_time(&curr_time); + if ((curr_time.tv_sec - pp->io_err_dis_reinstate_time) > +- pp->mpp->marginal_path_err_recheck_gap_time) { ++ pp->mpp->marginal_path_err_recheck_gap_time || ++ pp->io_err_dis_reinstate_time == 0) { + io_err_stat_log(4, "%s: reschedule checking after %d seconds", + pp->dev, + pp->mpp->marginal_path_err_recheck_gap_time); diff --git a/0023-Additional-NEWS.md-updates-for-0.10.1.patch b/0023-Additional-NEWS.md-updates-for-0.10.1.patch new file mode 100644 index 0000000..1093bd0 --- /dev/null +++ b/0023-Additional-NEWS.md-updates-for-0.10.1.patch @@ -0,0 +1,63 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 17 Jan 2025 22:38:26 +0100 +Subject: [PATCH] Additional NEWS.md updates for 0.10.1 + +Signed-off-by: Benjamin Marzinski +--- + .github/actions/spelling/expect.txt | 4 ++-- + NEWS.md | 8 ++++++++ + 2 files changed, 10 insertions(+), 2 deletions(-) + +diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt +index 934f582e..000d5ebb 100644 +--- a/.github/actions/spelling/expect.txt ++++ b/.github/actions/spelling/expect.txt +@@ -184,7 +184,6 @@ sas + sbp + scsi + sda +-sdc + setmarginal + setprkey + setprstatus +@@ -205,11 +204,11 @@ suse + svg + switchgroup + sys ++SYSDIR + sysfs + sysinit + tcp + terabytes +-SYSDIR + TESTDEPS + testname + tgill +@@ -231,6 +230,7 @@ unsetprkey + unsetprstatus + unspec + usb ++USEC + userdata + userspace + usr +diff --git a/NEWS.md b/NEWS.md +index b740efb1..3c51553e 100644 +--- a/NEWS.md ++++ b/NEWS.md +@@ -22,6 +22,14 @@ bug fixes from 0.11.0, and some CI-related fixes. + * Fixed the problem that, if there were multiple maps with deferred failback + (`failback` value > 0 in `multipath.conf`), some maps might fail back later + than configured. The problem existed since 0.9.6. ++* Removed a warning message that multipathd would print if systemd's ++ `WATCHDOG_USEC` environment variable had the value "0", which means that the ++ watchdog is simply disabled. This (minor) problem existed since 0.4.9. ++* Fixed a memory leak in the nvme foreign library. The bug existed since ++ 0.7.8. ++* Fixed a problem in the marginal path detection algorithm that could cause ++ the io error check for a recently failed path to be delayed. This bug ++ existed since 0.7.4. + + ## multipath-tools 0.10.0, 2024/08 + diff --git a/0024-libmultipath-fix-handling-of-pp-pgindex.patch b/0024-libmultipath-fix-handling-of-pp-pgindex.patch new file mode 100644 index 0000000..a9da346 --- /dev/null +++ b/0024-libmultipath-fix-handling-of-pp-pgindex.patch @@ -0,0 +1,138 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 25 Nov 2024 13:11:07 +0100 +Subject: [PATCH] libmultipath: fix handling of pp->pgindex + +pp->pgindex is set in disassemble_map() when a map is parsed. +There are various possiblities for this index to become invalid. +pp->pgindex is only used in enable_group() and followover_should_fallback(), +and both callers take no action if it is 0, which is the right +thing to do if we don't know the path's pathgroup. + +Make sure pp->pgindex is reset to 0 in various places: +- when it's orphaned, +- before (re)grouping paths, +- when we detect a bad mpp assignment in update_pathvec_from_dm(). +- when a pathgroup is deleted in update_pathvec_from_dm(). In this + case, pgindex needs to be invalidated for all paths in all pathgroups + after the one that was deleted. + +The hunk in group_paths is mostly redundant with the hunk in free_pgvec(), but +because we're looping over pg->paths in the former and over pg->pgp in +the latter, I think it's better too play safe. + +Fixes: 99db1bd ("[multipathd] re-enable disabled PG when at least one path is up") +Fixes: https://github.com/opensvc/multipath-tools/issues/105 +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +(cherry picked from commit cd912cffa2797a18c47426c816afa8eb2eae5b22) +(cherry picked from commit 714c20bebba6911255a527d937e7a62764ffe338) +Signed-off-by: Benjamin Marzinski +--- + libmultipath/pgpolicies.c | 6 ++++++ + libmultipath/structs.c | 12 +++++++++++- + libmultipath/structs_vec.c | 15 +++++++++++++++ + 3 files changed, 32 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/pgpolicies.c b/libmultipath/pgpolicies.c +index edc3c611..23ef2bdc 100644 +--- a/libmultipath/pgpolicies.c ++++ b/libmultipath/pgpolicies.c +@@ -127,6 +127,8 @@ fail: + int group_paths(struct multipath *mp, int marginal_pathgroups) + { + vector normal, marginal; ++ struct path *pp; ++ int i; + + if (!mp->pg) + mp->pg = vector_alloc(); +@@ -138,6 +140,10 @@ int group_paths(struct multipath *mp, int marginal_pathgroups) + if (!mp->pgpolicyfn) + goto fail; + ++ /* Reset pgindex, we're going to invalidate it */ ++ vector_foreach_slot(mp->paths, pp, i) ++ pp->pgindex = 0; ++ + if (!marginal_pathgroups || + split_marginal_paths(mp->paths, &normal, &marginal) != 0) { + if (mp->pgpolicyfn(mp, mp->paths) != 0) +diff --git a/libmultipath/structs.c b/libmultipath/structs.c +index 61c8f32c..48517252 100644 +--- a/libmultipath/structs.c ++++ b/libmultipath/structs.c +@@ -239,8 +239,18 @@ free_pgvec (vector pgvec, enum free_path_mode free_paths) + if (!pgvec) + return; + +- vector_foreach_slot(pgvec, pgp, i) ++ vector_foreach_slot(pgvec, pgp, i) { ++ ++ /* paths are going to be re-grouped, reset pgindex */ ++ if (free_paths != FREE_PATHS) { ++ struct path *pp; ++ int j; ++ ++ vector_foreach_slot(pgp->paths, pp, j) ++ pp->pgindex = 0; ++ } + free_pathgroup(pgp, free_paths); ++ } + + vector_free(pgvec); + } +diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c +index 5df495b3..9dc5a5ca 100644 +--- a/libmultipath/structs_vec.c ++++ b/libmultipath/structs_vec.c +@@ -108,6 +108,7 @@ static bool update_pathvec_from_dm(vector pathvec, struct multipath *mpp, + struct config *conf; + bool mpp_has_wwid; + bool must_reload = false; ++ bool pg_deleted = false; + + if (!mpp->pg) + return false; +@@ -125,6 +126,10 @@ static bool update_pathvec_from_dm(vector pathvec, struct multipath *mpp, + + vector_foreach_slot(pgp->paths, pp, j) { + ++ /* A pathgroup has been deleted before. Invalidate pgindex */ ++ if (pg_deleted) ++ pp->pgindex = 0; ++ + if (pp->mpp && pp->mpp != mpp) { + condlog(0, "BUG: %s: found path %s which is already in %s", + mpp->alias, pp->dev, pp->mpp->alias); +@@ -139,6 +144,13 @@ static bool update_pathvec_from_dm(vector pathvec, struct multipath *mpp, + must_reload = true; + dm_fail_path(mpp->alias, pp->dev_t); + vector_del_slot(pgp->paths, j--); ++ /* ++ * pp->pgindex has been set in disassemble_map(), ++ * which has probably been called just before for ++ * mpp. So he pgindex relates to mpp and may be ++ * wrong for pp->mpp. Invalidate it. ++ */ ++ pp->pgindex = 0; + continue; + } + pp->mpp = mpp; +@@ -237,6 +249,8 @@ static bool update_pathvec_from_dm(vector pathvec, struct multipath *mpp, + vector_del_slot(mpp->pg, i--); + free_pathgroup(pgp, KEEP_PATHS); + must_reload = true; ++ /* Invalidate pgindex for all other pathgroups */ ++ pg_deleted = true; + } + mpp->need_reload = mpp->need_reload || must_reload; + return must_reload; +@@ -354,6 +368,7 @@ void orphan_path(struct path *pp, const char *reason) + { + condlog(3, "%s: orphan path, %s", pp->dev, reason); + pp->mpp = NULL; ++ pp->pgindex = 0; + uninitialize_path(pp); + } + diff --git a/0025-libmultipath-make-pgcmp-detect-if-map-is-missing-a-p.patch b/0025-libmultipath-make-pgcmp-detect-if-map-is-missing-a-p.patch new file mode 100644 index 0000000..b2b9e48 --- /dev/null +++ b/0025-libmultipath-make-pgcmp-detect-if-map-is-missing-a-p.patch @@ -0,0 +1,70 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 25 Nov 2024 15:18:15 +0100 +Subject: [PATCH] libmultipath: make pgcmp detect if map is missing a path + group + +The previous algorithm didn't detect the case case where cpgp +contained a path that was not contained in pgp. Fix this. + +Cherry-picked from d4b35f61cb75c6e9b289e56c98457fc04ce4835e +Fixes: 90773ba ("libmultipath: resolve hash collisions in pgcmp()") +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/configure.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index a7257981..e86c1fd5 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -426,6 +426,11 @@ compute_pgid(struct pathgroup * pgp) + pgp->id ^= (long)pp; + } + ++static void cleanup_bitfield(struct bitfield **p) ++{ ++ free(*p); ++} ++ + static int + pgcmp (struct multipath * mpp, struct multipath * cmpp) + { +@@ -433,16 +438,25 @@ pgcmp (struct multipath * mpp, struct multipath * cmpp) + struct pathgroup * pgp; + struct pathgroup * cpgp; + int r = 0; ++ struct bitfield *bf __attribute__((cleanup(cleanup_bitfield))) = NULL; + + if (!mpp) + return 0; + ++ if (VECTOR_SIZE(mpp->pg) != VECTOR_SIZE(cmpp->pg)) ++ return 1; ++ ++ bf = alloc_bitfield(VECTOR_SIZE(cmpp->pg)); ++ if (!bf) ++ return 1; ++ + vector_foreach_slot (mpp->pg, pgp, i) { + compute_pgid(pgp); + + vector_foreach_slot (cmpp->pg, cpgp, j) { + if (pgp->id == cpgp->id && + !pathcmp(pgp, cpgp)) { ++ set_bit_in_bitfield(j, bf); + r = 0; + break; + } +@@ -451,6 +465,10 @@ pgcmp (struct multipath * mpp, struct multipath * cmpp) + if (r) + return r; + } ++ vector_foreach_slot (cmpp->pg, cpgp, j) { ++ if (!is_bit_set_in_bitfield(j, bf)) ++ return 1; ++ } + return r; + } + diff --git a/0026-libmultipath-trigger-uevents-upon-map-creation-in-do.patch b/0026-libmultipath-trigger-uevents-upon-map-creation-in-do.patch new file mode 100644 index 0000000..bd3a7a4 --- /dev/null +++ b/0026-libmultipath-trigger-uevents-upon-map-creation-in-do.patch @@ -0,0 +1,94 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 26 Nov 2024 22:37:20 +0100 +Subject: [PATCH] libmultipath: trigger uevents upon map creation in domap() + +If map creation succeeds, previously not multipathed devices are +now multipathed. udev may not have noticed this yet, thus trigger +path uevents to make it aware of the situation. Likewise, if +creating a map fails, the paths in question were likely considered +multipath members by udev, too. They will now be marked as failed, +so trigger an event in this situation as well. + +Fixes: https://github.com/opensvc/multipath-tools/issues/103 +Suggested-by: Benjamin Marzinski +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +(cherry picked from commit 98b3a7bd9ed2a89f068fe40c253843cf78261905) +Signed-off-by: Benjamin Marzinski +--- + libmultipath/configure.c | 11 ++++------- + libmultipath/devmapper.c | 9 +++------ + 2 files changed, 7 insertions(+), 13 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index e86c1fd5..d9fac384 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -581,8 +581,6 @@ trigger_paths_udev_change(struct multipath *mpp, bool is_mpath) + vector_foreach_slot(pgp->paths, pp, j) + trigger_path_udev_change(pp, is_mpath); + } +- +- mpp->needs_paths_uevent = 0; + } + + static int sysfs_set_max_sectors_kb(struct multipath *mpp) +@@ -954,10 +952,10 @@ int domap(struct multipath *mpp, char *params, int is_daemon) + * succeeded + */ + mpp->force_udev_reload = 0; +- if (mpp->action == ACT_CREATE && +- (remember_wwid(mpp->wwid) == 1 || +- mpp->needs_paths_uevent)) ++ if (mpp->action == ACT_CREATE) { ++ remember_wwid(mpp->wwid); + trigger_paths_udev_change(mpp, true); ++ } + if (!is_daemon) { + /* multipath client mode */ + dm_switchgroup(mpp->alias, mpp->bestpg); +@@ -982,8 +980,7 @@ int domap(struct multipath *mpp, char *params, int is_daemon) + } + dm_setgeometry(mpp); + return DOMAP_OK; +- } else if (r == DOMAP_FAIL && mpp->action == ACT_CREATE && +- mpp->needs_paths_uevent) ++ } else if (r == DOMAP_FAIL && mpp->action == ACT_CREATE) + trigger_paths_udev_change(mpp, false); + + return DOMAP_FAIL; +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index fe5637b3..a0070c56 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -536,7 +536,7 @@ static uint16_t build_udev_flags(const struct multipath *mpp, int reload) + MPATH_UDEV_RELOAD_FLAG : 0); + } + +-int dm_addmap_create (struct multipath *mpp, char * params) ++int dm_addmap_create (struct multipath *mpp, char *params) + { + int ro; + uint16_t udev_flags = build_udev_flags(mpp, 0); +@@ -546,9 +546,7 @@ int dm_addmap_create (struct multipath *mpp, char * params) + + if (dm_addmap(DM_DEVICE_CREATE, TGT_MPATH, mpp, params, ro, + udev_flags)) { +- if (unmark_failed_wwid(mpp->wwid) == +- WWID_FAILED_CHANGED) +- mpp->needs_paths_uevent = 1; ++ unmark_failed_wwid(mpp->wwid); + return 1; + } + /* +@@ -566,8 +564,7 @@ int dm_addmap_create (struct multipath *mpp, char * params) + break; + } + } +- if (mark_failed_wwid(mpp->wwid) == WWID_FAILED_CHANGED) +- mpp->needs_paths_uevent = 1; ++ mark_failed_wwid(mpp->wwid); + return 0; + } + diff --git a/0027-multipathd-trigger-uevents-upon-map-removal-in-coale.patch b/0027-multipathd-trigger-uevents-upon-map-removal-in-coale.patch new file mode 100644 index 0000000..f43ca0c --- /dev/null +++ b/0027-multipathd-trigger-uevents-upon-map-removal-in-coale.patch @@ -0,0 +1,41 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 27 Nov 2024 20:39:50 +0100 +Subject: [PATCH] multipathd: trigger uevents upon map removal in + coalesce_maps() + +... if a map has been flushed. In this case, we know that the +the paths haven't been multipathed by coalesce_paths() because of the current +configuration (failure to create the map can't be the reason if the map +exists in coalesce_maps()). Make sure udev sees the paths which have +been released from the map as non-multipath. + +Note that this is the only case where maps are flushed where it is correct +to trigger paths uevents. In other cases, e.g. after a "remove map" CLI +command, the configuration is unchanged and if we triggered an uevent, +the map would be re-created by multipathd when the uevent arrived. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +(cherry picked from commit ad3ea472b587c0c20d2100331b5c66f8602f8414) +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 3fb623fd..4b089c0e 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -794,8 +794,10 @@ coalesce_maps(struct vectors *vecs, vector nmpv) + vector_del_slot(ompv, i); + i--; + } +- else ++ else { + condlog(2, "%s devmap removed", ompp->alias); ++ trigger_paths_udev_change(ompp, false); ++ } + } else if (reassign_maps) { + condlog(3, "%s: Reassign existing device-mapper" + " devices", ompp->alias); diff --git a/0028-libmultipath-Don-t-skip-set_path_max_sectors_kb.patch b/0028-libmultipath-Don-t-skip-set_path_max_sectors_kb.patch new file mode 100644 index 0000000..6c001f5 --- /dev/null +++ b/0028-libmultipath-Don-t-skip-set_path_max_sectors_kb.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 4 Dec 2024 22:56:36 -0500 +Subject: [PATCH] libmultipath: Don't skip set_path_max_sectors_kb() + +If a multipath device already has need_reload set when a path is +adopted, it won't call set_path_max_sectors_kb() because of +short-circuit evaluation. This isn't what's intended. + +Fixes: e5e20c7b ("libmultipath: set max_sectors_kb in adopt_paths()") +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +(cherry picked from commit f5c0c4b25c5eaac87b78e6e0c8d52b0828c29893) +--- + libmultipath/structs_vec.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c +index 9dc5a5ca..683ab473 100644 +--- a/libmultipath/structs_vec.c ++++ b/libmultipath/structs_vec.c +@@ -349,8 +349,7 @@ int adopt_paths(vector pathvec, struct multipath *mpp, + */ + if (!current_mpp || + !mp_find_path_by_devt(current_mpp, pp->dev_t)) +- mpp->need_reload = mpp->need_reload || +- set_path_max_sectors_kb(pp, mpp->max_sectors_kb); ++ mpp->need_reload = set_path_max_sectors_kb(pp, mpp->max_sectors_kb) || mpp->need_reload; + } + + pp->mpp = mpp; diff --git a/0029-libmultipath-stop-static-analyzer-complaint-in-init_.patch b/0029-libmultipath-stop-static-analyzer-complaint-in-init_.patch new file mode 100644 index 0000000..e293a0e --- /dev/null +++ b/0029-libmultipath-stop-static-analyzer-complaint-in-init_.patch @@ -0,0 +1,27 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 22 Jan 2025 22:16:42 -0500 +Subject: [PATCH] libmultipath: stop static analyzer complaint in init_foreign + +This change doesn't actually fix anything. The code was already safe. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +(cherry picked from commit 85ec51e7930b4cadfbc12718afa91ce3a4adf4b5) +--- + libmultipath/foreign.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmultipath/foreign.c b/libmultipath/foreign.c +index 28d1b115..af5b0ed3 100644 +--- a/libmultipath/foreign.c ++++ b/libmultipath/foreign.c +@@ -129,7 +129,7 @@ static void free_pre(void *arg) + static int _init_foreign(const char *enable) + { + char pathbuf[PATH_MAX]; +- struct dirent **di; ++ struct dirent **di = NULL; + struct scandir_result sr; + int r, i; + regex_t *enable_re = NULL; diff --git a/0030-libmultipath-be-lenient-in-allowing-the-alua-based-p.patch b/0030-libmultipath-be-lenient-in-allowing-the-alua-based-p.patch new file mode 100644 index 0000000..06a1b0f --- /dev/null +++ b/0030-libmultipath-be-lenient-in-allowing-the-alua-based-p.patch @@ -0,0 +1,44 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 22 Jan 2025 22:16:43 -0500 +Subject: [PATCH] libmultipath: be lenient in allowing the alua-based + pgpolicies + +multipath wouldn't autodetect the GROUP_BY_PRIO path grouping policy or +allow the GROUP_BY_TPG policy if there was a path that didn't have its +prioritizer selected (for instance because multipathd was reconfigured +while it was offline). To avoid this, make verify_alua_prio() assume an +alua multipath device if all the paths with a prioritizer selected +(there must be at least one) use an alua-based prioritizer. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +(cherry picked from commit b47a577998eaff203018a00b57ba5e3674645848) +--- + libmultipath/propsel.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c +index a3fce203..c09a0619 100644 +--- a/libmultipath/propsel.c ++++ b/libmultipath/propsel.c +@@ -255,14 +255,18 @@ verify_alua_prio(struct multipath *mp) + { + int i; + struct path *pp; ++ bool assume_alua = false; + + vector_foreach_slot(mp->paths, pp, i) { + const char *name = prio_name(&pp->prio); ++ if (!prio_selected(&pp->prio)) ++ continue; + if (strncmp(name, PRIO_ALUA, PRIO_NAME_LEN) && + strncmp(name, PRIO_SYSFS, PRIO_NAME_LEN)) + return false; ++ assume_alua = true; + } +- return true; ++ return assume_alua; + } + + int select_detect_pgpolicy(struct config *conf, struct multipath *mp) diff --git a/0031-Update-NEWS.md-for-0.10.2.patch b/0031-Update-NEWS.md-for-0.10.2.patch new file mode 100644 index 0000000..fd31420 --- /dev/null +++ b/0031-Update-NEWS.md-for-0.10.2.patch @@ -0,0 +1,64 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 24 Jan 2025 20:03:15 +0100 +Subject: [PATCH] Update NEWS.md for 0.10.2 + +Signed-off-by: Benjamin Marzinski +--- + .github/actions/spelling/expect.txt | 2 ++ + NEWS.md | 23 ++++++++++++++++++++++- + 2 files changed, 24 insertions(+), 1 deletion(-) + +diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt +index 000d5ebb..4ac57510 100644 +--- a/.github/actions/spelling/expect.txt ++++ b/.github/actions/spelling/expect.txt +@@ -11,6 +11,7 @@ ata + autoconfig + autodetected + autoresize ++backported + barbie + BINDIR + blkid +@@ -122,6 +123,7 @@ Lun + lvm + lvmteam + Marzinski ++misdetection + mpath + mpathb + mpathpersist +diff --git a/NEWS.md b/NEWS.md +index 3c51553e..1b239ffa 100644 +--- a/NEWS.md ++++ b/NEWS.md +@@ -1,6 +1,27 @@ + # multipath-tools Release Notes + +-## multipath-tools 0.10.1, 2024/11 ++## multipath-tools 0.10.2, 2025/02 ++ ++This release contains backported bug fixes from the stable-0.11.y branch. ++ ++### Bug fixes ++ ++* Fix multipathd crash because of invalid path group index value, for example ++ if an invalid path device was removed from a map. ++ Fixes [#105](https://github.com/opensvc/multipath-tools/issues/105). ++* Make sure maps are reloaded in the path checker loop after detecting an ++ inconsistent or wrong kernel state (e.g. missing or falsely mapped path ++ device). Wrongly mapped paths will be unmapped and released to the system. ++ Fixes another issue reported in ++ [#105](https://github.com/opensvc/multipath-tools/issues/105). ++* Fix the problem that `group_by_tpg` might be disabled if one or more ++ paths were offline during initial configuration. ++* Fix possible misdetection of changed pathgroups in a map. ++* Fix the problem that if a map was scheduled to be reloaded already, ++ `max_sectors_kb` might not be set on a path device that ++ was being added to a multipath map. This problem was introduced in 0.9.9. ++ ++## multipath-tools 0.10.1, 2025/01 + + This is the first bug fix release on the `stable-0.10.y` branch. It contains + bug fixes from 0.11.0, and some CI-related fixes. diff --git a/0032-GitHub-Workflows-fix-abi-stable.yaml-for-pull-reques.patch b/0032-GitHub-Workflows-fix-abi-stable.yaml-for-pull-reques.patch new file mode 100644 index 0000000..3ddab39 --- /dev/null +++ b/0032-GitHub-Workflows-fix-abi-stable.yaml-for-pull-reques.patch @@ -0,0 +1,61 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Sat, 25 Jan 2025 00:49:19 +0100 +Subject: [PATCH] GitHub Workflows: fix abi-stable.yaml for pull request + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/abi-stable.yaml | 16 ++++++++++++---- + 1 file changed, 12 insertions(+), 4 deletions(-) + +diff --git a/.github/workflows/abi-stable.yaml b/.github/workflows/abi-stable.yaml +index a6746f23..472914ce 100644 +--- a/.github/workflows/abi-stable.yaml ++++ b/.github/workflows/abi-stable.yaml +@@ -15,12 +15,16 @@ on: + + jobs: + reference-abi: +- runs-on: ubuntu-20.04 ++ runs-on: ubuntu-22.04 + steps: + - name: get parent tag + run: > + echo ${{ github.ref }} | + sed -E 's,refs/heads/stable-([0-9]\.[0-9]*)\.y,PARENT_TAG=\1.0,' >> $GITHUB_ENV ++ if: ${{ github.event_name == 'push' }} ++ - name: get parent tag ++ run: echo PARENT_TAG=${{ github.base_ref }} >> $GITHUB_ENV ++ if: ${{ github.event_name == 'pull_request' }} + - name: assert parent tag + run: /bin/false + if: ${{ env.PARENT_TAG == '' }} +@@ -45,20 +49,24 @@ jobs: + path: abi + + check-abi: +- runs-on: ubuntu-20.04 ++ runs-on: ubuntu-22.04 + needs: reference-abi + steps: + - name: get parent tag + run: > + echo ${{ github.ref }} | + sed -E 's,refs/heads/stable-([0-9]\.[0-9]*)\.y,PARENT_TAG=\1.0,' >> $GITHUB_ENV ++ if: ${{ github.event_name == 'push' }} ++ - name: get parent tag ++ run: echo PARENT_TAG=${{ github.base_ref }} >> $GITHUB_ENV ++ if: ${{ github.event_name == 'pull_request' }} + - name: assert parent tag + run: /bin/false + if: ${{ env.PARENT_TAG == '' }} +- - name: checkout ${{ env.PARENT_TAG }} ++ - name: checkout ${{ github.base_ref }} + uses: actions/checkout@v4 + with: +- ref: ${{ env.PARENT_TAG }} ++ ref: ${{ github.base_ref }} + - name: download ABI for ${{ env.PARENT_TAG }} + id: download_abi + uses: actions/download-artifact@v4 diff --git a/0001-RH-fixup-udev-rules-for-redhat.patch b/0033-RH-fixup-udev-rules-for-redhat.patch similarity index 100% rename from 0001-RH-fixup-udev-rules-for-redhat.patch rename to 0033-RH-fixup-udev-rules-for-redhat.patch diff --git a/0002-RH-Remove-the-property-blacklist-exception-builtin.patch b/0034-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 100% rename from 0002-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0034-RH-Remove-the-property-blacklist-exception-builtin.patch diff --git a/0003-RH-don-t-start-without-a-config-file.patch b/0035-RH-don-t-start-without-a-config-file.patch similarity index 98% rename from 0003-RH-don-t-start-without-a-config-file.patch rename to 0035-RH-don-t-start-without-a-config-file.patch index 02827df..8a3c5b6 100644 --- a/0003-RH-don-t-start-without-a-config-file.patch +++ b/0035-RH-don-t-start-without-a-config-file.patch @@ -22,10 +22,10 @@ Signed-off-by: Benjamin Marzinski 7 files changed, 25 insertions(+) diff --git a/libmultipath/config.c b/libmultipath/config.c -index 0e3a5cc1..80f61914 100644 +index 226ddecb..588ae9ee 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c -@@ -959,6 +959,19 @@ int init_config__ (const char *file, struct config *conf) +@@ -962,6 +962,19 @@ int init_config__ (const char *file, struct config *conf) } factorize_hwtable(conf->hwtable, builtin_hwtable_size, file); validate_pctable(conf->overrides, 0, file); diff --git a/0004-RH-Fix-nvme-function-missing-argument.patch b/0036-RH-Fix-nvme-function-missing-argument.patch similarity index 100% rename from 0004-RH-Fix-nvme-function-missing-argument.patch rename to 0036-RH-Fix-nvme-function-missing-argument.patch diff --git a/0005-RH-use-rpm-optflags-if-present.patch b/0037-RH-use-rpm-optflags-if-present.patch similarity index 97% rename from 0005-RH-use-rpm-optflags-if-present.patch rename to 0037-RH-use-rpm-optflags-if-present.patch index 266e224..66d14bc 100644 --- a/0005-RH-use-rpm-optflags-if-present.patch +++ b/0037-RH-use-rpm-optflags-if-present.patch @@ -7,13 +7,14 @@ Use the passed in optflags when compiling as an RPM, and keep the default flags as close as possible to the current fedora flags, while still being generic. +Co-authored-by: Yaakov Selkowitz Signed-off-by: Benjamin Marzinski --- Makefile.inc | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 81cb61d2..35334a0c 100644 +index 81cb61d2..a5024bb7 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -99,28 +99,39 @@ SYSTEMD_LIBDEPS := $(if $(SYSTEMD),$(if $(shell test $(SYSTEMD) -gt 209 && echo diff --git a/0006-RH-add-mpathconf.patch b/0038-RH-add-mpathconf.patch similarity index 99% rename from 0006-RH-add-mpathconf.patch rename to 0038-RH-add-mpathconf.patch index 2ae48f3..103ca55 100644 --- a/0006-RH-add-mpathconf.patch +++ b/0038-RH-add-mpathconf.patch @@ -23,11 +23,11 @@ Signed-off-by: Benjamin Marzinski create mode 100644 multipath/mpathconf.8 diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt -index 934f582e..61351583 100644 +index 4ac57510..3602a071 100644 --- a/.github/actions/spelling/expect.txt +++ b/.github/actions/spelling/expect.txt -@@ -124,9 +124,11 @@ lvmteam - Marzinski +@@ -126,9 +126,11 @@ Marzinski + misdetection mpath mpathb +mpathconf @@ -38,7 +38,7 @@ index 934f582e..61351583 100644 multipathc multipathd multipathed -@@ -144,6 +146,7 @@ ontap +@@ -146,6 +148,7 @@ ontap OOM opensvc OPTFLAGS @@ -47,10 +47,10 @@ index 934f582e..61351583 100644 partx pathgroup diff --git a/libmultipath/config.c b/libmultipath/config.c -index 80f61914..1373f15b 100644 +index 588ae9ee..3cb8449c 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c -@@ -961,6 +961,8 @@ int init_config__ (const char *file, struct config *conf) +@@ -964,6 +964,8 @@ int init_config__ (const char *file, struct config *conf) validate_pctable(conf->overrides, 0, file); } else { condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices."); diff --git a/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0039-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 100% rename from 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0039-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch diff --git a/0008-RH-reset-default-find_mutipaths-value-to-off.patch b/0040-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 100% rename from 0008-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0040-RH-reset-default-find_mutipaths-value-to-off.patch diff --git a/0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0041-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 100% rename from 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0041-RH-attempt-to-get-ANA-info-via-sysfs-first.patch diff --git a/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch b/0042-RH-make-parse_vpd_pg83-match-scsi_id-output.patch similarity index 98% rename from 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch rename to 0042-RH-make-parse_vpd_pg83-match-scsi_id-output.patch index 06194f6..0d5baa3 100644 --- a/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +++ b/0042-RH-make-parse_vpd_pg83-match-scsi_id-output.patch @@ -14,7 +14,7 @@ Signed-off-by: Benjamin Marzinski 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index e94705bf..61ac27ef 100644 +index 5043330c..e14507e8 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c @@ -1221,13 +1221,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, diff --git a/0011-RH-add-scsi-device-handlers-to-modules-load.d.patch b/0043-RH-add-scsi-device-handlers-to-modules-load.d.patch similarity index 96% rename from 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch rename to 0043-RH-add-scsi-device-handlers-to-modules-load.d.patch index 3debe8a..ef0ee42 100644 --- a/0011-RH-add-scsi-device-handlers-to-modules-load.d.patch +++ b/0043-RH-add-scsi-device-handlers-to-modules-load.d.patch @@ -11,7 +11,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc -index 35334a0c..377125b6 100644 +index a5024bb7..834b63b9 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -16,7 +16,7 @@ READLINE := diff --git a/0012-RH-compile-with-libreadline-support.patch b/0044-RH-compile-with-libreadline-support.patch similarity index 96% rename from 0012-RH-compile-with-libreadline-support.patch rename to 0044-RH-compile-with-libreadline-support.patch index db04640..50781c3 100644 --- a/0012-RH-compile-with-libreadline-support.patch +++ b/0044-RH-compile-with-libreadline-support.patch @@ -12,7 +12,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc -index 377125b6..4a6528a9 100644 +index 834b63b9..c482a181 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -12,7 +12,7 @@ diff --git a/0013-RH-Add-mpathcleanup.patch b/0045-RH-Add-mpathcleanup.patch similarity index 100% rename from 0013-RH-Add-mpathcleanup.patch rename to 0045-RH-Add-mpathcleanup.patch diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index d2c3cc6..8e469ab 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.10.0 -Release: 4%{?dist} +Release: 5%{?dist} Summary: Tools to manage multipath devices using device-mapper # readline uses GPL-3.0-only License: GPL-2.0-only AND GPL-3.0-only @@ -11,19 +11,51 @@ URL: http://christophe.varoqui.free.fr/ # curl -L https://github.com/opensvc/multipath-tools/archive/0.10.0.tar.gz -o multipath-tools-0.10.0.tgz Source0: multipath-tools-0.10.0.tgz Source1: multipath.conf -Patch0001: 0001-RH-fixup-udev-rules-for-redhat.patch -Patch0002: 0002-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0003: 0003-RH-don-t-start-without-a-config-file.patch -Patch0004: 0004-RH-Fix-nvme-function-missing-argument.patch -Patch0005: 0005-RH-use-rpm-optflags-if-present.patch -Patch0006: 0006-RH-add-mpathconf.patch -Patch0007: 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0008: 0008-RH-reset-default-find_mutipaths-value-to-off.patch -Patch0009: 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch -Patch0010: 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch -Patch0011: 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch -Patch0012: 0012-RH-compile-with-libreadline-support.patch -Patch0013: 0013-RH-Add-mpathcleanup.patch +Patch0001: 0001-GitHub-workflows-use-upload-download-artifact-v4.patch +Patch0002: 0002-GitHub-workflows-update-dawidd6-action-download-arti.patch +Patch0003: 0003-Github-workflows-native.yml-use-mosteo-actions-docke.patch +Patch0004: 0004-GitHub-workflows-native.yml-use-extra-job-for-clang.patch +Patch0005: 0005-GitHub-workflows-native.yaml-make-test-and-archive-s.patch +Patch0006: 0006-GitHub-workflows-enable-unit-tests-for-stable-branch.patch +Patch0007: 0007-GitHub-Workflows-add-abi-check-for-stable-branches.patch +Patch0008: 0008-libmultipath-dm_get_maps-don-t-bail-out-for-single-m.patch +Patch0009: 0009-11-dm-mpath.rules.in-import-DM_COLDPLUG_SUSPENDED-on.patch +Patch0010: 0010-11-dm-mpath.rules.in-handle-inactive-suspended-devic.patch +Patch0011: 0011-11-dm-mpath.rules.in-clarify-DM_ACTIVATION-logic.patch +Patch0012: 0012-11-dm-mpath-rules.in-skip-one-.DM_NOSCAN-check.patch +Patch0013: 0013-11-dm-mpath.rules.in-set-.DM_NOSCAN-if-MPATH_UNCHANG.patch +Patch0014: 0014-libmultipath-don-t-set-dev_loss_tmo-to-0-for-NO_PATH.patch +Patch0015: 0015-multipathd-fix-deferred_failback_tick-for-reload-rem.patch +Patch0016: 0016-multipathd-fix-an-unsigned-int-ovwerflow.patch +Patch0017: 0017-libmpathutil-avoid-Wcast-function-type-mismatch-erro.patch +Patch0018: 0018-Update-NEWS.md-for-0.10.1.patch +Patch0019: 0019-libmultipath-don-t-print-error-message-if-WATCHDOG_U.patch +Patch0020: 0020-libmultipath-reduce-log-level-of-map-X-has-multiple-.patch +Patch0021: 0021-libmultipath-foreign-fix-memory-leak-in-nvme-foreign.patch +Patch0022: 0022-libmultipath-add-condition-for-enqueueing-path-to-io.patch +Patch0023: 0023-Additional-NEWS.md-updates-for-0.10.1.patch +Patch0024: 0024-libmultipath-fix-handling-of-pp-pgindex.patch +Patch0025: 0025-libmultipath-make-pgcmp-detect-if-map-is-missing-a-p.patch +Patch0026: 0026-libmultipath-trigger-uevents-upon-map-creation-in-do.patch +Patch0027: 0027-multipathd-trigger-uevents-upon-map-removal-in-coale.patch +Patch0028: 0028-libmultipath-Don-t-skip-set_path_max_sectors_kb.patch +Patch0029: 0029-libmultipath-stop-static-analyzer-complaint-in-init_.patch +Patch0030: 0030-libmultipath-be-lenient-in-allowing-the-alua-based-p.patch +Patch0031: 0031-Update-NEWS.md-for-0.10.2.patch +Patch0032: 0032-GitHub-Workflows-fix-abi-stable.yaml-for-pull-reques.patch +Patch0033: 0033-RH-fixup-udev-rules-for-redhat.patch +Patch0034: 0034-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0035: 0035-RH-don-t-start-without-a-config-file.patch +Patch0036: 0036-RH-Fix-nvme-function-missing-argument.patch +Patch0037: 0037-RH-use-rpm-optflags-if-present.patch +Patch0038: 0038-RH-add-mpathconf.patch +Patch0039: 0039-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0040: 0040-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0041: 0041-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0042: 0042-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +Patch0043: 0043-RH-add-scsi-device-handlers-to-modules-load.d.patch +Patch0044: 0044-RH-compile-with-libreadline-support.patch +Patch0045: 0045-RH-Add-mpathcleanup.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -233,6 +265,11 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Sat Feb 1 2025 Benjamin Marzinski - 0.10.0-5 +- Update source to upstream staging branch for 0.10.y (will be 0.10.2 when + merged). +- Rebase redhat patches + * Thu Jan 16 2025 Fedora Release Engineering - 0.10.0-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild From 30306052cc8ded97742c95e1b7e1c4a5ceeab621 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Mon, 3 Mar 2025 12:33:06 -0500 Subject: [PATCH 64/67] device-mapper-multipath-0.11.1-1 Update source to upstream staging branch for 0.11.1 plus additional stable branch patches. * Previous patches 0001-0032 are included in the tarball Rename redhat patches * Previous patches 0033-0045 are now patches 0005-0017 --- .gitignore | 1 + ...lows-use-upload-download-artifact-v4.patch | 122 ---------------- ...er-uevents-for-blacklisted-paths-in-.patch | 101 +++++++++++++ ...-update-dawidd6-action-download-arti.patch | 24 --- ...fix-compilation-with-latest-userspac.patch | 63 ++++++++ ...-native.yml-use-mosteo-actions-docke.patch | 98 ------------- ...-include-urcu.h-before-urcu-atomic.h.patch | 40 +++++ ...s-native.yml-use-extra-job-for-clang.patch | 43 ------ ...uxsock.c-Include-string.h-for-memcpy.patch | 29 ++++ ...-native.yaml-make-test-and-archive-s.patch | 51 ------- ... 0005-RH-fixup-udev-rules-for-redhat.patch | 2 +- ...-enable-unit-tests-for-stable-branch.patch | 133 ----------------- ...property-blacklist-exception-builtin.patch | 0 ...ws-add-abi-check-for-stable-branches.patch | 110 -------------- ...RH-don-t-start-without-a-config-file.patch | 8 +- ...H-Fix-nvme-function-missing-argument.patch | 0 ...get_maps-don-t-bail-out-for-single-m.patch | 32 ---- ...s.in-import-DM_COLDPLUG_SUSPENDED-on.patch | 42 ------ ... 0009-RH-use-rpm-optflags-if-present.patch | 7 +- ...s.in-handle-inactive-suspended-devic.patch | 66 --------- ...hconf.patch => 0010-RH-add-mpathconf.patch | 10 +- ...rules.in-clarify-DM_ACTIVATION-logic.patch | 78 ---------- ...om-kernel-cmdline-mpath.wwids-with-A.patch | 6 +- ...h-rules.in-skip-one-.DM_NOSCAN-check.patch | 28 ---- ...-default-find_mutipaths-value-to-off.patch | 0 ...s.in-set-.DM_NOSCAN-if-MPATH_UNCHANG.patch | 44 ------ ...empt-to-get-ANA-info-via-sysfs-first.patch | 0 ...-parse_vpd_pg83-match-scsi_id-output.patch | 6 +- ...-t-set-dev_loss_tmo-to-0-for-NO_PATH.patch | 31 ---- ...si-device-handlers-to-modules-load.d.patch | 2 +- ...eferred_failback_tick-for-reload-rem.patch | 35 ----- ...-RH-compile-with-libreadline-support.patch | 2 +- ...ipathd-fix-an-unsigned-int-ovwerflow.patch | 28 ---- ...up.patch => 0017-RH-Add-mpathcleanup.patch | 0 ...id-Wcast-function-type-mismatch-erro.patch | 36 ----- 0018-Update-NEWS.md-for-0.10.1.patch | 44 ------ ...-t-print-error-message-if-WATCHDOG_U.patch | 30 ---- ...uce-log-level-of-map-X-has-multiple-.patch | 38 ----- ...eign-fix-memory-leak-in-nvme-foreign.patch | 54 ------- ...-condition-for-enqueueing-path-to-io.patch | 41 ------ ...dditional-NEWS.md-updates-for-0.10.1.patch | 63 -------- ...multipath-fix-handling-of-pp-pgindex.patch | 138 ------------------ ...e-pgcmp-detect-if-map-is-missing-a-p.patch | 70 --------- ...gger-uevents-upon-map-creation-in-do.patch | 94 ------------ ...er-uevents-upon-map-removal-in-coale.patch | 41 ------ ...h-Don-t-skip-set_path_max_sectors_kb.patch | 31 ---- ...p-static-analyzer-complaint-in-init_.patch | 27 ---- ...lenient-in-allowing-the-alua-based-p.patch | 44 ------ 0031-Update-NEWS.md-for-0.10.2.patch | 64 -------- ...-fix-abi-stable.yaml-for-pull-reques.patch | 61 -------- device-mapper-multipath.spec | 79 ++++------ sources | 2 +- 52 files changed, 285 insertions(+), 1914 deletions(-) delete mode 100644 0001-GitHub-workflows-use-upload-download-artifact-v4.patch create mode 100644 0001-multipathd-trigger-uevents-for-blacklisted-paths-in-.patch delete mode 100644 0002-GitHub-workflows-update-dawidd6-action-download-arti.patch create mode 100644 0002-multipath-tools-fix-compilation-with-latest-userspac.patch delete mode 100644 0003-Github-workflows-native.yml-use-mosteo-actions-docke.patch create mode 100644 0003-libmultipath-include-urcu.h-before-urcu-atomic.h.patch delete mode 100644 0004-GitHub-workflows-native.yml-use-extra-job-for-clang.patch create mode 100644 0004-libmpathutils-uxsock.c-Include-string.h-for-memcpy.patch delete mode 100644 0005-GitHub-workflows-native.yaml-make-test-and-archive-s.patch rename 0033-RH-fixup-udev-rules-for-redhat.patch => 0005-RH-fixup-udev-rules-for-redhat.patch (98%) delete mode 100644 0006-GitHub-workflows-enable-unit-tests-for-stable-branch.patch rename 0034-RH-Remove-the-property-blacklist-exception-builtin.patch => 0006-RH-Remove-the-property-blacklist-exception-builtin.patch (100%) delete mode 100644 0007-GitHub-Workflows-add-abi-check-for-stable-branches.patch rename 0035-RH-don-t-start-without-a-config-file.patch => 0007-RH-don-t-start-without-a-config-file.patch (96%) rename 0036-RH-Fix-nvme-function-missing-argument.patch => 0008-RH-Fix-nvme-function-missing-argument.patch (100%) delete mode 100644 0008-libmultipath-dm_get_maps-don-t-bail-out-for-single-m.patch delete mode 100644 0009-11-dm-mpath.rules.in-import-DM_COLDPLUG_SUSPENDED-on.patch rename 0037-RH-use-rpm-optflags-if-present.patch => 0009-RH-use-rpm-optflags-if-present.patch (92%) delete mode 100644 0010-11-dm-mpath.rules.in-handle-inactive-suspended-devic.patch rename 0038-RH-add-mpathconf.patch => 0010-RH-add-mpathconf.patch (99%) delete mode 100644 0011-11-dm-mpath.rules.in-clarify-DM_ACTIVATION-logic.patch rename 0039-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch => 0011-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch (97%) delete mode 100644 0012-11-dm-mpath-rules.in-skip-one-.DM_NOSCAN-check.patch rename 0040-RH-reset-default-find_mutipaths-value-to-off.patch => 0012-RH-reset-default-find_mutipaths-value-to-off.patch (100%) delete mode 100644 0013-11-dm-mpath.rules.in-set-.DM_NOSCAN-if-MPATH_UNCHANG.patch rename 0041-RH-attempt-to-get-ANA-info-via-sysfs-first.patch => 0013-RH-attempt-to-get-ANA-info-via-sysfs-first.patch (100%) rename 0042-RH-make-parse_vpd_pg83-match-scsi_id-output.patch => 0014-RH-make-parse_vpd_pg83-match-scsi_id-output.patch (94%) delete mode 100644 0014-libmultipath-don-t-set-dev_loss_tmo-to-0-for-NO_PATH.patch rename 0043-RH-add-scsi-device-handlers-to-modules-load.d.patch => 0015-RH-add-scsi-device-handlers-to-modules-load.d.patch (96%) delete mode 100644 0015-multipathd-fix-deferred_failback_tick-for-reload-rem.patch rename 0044-RH-compile-with-libreadline-support.patch => 0016-RH-compile-with-libreadline-support.patch (96%) delete mode 100644 0016-multipathd-fix-an-unsigned-int-ovwerflow.patch rename 0045-RH-Add-mpathcleanup.patch => 0017-RH-Add-mpathcleanup.patch (100%) delete mode 100644 0017-libmpathutil-avoid-Wcast-function-type-mismatch-erro.patch delete mode 100644 0018-Update-NEWS.md-for-0.10.1.patch delete mode 100644 0019-libmultipath-don-t-print-error-message-if-WATCHDOG_U.patch delete mode 100644 0020-libmultipath-reduce-log-level-of-map-X-has-multiple-.patch delete mode 100644 0021-libmultipath-foreign-fix-memory-leak-in-nvme-foreign.patch delete mode 100644 0022-libmultipath-add-condition-for-enqueueing-path-to-io.patch delete mode 100644 0023-Additional-NEWS.md-updates-for-0.10.1.patch delete mode 100644 0024-libmultipath-fix-handling-of-pp-pgindex.patch delete mode 100644 0025-libmultipath-make-pgcmp-detect-if-map-is-missing-a-p.patch delete mode 100644 0026-libmultipath-trigger-uevents-upon-map-creation-in-do.patch delete mode 100644 0027-multipathd-trigger-uevents-upon-map-removal-in-coale.patch delete mode 100644 0028-libmultipath-Don-t-skip-set_path_max_sectors_kb.patch delete mode 100644 0029-libmultipath-stop-static-analyzer-complaint-in-init_.patch delete mode 100644 0030-libmultipath-be-lenient-in-allowing-the-alua-based-p.patch delete mode 100644 0031-Update-NEWS.md-for-0.10.2.patch delete mode 100644 0032-GitHub-Workflows-fix-abi-stable.yaml-for-pull-reques.patch diff --git a/.gitignore b/.gitignore index 908094d..8cd21df 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,4 @@ multipath-tools-091027.tar.gz /multipath-tools-0.9.8.tgz /multipath-tools-0.9.9.tgz /multipath-tools-0.10.0.tgz +/multipath-tools-0.11.1.tgz diff --git a/0001-GitHub-workflows-use-upload-download-artifact-v4.patch b/0001-GitHub-workflows-use-upload-download-artifact-v4.patch deleted file mode 100644 index c8247ca..0000000 --- a/0001-GitHub-workflows-use-upload-download-artifact-v4.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 13 Sep 2024 09:09:19 +0200 -Subject: [PATCH] GitHub workflows: use {upload,download}-artifact@v4 - -The @v1 releases are deprecated. -https://github.blog/changelog/2024-02-13-deprecation-notice-v1-and-v2-of-the-artifact-actions/ - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/abi.yaml | 6 ++++-- - .github/workflows/foreign.yaml | 15 +++++++-------- - .github/workflows/native.yaml | 5 +++-- - 3 files changed, 14 insertions(+), 12 deletions(-) - -diff --git a/.github/workflows/abi.yaml b/.github/workflows/abi.yaml -index 393322e5..dce09f5c 100644 ---- a/.github/workflows/abi.yaml -+++ b/.github/workflows/abi.yaml -@@ -45,10 +45,11 @@ jobs: - - name: create ABI - run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) abi.tar.gz - - name: save ABI -- uses: actions/upload-artifact@v1 -+ uses: actions/upload-artifact@v4 - with: - name: abi - path: abi -+ overwrite: true - - name: compare ABI against reference - id: compare - continue-on-error: true -@@ -56,10 +57,11 @@ jobs: - run: make abi-test - - name: save differences - if: ${{ steps.compare.outcome == 'failure' }} -- uses: actions/upload-artifact@v1 -+ uses: actions/upload-artifact@v4 - with: - name: abi-test - path: abi-test -+ overwrite: true - - - name: fail - # MUST use >- here, otherwise the condition always evaluates to true -diff --git a/.github/workflows/foreign.yaml b/.github/workflows/foreign.yaml -index 9e4d35e0..d68650df 100644 ---- a/.github/workflows/foreign.yaml -+++ b/.github/workflows/foreign.yaml -@@ -36,14 +36,13 @@ jobs: - - name: checkout - uses: actions/checkout@v1 - - name: build -- run: make -j8 -Orecurse test-progs -- - name: create binary archive -- run: make test-progs.tar -+ run: make -j -Orecurse test-progs.tar - - name: upload binary archive -- uses: actions/upload-artifact@v1 -+ uses: actions/upload-artifact@v4 - with: - name: cross-${{ matrix.os }}-${{ matrix.arch }} - path: test-progs.tar -+ overwrite: true - - test: - runs-on: ubuntu-22.04 -@@ -61,11 +60,11 @@ jobs: - run: echo CONTAINER_ARCH="arm/v7" >> $GITHUB_ENV - if: ${{ matrix.arch == 'armhf' }} - - name: download binary archive -- uses: actions/download-artifact@v1 -+ uses: actions/download-artifact@v4 - with: - name: cross-${{ matrix.os }}-${{ matrix.arch }} - - name: unpack binary archive -- run: tar xfv cross-${{ matrix.os }}-${{ matrix.arch }}/test-progs.tar -+ run: tar xfv test-progs.tar - - name: enable foreign arch - uses: dbhi/qus/action@main - - name: run tests -@@ -100,11 +99,11 @@ jobs: - run: echo CONTAINER_ARCH="arm/v7" >> $GITHUB_ENV - if: ${{ matrix.arch == 'armhf' }} - - name: download binary archive -- uses: actions/download-artifact@v1 -+ uses: actions/download-artifact@v4 - with: - name: cross-${{ matrix.os }}-${{ matrix.arch }} - - name: unpack binary archive -- run: tar xfv cross-${{ matrix.os }}-${{ matrix.arch }}/test-progs.tar -+ run: tar xfv test-progs.tar - - name: enable foreign arch - uses: dbhi/qus/action@main - - name: run tests -diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml -index 80ff6df5..500becaa 100644 ---- a/.github/workflows/native.yaml -+++ b/.github/workflows/native.yaml -@@ -57,10 +57,11 @@ jobs: - - name: create binary archive - run: make ${{ env.ARCHIVE_TGT }} - - name: upload binary archive -- uses: actions/upload-artifact@v1 -+ uses: actions/upload-artifact@v4 - with: - name: native-${{ matrix.os }} - path: ${{ env.ARCHIVE_TGT }} -+ overwrite: true - - - name: clean - run: make clean -@@ -98,7 +99,7 @@ jobs: - uses: actions/checkout@v1 - - - name: download binary archive -- uses: actions/download-artifact@v1 -+ uses: actions/download-artifact@v4 - with: - name: native-${{ matrix.os }} - - name: unpack binary archive diff --git a/0001-multipathd-trigger-uevents-for-blacklisted-paths-in-.patch b/0001-multipathd-trigger-uevents-for-blacklisted-paths-in-.patch new file mode 100644 index 0000000..72bcf69 --- /dev/null +++ b/0001-multipathd-trigger-uevents-for-blacklisted-paths-in-.patch @@ -0,0 +1,101 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 23 Jan 2025 22:19:39 +0100 +Subject: [PATCH] multipathd: trigger uevents for blacklisted paths in + reconfigure + +If multipathd has already configured maps, and the user changes the +blacklist or other parameters that cause currently multipathed +devices to be skipped, and then runs "multipathd reconfigure" +or restarts multipathd, multipathd flushes the maps in question, +but doesn't trigger uevents for the now-blacklisted paths. + +This is because the blacklisted paths are removed from the discovered +maps internally when update_pathvec_from_dm() is called through +map_discovery() and update_multipath_table(); when later +trigger_paths_udev_change() is called from coalesce_maps(), the +map contains no paths for which an uevent could be triggered. + +The map_discovery() code flow is special, because we will call +coalesce_paths() afterwards anyway and reconstruct the mpvec. Unlike the +regular code flow, we don't want the maps to be "corrected" in this +case, because the maps discovered here aren't going to be reloaded. +We just want update_pathvec_from_dm() to populate the pathvec. + +Therefore add a new flag DI_DISCOVERY, which is only set when +update_multipath_table() is called from map_discovery(), and if +this flag is set, keep PATHINFO_SKIPPED paths in the map's table in +update_pathvec_from_dm(). Later on, the paths will still be visible +in the old mpp (ompp) in coalesce_maps(), and uevents will be +triggered for them to release them to systemd. + +We can't always do this for PATHINFO_SKIPPED, because in some cases +paths may be accepted in a map first and SKIPPED later (for example if +the WWID wasn't yet available at startup). Therefore the special +case for DI_DISCOVERY is necessary. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/discovery.h | 2 ++ + libmultipath/structs_vec.c | 6 +++++- + multipathd/main.c | 2 +- + 3 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/discovery.h b/libmultipath/discovery.h +index 7d42eae5..9824a8d3 100644 +--- a/libmultipath/discovery.h ++++ b/libmultipath/discovery.h +@@ -72,6 +72,7 @@ enum discovery_mode { + DI_BLACKLIST__, + DI_NOIO__, + DI_NOFALLBACK__, ++ DI_DISCOVERY__, + }; + + #define DI_SYSFS (1 << DI_SYSFS__) +@@ -82,6 +83,7 @@ enum discovery_mode { + #define DI_BLACKLIST (1 << DI_BLACKLIST__) + #define DI_NOIO (1 << DI_NOIO__) /* Avoid IO on the device */ + #define DI_NOFALLBACK (1 << DI_NOFALLBACK__) /* do not allow wwid fallback */ ++#define DI_DISCOVERY (1 << DI_DISCOVERY__) /* set only during map discovery */ + + #define DI_ALL (DI_SYSFS | DI_SERIAL | DI_CHECKER | DI_PRIO | \ + DI_WWID) +diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c +index 7a4e3eb0..5ccdaea0 100644 +--- a/libmultipath/structs_vec.c ++++ b/libmultipath/structs_vec.c +@@ -109,6 +109,9 @@ static bool update_pathvec_from_dm(vector pathvec, struct multipath *mpp, + bool mpp_has_wwid; + bool must_reload = false; + bool pg_deleted = false; ++ bool map_discovery = !!(pathinfo_flags & DI_DISCOVERY); ++ ++ pathinfo_flags &= ~DI_DISCOVERY; + + if (!mpp->pg) + return false; +@@ -195,7 +198,8 @@ static bool update_pathvec_from_dm(vector pathvec, struct multipath *mpp, + rc = pathinfo(pp, conf, + DI_SYSFS|DI_WWID|DI_BLACKLIST|DI_NOFALLBACK|pathinfo_flags); + pthread_cleanup_pop(1); +- if (rc != PATHINFO_OK) { ++ if (rc == PATHINFO_FAILED || ++ (rc == PATHINFO_SKIPPED && !map_discovery)) { + condlog(1, "%s: error %d in pathinfo, discarding path", + pp->dev, rc); + vector_del_slot(pgp->paths, j--); +diff --git a/multipathd/main.c b/multipathd/main.c +index 9ed27da0..fb3e44a8 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -1763,7 +1763,7 @@ map_discovery (struct vectors * vecs) + return 1; + + vector_foreach_slot (vecs->mpvec, mpp, i) +- if (update_multipath_table(mpp, vecs->pathvec, 0) != DMP_OK) { ++ if (update_multipath_table(mpp, vecs->pathvec, DI_DISCOVERY) != DMP_OK) { + remove_map(mpp, vecs->pathvec, vecs->mpvec); + i--; + } diff --git a/0002-GitHub-workflows-update-dawidd6-action-download-arti.patch b/0002-GitHub-workflows-update-dawidd6-action-download-arti.patch deleted file mode 100644 index 423bf56..0000000 --- a/0002-GitHub-workflows-update-dawidd6-action-download-arti.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 13 Sep 2024 09:10:38 +0200 -Subject: [PATCH] GitHub workflows: update dawidd6/action-download-artifact - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/abi.yaml | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/.github/workflows/abi.yaml b/.github/workflows/abi.yaml -index dce09f5c..d5f8b477 100644 ---- a/.github/workflows/abi.yaml -+++ b/.github/workflows/abi.yaml -@@ -28,7 +28,7 @@ jobs: - - name: get reference ABI - id: reference - continue-on-error: true -- uses: dawidd6/action-download-artifact@v2 -+ uses: dawidd6/action-download-artifact@v6 - with: - workflow: abi.yaml - branch: ${{ env.ABI_BRANCH }} diff --git a/0002-multipath-tools-fix-compilation-with-latest-userspac.patch b/0002-multipath-tools-fix-compilation-with-latest-userspac.patch new file mode 100644 index 0000000..03d7d9d --- /dev/null +++ b/0002-multipath-tools-fix-compilation-with-latest-userspac.patch @@ -0,0 +1,63 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 3 Feb 2025 16:43:42 -0500 +Subject: [PATCH] multipath-tools: fix compilation with latest userspace-rcu + code + +starting with version 0.15, userspace-rcu can be compiled with +CONFIG_RCU_USE_ATOMIC_BUILTINS. If it is, then any programs using it +must be compiled with at least the C11 standard. See: +https://github.com/urcu/userspace-rcu/commit/89280d020bf064d1055c360fb9974f128051043f + +To deal with this, check if compiling with gnu99 fails, and if so, +switch to using gnu11. + +Based-on-patch-by: Yaakov Selkowitz +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + Makefile.inc | 2 +- + create-config.mk | 13 +++++++++++++ + 2 files changed, 14 insertions(+), 1 deletion(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 729618bd..65f6efc8 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -115,7 +115,7 @@ CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) $(D_URCU_VERSION) \ + -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(TGTDIR)$(configdir)\" \ + -DDEFAULT_CONFIGFILE=\"$(TGTDIR)$(configfile)\" -DSTATE_DIR=\"$(TGTDIR)$(statedir)\" \ + -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP +-CFLAGS := -std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ ++CFLAGS := -std=$(C_STD) $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ + -fexceptions + BIN_CFLAGS := -fPIE -DPIE + LIB_CFLAGS := -fPIC +diff --git a/create-config.mk b/create-config.mk +index 8bd2c20c..ab163ed1 100644 +--- a/create-config.mk ++++ b/create-config.mk +@@ -157,6 +157,18 @@ FORTIFY_OPT := $(shell \ + echo "-D_FORTIFY_SOURCE=2"; \ + fi) + ++# Check is you can compile with the urcu.h header, using the C99 standard. ++# If urcu/config-.h defines CONFIG_RCU_USE_ATOMIC_BUILTINS, then anything ++# including urcu.h must be compiled with at least the C11 standard. See: ++# https://github.com/urcu/userspace-rcu/commit/89280d020bf064d1055c360fb9974f128051043f ++C_STD := $(shell \ ++ if printf '$(__HASH__)include \nint main(void) { return 0; }\n' | $(CC) -o /dev/null -c -xc --std=gnu99 - 2>/dev/null; \ ++ then \ ++ echo "gnu99"; \ ++ else \ ++ echo "gnu11"; \ ++ fi) ++ + STACKPROT := + + all: $(TOPDIR)/config.mk +@@ -182,3 +194,4 @@ $(TOPDIR)/config.mk: $(multipathdir)/autoconfig.h + @echo "W_MISSING_INITIALIZERS := $(call TEST_MISSING_INITIALIZERS)" >>$@ + @echo "W_URCU_TYPE_LIMITS := $(call TEST_URCU_TYPE_LIMITS)" >>$@ + @echo "ENABLE_LIBDMMP := $(ENABLE_LIBDMMP)" >>$@ ++ @echo "C_STD := $(C_STD)" >>$@ diff --git a/0003-Github-workflows-native.yml-use-mosteo-actions-docke.patch b/0003-Github-workflows-native.yml-use-mosteo-actions-docke.patch deleted file mode 100644 index 63aa273..0000000 --- a/0003-Github-workflows-native.yml-use-mosteo-actions-docke.patch +++ /dev/null @@ -1,98 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 13 Sep 2024 09:45:25 +0200 -Subject: [PATCH] Github workflows: native.yml: use mosteo-actions/docker-run - -We can't use "container:" any more because upload-artifact@v4 doesn't -work on Debian Jessie. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/native.yaml | 45 +++++++++++++++++++++-------------- - 1 file changed, 27 insertions(+), 18 deletions(-) - -diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml -index 500becaa..70d01c55 100644 ---- a/.github/workflows/native.yaml -+++ b/.github/workflows/native.yaml -@@ -35,17 +35,9 @@ jobs: - - debian-bookworm - - fedora-40 - - opensuse-leap -- container: ghcr.io/mwilck/multipath-build-${{ matrix.os }} - steps: - - name: checkout - uses: actions/checkout@v1 -- - name: build and test -- if: ${{ matrix.os != 'debian-jessie' }} -- run: make -j -Orecurse test -- - name: build and test (jessie) -- # On jessie, we use libreadline 5 (no licensing issue) -- if: ${{ matrix.os == 'debian-jessie' }} -- run: make -j -Orecurse READLINE=libreadline test - - - name: set archive name - # Leap containers have cpio but not tar -@@ -54,8 +46,21 @@ jobs: - - name: set archive name - run: echo ARCHIVE_TGT=test-progs.tar >> $GITHUB_ENV - if: ${{ matrix.os != 'opensuse-leap' }} -- - name: create binary archive -- run: make ${{ env.ARCHIVE_TGT }} -+ -+ - name: build and test -+ if: ${{ matrix.os != 'debian-jessie' }} -+ uses: mosteo-actions/docker-run@v1 -+ with: -+ image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} -+ command: -j -Orecurse ${{ env.ARCHIVE_TGT }} test -+ - name: build and test (jessie) -+ # On jessie, we use libreadline 5 (no licensing issue) -+ if: ${{ matrix.os == 'debian-jessie' }} -+ uses: mosteo-actions/docker-run@v1 -+ with: -+ image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} -+ command: -j -Orecurse READLINE=libreadline ${{ env.ARCHIVE_TGT }} test -+ - - name: upload binary archive - uses: actions/upload-artifact@v4 - with: -@@ -67,14 +72,18 @@ jobs: - run: make clean - - name: clang - if: ${{ matrix.os != 'debian-jessie' }} -- env: -- CC: clang -- run: make -j -Orecurse test -+ uses: mosteo-actions/docker-run@v1 -+ with: -+ image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} -+ params: -e CC=clang -+ command: -j -Orecurse test - - name: clang (jessie) - if: ${{ matrix.os == 'debian-jessie' }} -- env: -- CC: clang -- run: make READLINE=libreadline test -+ uses: mosteo-actions/docker-run@v1 -+ with: -+ image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} -+ params: -e CC=clang -+ command: -j -Orecurse READLINE=libreadline test - - root-test: - runs-on: ubuntu-22.04 -@@ -103,10 +112,10 @@ jobs: - with: - name: native-${{ matrix.os }} - - name: unpack binary archive -- run: cpio -idv < native-${{ matrix.os }}/test-progs.cpio -+ run: cpio -idv < test-progs.cpio - if: ${{ matrix.os == 'opensuse-leap' }} - - name: unpack binary archive -- run: tar xfmv native-${{ matrix.os }}/test-progs.tar -+ run: tar xfmv test-progs.tar - if: ${{ matrix.os != 'opensuse-leap' }} - - - name: run root tests diff --git a/0003-libmultipath-include-urcu.h-before-urcu-atomic.h.patch b/0003-libmultipath-include-urcu.h-before-urcu-atomic.h.patch new file mode 100644 index 0000000..8da3ce7 --- /dev/null +++ b/0003-libmultipath-include-urcu.h-before-urcu-atomic.h.patch @@ -0,0 +1,40 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 11 Feb 2025 13:11:03 -0500 +Subject: [PATCH] libmultipath: include urcu.h before urcu/atomic.h + +urcu/atomic.h requires some header files included by urcu.h. Make sure +to include it first. + +Fixes: https://github.com/opensvc/multipath-tools/issues/112 +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/checkers/tur.c | 1 + + libmultipath/lock.h | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/libmultipath/checkers/tur.c b/libmultipath/checkers/tur.c +index e70a2e11..0010acf8 100644 +--- a/libmultipath/checkers/tur.c ++++ b/libmultipath/checkers/tur.c +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + #include + + #include "checkers.h" +diff --git a/libmultipath/lock.h b/libmultipath/lock.h +index 38473a8c..5f323055 100644 +--- a/libmultipath/lock.h ++++ b/libmultipath/lock.h +@@ -2,6 +2,7 @@ + #define LOCK_H_INCLUDED + + #include ++#include + #include + #include + diff --git a/0004-GitHub-workflows-native.yml-use-extra-job-for-clang.patch b/0004-GitHub-workflows-native.yml-use-extra-job-for-clang.patch deleted file mode 100644 index e6d618c..0000000 --- a/0004-GitHub-workflows-native.yml-use-extra-job-for-clang.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 13 Sep 2024 10:17:17 +0200 -Subject: [PATCH] GitHub workflows: native.yml: use extra job for clang - -Running "make" in a container and "make clean" outside doesn't -work (access right issues). So just use separate jobs. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/native.yaml | 18 ++++++++++++++++-- - 1 file changed, 16 insertions(+), 2 deletions(-) - -diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml -index 70d01c55..95b53b87 100644 ---- a/.github/workflows/native.yaml -+++ b/.github/workflows/native.yaml -@@ -68,8 +68,22 @@ jobs: - path: ${{ env.ARCHIVE_TGT }} - overwrite: true - -- - name: clean -- run: make clean -+ clang: -+ runs-on: ubuntu-22.04 -+ strategy: -+ fail-fast: false -+ matrix: -+ os: -+ - debian-jessie -+ - debian-buster -+ - debian-bullseye -+ - debian-bookworm -+ - fedora-40 -+ - opensuse-leap -+ steps: -+ - name: checkout -+ uses: actions/checkout@v1 -+ - - name: clang - if: ${{ matrix.os != 'debian-jessie' }} - uses: mosteo-actions/docker-run@v1 diff --git a/0004-libmpathutils-uxsock.c-Include-string.h-for-memcpy.patch b/0004-libmpathutils-uxsock.c-Include-string.h-for-memcpy.patch new file mode 100644 index 0000000..8fc3211 --- /dev/null +++ b/0004-libmpathutils-uxsock.c-Include-string.h-for-memcpy.patch @@ -0,0 +1,29 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Khem Raj +Date: Mon, 17 Feb 2025 12:05:03 -0800 +Subject: [PATCH] libmpathutils/uxsock.c: Include string.h for memcpy + +Fixes +uxsock.c:72:2: error: call to undeclared library function 'memcpy' with type 'void *(void *, const void *, unsigned long)'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] + +Signed-off-by: Khem Raj +Cc: Benjamin Marzinski +Cc: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmpathutil/uxsock.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/libmpathutil/uxsock.c b/libmpathutil/uxsock.c +index 2135476d..a474874e 100644 +--- a/libmpathutil/uxsock.c ++++ b/libmpathutil/uxsock.c +@@ -8,6 +8,7 @@ + #include + #include + #include ++#include + #include + #include + #include diff --git a/0005-GitHub-workflows-native.yaml-make-test-and-archive-s.patch b/0005-GitHub-workflows-native.yaml-make-test-and-archive-s.patch deleted file mode 100644 index cabfbcf..0000000 --- a/0005-GitHub-workflows-native.yaml-make-test-and-archive-s.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 13 Sep 2024 10:30:47 +0200 -Subject: [PATCH] GitHub workflows: native.yaml: make test and archive - separately - -Avoid "text file busy" error on GitHub. - -dmevents-test: Text file busy -Makefile:74: recipe for target 'dmevents.out' failed - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/native.yaml | 17 +++++++++++++++-- - 1 file changed, 15 insertions(+), 2 deletions(-) - -diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml -index 95b53b87..f06b09df 100644 ---- a/.github/workflows/native.yaml -+++ b/.github/workflows/native.yaml -@@ -52,14 +52,27 @@ jobs: - uses: mosteo-actions/docker-run@v1 - with: - image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} -- command: -j -Orecurse ${{ env.ARCHIVE_TGT }} test -+ command: -j -Orecurse test - - name: build and test (jessie) - # On jessie, we use libreadline 5 (no licensing issue) - if: ${{ matrix.os == 'debian-jessie' }} - uses: mosteo-actions/docker-run@v1 - with: - image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} -- command: -j -Orecurse READLINE=libreadline ${{ env.ARCHIVE_TGT }} test -+ command: -j -Orecurse READLINE=libreadline test -+ -+ - name: create ${{ env.ARCHIVE_TGT }} -+ if: ${{ matrix.os != 'debian-jessie' }} -+ uses: mosteo-actions/docker-run@v1 -+ with: -+ image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} -+ command: ${{ env.ARCHIVE_TGT }} -+ - name: create ${{ env.ARCHIVE_TGT }} (jessie) -+ if: ${{ matrix.os == 'debian-jessie' }} -+ uses: mosteo-actions/docker-run@v1 -+ with: -+ image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} -+ command: READLINE=libreadline ${{ env.ARCHIVE_TGT }} - - - name: upload binary archive - uses: actions/upload-artifact@v4 diff --git a/0033-RH-fixup-udev-rules-for-redhat.patch b/0005-RH-fixup-udev-rules-for-redhat.patch similarity index 98% rename from 0033-RH-fixup-udev-rules-for-redhat.patch rename to 0005-RH-fixup-udev-rules-for-redhat.patch index 0645240..0135f49 100644 --- a/0033-RH-fixup-udev-rules-for-redhat.patch +++ b/0005-RH-fixup-udev-rules-for-redhat.patch @@ -15,7 +15,7 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 729618bd..81cb61d2 100644 +index 65f6efc8..c225a1ed 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -34,7 +34,7 @@ endif diff --git a/0006-GitHub-workflows-enable-unit-tests-for-stable-branch.patch b/0006-GitHub-workflows-enable-unit-tests-for-stable-branch.patch deleted file mode 100644 index 4a9b254..0000000 --- a/0006-GitHub-workflows-enable-unit-tests-for-stable-branch.patch +++ /dev/null @@ -1,133 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 14 Nov 2024 16:02:38 +0100 -Subject: [PATCH] GitHub workflows: enable unit tests for stable branches - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/build-and-unittest.yaml | 2 ++ - .github/workflows/foreign.yaml | 2 ++ - .github/workflows/multiarch-stable.yaml | 2 ++ - .github/workflows/multiarch.yaml | 2 ++ - .github/workflows/native.yaml | 2 ++ - .github/workflows/rolling.yaml | 2 ++ - 6 files changed, 12 insertions(+) - -diff --git a/.github/workflows/build-and-unittest.yaml b/.github/workflows/build-and-unittest.yaml -index a838f9a2..1a727e14 100644 ---- a/.github/workflows/build-and-unittest.yaml -+++ b/.github/workflows/build-and-unittest.yaml -@@ -5,10 +5,12 @@ on: - - master - - queue - - tip -+ - 'stable-*' - pull_request: - branches: - - master - - queue -+ - 'stable-*' - jobs: - jammy: - runs-on: ubuntu-22.04 -diff --git a/.github/workflows/foreign.yaml b/.github/workflows/foreign.yaml -index d68650df..0f80957b 100644 ---- a/.github/workflows/foreign.yaml -+++ b/.github/workflows/foreign.yaml -@@ -5,6 +5,7 @@ on: - - master - - queue - - tip -+ - 'stable-*' - paths: - - '.github/workflows/foreign.yaml' - - '**.h' -@@ -15,6 +16,7 @@ on: - branches: - - master - - queue -+ - 'stable-*' - paths: - - '.github/workflows/foreign.yaml' - - '**.h' -diff --git a/.github/workflows/multiarch-stable.yaml b/.github/workflows/multiarch-stable.yaml -index e51d383c..ffede53d 100644 ---- a/.github/workflows/multiarch-stable.yaml -+++ b/.github/workflows/multiarch-stable.yaml -@@ -5,6 +5,7 @@ on: - - master - - queue - - tip -+ - 'stable-*' - paths: - - '.github/workflows/multiarch-stable.yaml' - - '**.h' -@@ -15,6 +16,7 @@ on: - branches: - - master - - queue -+ - 'stable-*' - paths: - - '.github/workflows/multiarch-stable.yaml' - - '**.h' -diff --git a/.github/workflows/multiarch.yaml b/.github/workflows/multiarch.yaml -index df95a02f..d2b833a4 100644 ---- a/.github/workflows/multiarch.yaml -+++ b/.github/workflows/multiarch.yaml -@@ -5,6 +5,7 @@ on: - - master - - queue - - tip -+ - 'stable-*' - paths: - - '.github/workflows/multiarch.yaml' - - '**.h' -@@ -15,6 +16,7 @@ on: - branches: - - master - - queue -+ - 'stable-*' - paths: - - '.github/workflows/multiarch.yaml' - - '**.h' -diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml -index f06b09df..c9d9df9e 100644 ---- a/.github/workflows/native.yaml -+++ b/.github/workflows/native.yaml -@@ -5,6 +5,7 @@ on: - - master - - queue - - tip -+ - 'stable-*' - paths: - - '.github/workflows/native.yaml' - - '**.h' -@@ -15,6 +16,7 @@ on: - branches: - - master - - queue -+ - 'stable-*' - paths: - - '.github/workflows/native.yaml' - - '**.h' -diff --git a/.github/workflows/rolling.yaml b/.github/workflows/rolling.yaml -index 3536b944..66af7a44 100644 ---- a/.github/workflows/rolling.yaml -+++ b/.github/workflows/rolling.yaml -@@ -5,6 +5,7 @@ on: - - master - - queue - - tip -+ - 'stable-*' - paths: - - '.github/workflows/rolling.yaml' - - '**.h' -@@ -15,6 +16,7 @@ on: - branches: - - master - - queue -+ - 'stable-*' - paths: - - '.github/workflows/rolling.yaml' - - '**.h' diff --git a/0034-RH-Remove-the-property-blacklist-exception-builtin.patch b/0006-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 100% rename from 0034-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0006-RH-Remove-the-property-blacklist-exception-builtin.patch diff --git a/0007-GitHub-Workflows-add-abi-check-for-stable-branches.patch b/0007-GitHub-Workflows-add-abi-check-for-stable-branches.patch deleted file mode 100644 index c19980f..0000000 --- a/0007-GitHub-Workflows-add-abi-check-for-stable-branches.patch +++ /dev/null @@ -1,110 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 14 Nov 2024 16:51:05 +0100 -Subject: [PATCH] GitHub Workflows: add abi check for stable branches - -The ABI should never change on a stable branch. This workflow -asserts that. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/abi-stable.yaml | 89 +++++++++++++++++++++++++++++++ - 1 file changed, 89 insertions(+) - create mode 100644 .github/workflows/abi-stable.yaml - -diff --git a/.github/workflows/abi-stable.yaml b/.github/workflows/abi-stable.yaml -new file mode 100644 -index 00000000..a6746f23 ---- /dev/null -+++ b/.github/workflows/abi-stable.yaml -@@ -0,0 +1,89 @@ -+name: check-abi for stable branch -+on: -+ push: -+ branches: -+ - 'stable-*' -+ paths: -+ - '.github/workflows/abi-stable.yaml' -+ - '**.h' -+ - '**.c' -+ - '**.version' -+ pull_request: -+ branches: -+ - 'stable-*' -+ workflow_dispatch: -+ -+jobs: -+ reference-abi: -+ runs-on: ubuntu-20.04 -+ steps: -+ - name: get parent tag -+ run: > -+ echo ${{ github.ref }} | -+ sed -E 's,refs/heads/stable-([0-9]\.[0-9]*)\.y,PARENT_TAG=\1.0,' >> $GITHUB_ENV -+ - name: assert parent tag -+ run: /bin/false -+ if: ${{ env.PARENT_TAG == '' }} -+ - name: update -+ run: sudo apt-get update -+ - name: dependencies -+ run: > -+ sudo apt-get install --yes gcc -+ gcc make pkg-config abigail-tools -+ libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev -+ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev -+ - name: checkout ${{ env.PARENT_TAG }} -+ uses: actions/checkout@v4 -+ with: -+ ref: ${{ env.PARENT_TAG }} -+ - name: build ABI for ${{ env.PARENT_TAG }} -+ run: make -j$(grep -c ^processor /proc/cpuinfo) -Orecurse abi -+ - name: save ABI -+ uses: actions/upload-artifact@v4 -+ with: -+ name: multipath-abi-${{ env.PARENT_TAG }} -+ path: abi -+ -+ check-abi: -+ runs-on: ubuntu-20.04 -+ needs: reference-abi -+ steps: -+ - name: get parent tag -+ run: > -+ echo ${{ github.ref }} | -+ sed -E 's,refs/heads/stable-([0-9]\.[0-9]*)\.y,PARENT_TAG=\1.0,' >> $GITHUB_ENV -+ - name: assert parent tag -+ run: /bin/false -+ if: ${{ env.PARENT_TAG == '' }} -+ - name: checkout ${{ env.PARENT_TAG }} -+ uses: actions/checkout@v4 -+ with: -+ ref: ${{ env.PARENT_TAG }} -+ - name: download ABI for ${{ env.PARENT_TAG }} -+ id: download_abi -+ uses: actions/download-artifact@v4 -+ with: -+ name: multipath-abi-${{ env.PARENT_TAG }} -+ path: reference-abi -+ - name: update -+ run: sudo apt-get update -+ if: steps.download_abi.outcome != 'success' -+ - name: dependencies -+ run: > -+ sudo apt-get install --yes gcc -+ gcc make pkg-config abigail-tools -+ libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev -+ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev -+ - name: check ABI of ${{ github.ref }} against ${{ env.PARENT_TAG }} -+ id: check_abi -+ run: make -j$(grep -c ^processor /proc/cpuinfo) -Orecurse abi-test -+ continue-on-error: true -+ - name: save differences -+ if: ${{ steps.check_abi.outcome != 'success' }} -+ uses: actions/upload-artifact@v4 -+ with: -+ name: abi-test -+ path: abi-test -+ - name: fail -+ run: /bin/false -+ if: steps.check_abi.outcome != 'success' diff --git a/0035-RH-don-t-start-without-a-config-file.patch b/0007-RH-don-t-start-without-a-config-file.patch similarity index 96% rename from 0035-RH-don-t-start-without-a-config-file.patch rename to 0007-RH-don-t-start-without-a-config-file.patch index 8a3c5b6..edbc647 100644 --- a/0035-RH-don-t-start-without-a-config-file.patch +++ b/0007-RH-don-t-start-without-a-config-file.patch @@ -22,10 +22,10 @@ Signed-off-by: Benjamin Marzinski 7 files changed, 25 insertions(+) diff --git a/libmultipath/config.c b/libmultipath/config.c -index 226ddecb..588ae9ee 100644 +index 8b424d18..b8317f4d 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c -@@ -962,6 +962,19 @@ int init_config__ (const char *file, struct config *conf) +@@ -937,6 +937,19 @@ int init_config__ (const char *file, struct config *conf) } factorize_hwtable(conf->hwtable, builtin_hwtable_size, file); validate_pctable(conf->overrides, 0, file); @@ -46,7 +46,7 @@ index 226ddecb..588ae9ee 100644 conf->processed_main_config = 1; diff --git a/libmultipath/config.h b/libmultipath/config.h -index 94cdf252..534b6142 100644 +index 5b4ebf8c..2302eacc 100644 --- a/libmultipath/config.h +++ b/libmultipath/config.h @@ -10,6 +10,7 @@ @@ -112,7 +112,7 @@ index 7bc8806e..315884eb 100644 . .\" ---------------------------------------------------------------------------- diff --git a/multipathd/multipathd.service.in b/multipathd/multipathd.service.in -index 646001e6..72e44849 100644 +index b6a25b31..3d957733 100644 --- a/multipathd/multipathd.service.in +++ b/multipathd/multipathd.service.in @@ -6,6 +6,7 @@ Wants=systemd-udevd-kernel.socket @MODPROBE_UNIT@ diff --git a/0036-RH-Fix-nvme-function-missing-argument.patch b/0008-RH-Fix-nvme-function-missing-argument.patch similarity index 100% rename from 0036-RH-Fix-nvme-function-missing-argument.patch rename to 0008-RH-Fix-nvme-function-missing-argument.patch diff --git a/0008-libmultipath-dm_get_maps-don-t-bail-out-for-single-m.patch b/0008-libmultipath-dm_get_maps-don-t-bail-out-for-single-m.patch deleted file mode 100644 index 88122b0..0000000 --- a/0008-libmultipath-dm_get_maps-don-t-bail-out-for-single-m.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 12 Nov 2024 13:06:10 +0100 -Subject: [PATCH] libmultipath: dm_get_maps(): don't bail out for single-map - failures - -dm_get_maps() traverses the entire list of dm maps. We shouldn't -give up just because probing a single map failed. - -Fixes: bf3a4ad ("libmultipath: simplify dm_get_maps()") -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/devmapper.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index c497c225..52bfe9ce 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -1262,10 +1262,8 @@ int dm_get_maps(vector mp) - } - vector_set_slot(mp, mpp); - break; -- case DMP_NO_MATCH: -- break; - default: -- return 1; -+ break; - } - next = names->next; - names = (void *) names + next; diff --git a/0009-11-dm-mpath.rules.in-import-DM_COLDPLUG_SUSPENDED-on.patch b/0009-11-dm-mpath.rules.in-import-DM_COLDPLUG_SUSPENDED-on.patch deleted file mode 100644 index b380f75..0000000 --- a/0009-11-dm-mpath.rules.in-import-DM_COLDPLUG_SUSPENDED-on.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 31 Oct 2024 12:08:08 +0100 -Subject: [PATCH] 11-dm-mpath.rules.in: import DM_COLDPLUG_SUSPENDED only once - -We import DM_COLDPLUG_SUSPENDED in all code flows below mpath_coldplug_end. -Clarify this in the code. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/11-dm-mpath.rules.in | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in -index 30647b99..67838261 100644 ---- a/multipath/11-dm-mpath.rules.in -+++ b/multipath/11-dm-mpath.rules.in -@@ -24,12 +24,13 @@ ENV{DM_UDEV_RULES_VSN}=="1|2", ENV{.DM_SUSPENDED}!="1", ENV{DISK_RO}!="1", \ - ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="", GOTO="scan_import" - LABEL="mpath_coldplug_end" - -+IMPORT{db}="DM_COLDPLUG_SUSPENDED" -+ - # If this uevent didn't come from dm, don't try to update the - # device state - # Note that .MPATH_DEVICE_READY_OLD=="" here. Thus we won't activate the - # device below at mpath_is_ready, which is correct. - ENV{DM_COOKIE}!="?*", ENV{DM_ACTION}!="PATH_*", \ -- IMPORT{db}="DM_COLDPLUG_SUSPENDED", \ - GOTO="check_mpath_ready" - - ENV{.MPATH_DEVICE_READY_OLD}="$env{MPATH_DEVICE_READY}" -@@ -67,7 +68,6 @@ LABEL="check_mpath_unchanged" - # A previous coldplug event occurred while the device was suspended. - # Activation might have been partially skipped. Activate the device now, - # i.e. disable the MPATH_UNCHANGED logic and set DM_ACTIVATION=1. --IMPORT{db}="DM_COLDPLUG_SUSPENDED" - ENV{DM_COLDPLUG_SUSPENDED}=="1", ENV{.DM_SUSPENDED}!="1", \ - ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0", \ - PROGRAM="@SYSDIR_BIN@/logger -t 11-dm-mpath.rules -p daemon.notice \"Forcing activation of previously suspended device\"", \ diff --git a/0037-RH-use-rpm-optflags-if-present.patch b/0009-RH-use-rpm-optflags-if-present.patch similarity index 92% rename from 0037-RH-use-rpm-optflags-if-present.patch rename to 0009-RH-use-rpm-optflags-if-present.patch index 66d14bc..1b96a3a 100644 --- a/0037-RH-use-rpm-optflags-if-present.patch +++ b/0009-RH-use-rpm-optflags-if-present.patch @@ -7,14 +7,13 @@ Use the passed in optflags when compiling as an RPM, and keep the default flags as close as possible to the current fedora flags, while still being generic. -Co-authored-by: Yaakov Selkowitz Signed-off-by: Benjamin Marzinski --- Makefile.inc | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 81cb61d2..a5024bb7 100644 +index c225a1ed..7774f1f4 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -99,28 +99,39 @@ SYSTEMD_LIBDEPS := $(if $(SYSTEMD),$(if $(shell test $(SYSTEMD) -gt 209 && echo @@ -53,9 +52,9 @@ index 81cb61d2..a5024bb7 100644 -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(TGTDIR)$(configdir)\" \ -DDEFAULT_CONFIGFILE=\"$(TGTDIR)$(configfile)\" -DSTATE_DIR=\"$(TGTDIR)$(statedir)\" \ -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP --CFLAGS := -std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ +-CFLAGS := -std=$(C_STD) $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ - -fexceptions -+CFLAGS := -std=gnu11 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe ++CFLAGS := -std=$(C_STD) $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe BIN_CFLAGS := -fPIE -DPIE LIB_CFLAGS := -fPIC SHARED_FLAGS := -shared diff --git a/0010-11-dm-mpath.rules.in-handle-inactive-suspended-devic.patch b/0010-11-dm-mpath.rules.in-handle-inactive-suspended-devic.patch deleted file mode 100644 index f34e699..0000000 --- a/0010-11-dm-mpath.rules.in-handle-inactive-suspended-devic.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 31 Oct 2024 12:59:03 +0100 -Subject: [PATCH] 11-dm-mpath.rules.in: handle inactive suspended devices - correctly - -Since b22c273 ("11-dm-mpath.rules: Don't force activation while device is -suspended"), we've handled the case where a device is suspended while -an uevent is processed (e.g. because multipathd is reloading the -map again at the same time). But we were missing the case where -The device had never been initialized before. If .MPATH_DEVICE_READY_OLD -was empty, we'd jump to scan_import without setting MPATH_DEVICE_READY -to 0. This can cause a device not to be fully activated at boot time, -because in follow-up uevents we'd assume that the device had already -been set up. - -Treat the case in which an uevent is processed for a previously not -fully set-up, suspended device like other situations where we set -MPATH_DEVICE_READY to 0. - -Fixes: b22c273 ("11-dm-mpath.rules: Don't force activation while device is -suspended") -Reviewed-by: Benjamin Marzinski - -Signed-off-by: Benjamin Marzinski ---- - multipath/11-dm-mpath.rules.in | 19 +++++++++++-------- - 1 file changed, 11 insertions(+), 8 deletions(-) - -diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in -index 67838261..20f8c6ac 100644 ---- a/multipath/11-dm-mpath.rules.in -+++ b/multipath/11-dm-mpath.rules.in -@@ -35,6 +35,13 @@ ENV{DM_COOKIE}!="?*", ENV{DM_ACTION}!="PATH_*", \ - - ENV{.MPATH_DEVICE_READY_OLD}="$env{MPATH_DEVICE_READY}" - -+# If the device wasn't ready previously and is currently suspended, -+# we have to postpone the activation until the next event. -+# In this case, we have to set MPATH_DEVICE_READY=0; otherwise, the -+# MPATH_UNCHANGED logic will cause later rules to skipped in the next event. -+ENV{.MPATH_DEVICE_READY_OLD}!="1", ENV{.DM_SUSPENDED}=="1", \ -+ ENV{MPATH_DEVICE_READY}="0", GOTO="check_mpath_unchanged" -+ - # multipath sets DM_SUBSYSTEM_UDEV_FLAG2 when it reloads a - # table with no active devices. If this happens, mark the - # device not ready -@@ -106,14 +113,10 @@ GOTO="scan_import" - LABEL="mpath_is_ready" - - # If the device comes back online, set DM_ACTIVATION so that --# upper layers do a rescan. If the device is currently suspended, --# we have to postpone the activation until the next event. --# In this case, we have to set MPATH_DEVICE_READY=0; otherwise, the --# MPATH_UNCHANGED logic will cause later rules to skipped in the next event. --ENV{.MPATH_DEVICE_READY_OLD}!="0", GOTO="scan_import" --ENV{.DM_SUSPENDED}=="1", ENV{MPATH_DEVICE_READY}="0", GOTO="scan_import" -- --ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0" -+# upper layers will do a rescan. Don't do this if .MPATH_DEVICE_READY_OLD -+# is just empty (see comment above the DM_COOKIE test above). -+ENV{.MPATH_DEVICE_READY_OLD}=="0", \ -+ ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0" - - # The code to check multipath state ends here. We need to set - # properties and symlinks regardless whether the map is usable or diff --git a/0038-RH-add-mpathconf.patch b/0010-RH-add-mpathconf.patch similarity index 99% rename from 0038-RH-add-mpathconf.patch rename to 0010-RH-add-mpathconf.patch index 103ca55..c587841 100644 --- a/0038-RH-add-mpathconf.patch +++ b/0010-RH-add-mpathconf.patch @@ -23,10 +23,10 @@ Signed-off-by: Benjamin Marzinski create mode 100644 multipath/mpathconf.8 diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt -index 4ac57510..3602a071 100644 +index 7843c380..ab5259cf 100644 --- a/.github/actions/spelling/expect.txt +++ b/.github/actions/spelling/expect.txt -@@ -126,9 +126,11 @@ Marzinski +@@ -127,9 +127,11 @@ Marzinski misdetection mpath mpathb @@ -38,7 +38,7 @@ index 4ac57510..3602a071 100644 multipathc multipathd multipathed -@@ -146,6 +148,7 @@ ontap +@@ -147,6 +149,7 @@ ontap OOM opensvc OPTFLAGS @@ -47,10 +47,10 @@ index 4ac57510..3602a071 100644 partx pathgroup diff --git a/libmultipath/config.c b/libmultipath/config.c -index 588ae9ee..3cb8449c 100644 +index b8317f4d..0bbaa981 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c -@@ -964,6 +964,8 @@ int init_config__ (const char *file, struct config *conf) +@@ -939,6 +939,8 @@ int init_config__ (const char *file, struct config *conf) validate_pctable(conf->overrides, 0, file); } else { condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices."); diff --git a/0011-11-dm-mpath.rules.in-clarify-DM_ACTIVATION-logic.patch b/0011-11-dm-mpath.rules.in-clarify-DM_ACTIVATION-logic.patch deleted file mode 100644 index cb129bf..0000000 --- a/0011-11-dm-mpath.rules.in-clarify-DM_ACTIVATION-logic.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 31 Oct 2024 13:11:21 +0100 -Subject: [PATCH] 11-dm-mpath.rules.in: clarify DM_ACTIVATION logic - -Our code is always setting MPATH_UNCHANGED and DM_ACTIVATION in -pairs. While DM_ACTIVATION is a global DM property, MPATH_UNCHANGED -is owned by us. Just set MPATH_UNCHANGED, and adapt DM_ACTIVATION -when necessary just in one place. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/11-dm-mpath.rules.in | 21 ++++++++++++--------- - 1 file changed, 12 insertions(+), 9 deletions(-) - -diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in -index 20f8c6ac..a2655cb2 100644 ---- a/multipath/11-dm-mpath.rules.in -+++ b/multipath/11-dm-mpath.rules.in -@@ -74,25 +74,25 @@ LABEL="check_mpath_unchanged" - - # A previous coldplug event occurred while the device was suspended. - # Activation might have been partially skipped. Activate the device now, --# i.e. disable the MPATH_UNCHANGED logic and set DM_ACTIVATION=1. -+# i.e. disable the MPATH_UNCHANGED logic. - ENV{DM_COLDPLUG_SUSPENDED}=="1", ENV{.DM_SUSPENDED}!="1", \ -- ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0", \ -+ ENV{MPATH_UNCHANGED}="0", \ - PROGRAM="@SYSDIR_BIN@/logger -t 11-dm-mpath.rules -p daemon.notice \"Forcing activation of previously suspended device\"", \ - GOTO="check_mpath_ready" - - # DM_SUBSYSTEM_UDEV_FLAG0 is the "RELOAD" flag for multipath subsystem. --# Drop the DM_ACTIVATION flag here as mpath reloads tables if any of its -+# Set the MPATH_UNCHANGED flag here as mpath reloads tables if any of its - # paths are lost/recovered. For any stack above the mpath device, this is not - # something that should be reacted upon since it would be useless extra work. - # It's exactly mpath's job to provide *seamless* device access to any of the - # paths that are available underneath. - ENV{DM_SUBSYSTEM_UDEV_FLAG0}=="1", \ -- ENV{DM_ACTIVATION}="0", ENV{MPATH_UNCHANGED}="1" -+ ENV{MPATH_UNCHANGED}="1" - --# For path failed or reinstated events, unset DM_ACTIVATION. -+# For path failed or reinstated events, set MPATH_UNCHANGED. - # This is similar to the DM_SUBSYSTEM_UDEV_FLAG0 case above. - ENV{DM_ACTION}=="PATH_FAILED|PATH_REINSTATED", \ -- ENV{DM_ACTIVATION}="0", ENV{MPATH_UNCHANGED}="1" -+ ENV{MPATH_UNCHANGED}="1" - - LABEL="check_mpath_ready" - -@@ -112,11 +112,10 @@ GOTO="scan_import" - - LABEL="mpath_is_ready" - --# If the device comes back online, set DM_ACTIVATION so that -+# If the device comes back online, clear MPATH_UNCHANGED so that - # upper layers will do a rescan. Don't do this if .MPATH_DEVICE_READY_OLD - # is just empty (see comment above the DM_COOKIE test above). --ENV{.MPATH_DEVICE_READY_OLD}=="0", \ -- ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0" -+ENV{.MPATH_DEVICE_READY_OLD}=="0", ENV{MPATH_UNCHANGED}="0" - - # The code to check multipath state ends here. We need to set - # properties and symlinks regardless whether the map is usable or -@@ -146,6 +145,10 @@ IMPORT{db}="ID_PART_GPT_AUTO_ROOT" - - LABEL="import_end" - -+# If MPATH_UNCHANGED is set, adapt DM_ACTIVATION. -+ENV{MPATH_UNCHANGED}=="0", ENV{DM_ACTIVATION}="1" -+ENV{MPATH_UNCHANGED}=="1", ENV{DM_ACTIVATION}="0" -+ - # Reset previous DM_COLDPLUG_SUSPENDED if activation happens now - ENV{.DM_SUSPENDED}!="1", ENV{DM_ACTIVATION}=="1", ENV{DM_COLDPLUG_SUSPENDED}="" - diff --git a/0039-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0011-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 97% rename from 0039-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0011-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch index 4e781fa..612d876 100644 --- a/0039-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +++ b/0011-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch @@ -138,14 +138,14 @@ index b88e9a4c..edd742aa 100644 Remove the WWID for the specified device from the WWIDs file. . diff --git a/multipathd/multipathd.service.in b/multipathd/multipathd.service.in -index 72e44849..69a6c39d 100644 +index 3d957733..7ef6e99e 100644 --- a/multipathd/multipathd.service.in +++ b/multipathd/multipathd.service.in -@@ -17,6 +17,7 @@ ConditionVirtualization=!container +@@ -19,6 +19,7 @@ StartLimitBurst=3 [Service] Type=notify NotifyAccess=main +ExecStartPre=-@BINDIR@/multipath -A ExecStart=@BINDIR@/multipathd -d -s ExecReload=@BINDIR@/multipathd reconfigure - TasksMax=infinity + Restart=on-failure diff --git a/0012-11-dm-mpath-rules.in-skip-one-.DM_NOSCAN-check.patch b/0012-11-dm-mpath-rules.in-skip-one-.DM_NOSCAN-check.patch deleted file mode 100644 index cb1620a..0000000 --- a/0012-11-dm-mpath-rules.in-skip-one-.DM_NOSCAN-check.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Sun, 3 Nov 2024 23:04:08 +0100 -Subject: [PATCH] 11-dm-mpath-rules.in: skip one .DM_NOSCAN check - -We set .DM_NOSCAN above where we set DM_UDEV_DISABLE_OTHER_RULES_FLAG, too. If -the latter isn't set, .DM_NOSCAN can't be set. Skip the redundant test. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/11-dm-mpath.rules.in | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in -index a2655cb2..79227bec 100644 ---- a/multipath/11-dm-mpath.rules.in -+++ b/multipath/11-dm-mpath.rules.in -@@ -132,7 +132,7 @@ ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}!="1", GOTO="import_end" - ENV{DM_UDEV_RULES_VSN}!="1|2", GOTO="import_end" - - # Don't import the properties from db if we will run blkid later. --ENV{.DM_NOSCAN}!="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}!="1", GOTO="import_end" -+ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}!="1", GOTO="import_end" - - IMPORT{db}="ID_FS_TYPE" - IMPORT{db}="ID_FS_USAGE" diff --git a/0040-RH-reset-default-find_mutipaths-value-to-off.patch b/0012-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 100% rename from 0040-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0012-RH-reset-default-find_mutipaths-value-to-off.patch diff --git a/0013-11-dm-mpath.rules.in-set-.DM_NOSCAN-if-MPATH_UNCHANG.patch b/0013-11-dm-mpath.rules.in-set-.DM_NOSCAN-if-MPATH_UNCHANG.patch deleted file mode 100644 index 36cd91d..0000000 --- a/0013-11-dm-mpath.rules.in-set-.DM_NOSCAN-if-MPATH_UNCHANG.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Sun, 3 Nov 2024 23:07:23 +0100 -Subject: [PATCH] 11-dm-mpath.rules.in: set .DM_NOSCAN if MPATH_UNCHANGED is - set - -When multipath reloads a device or fails or restores a path, the udev -rules disable LVM scanning, but since .DM_NOSCAN isn't set, blkid is -still run on the device. When multipath devices that are set to -queue_if_no_path lose all their paths at close to the same time, udev -workers can hang trying to run blkid. The blkid results shouldn't -change when multipathd is adding, removing, failing or reinstating -paths, aside from avoiding hanging udev processes, we're skipping -unnecessary work. - -Hence, set .DM_NOSCAN if MPATH_UNCHANGED is set, to avoid blkid from -being called in 13-dm.rules. - -Suggested-by: Benjamin Marzinski -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/11-dm-mpath.rules.in | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in -index 79227bec..a816edbf 100644 ---- a/multipath/11-dm-mpath.rules.in -+++ b/multipath/11-dm-mpath.rules.in -@@ -145,9 +145,11 @@ IMPORT{db}="ID_PART_GPT_AUTO_ROOT" - - LABEL="import_end" - --# If MPATH_UNCHANGED is set, adapt DM_ACTIVATION. -+# If MPATH_UNCHANGED is set, adapt DM_ACTIVATION and DM_NOSCAN. -+# .DM_NOSCAN controls whether blkid will be run in 13-dm-disk.rules; -+# we don't want to do that if MPATH_UNCHANGED is 1. - ENV{MPATH_UNCHANGED}=="0", ENV{DM_ACTIVATION}="1" --ENV{MPATH_UNCHANGED}=="1", ENV{DM_ACTIVATION}="0" -+ENV{MPATH_UNCHANGED}=="1", ENV{DM_ACTIVATION}="0", ENV{.DM_NOSCAN}="1" - - # Reset previous DM_COLDPLUG_SUSPENDED if activation happens now - ENV{.DM_SUSPENDED}!="1", ENV{DM_ACTIVATION}=="1", ENV{DM_COLDPLUG_SUSPENDED}="" diff --git a/0041-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0013-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 100% rename from 0041-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0013-RH-attempt-to-get-ANA-info-via-sysfs-first.patch diff --git a/0042-RH-make-parse_vpd_pg83-match-scsi_id-output.patch b/0014-RH-make-parse_vpd_pg83-match-scsi_id-output.patch similarity index 94% rename from 0042-RH-make-parse_vpd_pg83-match-scsi_id-output.patch rename to 0014-RH-make-parse_vpd_pg83-match-scsi_id-output.patch index 0d5baa3..3243375 100644 --- a/0042-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +++ b/0014-RH-make-parse_vpd_pg83-match-scsi_id-output.patch @@ -14,10 +14,10 @@ Signed-off-by: Benjamin Marzinski 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 5043330c..e14507e8 100644 +index b5851561..a3cc6e83 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c -@@ -1221,13 +1221,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, +@@ -1219,13 +1219,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, good_len = 8; break; case 2: @@ -33,7 +33,7 @@ index 5043330c..e14507e8 100644 good_len = 8; break; default: -@@ -1245,10 +1241,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, +@@ -1243,10 +1239,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, break; case 0x8: /* SCSI Name: Prio 3 */ diff --git a/0014-libmultipath-don-t-set-dev_loss_tmo-to-0-for-NO_PATH.patch b/0014-libmultipath-don-t-set-dev_loss_tmo-to-0-for-NO_PATH.patch deleted file mode 100644 index b7ae3c4..0000000 --- a/0014-libmultipath-don-t-set-dev_loss_tmo-to-0-for-NO_PATH.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 7 Nov 2024 22:07:03 +0100 -Subject: [PATCH] libmultipath: don't set dev_loss_tmo to 0 for - NO_PATH_RETRY_FAIL - -If pp->dev_loss is DEV_LOSS_TMO_UNSET and min_dev_loss is 0 (which is -the case if no_path_retry is NO_PATH_RETRY_FAIL or NO_PATH_RETRY_UNDEF), -we will set pp->dev_loss to 0, which is wrong. Fix it. - -Fixes: 058b5f5 ("libmultipath: fix dev_loss_tmo even if not set in configuration") -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/discovery.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index e94705bf..5043330c 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -942,7 +942,7 @@ sysfs_set_scsi_tmo (struct config *conf, struct multipath *mpp) - continue; - } - -- if (pp->dev_loss == DEV_LOSS_TMO_UNSET) -+ if (pp->dev_loss == DEV_LOSS_TMO_UNSET && min_dev_loss != 0) - pp->dev_loss = min_dev_loss; - else if (pp->dev_loss < min_dev_loss) { - pp->dev_loss = min_dev_loss; diff --git a/0043-RH-add-scsi-device-handlers-to-modules-load.d.patch b/0015-RH-add-scsi-device-handlers-to-modules-load.d.patch similarity index 96% rename from 0043-RH-add-scsi-device-handlers-to-modules-load.d.patch rename to 0015-RH-add-scsi-device-handlers-to-modules-load.d.patch index ef0ee42..97fb4df 100644 --- a/0043-RH-add-scsi-device-handlers-to-modules-load.d.patch +++ b/0015-RH-add-scsi-device-handlers-to-modules-load.d.patch @@ -11,7 +11,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc -index a5024bb7..834b63b9 100644 +index 7774f1f4..0e836f0a 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -16,7 +16,7 @@ READLINE := diff --git a/0015-multipathd-fix-deferred_failback_tick-for-reload-rem.patch b/0015-multipathd-fix-deferred_failback_tick-for-reload-rem.patch deleted file mode 100644 index f775e85..0000000 --- a/0015-multipathd-fix-deferred_failback_tick-for-reload-rem.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 14 Oct 2024 23:28:30 -0400 -Subject: [PATCH] multipathd: fix deferred_failback_tick for reload removes - -If reload_and_sync_map() removes the multipath device, -deferred_failback_tick() needs to decrement the counter so that it -doesn't skip the following device. - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 1b7fd04f..e4ef9a1d 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -2080,9 +2080,12 @@ deferred_failback_tick (struct vectors *vecs) - - if (!mpp->failback_tick && - need_switch_pathgroup(mpp, &need_reload)) { -- if (need_reload) -- reload_and_sync_map(mpp, vecs); -- else -+ if (need_reload) { -+ if (reload_and_sync_map(mpp, vecs) == 2) { -+ /* multipath device removed */ -+ i--; -+ } -+ } else - switch_pathgroup(mpp); - } - } diff --git a/0044-RH-compile-with-libreadline-support.patch b/0016-RH-compile-with-libreadline-support.patch similarity index 96% rename from 0044-RH-compile-with-libreadline-support.patch rename to 0016-RH-compile-with-libreadline-support.patch index 50781c3..e7579b0 100644 --- a/0044-RH-compile-with-libreadline-support.patch +++ b/0016-RH-compile-with-libreadline-support.patch @@ -12,7 +12,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc -index 834b63b9..c482a181 100644 +index 0e836f0a..e1d3fcd1 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -12,7 +12,7 @@ diff --git a/0016-multipathd-fix-an-unsigned-int-ovwerflow.patch b/0016-multipathd-fix-an-unsigned-int-ovwerflow.patch deleted file mode 100644 index 12c9a51..0000000 --- a/0016-multipathd-fix-an-unsigned-int-ovwerflow.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 13 Nov 2024 16:19:49 +0100 -Subject: [PATCH] multipathd: fix an unsigned int ovwerflow - -Reported by coverity: "i--" may cause an underflow, which will again -cause an overflow when the loop continues. Use a signed int for -loops like this to make coverity happy. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index e4ef9a1d..3fb623fd 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -2068,7 +2068,7 @@ static void - deferred_failback_tick (struct vectors *vecs) - { - struct multipath * mpp; -- unsigned int i; -+ int i; - bool need_reload; - - vector_foreach_slot (vecs->mpvec, mpp, i) { diff --git a/0045-RH-Add-mpathcleanup.patch b/0017-RH-Add-mpathcleanup.patch similarity index 100% rename from 0045-RH-Add-mpathcleanup.patch rename to 0017-RH-Add-mpathcleanup.patch diff --git a/0017-libmpathutil-avoid-Wcast-function-type-mismatch-erro.patch b/0017-libmpathutil-avoid-Wcast-function-type-mismatch-erro.patch deleted file mode 100644 index 64b90d7..0000000 --- a/0017-libmpathutil-avoid-Wcast-function-type-mismatch-erro.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 6 Nov 2024 22:17:16 +0100 -Subject: [PATCH] libmpathutil: avoid -Wcast-function-type-mismatch error with - clang 19 - -Avoid the following error with clang 19: - -msort.c:268:27: error: cast from '__compar_fn_t' (aka 'int (*)(const void *, const void *)') to '__compar_d_fn_t' (aka 'int (*)(const void *, const void *, void *)') converts to incompatible function type [-Werror,-Wcast-function-type-mismatch] - 268 | return msort_r (b, n, s, (__compar_d_fn_t)cmp, NULL); - | ^~~~~~~~~~~~~~~~~~~~ - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmpathutil/msort.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/libmpathutil/msort.c b/libmpathutil/msort.c -index 50f799d9..9df7b267 100644 ---- a/libmpathutil/msort.c -+++ b/libmpathutil/msort.c -@@ -259,9 +259,12 @@ msort_r (void *b, size_t n, size_t s, __compar_d_fn_t cmp, void *arg) - * If this is safe for them, it should be for us, too. - */ - #pragma GCC diagnostic push --#if __GNUC__ >= 8 -+#if __GNUC__ >= 8 || __clang_major__ >= 19 - #pragma GCC diagnostic ignored "-Wcast-function-type" - #endif -+#if __clang_major__ >= 19 -+#pragma GCC diagnostic ignored "-Wcast-function-type-mismatch" -+#endif - void - msort (void *b, size_t n, size_t s, __compar_fn_t cmp) - { diff --git a/0018-Update-NEWS.md-for-0.10.1.patch b/0018-Update-NEWS.md-for-0.10.1.patch deleted file mode 100644 index 601b6e5..0000000 --- a/0018-Update-NEWS.md-for-0.10.1.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 14 Nov 2024 17:59:14 +0100 -Subject: [PATCH] Update NEWS.md for 0.10.1 - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - NEWS.md | 23 +++++++++++++++++++++++ - 1 file changed, 23 insertions(+) - -diff --git a/NEWS.md b/NEWS.md -index 69acda47..b740efb1 100644 ---- a/NEWS.md -+++ b/NEWS.md -@@ -1,5 +1,28 @@ - # multipath-tools Release Notes - -+## multipath-tools 0.10.1, 2024/11 -+ -+This is the first bug fix release on the `stable-0.10.y` branch. It contains -+bug fixes from 0.11.0, and some CI-related fixes. -+ -+### Bug fixes -+ -+* Fixed the problem that multipathd wouldn't start on systems with certain types -+ of device mapper devices, in particular devices with multiple DM targets. -+ The problem was introduced in 0.10.0. -+ Fixes [#102](https://github.com/opensvc/multipath-tools/issues/102). -+* Fixed a corner case in the udev rules which could cause a device not to be -+ activated during boot if a cold plug uevent is processed for a previously -+ not configured multipath map while this map was suspended. This problem existed -+ since 0.9.8. -+* Fixed the problem that devices with `no_path_retry fail` and no setting -+ for `dev_loss_tmo` might get the `dev_loss_tmo` set to 0, causing the -+ device to be deleted immediately in the event of a transport disruption. -+ This bug was introduced in 0.9.6. -+* Fixed the problem that, if there were multiple maps with deferred failback -+ (`failback` value > 0 in `multipath.conf`), some maps might fail back later -+ than configured. The problem existed since 0.9.6. -+ - ## multipath-tools 0.10.0, 2024/08 - - ### User-Visible Changes diff --git a/0019-libmultipath-don-t-print-error-message-if-WATCHDOG_U.patch b/0019-libmultipath-don-t-print-error-message-if-WATCHDOG_U.patch deleted file mode 100644 index 18fb614..0000000 --- a/0019-libmultipath-don-t-print-error-message-if-WATCHDOG_U.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 14 Nov 2024 15:20:24 +0100 -Subject: [PATCH] libmultipath: don't print error message if WATCHDOG_USEC is 0 - -WATCHDOG_USEC may be set to 0, which means that the watchdog -is disabled in systemd. - -Fixes: 9366cfb ("multipathd: Implement systemd watchdog integration") -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/config.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/libmultipath/config.c b/libmultipath/config.c -index 0e3a5cc1..226ddecb 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -865,6 +865,9 @@ static void set_max_checkint_from_watchdog(struct config *conf) - unsigned long checkint; - - if (envp && sscanf(envp, "%lu", &checkint) == 1) { -+ if (checkint == 0) -+ /* watchdog disabled */ -+ return; - /* Value is in microseconds */ - checkint /= 1000000; - if (checkint < 1 || checkint > UINT_MAX) { diff --git a/0020-libmultipath-reduce-log-level-of-map-X-has-multiple-.patch b/0020-libmultipath-reduce-log-level-of-map-X-has-multiple-.patch deleted file mode 100644 index 7467627..0000000 --- a/0020-libmultipath-reduce-log-level-of-map-X-has-multiple-.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 25 Nov 2024 18:01:32 +0100 -Subject: [PATCH] libmultipath: reduce log level of "map X has multiple - targets" - -On systems with LVM volumes, "multipath -ll" will spit out lots of messages -like - - libmp_mapinfo: map vg-lv0 has multiple targets - -which is irritating. Reduce the log level of these messages to 3, as they -are harmless most of the time. - -This is a backport of e8949c2 ("libmultipath: reduce log level of -libmp_mapinfo() messages") from the master branch. We can't apply exactly -the same fix because the stable branch is missing 8c772d3 ("libmultipath: -check DM UUID earlier in libmp_mapinfo__"). - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/devmapper.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index 52bfe9ce..fe5637b3 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -718,7 +718,7 @@ static int libmp_mapinfo__(int flags, mapid_t id, mapinfo_t info, const char *ma - if (info.target || info.status || info.size || flags & MAPINFO_TGT_TYPE__) { - if (dm_get_next_target(dmt, NULL, &start, &length, - &target_type, ¶ms) != NULL) { -- condlog(2, "%s: map %s has multiple targets", fname__, map_id); -+ condlog(3, "%s: map %s has multiple targets", fname__, map_id); - return DMP_NOT_FOUND; - } - if (!params) { diff --git a/0021-libmultipath-foreign-fix-memory-leak-in-nvme-foreign.patch b/0021-libmultipath-foreign-fix-memory-leak-in-nvme-foreign.patch deleted file mode 100644 index 2610c6d..0000000 --- a/0021-libmultipath-foreign-fix-memory-leak-in-nvme-foreign.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 8 Jan 2025 19:06:53 -0500 -Subject: [PATCH] libmultipath/foreign: fix memory leak in nvme foreign handler - -_find_controllers() needs to free the udev device if it doesn't get -added to a path. Otherwise it can leak memory whenever check_foreign() -is called, causing multipathd's memory usage to continually grow. - -Fixes: 7b47762 ("libmultipath: nvme: fix path detection for kernel 4.16") -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck -(cherry picked from commit 5a3d334e416a4a35ee88d7b8f1433ff7f57923ad) ---- - libmultipath/foreign/nvme.c | 9 +++++---- - 1 file changed, 5 insertions(+), 4 deletions(-) - -diff --git a/libmultipath/foreign/nvme.c b/libmultipath/foreign/nvme.c -index 0b7f4eab..cde660ce 100644 ---- a/libmultipath/foreign/nvme.c -+++ b/libmultipath/foreign/nvme.c -@@ -675,7 +675,8 @@ static void _find_controllers(struct context *ctx, struct nvme_map *map) - pthread_cleanup_push_cast(free_scandir_result, &sr); - for (i = 0; i < r; i++) { - char *fn = di[i]->d_name; -- struct udev_device *ctrl, *udev; -+ struct udev_device *ctrl; -+ struct udev_device *udev __attribute__((cleanup(cleanup_udev_device))) = NULL; - - if (safe_snprintf(pathbuf + n, sizeof(pathbuf) - n, "/%s", fn)) - continue; -@@ -719,11 +720,11 @@ static void _find_controllers(struct context *ctx, struct nvme_map *map) - continue; - - path->gen.ops = &nvme_path_ops; -- path->udev = udev; -+ path->udev = steal_ptr(udev); - path->seen = true; - path->map = map; - path->ctl = udev_device_get_parent_with_subsystem_devtype -- (udev, "nvme", NULL); -+ (path->udev, "nvme", NULL); - if (path->ctl == NULL) { - condlog(1, "%s: %s: failed to get controller for %s", - __func__, THIS, fn); -@@ -744,7 +745,7 @@ static void _find_controllers(struct context *ctx, struct nvme_map *map) - } - vector_set_slot(&map->pgvec, &path->pg); - condlog(3, "%s: %s: new path %s added to %s", -- __func__, THIS, udev_device_get_sysname(udev), -+ __func__, THIS, udev_device_get_sysname(path->udev), - udev_device_get_sysname(map->udev)); - } - pthread_cleanup_pop(1); diff --git a/0022-libmultipath-add-condition-for-enqueueing-path-to-io.patch b/0022-libmultipath-add-condition-for-enqueueing-path-to-io.patch deleted file mode 100644 index cf8d80a..0000000 --- a/0022-libmultipath-add-condition-for-enqueueing-path-to-io.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: chenrenhui -Date: Fri, 10 Jan 2025 14:38:16 +0800 -Subject: [PATCH] libmultipath: add condition for enqueueing path to io error - check - -In function io_err_stat_handle_pathfail(), path->io_err_dis_reinstate_time -is set to 0 to enqueue path to io error check as soon as possible. But -multipathd can not do it within marginal_path_err_recheck_gap_time seconds -after power-on, because curr_time is less than -marginal_path_err_recheck_gap_time. - -To handle the early marginal path, we can enqueue path when -io_err_dis_reinstate_time is 0. - -Signed-off-by: chenrenhui -Reviewed-by: Benjamin Marzinski -Reviewed-by: Martin Wilck - -> - -(cherry picked from commit a1e3cf2d42cc4bab10753e466c8adb7efa83c99e) -Signed-off-by: Benjamin Marzinski ---- - libmultipath/io_err_stat.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/io_err_stat.c b/libmultipath/io_err_stat.c -index 4996c0b0..879c310a 100644 ---- a/libmultipath/io_err_stat.c -+++ b/libmultipath/io_err_stat.c -@@ -367,7 +367,8 @@ int need_io_err_check(struct path *pp) - return 1; - get_monotonic_time(&curr_time); - if ((curr_time.tv_sec - pp->io_err_dis_reinstate_time) > -- pp->mpp->marginal_path_err_recheck_gap_time) { -+ pp->mpp->marginal_path_err_recheck_gap_time || -+ pp->io_err_dis_reinstate_time == 0) { - io_err_stat_log(4, "%s: reschedule checking after %d seconds", - pp->dev, - pp->mpp->marginal_path_err_recheck_gap_time); diff --git a/0023-Additional-NEWS.md-updates-for-0.10.1.patch b/0023-Additional-NEWS.md-updates-for-0.10.1.patch deleted file mode 100644 index 1093bd0..0000000 --- a/0023-Additional-NEWS.md-updates-for-0.10.1.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 17 Jan 2025 22:38:26 +0100 -Subject: [PATCH] Additional NEWS.md updates for 0.10.1 - -Signed-off-by: Benjamin Marzinski ---- - .github/actions/spelling/expect.txt | 4 ++-- - NEWS.md | 8 ++++++++ - 2 files changed, 10 insertions(+), 2 deletions(-) - -diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt -index 934f582e..000d5ebb 100644 ---- a/.github/actions/spelling/expect.txt -+++ b/.github/actions/spelling/expect.txt -@@ -184,7 +184,6 @@ sas - sbp - scsi - sda --sdc - setmarginal - setprkey - setprstatus -@@ -205,11 +204,11 @@ suse - svg - switchgroup - sys -+SYSDIR - sysfs - sysinit - tcp - terabytes --SYSDIR - TESTDEPS - testname - tgill -@@ -231,6 +230,7 @@ unsetprkey - unsetprstatus - unspec - usb -+USEC - userdata - userspace - usr -diff --git a/NEWS.md b/NEWS.md -index b740efb1..3c51553e 100644 ---- a/NEWS.md -+++ b/NEWS.md -@@ -22,6 +22,14 @@ bug fixes from 0.11.0, and some CI-related fixes. - * Fixed the problem that, if there were multiple maps with deferred failback - (`failback` value > 0 in `multipath.conf`), some maps might fail back later - than configured. The problem existed since 0.9.6. -+* Removed a warning message that multipathd would print if systemd's -+ `WATCHDOG_USEC` environment variable had the value "0", which means that the -+ watchdog is simply disabled. This (minor) problem existed since 0.4.9. -+* Fixed a memory leak in the nvme foreign library. The bug existed since -+ 0.7.8. -+* Fixed a problem in the marginal path detection algorithm that could cause -+ the io error check for a recently failed path to be delayed. This bug -+ existed since 0.7.4. - - ## multipath-tools 0.10.0, 2024/08 - diff --git a/0024-libmultipath-fix-handling-of-pp-pgindex.patch b/0024-libmultipath-fix-handling-of-pp-pgindex.patch deleted file mode 100644 index a9da346..0000000 --- a/0024-libmultipath-fix-handling-of-pp-pgindex.patch +++ /dev/null @@ -1,138 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 25 Nov 2024 13:11:07 +0100 -Subject: [PATCH] libmultipath: fix handling of pp->pgindex - -pp->pgindex is set in disassemble_map() when a map is parsed. -There are various possiblities for this index to become invalid. -pp->pgindex is only used in enable_group() and followover_should_fallback(), -and both callers take no action if it is 0, which is the right -thing to do if we don't know the path's pathgroup. - -Make sure pp->pgindex is reset to 0 in various places: -- when it's orphaned, -- before (re)grouping paths, -- when we detect a bad mpp assignment in update_pathvec_from_dm(). -- when a pathgroup is deleted in update_pathvec_from_dm(). In this - case, pgindex needs to be invalidated for all paths in all pathgroups - after the one that was deleted. - -The hunk in group_paths is mostly redundant with the hunk in free_pgvec(), but -because we're looping over pg->paths in the former and over pg->pgp in -the latter, I think it's better too play safe. - -Fixes: 99db1bd ("[multipathd] re-enable disabled PG when at least one path is up") -Fixes: https://github.com/opensvc/multipath-tools/issues/105 -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -(cherry picked from commit cd912cffa2797a18c47426c816afa8eb2eae5b22) -(cherry picked from commit 714c20bebba6911255a527d937e7a62764ffe338) -Signed-off-by: Benjamin Marzinski ---- - libmultipath/pgpolicies.c | 6 ++++++ - libmultipath/structs.c | 12 +++++++++++- - libmultipath/structs_vec.c | 15 +++++++++++++++ - 3 files changed, 32 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/pgpolicies.c b/libmultipath/pgpolicies.c -index edc3c611..23ef2bdc 100644 ---- a/libmultipath/pgpolicies.c -+++ b/libmultipath/pgpolicies.c -@@ -127,6 +127,8 @@ fail: - int group_paths(struct multipath *mp, int marginal_pathgroups) - { - vector normal, marginal; -+ struct path *pp; -+ int i; - - if (!mp->pg) - mp->pg = vector_alloc(); -@@ -138,6 +140,10 @@ int group_paths(struct multipath *mp, int marginal_pathgroups) - if (!mp->pgpolicyfn) - goto fail; - -+ /* Reset pgindex, we're going to invalidate it */ -+ vector_foreach_slot(mp->paths, pp, i) -+ pp->pgindex = 0; -+ - if (!marginal_pathgroups || - split_marginal_paths(mp->paths, &normal, &marginal) != 0) { - if (mp->pgpolicyfn(mp, mp->paths) != 0) -diff --git a/libmultipath/structs.c b/libmultipath/structs.c -index 61c8f32c..48517252 100644 ---- a/libmultipath/structs.c -+++ b/libmultipath/structs.c -@@ -239,8 +239,18 @@ free_pgvec (vector pgvec, enum free_path_mode free_paths) - if (!pgvec) - return; - -- vector_foreach_slot(pgvec, pgp, i) -+ vector_foreach_slot(pgvec, pgp, i) { -+ -+ /* paths are going to be re-grouped, reset pgindex */ -+ if (free_paths != FREE_PATHS) { -+ struct path *pp; -+ int j; -+ -+ vector_foreach_slot(pgp->paths, pp, j) -+ pp->pgindex = 0; -+ } - free_pathgroup(pgp, free_paths); -+ } - - vector_free(pgvec); - } -diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c -index 5df495b3..9dc5a5ca 100644 ---- a/libmultipath/structs_vec.c -+++ b/libmultipath/structs_vec.c -@@ -108,6 +108,7 @@ static bool update_pathvec_from_dm(vector pathvec, struct multipath *mpp, - struct config *conf; - bool mpp_has_wwid; - bool must_reload = false; -+ bool pg_deleted = false; - - if (!mpp->pg) - return false; -@@ -125,6 +126,10 @@ static bool update_pathvec_from_dm(vector pathvec, struct multipath *mpp, - - vector_foreach_slot(pgp->paths, pp, j) { - -+ /* A pathgroup has been deleted before. Invalidate pgindex */ -+ if (pg_deleted) -+ pp->pgindex = 0; -+ - if (pp->mpp && pp->mpp != mpp) { - condlog(0, "BUG: %s: found path %s which is already in %s", - mpp->alias, pp->dev, pp->mpp->alias); -@@ -139,6 +144,13 @@ static bool update_pathvec_from_dm(vector pathvec, struct multipath *mpp, - must_reload = true; - dm_fail_path(mpp->alias, pp->dev_t); - vector_del_slot(pgp->paths, j--); -+ /* -+ * pp->pgindex has been set in disassemble_map(), -+ * which has probably been called just before for -+ * mpp. So he pgindex relates to mpp and may be -+ * wrong for pp->mpp. Invalidate it. -+ */ -+ pp->pgindex = 0; - continue; - } - pp->mpp = mpp; -@@ -237,6 +249,8 @@ static bool update_pathvec_from_dm(vector pathvec, struct multipath *mpp, - vector_del_slot(mpp->pg, i--); - free_pathgroup(pgp, KEEP_PATHS); - must_reload = true; -+ /* Invalidate pgindex for all other pathgroups */ -+ pg_deleted = true; - } - mpp->need_reload = mpp->need_reload || must_reload; - return must_reload; -@@ -354,6 +368,7 @@ void orphan_path(struct path *pp, const char *reason) - { - condlog(3, "%s: orphan path, %s", pp->dev, reason); - pp->mpp = NULL; -+ pp->pgindex = 0; - uninitialize_path(pp); - } - diff --git a/0025-libmultipath-make-pgcmp-detect-if-map-is-missing-a-p.patch b/0025-libmultipath-make-pgcmp-detect-if-map-is-missing-a-p.patch deleted file mode 100644 index b2b9e48..0000000 --- a/0025-libmultipath-make-pgcmp-detect-if-map-is-missing-a-p.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 25 Nov 2024 15:18:15 +0100 -Subject: [PATCH] libmultipath: make pgcmp detect if map is missing a path - group - -The previous algorithm didn't detect the case case where cpgp -contained a path that was not contained in pgp. Fix this. - -Cherry-picked from d4b35f61cb75c6e9b289e56c98457fc04ce4835e -Fixes: 90773ba ("libmultipath: resolve hash collisions in pgcmp()") -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 18 ++++++++++++++++++ - 1 file changed, 18 insertions(+) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index a7257981..e86c1fd5 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -426,6 +426,11 @@ compute_pgid(struct pathgroup * pgp) - pgp->id ^= (long)pp; - } - -+static void cleanup_bitfield(struct bitfield **p) -+{ -+ free(*p); -+} -+ - static int - pgcmp (struct multipath * mpp, struct multipath * cmpp) - { -@@ -433,16 +438,25 @@ pgcmp (struct multipath * mpp, struct multipath * cmpp) - struct pathgroup * pgp; - struct pathgroup * cpgp; - int r = 0; -+ struct bitfield *bf __attribute__((cleanup(cleanup_bitfield))) = NULL; - - if (!mpp) - return 0; - -+ if (VECTOR_SIZE(mpp->pg) != VECTOR_SIZE(cmpp->pg)) -+ return 1; -+ -+ bf = alloc_bitfield(VECTOR_SIZE(cmpp->pg)); -+ if (!bf) -+ return 1; -+ - vector_foreach_slot (mpp->pg, pgp, i) { - compute_pgid(pgp); - - vector_foreach_slot (cmpp->pg, cpgp, j) { - if (pgp->id == cpgp->id && - !pathcmp(pgp, cpgp)) { -+ set_bit_in_bitfield(j, bf); - r = 0; - break; - } -@@ -451,6 +465,10 @@ pgcmp (struct multipath * mpp, struct multipath * cmpp) - if (r) - return r; - } -+ vector_foreach_slot (cmpp->pg, cpgp, j) { -+ if (!is_bit_set_in_bitfield(j, bf)) -+ return 1; -+ } - return r; - } - diff --git a/0026-libmultipath-trigger-uevents-upon-map-creation-in-do.patch b/0026-libmultipath-trigger-uevents-upon-map-creation-in-do.patch deleted file mode 100644 index bd3a7a4..0000000 --- a/0026-libmultipath-trigger-uevents-upon-map-creation-in-do.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 26 Nov 2024 22:37:20 +0100 -Subject: [PATCH] libmultipath: trigger uevents upon map creation in domap() - -If map creation succeeds, previously not multipathed devices are -now multipathed. udev may not have noticed this yet, thus trigger -path uevents to make it aware of the situation. Likewise, if -creating a map fails, the paths in question were likely considered -multipath members by udev, too. They will now be marked as failed, -so trigger an event in this situation as well. - -Fixes: https://github.com/opensvc/multipath-tools/issues/103 -Suggested-by: Benjamin Marzinski -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -(cherry picked from commit 98b3a7bd9ed2a89f068fe40c253843cf78261905) -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 11 ++++------- - libmultipath/devmapper.c | 9 +++------ - 2 files changed, 7 insertions(+), 13 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index e86c1fd5..d9fac384 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -581,8 +581,6 @@ trigger_paths_udev_change(struct multipath *mpp, bool is_mpath) - vector_foreach_slot(pgp->paths, pp, j) - trigger_path_udev_change(pp, is_mpath); - } -- -- mpp->needs_paths_uevent = 0; - } - - static int sysfs_set_max_sectors_kb(struct multipath *mpp) -@@ -954,10 +952,10 @@ int domap(struct multipath *mpp, char *params, int is_daemon) - * succeeded - */ - mpp->force_udev_reload = 0; -- if (mpp->action == ACT_CREATE && -- (remember_wwid(mpp->wwid) == 1 || -- mpp->needs_paths_uevent)) -+ if (mpp->action == ACT_CREATE) { -+ remember_wwid(mpp->wwid); - trigger_paths_udev_change(mpp, true); -+ } - if (!is_daemon) { - /* multipath client mode */ - dm_switchgroup(mpp->alias, mpp->bestpg); -@@ -982,8 +980,7 @@ int domap(struct multipath *mpp, char *params, int is_daemon) - } - dm_setgeometry(mpp); - return DOMAP_OK; -- } else if (r == DOMAP_FAIL && mpp->action == ACT_CREATE && -- mpp->needs_paths_uevent) -+ } else if (r == DOMAP_FAIL && mpp->action == ACT_CREATE) - trigger_paths_udev_change(mpp, false); - - return DOMAP_FAIL; -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index fe5637b3..a0070c56 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -536,7 +536,7 @@ static uint16_t build_udev_flags(const struct multipath *mpp, int reload) - MPATH_UDEV_RELOAD_FLAG : 0); - } - --int dm_addmap_create (struct multipath *mpp, char * params) -+int dm_addmap_create (struct multipath *mpp, char *params) - { - int ro; - uint16_t udev_flags = build_udev_flags(mpp, 0); -@@ -546,9 +546,7 @@ int dm_addmap_create (struct multipath *mpp, char * params) - - if (dm_addmap(DM_DEVICE_CREATE, TGT_MPATH, mpp, params, ro, - udev_flags)) { -- if (unmark_failed_wwid(mpp->wwid) == -- WWID_FAILED_CHANGED) -- mpp->needs_paths_uevent = 1; -+ unmark_failed_wwid(mpp->wwid); - return 1; - } - /* -@@ -566,8 +564,7 @@ int dm_addmap_create (struct multipath *mpp, char * params) - break; - } - } -- if (mark_failed_wwid(mpp->wwid) == WWID_FAILED_CHANGED) -- mpp->needs_paths_uevent = 1; -+ mark_failed_wwid(mpp->wwid); - return 0; - } - diff --git a/0027-multipathd-trigger-uevents-upon-map-removal-in-coale.patch b/0027-multipathd-trigger-uevents-upon-map-removal-in-coale.patch deleted file mode 100644 index f43ca0c..0000000 --- a/0027-multipathd-trigger-uevents-upon-map-removal-in-coale.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 27 Nov 2024 20:39:50 +0100 -Subject: [PATCH] multipathd: trigger uevents upon map removal in - coalesce_maps() - -... if a map has been flushed. In this case, we know that the -the paths haven't been multipathed by coalesce_paths() because of the current -configuration (failure to create the map can't be the reason if the map -exists in coalesce_maps()). Make sure udev sees the paths which have -been released from the map as non-multipath. - -Note that this is the only case where maps are flushed where it is correct -to trigger paths uevents. In other cases, e.g. after a "remove map" CLI -command, the configuration is unchanged and if we triggered an uevent, -the map would be re-created by multipathd when the uevent arrived. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -(cherry picked from commit ad3ea472b587c0c20d2100331b5c66f8602f8414) -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 3fb623fd..4b089c0e 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -794,8 +794,10 @@ coalesce_maps(struct vectors *vecs, vector nmpv) - vector_del_slot(ompv, i); - i--; - } -- else -+ else { - condlog(2, "%s devmap removed", ompp->alias); -+ trigger_paths_udev_change(ompp, false); -+ } - } else if (reassign_maps) { - condlog(3, "%s: Reassign existing device-mapper" - " devices", ompp->alias); diff --git a/0028-libmultipath-Don-t-skip-set_path_max_sectors_kb.patch b/0028-libmultipath-Don-t-skip-set_path_max_sectors_kb.patch deleted file mode 100644 index 6c001f5..0000000 --- a/0028-libmultipath-Don-t-skip-set_path_max_sectors_kb.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 4 Dec 2024 22:56:36 -0500 -Subject: [PATCH] libmultipath: Don't skip set_path_max_sectors_kb() - -If a multipath device already has need_reload set when a path is -adopted, it won't call set_path_max_sectors_kb() because of -short-circuit evaluation. This isn't what's intended. - -Fixes: e5e20c7b ("libmultipath: set max_sectors_kb in adopt_paths()") -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck -(cherry picked from commit f5c0c4b25c5eaac87b78e6e0c8d52b0828c29893) ---- - libmultipath/structs_vec.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c -index 9dc5a5ca..683ab473 100644 ---- a/libmultipath/structs_vec.c -+++ b/libmultipath/structs_vec.c -@@ -349,8 +349,7 @@ int adopt_paths(vector pathvec, struct multipath *mpp, - */ - if (!current_mpp || - !mp_find_path_by_devt(current_mpp, pp->dev_t)) -- mpp->need_reload = mpp->need_reload || -- set_path_max_sectors_kb(pp, mpp->max_sectors_kb); -+ mpp->need_reload = set_path_max_sectors_kb(pp, mpp->max_sectors_kb) || mpp->need_reload; - } - - pp->mpp = mpp; diff --git a/0029-libmultipath-stop-static-analyzer-complaint-in-init_.patch b/0029-libmultipath-stop-static-analyzer-complaint-in-init_.patch deleted file mode 100644 index e293a0e..0000000 --- a/0029-libmultipath-stop-static-analyzer-complaint-in-init_.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 22 Jan 2025 22:16:42 -0500 -Subject: [PATCH] libmultipath: stop static analyzer complaint in init_foreign - -This change doesn't actually fix anything. The code was already safe. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck -(cherry picked from commit 85ec51e7930b4cadfbc12718afa91ce3a4adf4b5) ---- - libmultipath/foreign.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/foreign.c b/libmultipath/foreign.c -index 28d1b115..af5b0ed3 100644 ---- a/libmultipath/foreign.c -+++ b/libmultipath/foreign.c -@@ -129,7 +129,7 @@ static void free_pre(void *arg) - static int _init_foreign(const char *enable) - { - char pathbuf[PATH_MAX]; -- struct dirent **di; -+ struct dirent **di = NULL; - struct scandir_result sr; - int r, i; - regex_t *enable_re = NULL; diff --git a/0030-libmultipath-be-lenient-in-allowing-the-alua-based-p.patch b/0030-libmultipath-be-lenient-in-allowing-the-alua-based-p.patch deleted file mode 100644 index 06a1b0f..0000000 --- a/0030-libmultipath-be-lenient-in-allowing-the-alua-based-p.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 22 Jan 2025 22:16:43 -0500 -Subject: [PATCH] libmultipath: be lenient in allowing the alua-based - pgpolicies - -multipath wouldn't autodetect the GROUP_BY_PRIO path grouping policy or -allow the GROUP_BY_TPG policy if there was a path that didn't have its -prioritizer selected (for instance because multipathd was reconfigured -while it was offline). To avoid this, make verify_alua_prio() assume an -alua multipath device if all the paths with a prioritizer selected -(there must be at least one) use an alua-based prioritizer. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck -(cherry picked from commit b47a577998eaff203018a00b57ba5e3674645848) ---- - libmultipath/propsel.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c -index a3fce203..c09a0619 100644 ---- a/libmultipath/propsel.c -+++ b/libmultipath/propsel.c -@@ -255,14 +255,18 @@ verify_alua_prio(struct multipath *mp) - { - int i; - struct path *pp; -+ bool assume_alua = false; - - vector_foreach_slot(mp->paths, pp, i) { - const char *name = prio_name(&pp->prio); -+ if (!prio_selected(&pp->prio)) -+ continue; - if (strncmp(name, PRIO_ALUA, PRIO_NAME_LEN) && - strncmp(name, PRIO_SYSFS, PRIO_NAME_LEN)) - return false; -+ assume_alua = true; - } -- return true; -+ return assume_alua; - } - - int select_detect_pgpolicy(struct config *conf, struct multipath *mp) diff --git a/0031-Update-NEWS.md-for-0.10.2.patch b/0031-Update-NEWS.md-for-0.10.2.patch deleted file mode 100644 index fd31420..0000000 --- a/0031-Update-NEWS.md-for-0.10.2.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 24 Jan 2025 20:03:15 +0100 -Subject: [PATCH] Update NEWS.md for 0.10.2 - -Signed-off-by: Benjamin Marzinski ---- - .github/actions/spelling/expect.txt | 2 ++ - NEWS.md | 23 ++++++++++++++++++++++- - 2 files changed, 24 insertions(+), 1 deletion(-) - -diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt -index 000d5ebb..4ac57510 100644 ---- a/.github/actions/spelling/expect.txt -+++ b/.github/actions/spelling/expect.txt -@@ -11,6 +11,7 @@ ata - autoconfig - autodetected - autoresize -+backported - barbie - BINDIR - blkid -@@ -122,6 +123,7 @@ Lun - lvm - lvmteam - Marzinski -+misdetection - mpath - mpathb - mpathpersist -diff --git a/NEWS.md b/NEWS.md -index 3c51553e..1b239ffa 100644 ---- a/NEWS.md -+++ b/NEWS.md -@@ -1,6 +1,27 @@ - # multipath-tools Release Notes - --## multipath-tools 0.10.1, 2024/11 -+## multipath-tools 0.10.2, 2025/02 -+ -+This release contains backported bug fixes from the stable-0.11.y branch. -+ -+### Bug fixes -+ -+* Fix multipathd crash because of invalid path group index value, for example -+ if an invalid path device was removed from a map. -+ Fixes [#105](https://github.com/opensvc/multipath-tools/issues/105). -+* Make sure maps are reloaded in the path checker loop after detecting an -+ inconsistent or wrong kernel state (e.g. missing or falsely mapped path -+ device). Wrongly mapped paths will be unmapped and released to the system. -+ Fixes another issue reported in -+ [#105](https://github.com/opensvc/multipath-tools/issues/105). -+* Fix the problem that `group_by_tpg` might be disabled if one or more -+ paths were offline during initial configuration. -+* Fix possible misdetection of changed pathgroups in a map. -+* Fix the problem that if a map was scheduled to be reloaded already, -+ `max_sectors_kb` might not be set on a path device that -+ was being added to a multipath map. This problem was introduced in 0.9.9. -+ -+## multipath-tools 0.10.1, 2025/01 - - This is the first bug fix release on the `stable-0.10.y` branch. It contains - bug fixes from 0.11.0, and some CI-related fixes. diff --git a/0032-GitHub-Workflows-fix-abi-stable.yaml-for-pull-reques.patch b/0032-GitHub-Workflows-fix-abi-stable.yaml-for-pull-reques.patch deleted file mode 100644 index 3ddab39..0000000 --- a/0032-GitHub-Workflows-fix-abi-stable.yaml-for-pull-reques.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Sat, 25 Jan 2025 00:49:19 +0100 -Subject: [PATCH] GitHub Workflows: fix abi-stable.yaml for pull request - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/abi-stable.yaml | 16 ++++++++++++---- - 1 file changed, 12 insertions(+), 4 deletions(-) - -diff --git a/.github/workflows/abi-stable.yaml b/.github/workflows/abi-stable.yaml -index a6746f23..472914ce 100644 ---- a/.github/workflows/abi-stable.yaml -+++ b/.github/workflows/abi-stable.yaml -@@ -15,12 +15,16 @@ on: - - jobs: - reference-abi: -- runs-on: ubuntu-20.04 -+ runs-on: ubuntu-22.04 - steps: - - name: get parent tag - run: > - echo ${{ github.ref }} | - sed -E 's,refs/heads/stable-([0-9]\.[0-9]*)\.y,PARENT_TAG=\1.0,' >> $GITHUB_ENV -+ if: ${{ github.event_name == 'push' }} -+ - name: get parent tag -+ run: echo PARENT_TAG=${{ github.base_ref }} >> $GITHUB_ENV -+ if: ${{ github.event_name == 'pull_request' }} - - name: assert parent tag - run: /bin/false - if: ${{ env.PARENT_TAG == '' }} -@@ -45,20 +49,24 @@ jobs: - path: abi - - check-abi: -- runs-on: ubuntu-20.04 -+ runs-on: ubuntu-22.04 - needs: reference-abi - steps: - - name: get parent tag - run: > - echo ${{ github.ref }} | - sed -E 's,refs/heads/stable-([0-9]\.[0-9]*)\.y,PARENT_TAG=\1.0,' >> $GITHUB_ENV -+ if: ${{ github.event_name == 'push' }} -+ - name: get parent tag -+ run: echo PARENT_TAG=${{ github.base_ref }} >> $GITHUB_ENV -+ if: ${{ github.event_name == 'pull_request' }} - - name: assert parent tag - run: /bin/false - if: ${{ env.PARENT_TAG == '' }} -- - name: checkout ${{ env.PARENT_TAG }} -+ - name: checkout ${{ github.base_ref }} - uses: actions/checkout@v4 - with: -- ref: ${{ env.PARENT_TAG }} -+ ref: ${{ github.base_ref }} - - name: download ABI for ${{ env.PARENT_TAG }} - id: download_abi - uses: actions/download-artifact@v4 diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 8e469ab..2de9457 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath -Version: 0.10.0 -Release: 5%{?dist} +Version: 0.11.1 +Release: 1%{?dist} Summary: Tools to manage multipath devices using device-mapper # readline uses GPL-3.0-only License: GPL-2.0-only AND GPL-3.0-only @@ -8,54 +8,26 @@ 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 -L https://github.com/opensvc/multipath-tools/archive/0.10.0.tar.gz -o multipath-tools-0.10.0.tgz -Source0: multipath-tools-0.10.0.tgz +# curl -L https://github.com/opensvc/multipath-tools/archive/0.11.1.tar.gz -o multipath-tools-0.11.1.tgz +Source0: multipath-tools-0.11.1.tgz Source1: multipath.conf -Patch0001: 0001-GitHub-workflows-use-upload-download-artifact-v4.patch -Patch0002: 0002-GitHub-workflows-update-dawidd6-action-download-arti.patch -Patch0003: 0003-Github-workflows-native.yml-use-mosteo-actions-docke.patch -Patch0004: 0004-GitHub-workflows-native.yml-use-extra-job-for-clang.patch -Patch0005: 0005-GitHub-workflows-native.yaml-make-test-and-archive-s.patch -Patch0006: 0006-GitHub-workflows-enable-unit-tests-for-stable-branch.patch -Patch0007: 0007-GitHub-Workflows-add-abi-check-for-stable-branches.patch -Patch0008: 0008-libmultipath-dm_get_maps-don-t-bail-out-for-single-m.patch -Patch0009: 0009-11-dm-mpath.rules.in-import-DM_COLDPLUG_SUSPENDED-on.patch -Patch0010: 0010-11-dm-mpath.rules.in-handle-inactive-suspended-devic.patch -Patch0011: 0011-11-dm-mpath.rules.in-clarify-DM_ACTIVATION-logic.patch -Patch0012: 0012-11-dm-mpath-rules.in-skip-one-.DM_NOSCAN-check.patch -Patch0013: 0013-11-dm-mpath.rules.in-set-.DM_NOSCAN-if-MPATH_UNCHANG.patch -Patch0014: 0014-libmultipath-don-t-set-dev_loss_tmo-to-0-for-NO_PATH.patch -Patch0015: 0015-multipathd-fix-deferred_failback_tick-for-reload-rem.patch -Patch0016: 0016-multipathd-fix-an-unsigned-int-ovwerflow.patch -Patch0017: 0017-libmpathutil-avoid-Wcast-function-type-mismatch-erro.patch -Patch0018: 0018-Update-NEWS.md-for-0.10.1.patch -Patch0019: 0019-libmultipath-don-t-print-error-message-if-WATCHDOG_U.patch -Patch0020: 0020-libmultipath-reduce-log-level-of-map-X-has-multiple-.patch -Patch0021: 0021-libmultipath-foreign-fix-memory-leak-in-nvme-foreign.patch -Patch0022: 0022-libmultipath-add-condition-for-enqueueing-path-to-io.patch -Patch0023: 0023-Additional-NEWS.md-updates-for-0.10.1.patch -Patch0024: 0024-libmultipath-fix-handling-of-pp-pgindex.patch -Patch0025: 0025-libmultipath-make-pgcmp-detect-if-map-is-missing-a-p.patch -Patch0026: 0026-libmultipath-trigger-uevents-upon-map-creation-in-do.patch -Patch0027: 0027-multipathd-trigger-uevents-upon-map-removal-in-coale.patch -Patch0028: 0028-libmultipath-Don-t-skip-set_path_max_sectors_kb.patch -Patch0029: 0029-libmultipath-stop-static-analyzer-complaint-in-init_.patch -Patch0030: 0030-libmultipath-be-lenient-in-allowing-the-alua-based-p.patch -Patch0031: 0031-Update-NEWS.md-for-0.10.2.patch -Patch0032: 0032-GitHub-Workflows-fix-abi-stable.yaml-for-pull-reques.patch -Patch0033: 0033-RH-fixup-udev-rules-for-redhat.patch -Patch0034: 0034-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0035: 0035-RH-don-t-start-without-a-config-file.patch -Patch0036: 0036-RH-Fix-nvme-function-missing-argument.patch -Patch0037: 0037-RH-use-rpm-optflags-if-present.patch -Patch0038: 0038-RH-add-mpathconf.patch -Patch0039: 0039-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0040: 0040-RH-reset-default-find_mutipaths-value-to-off.patch -Patch0041: 0041-RH-attempt-to-get-ANA-info-via-sysfs-first.patch -Patch0042: 0042-RH-make-parse_vpd_pg83-match-scsi_id-output.patch -Patch0043: 0043-RH-add-scsi-device-handlers-to-modules-load.d.patch -Patch0044: 0044-RH-compile-with-libreadline-support.patch -Patch0045: 0045-RH-Add-mpathcleanup.patch +Patch0001: 0001-multipathd-trigger-uevents-for-blacklisted-paths-in-.patch +Patch0002: 0002-multipath-tools-fix-compilation-with-latest-userspac.patch +Patch0003: 0003-libmultipath-include-urcu.h-before-urcu-atomic.h.patch +Patch0004: 0004-libmpathutils-uxsock.c-Include-string.h-for-memcpy.patch +Patch0005: 0005-RH-fixup-udev-rules-for-redhat.patch +Patch0006: 0006-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0007: 0007-RH-don-t-start-without-a-config-file.patch +Patch0008: 0008-RH-Fix-nvme-function-missing-argument.patch +Patch0009: 0009-RH-use-rpm-optflags-if-present.patch +Patch0010: 0010-RH-add-mpathconf.patch +Patch0011: 0011-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0012: 0012-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0013: 0013-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0014: 0014-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +Patch0015: 0015-RH-add-scsi-device-handlers-to-modules-load.d.patch +Patch0016: 0016-RH-compile-with-libreadline-support.patch +Patch0017: 0017-RH-Add-mpathcleanup.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -143,7 +115,7 @@ This package contains the files needed to develop applications that use device-mapper-multipath's libdmmp C API library %prep -%autosetup -n multipath-tools-0.10.0 -p1 +%autosetup -n multipath-tools-0.11.1 -p1 cp %{SOURCE1} . %build @@ -265,6 +237,13 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Thu Feb 27 2025 Benjamin Marzinski - 0.11.1-1 +- Update source to upstream staging branch for 0.11.1 plus additional + stable branch patches. + * Previous patches 0001-0032 are included in the tarball +- Rename redhat patches + * Previous patches 0033-0045 are now patches 0005-0017 + * Sat Feb 1 2025 Benjamin Marzinski - 0.10.0-5 - Update source to upstream staging branch for 0.10.y (will be 0.10.2 when merged). diff --git a/sources b/sources index da06e16..5eea94e 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (multipath-tools-0.10.0.tgz) = 8f545609fa20df7547428f2929571dc0df87c17d9f61f11aad3559446c2e94755e18b1c4b3780b3de92ec2cbc450939ca15a9d6c95551eee4084064d83874b2d +SHA512 (multipath-tools-0.11.1.tgz) = ac6bacd725bc831a140b75a72c81296eb1ed4080fb6350caf6178914d1bdce743705f3bd4e31f318068f6272dc98e12d63ee38228a3521a3d1c7bc8eb30812f9 SHA512 (multipath.conf) = 71953dce5a68adcf60a942305f5a66023e6f4c4baf53b1bfdb4edf65ed5b8e03db804363c36d1dcfd85591f4766f52b515269904c53b84d7b076da0b80b09942 From 9f48ebd2e22ad64a101f59f06a9e8306f6e3b317 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 23 Jul 2025 19:12:54 +0000 Subject: [PATCH 65/67] Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild --- device-mapper-multipath.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 2de9457..232daba 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.11.1 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Tools to manage multipath devices using device-mapper # readline uses GPL-3.0-only License: GPL-2.0-only AND GPL-3.0-only @@ -237,6 +237,9 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Wed Jul 23 2025 Fedora Release Engineering - 0.11.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild + * Thu Feb 27 2025 Benjamin Marzinski - 0.11.1-1 - Update source to upstream staging branch for 0.11.1 plus additional stable branch patches. From 3c9f48504bb89ec2a2c84cfffbeaf2f2811fcefd Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Tue, 4 Nov 2025 18:02:43 -0500 Subject: [PATCH 66/67] device-mapper-multipath-0.13.0-1 Update source to upstream release 0.13.0 * Previous patches 0001-0004 are included in the tarball Install /lib/systemd/system/multipathd-queueing.service Rename redhat patches * Previous patches 0005-0017 are now patches 0001-0013 --- .gitignore | 1 + ... 0001-RH-fixup-udev-rules-for-redhat.patch | 4 +- ...er-uevents-for-blacklisted-paths-in-.patch | 101 ------------------ ...property-blacklist-exception-builtin.patch | 14 +-- ...fix-compilation-with-latest-userspac.patch | 63 ----------- ...RH-don-t-start-without-a-config-file.patch | 24 ++--- ...-include-urcu.h-before-urcu-atomic.h.patch | 40 ------- ...H-Fix-nvme-function-missing-argument.patch | 6 +- ...uxsock.c-Include-string.h-for-memcpy.patch | 29 ----- ... 0005-RH-use-rpm-optflags-if-present.patch | 12 ++- ...hconf.patch => 0006-RH-add-mpathconf.patch | 8 +- ...om-kernel-cmdline-mpath.wwids-with-A.patch | 16 +-- ...-default-find_mutipaths-value-to-off.patch | 8 +- ...empt-to-get-ANA-info-via-sysfs-first.patch | 14 +-- ...-parse_vpd_pg83-match-scsi_id-output.patch | 8 +- ...si-device-handlers-to-modules-load.d.patch | 4 +- ...-RH-compile-with-libreadline-support.patch | 4 +- ...up.patch => 0013-RH-Add-mpathcleanup.patch | 2 +- device-mapper-multipath.spec | 48 +++++---- sources | 2 +- 20 files changed, 91 insertions(+), 317 deletions(-) rename 0005-RH-fixup-udev-rules-for-redhat.patch => 0001-RH-fixup-udev-rules-for-redhat.patch (96%) delete mode 100644 0001-multipathd-trigger-uevents-for-blacklisted-paths-in-.patch rename 0006-RH-Remove-the-property-blacklist-exception-builtin.patch => 0002-RH-Remove-the-property-blacklist-exception-builtin.patch (91%) delete mode 100644 0002-multipath-tools-fix-compilation-with-latest-userspac.patch rename 0007-RH-don-t-start-without-a-config-file.patch => 0003-RH-don-t-start-without-a-config-file.patch (88%) delete mode 100644 0003-libmultipath-include-urcu.h-before-urcu-atomic.h.patch rename 0008-RH-Fix-nvme-function-missing-argument.patch => 0004-RH-Fix-nvme-function-missing-argument.patch (84%) delete mode 100644 0004-libmpathutils-uxsock.c-Include-string.h-for-memcpy.patch rename 0009-RH-use-rpm-optflags-if-present.patch => 0005-RH-use-rpm-optflags-if-present.patch (85%) rename 0010-RH-add-mpathconf.patch => 0006-RH-add-mpathconf.patch (99%) rename 0011-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch => 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch (92%) rename 0012-RH-reset-default-find_mutipaths-value-to-off.patch => 0008-RH-reset-default-find_mutipaths-value-to-off.patch (87%) rename 0013-RH-attempt-to-get-ANA-info-via-sysfs-first.patch => 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch (86%) rename 0014-RH-make-parse_vpd_pg83-match-scsi_id-output.patch => 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch (91%) rename 0015-RH-add-scsi-device-handlers-to-modules-load.d.patch => 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch (89%) rename 0016-RH-compile-with-libreadline-support.patch => 0012-RH-compile-with-libreadline-support.patch (89%) rename 0017-RH-Add-mpathcleanup.patch => 0013-RH-Add-mpathcleanup.patch (98%) diff --git a/.gitignore b/.gitignore index 8cd21df..c297b30 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,4 @@ multipath-tools-091027.tar.gz /multipath-tools-0.9.9.tgz /multipath-tools-0.10.0.tgz /multipath-tools-0.11.1.tgz +/multipath-tools-0.13.0.tgz diff --git a/0005-RH-fixup-udev-rules-for-redhat.patch b/0001-RH-fixup-udev-rules-for-redhat.patch similarity index 96% rename from 0005-RH-fixup-udev-rules-for-redhat.patch rename to 0001-RH-fixup-udev-rules-for-redhat.patch index 0135f49..ed5b7e9 100644 --- a/0005-RH-fixup-udev-rules-for-redhat.patch +++ b/0001-RH-fixup-udev-rules-for-redhat.patch @@ -1,4 +1,4 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 64a07df23affd21842fdc604887276e62e5b41de Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 13 Apr 2017 07:22:23 -0500 Subject: [PATCH] RH: fixup udev rules for redhat @@ -15,7 +15,7 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 65f6efc8..c225a1ed 100644 +index 9e3dc466..ead89030 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -34,7 +34,7 @@ endif diff --git a/0001-multipathd-trigger-uevents-for-blacklisted-paths-in-.patch b/0001-multipathd-trigger-uevents-for-blacklisted-paths-in-.patch deleted file mode 100644 index 72bcf69..0000000 --- a/0001-multipathd-trigger-uevents-for-blacklisted-paths-in-.patch +++ /dev/null @@ -1,101 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 23 Jan 2025 22:19:39 +0100 -Subject: [PATCH] multipathd: trigger uevents for blacklisted paths in - reconfigure - -If multipathd has already configured maps, and the user changes the -blacklist or other parameters that cause currently multipathed -devices to be skipped, and then runs "multipathd reconfigure" -or restarts multipathd, multipathd flushes the maps in question, -but doesn't trigger uevents for the now-blacklisted paths. - -This is because the blacklisted paths are removed from the discovered -maps internally when update_pathvec_from_dm() is called through -map_discovery() and update_multipath_table(); when later -trigger_paths_udev_change() is called from coalesce_maps(), the -map contains no paths for which an uevent could be triggered. - -The map_discovery() code flow is special, because we will call -coalesce_paths() afterwards anyway and reconstruct the mpvec. Unlike the -regular code flow, we don't want the maps to be "corrected" in this -case, because the maps discovered here aren't going to be reloaded. -We just want update_pathvec_from_dm() to populate the pathvec. - -Therefore add a new flag DI_DISCOVERY, which is only set when -update_multipath_table() is called from map_discovery(), and if -this flag is set, keep PATHINFO_SKIPPED paths in the map's table in -update_pathvec_from_dm(). Later on, the paths will still be visible -in the old mpp (ompp) in coalesce_maps(), and uevents will be -triggered for them to release them to systemd. - -We can't always do this for PATHINFO_SKIPPED, because in some cases -paths may be accepted in a map first and SKIPPED later (for example if -the WWID wasn't yet available at startup). Therefore the special -case for DI_DISCOVERY is necessary. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/discovery.h | 2 ++ - libmultipath/structs_vec.c | 6 +++++- - multipathd/main.c | 2 +- - 3 files changed, 8 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/discovery.h b/libmultipath/discovery.h -index 7d42eae5..9824a8d3 100644 ---- a/libmultipath/discovery.h -+++ b/libmultipath/discovery.h -@@ -72,6 +72,7 @@ enum discovery_mode { - DI_BLACKLIST__, - DI_NOIO__, - DI_NOFALLBACK__, -+ DI_DISCOVERY__, - }; - - #define DI_SYSFS (1 << DI_SYSFS__) -@@ -82,6 +83,7 @@ enum discovery_mode { - #define DI_BLACKLIST (1 << DI_BLACKLIST__) - #define DI_NOIO (1 << DI_NOIO__) /* Avoid IO on the device */ - #define DI_NOFALLBACK (1 << DI_NOFALLBACK__) /* do not allow wwid fallback */ -+#define DI_DISCOVERY (1 << DI_DISCOVERY__) /* set only during map discovery */ - - #define DI_ALL (DI_SYSFS | DI_SERIAL | DI_CHECKER | DI_PRIO | \ - DI_WWID) -diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c -index 7a4e3eb0..5ccdaea0 100644 ---- a/libmultipath/structs_vec.c -+++ b/libmultipath/structs_vec.c -@@ -109,6 +109,9 @@ static bool update_pathvec_from_dm(vector pathvec, struct multipath *mpp, - bool mpp_has_wwid; - bool must_reload = false; - bool pg_deleted = false; -+ bool map_discovery = !!(pathinfo_flags & DI_DISCOVERY); -+ -+ pathinfo_flags &= ~DI_DISCOVERY; - - if (!mpp->pg) - return false; -@@ -195,7 +198,8 @@ static bool update_pathvec_from_dm(vector pathvec, struct multipath *mpp, - rc = pathinfo(pp, conf, - DI_SYSFS|DI_WWID|DI_BLACKLIST|DI_NOFALLBACK|pathinfo_flags); - pthread_cleanup_pop(1); -- if (rc != PATHINFO_OK) { -+ if (rc == PATHINFO_FAILED || -+ (rc == PATHINFO_SKIPPED && !map_discovery)) { - condlog(1, "%s: error %d in pathinfo, discarding path", - pp->dev, rc); - vector_del_slot(pgp->paths, j--); -diff --git a/multipathd/main.c b/multipathd/main.c -index 9ed27da0..fb3e44a8 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -1763,7 +1763,7 @@ map_discovery (struct vectors * vecs) - return 1; - - vector_foreach_slot (vecs->mpvec, mpp, i) -- if (update_multipath_table(mpp, vecs->pathvec, 0) != DMP_OK) { -+ if (update_multipath_table(mpp, vecs->pathvec, DI_DISCOVERY) != DMP_OK) { - remove_map(mpp, vecs->pathvec, vecs->mpvec); - i--; - } diff --git a/0006-RH-Remove-the-property-blacklist-exception-builtin.patch b/0002-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 91% rename from 0006-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0002-RH-Remove-the-property-blacklist-exception-builtin.patch index a74e6c2..b8e580a 100644 --- a/0006-RH-Remove-the-property-blacklist-exception-builtin.patch +++ b/0002-RH-Remove-the-property-blacklist-exception-builtin.patch @@ -1,4 +1,4 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From f7be16ac9fce97585a4552d49f3d3c54a93c9c17 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 @@ -42,10 +42,10 @@ index 17e1b54a..10d13e98 100644 udev_device_get_properties_list_entry(udev)) { diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in -index 4388baad..af9fbb96 100644 +index 3c9ae097..ba291e11 100644 --- a/multipath/multipath.conf.5.in +++ b/multipath/multipath.conf.5.in -@@ -1469,9 +1469,14 @@ keywords. Both are regular expressions. For a full description of these keywords +@@ -1470,9 +1470,14 @@ keywords. Both are regular expressions. For a full description of these keywords Regular expression for an udev property. All devices that have matching udev properties will be excluded/included. The handling of the \fIproperty\fR keyword is special, @@ -61,7 +61,7 @@ index 4388baad..af9fbb96 100644 . .RS .PP -@@ -1482,10 +1487,6 @@ Blacklisting by missing properties is only applied to devices which do have the +@@ -1483,10 +1488,6 @@ Blacklisting by missing properties is only applied to devices which do have the property specified by \fIuid_attribute\fR (e.g. \fIID_SERIAL\fR) set. Previously, it was applied to every device, possibly causing devices to be blacklisted because of temporary I/O error conditions. @@ -73,10 +73,10 @@ index 4388baad..af9fbb96 100644 .TP .B protocol diff --git a/tests/blacklist.c b/tests/blacklist.c -index ba8dfd07..693db3fa 100644 +index ab3da619..52ae03e0 100644 --- a/tests/blacklist.c +++ b/tests/blacklist.c -@@ -384,9 +384,8 @@ static void test_property_missing(void **state) +@@ -371,9 +371,8 @@ static void test_property_missing(void **state) { static struct udev_device udev = { "sdb", { "ID_FOO", "ID_BAZ", "ID_BAR", "ID_SERIAL", NULL } }; conf.blist_property = blist_property_wwn; @@ -87,7 +87,7 @@ index ba8dfd07..693db3fa 100644 assert_int_equal(filter_property(&conf, &udev, 3, "ID_BLAH"), MATCH_NOTHING); assert_int_equal(filter_property(&conf, &udev, 3, ""), -@@ -478,9 +477,7 @@ static void test_filter_path_missing1(void **state) +@@ -465,9 +464,7 @@ static void test_filter_path_missing1(void **state) conf.blist_device = blist_device_foo_bar; conf.blist_protocol = blist_protocol_fcp; conf.blist_wwid = blist_wwid_xyzzy; diff --git a/0002-multipath-tools-fix-compilation-with-latest-userspac.patch b/0002-multipath-tools-fix-compilation-with-latest-userspac.patch deleted file mode 100644 index 03d7d9d..0000000 --- a/0002-multipath-tools-fix-compilation-with-latest-userspac.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 3 Feb 2025 16:43:42 -0500 -Subject: [PATCH] multipath-tools: fix compilation with latest userspace-rcu - code - -starting with version 0.15, userspace-rcu can be compiled with -CONFIG_RCU_USE_ATOMIC_BUILTINS. If it is, then any programs using it -must be compiled with at least the C11 standard. See: -https://github.com/urcu/userspace-rcu/commit/89280d020bf064d1055c360fb9974f128051043f - -To deal with this, check if compiling with gnu99 fails, and if so, -switch to using gnu11. - -Based-on-patch-by: Yaakov Selkowitz -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - Makefile.inc | 2 +- - create-config.mk | 13 +++++++++++++ - 2 files changed, 14 insertions(+), 1 deletion(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 729618bd..65f6efc8 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -115,7 +115,7 @@ CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) $(D_URCU_VERSION) \ - -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(TGTDIR)$(configdir)\" \ - -DDEFAULT_CONFIGFILE=\"$(TGTDIR)$(configfile)\" -DSTATE_DIR=\"$(TGTDIR)$(statedir)\" \ - -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP --CFLAGS := -std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ -+CFLAGS := -std=$(C_STD) $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ - -fexceptions - BIN_CFLAGS := -fPIE -DPIE - LIB_CFLAGS := -fPIC -diff --git a/create-config.mk b/create-config.mk -index 8bd2c20c..ab163ed1 100644 ---- a/create-config.mk -+++ b/create-config.mk -@@ -157,6 +157,18 @@ FORTIFY_OPT := $(shell \ - echo "-D_FORTIFY_SOURCE=2"; \ - fi) - -+# Check is you can compile with the urcu.h header, using the C99 standard. -+# If urcu/config-.h defines CONFIG_RCU_USE_ATOMIC_BUILTINS, then anything -+# including urcu.h must be compiled with at least the C11 standard. See: -+# https://github.com/urcu/userspace-rcu/commit/89280d020bf064d1055c360fb9974f128051043f -+C_STD := $(shell \ -+ if printf '$(__HASH__)include \nint main(void) { return 0; }\n' | $(CC) -o /dev/null -c -xc --std=gnu99 - 2>/dev/null; \ -+ then \ -+ echo "gnu99"; \ -+ else \ -+ echo "gnu11"; \ -+ fi) -+ - STACKPROT := - - all: $(TOPDIR)/config.mk -@@ -182,3 +194,4 @@ $(TOPDIR)/config.mk: $(multipathdir)/autoconfig.h - @echo "W_MISSING_INITIALIZERS := $(call TEST_MISSING_INITIALIZERS)" >>$@ - @echo "W_URCU_TYPE_LIMITS := $(call TEST_URCU_TYPE_LIMITS)" >>$@ - @echo "ENABLE_LIBDMMP := $(ENABLE_LIBDMMP)" >>$@ -+ @echo "C_STD := $(C_STD)" >>$@ diff --git a/0007-RH-don-t-start-without-a-config-file.patch b/0003-RH-don-t-start-without-a-config-file.patch similarity index 88% rename from 0007-RH-don-t-start-without-a-config-file.patch rename to 0003-RH-don-t-start-without-a-config-file.patch index edbc647..05d4e7a 100644 --- a/0007-RH-don-t-start-without-a-config-file.patch +++ b/0003-RH-don-t-start-without-a-config-file.patch @@ -1,4 +1,4 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 5613e07ce9cabf2fdc402f6f102cc54bd1059800 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Wed, 15 Oct 2014 10:39:30 -0500 Subject: [PATCH] RH: don't start without a config file @@ -18,7 +18,7 @@ Signed-off-by: Benjamin Marzinski multipath/multipath.rules.in | 1 + multipathd/multipathd.8.in | 2 ++ multipathd/multipathd.service.in | 1 + - multipathd/multipathd.socket | 1 + + multipathd/multipathd.socket.in | 1 + 7 files changed, 25 insertions(+) diff --git a/libmultipath/config.c b/libmultipath/config.c @@ -58,10 +58,10 @@ index 5b4ebf8c..2302eacc 100644 enum devtypes { DEV_NONE, diff --git a/multipath/main.c b/multipath/main.c -index 28e3a055..346acb61 100644 +index f2adcdeb..31012874 100644 --- a/multipath/main.c +++ b/multipath/main.c -@@ -843,11 +843,14 @@ main (int argc, char *argv[]) +@@ -834,11 +834,14 @@ main (int argc, char *argv[]) char *dev = NULL; struct config *conf; bool enable_foreign = false; @@ -76,7 +76,7 @@ index 28e3a055..346acb61 100644 if (init_config(DEFAULT_CONFIGFILE)) exit(RTVL_FAIL); if (atexit(uninit_config)) -@@ -1101,6 +1104,9 @@ main (int argc, char *argv[]) +@@ -1092,6 +1095,9 @@ main (int argc, char *argv[]) while ((r = configure(conf, cmd, dev_type, dev)) == RTVL_RETRY) condlog(3, "restart multipath configuration process"); @@ -99,7 +99,7 @@ index 2ac1972f..cc248231 100644 ENV{DEVTYPE}!="partition", GOTO="test_dev" IMPORT{parent}="DM_MULTIPATH_DEVICE_PATH" diff --git a/multipathd/multipathd.8.in b/multipathd/multipathd.8.in -index 7bc8806e..315884eb 100644 +index 8815e099..342e363e 100644 --- a/multipathd/multipathd.8.in +++ b/multipathd/multipathd.8.in @@ -49,6 +49,8 @@ map regains its maximum performance and redundancy. @@ -112,10 +112,10 @@ index 7bc8806e..315884eb 100644 . .\" ---------------------------------------------------------------------------- diff --git a/multipathd/multipathd.service.in b/multipathd/multipathd.service.in -index b6a25b31..3d957733 100644 +index eb58943c..ab166435 100644 --- a/multipathd/multipathd.service.in +++ b/multipathd/multipathd.service.in -@@ -6,6 +6,7 @@ Wants=systemd-udevd-kernel.socket @MODPROBE_UNIT@ +@@ -6,6 +6,7 @@ Wants=systemd-udevd-kernel.socket multipathd-queueing.service @MODPROBE_UNIT@ After=systemd-udevd-kernel.socket @MODPROBE_UNIT@ After=multipathd.socket systemd-remount-fs.service Before=initrd-cleanup.service @@ -123,10 +123,10 @@ index b6a25b31..3d957733 100644 DefaultDependencies=no Conflicts=shutdown.target Conflicts=initrd-cleanup.service -diff --git a/multipathd/multipathd.socket b/multipathd/multipathd.socket -index 6a62f5fd..263b6b0c 100644 ---- a/multipathd/multipathd.socket -+++ b/multipathd/multipathd.socket +diff --git a/multipathd/multipathd.socket.in b/multipathd/multipathd.socket.in +index 11002fce..5ed24757 100644 +--- a/multipathd/multipathd.socket.in ++++ b/multipathd/multipathd.socket.in @@ -1,6 +1,7 @@ [Unit] Description=multipathd control socket diff --git a/0003-libmultipath-include-urcu.h-before-urcu-atomic.h.patch b/0003-libmultipath-include-urcu.h-before-urcu-atomic.h.patch deleted file mode 100644 index 8da3ce7..0000000 --- a/0003-libmultipath-include-urcu.h-before-urcu-atomic.h.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 11 Feb 2025 13:11:03 -0500 -Subject: [PATCH] libmultipath: include urcu.h before urcu/atomic.h - -urcu/atomic.h requires some header files included by urcu.h. Make sure -to include it first. - -Fixes: https://github.com/opensvc/multipath-tools/issues/112 -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/checkers/tur.c | 1 + - libmultipath/lock.h | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/libmultipath/checkers/tur.c b/libmultipath/checkers/tur.c -index e70a2e11..0010acf8 100644 ---- a/libmultipath/checkers/tur.c -+++ b/libmultipath/checkers/tur.c -@@ -15,6 +15,7 @@ - #include - #include - #include -+#include - #include - - #include "checkers.h" -diff --git a/libmultipath/lock.h b/libmultipath/lock.h -index 38473a8c..5f323055 100644 ---- a/libmultipath/lock.h -+++ b/libmultipath/lock.h -@@ -2,6 +2,7 @@ - #define LOCK_H_INCLUDED - - #include -+#include - #include - #include - diff --git a/0008-RH-Fix-nvme-function-missing-argument.patch b/0004-RH-Fix-nvme-function-missing-argument.patch similarity index 84% rename from 0008-RH-Fix-nvme-function-missing-argument.patch rename to 0004-RH-Fix-nvme-function-missing-argument.patch index 74b7b53..33a8d5f 100644 --- a/0008-RH-Fix-nvme-function-missing-argument.patch +++ b/0004-RH-Fix-nvme-function-missing-argument.patch @@ -1,4 +1,4 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 283b5dd645663a2cf16f2813581772d7a84db6ad Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Fri, 25 Jan 2019 14:54:56 -0600 Subject: [PATCH] RH: Fix nvme function missing argument @@ -12,10 +12,10 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmultipath/nvme/argconfig.h b/libmultipath/nvme/argconfig.h -index e6c54453..0c6c9439 100644 +index b3caa7be..f91504c9 100644 --- a/libmultipath/nvme/argconfig.h +++ b/libmultipath/nvme/argconfig.h -@@ -76,7 +76,7 @@ struct argconfig_commandline_options { +@@ -63,7 +63,7 @@ struct argconfig_commandline_options { extern "C" { #endif diff --git a/0004-libmpathutils-uxsock.c-Include-string.h-for-memcpy.patch b/0004-libmpathutils-uxsock.c-Include-string.h-for-memcpy.patch deleted file mode 100644 index 8fc3211..0000000 --- a/0004-libmpathutils-uxsock.c-Include-string.h-for-memcpy.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Khem Raj -Date: Mon, 17 Feb 2025 12:05:03 -0800 -Subject: [PATCH] libmpathutils/uxsock.c: Include string.h for memcpy - -Fixes -uxsock.c:72:2: error: call to undeclared library function 'memcpy' with type 'void *(void *, const void *, unsigned long)'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] - -Signed-off-by: Khem Raj -Cc: Benjamin Marzinski -Cc: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmpathutil/uxsock.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/libmpathutil/uxsock.c b/libmpathutil/uxsock.c -index 2135476d..a474874e 100644 ---- a/libmpathutil/uxsock.c -+++ b/libmpathutil/uxsock.c -@@ -8,6 +8,7 @@ - #include - #include - #include -+#include - #include - #include - #include diff --git a/0009-RH-use-rpm-optflags-if-present.patch b/0005-RH-use-rpm-optflags-if-present.patch similarity index 85% rename from 0009-RH-use-rpm-optflags-if-present.patch rename to 0005-RH-use-rpm-optflags-if-present.patch index 1b96a3a..7a6f57f 100644 --- a/0009-RH-use-rpm-optflags-if-present.patch +++ b/0005-RH-use-rpm-optflags-if-present.patch @@ -1,4 +1,4 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From bf46f8029998498045bb055415ba3ff515c79eaa Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Wed, 19 Apr 2017 06:10:01 -0500 Subject: [PATCH] RH: use rpm optflags if present @@ -13,10 +13,10 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index c225a1ed..7774f1f4 100644 +index ead89030..03aee175 100644 --- a/Makefile.inc +++ b/Makefile.inc -@@ -99,28 +99,39 @@ SYSTEMD_LIBDEPS := $(if $(SYSTEMD),$(if $(shell test $(SYSTEMD) -gt 209 && echo +@@ -102,17 +102,29 @@ SYSTEMD_LIBDEPS := $(if $(SYSTEMD),$(if $(shell test $(SYSTEMD) -gt 209 && echo MODPROBE_UNIT := $(shell test "0$(SYSTEMD)" -lt 245 2>/dev/null || \ echo "modprobe@dm_multipath.service") @@ -50,8 +50,10 @@ index c225a1ed..7774f1f4 100644 -D_FILE_OFFSET_BITS=64 \ -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(TGTDIR)$(plugindir)\" \ -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(TGTDIR)$(configdir)\" \ - -DDEFAULT_CONFIGFILE=\"$(TGTDIR)$(configfile)\" -DSTATE_DIR=\"$(TGTDIR)$(statedir)\" \ - -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP +@@ -121,12 +133,11 @@ CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) $(D_URCU_VERSION) \ + -DABSTRACT_SOCKET=\"$(abstract_socket)\" -DPATHNAME_SOCKET=\"$(pathname_socket)\" \ + -DWSTRINGOP_TRUNCATION=$(if $(WSTRINGOP_TRUNCATION),1,0) \ + -MMD -MP -CFLAGS := -std=$(C_STD) $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ - -fexceptions +CFLAGS := -std=$(C_STD) $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe diff --git a/0010-RH-add-mpathconf.patch b/0006-RH-add-mpathconf.patch similarity index 99% rename from 0010-RH-add-mpathconf.patch rename to 0006-RH-add-mpathconf.patch index c587841..46f1126 100644 --- a/0010-RH-add-mpathconf.patch +++ b/0006-RH-add-mpathconf.patch @@ -1,4 +1,4 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 29e5c6d6e2177e73d1be2ed2af66c1007487bf60 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 16 Oct 2014 15:49:01 -0500 Subject: [PATCH] RH: add mpathconf @@ -23,10 +23,10 @@ Signed-off-by: Benjamin Marzinski create mode 100644 multipath/mpathconf.8 diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt -index 7843c380..ab5259cf 100644 +index a5856bcc..5c9113ba 100644 --- a/.github/actions/spelling/expect.txt +++ b/.github/actions/spelling/expect.txt -@@ -127,9 +127,11 @@ Marzinski +@@ -131,9 +131,11 @@ Marzinski misdetection mpath mpathb @@ -38,7 +38,7 @@ index 7843c380..ab5259cf 100644 multipathc multipathd multipathed -@@ -147,6 +149,7 @@ ontap +@@ -154,6 +156,7 @@ ontap OOM opensvc OPTFLAGS diff --git a/0011-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 92% rename from 0011-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch index 612d876..cef8b56 100644 --- a/0011-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +++ b/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch @@ -1,4 +1,4 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From d6ad888bad3850bb0a342ebcdc9fd78773eb3b2a Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Fri, 17 Oct 2014 11:20:34 -0500 Subject: [PATCH] RH: add wwids from kernel cmdline mpath.wwids with -A @@ -20,10 +20,10 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/multipath/main.c b/multipath/main.c -index 346acb61..adc50d69 100644 +index 31012874..a667c2ee 100644 --- a/multipath/main.c +++ b/multipath/main.c -@@ -120,7 +120,7 @@ usage (char * progname) +@@ -111,7 +111,7 @@ usage (char * progname) fprintf (stderr, " %s [-v level] [-R retries] -F\n", progname); fprintf (stderr, " %s [-v level] [-l|-ll] [device]\n", progname); fprintf (stderr, " %s [-v level] [-a|-w] device\n", progname); @@ -32,7 +32,7 @@ index 346acb61..adc50d69 100644 fprintf (stderr, " %s [-v level] [-i] [-c|-C] device\n", progname); fprintf (stderr, " %s [-v level] [-i] [-u|-U]\n", progname); fprintf (stderr, " %s [-h|-t|-T]\n", progname); -@@ -134,6 +134,8 @@ usage (char * progname) +@@ -125,6 +125,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" @@ -41,7 +41,7 @@ index 346acb61..adc50d69 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" -@@ -449,6 +451,50 @@ static void cleanup_vecs(void) +@@ -440,6 +442,50 @@ static void cleanup_vecs(void) free_pathvec(vecs.pathvec, FREE_PATHS); } @@ -92,7 +92,7 @@ index 346acb61..adc50d69 100644 static int configure (struct config *conf, enum mpath_cmds cmd, enum devtypes dev_type, char *devpath) -@@ -860,7 +906,7 @@ main (int argc, char *argv[]) +@@ -851,7 +897,7 @@ main (int argc, char *argv[]) condlog(1, "failed to register cleanup handler for vecs: %m"); if (atexit(cleanup_bindings)) condlog(1, "failed to register cleanup handler for bindings: %m"); @@ -101,7 +101,7 @@ index 346acb61..adc50d69 100644 switch(arg) { case 'v': if (!isdigit(optarg[0])) { -@@ -931,6 +977,10 @@ main (int argc, char *argv[]) +@@ -922,6 +968,10 @@ main (int argc, char *argv[]) case 'T': cmd = CMD_DUMP_CONFIG; break; @@ -138,7 +138,7 @@ index b88e9a4c..edd742aa 100644 Remove the WWID for the specified device from the WWIDs file. . diff --git a/multipathd/multipathd.service.in b/multipathd/multipathd.service.in -index 3d957733..7ef6e99e 100644 +index ab166435..1ec08c6e 100644 --- a/multipathd/multipathd.service.in +++ b/multipathd/multipathd.service.in @@ -19,6 +19,7 @@ StartLimitBurst=3 diff --git a/0012-RH-reset-default-find_mutipaths-value-to-off.patch b/0008-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 87% rename from 0012-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0008-RH-reset-default-find_mutipaths-value-to-off.patch index 5789916..fdc90d4 100644 --- a/0012-RH-reset-default-find_mutipaths-value-to-off.patch +++ b/0008-RH-reset-default-find_mutipaths-value-to-off.patch @@ -1,4 +1,4 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 064d761121e7e2c7b63ab280e341d8010a413119 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 7 Jun 2018 17:43:52 -0500 Subject: [PATCH] RH: reset default find_mutipaths value to off @@ -14,7 +14,7 @@ Signed-off-by: Benjamin Marzinski 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h -index 02f7e57c..cd03fd1a 100644 +index 134b690a..e2fe7ac4 100644 --- a/libmultipath/defaults.h +++ b/libmultipath/defaults.h @@ -24,7 +24,7 @@ @@ -27,10 +27,10 @@ index 02f7e57c..cd03fd1a 100644 #define DEFAULT_DEV_LOSS_TMO 600 #define DEFAULT_RETAIN_HWHANDLER RETAIN_HWHANDLER_ON diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in -index af9fbb96..0c1eff40 100644 +index ba291e11..b8389db3 100644 --- a/multipath/multipath.conf.5.in +++ b/multipath/multipath.conf.5.in -@@ -1226,7 +1226,7 @@ as non-multipath and passed on to upper layers. +@@ -1227,7 +1227,7 @@ as non-multipath and passed on to upper layers. \fBNote:\fR this may cause delays during device detection if there are single-path devices which aren\'t blacklisted. .TP diff --git a/0013-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 86% rename from 0013-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch index 1f94eb3..8065e9f 100644 --- a/0013-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +++ b/0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch @@ -1,4 +1,4 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 335b8eb2773b07a602e84e14c1f3e289a9b25b5a Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 11 Apr 2019 13:25:42 -0500 Subject: [PATCH] RH: attempt to get ANA info via sysfs first @@ -13,10 +13,10 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/libmultipath/prioritizers/ana.c b/libmultipath/prioritizers/ana.c -index e9827dca..80a32aa3 100644 +index 34527b22..4eaa3cc3 100644 --- a/libmultipath/prioritizers/ana.c +++ b/libmultipath/prioritizers/ana.c -@@ -24,6 +24,7 @@ +@@ -23,6 +23,7 @@ #include "prio.h" #include "util.h" #include "structs.h" @@ -24,7 +24,7 @@ index e9827dca..80a32aa3 100644 enum { ANA_ERR_GETCTRL_FAILED = 1, -@@ -36,6 +37,7 @@ enum { +@@ -35,6 +36,7 @@ enum { ANA_ERR_GETNS_FAILED, ANA_ERR_NO_MEMORY, ANA_ERR_NO_INFORMATION, @@ -32,7 +32,7 @@ index e9827dca..80a32aa3 100644 }; static const char *ana_errmsg[] = { -@@ -49,6 +51,7 @@ static const char *ana_errmsg[] = { +@@ -48,6 +50,7 @@ static const char *ana_errmsg[] = { [ANA_ERR_GETNS_FAILED] = "couldn't get namespace info", [ANA_ERR_NO_MEMORY] = "out of memory", [ANA_ERR_NO_INFORMATION] = "invalid fd", @@ -40,7 +40,7 @@ index e9827dca..80a32aa3 100644 }; static const char *anas_string[] = { -@@ -107,6 +110,27 @@ static int get_ana_state(__u32 nsid, __u32 anagrpid, void *ana_log, +@@ -106,6 +109,27 @@ static int get_ana_state(__u32 nsid, __u32 anagrpid, void *ana_log, return -ANA_ERR_GETANAS_NOTFOUND; } @@ -68,7 +68,7 @@ index e9827dca..80a32aa3 100644 static int get_ana_info(struct path * pp) { int rc; -@@ -209,8 +233,11 @@ int getprio(struct path *pp, __attribute__((unused)) char *args) +@@ -208,8 +232,11 @@ int getprio(struct path *pp, __attribute__((unused)) char *args) if (pp->fd < 0) rc = -ANA_ERR_NO_INFORMATION; diff --git a/0014-RH-make-parse_vpd_pg83-match-scsi_id-output.patch b/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch similarity index 91% rename from 0014-RH-make-parse_vpd_pg83-match-scsi_id-output.patch rename to 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch index 3243375..f7bca92 100644 --- a/0014-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +++ b/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch @@ -1,4 +1,4 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 137c96d16b6bb03d8a52854e152db4ee36b7d9e4 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 25 Mar 2021 13:05:10 -0500 Subject: [PATCH] RH: make parse_vpd_pg83 match scsi_id output @@ -14,10 +14,10 @@ Signed-off-by: Benjamin Marzinski 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index b5851561..a3cc6e83 100644 +index 31db8758..21cfcc73 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c -@@ -1219,13 +1219,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, +@@ -1225,13 +1225,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, good_len = 8; break; case 2: @@ -33,7 +33,7 @@ index b5851561..a3cc6e83 100644 good_len = 8; break; default: -@@ -1243,10 +1239,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, +@@ -1249,10 +1245,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, break; case 0x8: /* SCSI Name: Prio 3 */ diff --git a/0015-RH-add-scsi-device-handlers-to-modules-load.d.patch b/0011-RH-add-scsi-device-handlers-to-modules-load.d.patch similarity index 89% rename from 0015-RH-add-scsi-device-handlers-to-modules-load.d.patch rename to 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch index 97fb4df..3fe7c25 100644 --- a/0015-RH-add-scsi-device-handlers-to-modules-load.d.patch +++ b/0011-RH-add-scsi-device-handlers-to-modules-load.d.patch @@ -1,4 +1,4 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 374755791536be4870ab2e93ae36549cbaaeb800 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Fri, 25 Mar 2022 18:12:06 -0500 Subject: [PATCH] RH: add scsi device handlers to modules-load.d @@ -11,7 +11,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc -index 7774f1f4..0e836f0a 100644 +index 03aee175..936a622f 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -16,7 +16,7 @@ READLINE := diff --git a/0016-RH-compile-with-libreadline-support.patch b/0012-RH-compile-with-libreadline-support.patch similarity index 89% rename from 0016-RH-compile-with-libreadline-support.patch rename to 0012-RH-compile-with-libreadline-support.patch index e7579b0..0964c42 100644 --- a/0016-RH-compile-with-libreadline-support.patch +++ b/0012-RH-compile-with-libreadline-support.patch @@ -1,4 +1,4 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From cc15379130e8aa068e97c64afd46be212b456d4f Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Tue, 15 Nov 2022 18:03:33 -0600 Subject: [PATCH] RH: compile with libreadline support @@ -12,7 +12,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc -index 0e836f0a..e1d3fcd1 100644 +index 936a622f..f475f70f 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -12,7 +12,7 @@ diff --git a/0017-RH-Add-mpathcleanup.patch b/0013-RH-Add-mpathcleanup.patch similarity index 98% rename from 0017-RH-Add-mpathcleanup.patch rename to 0013-RH-Add-mpathcleanup.patch index bd2dcd6..d1a8e84 100644 --- a/0017-RH-Add-mpathcleanup.patch +++ b/0013-RH-Add-mpathcleanup.patch @@ -1,4 +1,4 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 2ef5bd86052ba0b22f4d3a16e69cdf268d90a53a Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Fri, 7 Jul 2023 15:25:59 -0500 Subject: [PATCH] RH: Add mpathcleanup diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 232daba..24b00bd 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath -Version: 0.11.1 -Release: 2%{?dist} +Version: 0.13.0 +Release: 1%{?dist} Summary: Tools to manage multipath devices using device-mapper # readline uses GPL-3.0-only License: GPL-2.0-only AND GPL-3.0-only @@ -8,26 +8,22 @@ 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 -L https://github.com/opensvc/multipath-tools/archive/0.11.1.tar.gz -o multipath-tools-0.11.1.tgz -Source0: multipath-tools-0.11.1.tgz +# curl -L https://github.com/opensvc/multipath-tools/archive/0.13.0.tar.gz -o multipath-tools-0.13.0.tgz +Source0: multipath-tools-0.13.0.tgz Source1: multipath.conf -Patch0001: 0001-multipathd-trigger-uevents-for-blacklisted-paths-in-.patch -Patch0002: 0002-multipath-tools-fix-compilation-with-latest-userspac.patch -Patch0003: 0003-libmultipath-include-urcu.h-before-urcu-atomic.h.patch -Patch0004: 0004-libmpathutils-uxsock.c-Include-string.h-for-memcpy.patch -Patch0005: 0005-RH-fixup-udev-rules-for-redhat.patch -Patch0006: 0006-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0007: 0007-RH-don-t-start-without-a-config-file.patch -Patch0008: 0008-RH-Fix-nvme-function-missing-argument.patch -Patch0009: 0009-RH-use-rpm-optflags-if-present.patch -Patch0010: 0010-RH-add-mpathconf.patch -Patch0011: 0011-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0012: 0012-RH-reset-default-find_mutipaths-value-to-off.patch -Patch0013: 0013-RH-attempt-to-get-ANA-info-via-sysfs-first.patch -Patch0014: 0014-RH-make-parse_vpd_pg83-match-scsi_id-output.patch -Patch0015: 0015-RH-add-scsi-device-handlers-to-modules-load.d.patch -Patch0016: 0016-RH-compile-with-libreadline-support.patch -Patch0017: 0017-RH-Add-mpathcleanup.patch +Patch0001: 0001-RH-fixup-udev-rules-for-redhat.patch +Patch0002: 0002-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0003: 0003-RH-don-t-start-without-a-config-file.patch +Patch0004: 0004-RH-Fix-nvme-function-missing-argument.patch +Patch0005: 0005-RH-use-rpm-optflags-if-present.patch +Patch0006: 0006-RH-add-mpathconf.patch +Patch0007: 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0008: 0008-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0009: 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0010: 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +Patch0011: 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch +Patch0012: 0012-RH-compile-with-libreadline-support.patch +Patch0013: 0013-RH-Add-mpathcleanup.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -115,7 +111,7 @@ This package contains the files needed to develop applications that use device-mapper-multipath's libdmmp C API library %prep -%autosetup -n multipath-tools-0.11.1 -p1 +%autosetup -n multipath-tools-0.13.0 -p1 cp %{SOURCE1} . %build @@ -167,6 +163,7 @@ fi %{_sbindir}/mpathcleanup %{_sbindir}/mpathpersist %{_unitdir}/multipathd.service +%{_unitdir}/multipathd-queueing.service %{_unitdir}/multipathd.socket %{_mandir}/man5/multipath.conf.5* %{_mandir}/man8/multipath.8* @@ -237,6 +234,13 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Tue Nov 4 2025 Benjamin Marzinski - 0.13.0-1 +- Update source to upstream release 0.13.0 + * Previous patches 0001-0004 are included in the tarball +- Install /lib/systemd/system/multipathd-queueing.service +- Rename redhat patches + * Previous patches 0005-0017 are now patches 0001-0013 + * Wed Jul 23 2025 Fedora Release Engineering - 0.11.1-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild diff --git a/sources b/sources index 5eea94e..233c4ea 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (multipath-tools-0.11.1.tgz) = ac6bacd725bc831a140b75a72c81296eb1ed4080fb6350caf6178914d1bdce743705f3bd4e31f318068f6272dc98e12d63ee38228a3521a3d1c7bc8eb30812f9 +SHA512 (multipath-tools-0.13.0.tgz) = 75c84524ee27590b8b751ea500898a44e5ac3d58d55be6bcab919d0d423049db3a4466fcb9135705cf63ba074416973bb651255063269e9f682f11d21ba57e59 SHA512 (multipath.conf) = 71953dce5a68adcf60a942305f5a66023e6f4c4baf53b1bfdb4edf65ed5b8e03db804363c36d1dcfd85591f4766f52b515269904c53b84d7b076da0b80b09942 From d6f2be9e59baa23b2d610a68d3635da3d5b6b991 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 13 Nov 2025 19:23:18 -0500 Subject: [PATCH 67/67] device-mapper-multipath-0.13.0-2 Move STI tests to TMT --- {tests/.fmf => .fmf}/version | 0 device-mapper-multipath.spec | 5 +++- plans/multipath.fmf | 58 ++++++++++++++++++++++++++++++++++++ tests/provision.fmf | 5 ---- tests/tests.yml | 44 --------------------------- 5 files changed, 62 insertions(+), 50 deletions(-) rename {tests/.fmf => .fmf}/version (100%) create mode 100644 plans/multipath.fmf delete mode 100644 tests/provision.fmf delete mode 100644 tests/tests.yml diff --git a/tests/.fmf/version b/.fmf/version similarity index 100% rename from tests/.fmf/version rename to .fmf/version diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 24b00bd..5d80d4e 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.13.0 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Tools to manage multipath devices using device-mapper # readline uses GPL-3.0-only License: GPL-2.0-only AND GPL-3.0-only @@ -234,6 +234,9 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Thu Nov 13 2025 Benjamin Marzinski - 0.13.0-2 +- Move STI tests to TMT + * Tue Nov 4 2025 Benjamin Marzinski - 0.13.0-1 - Update source to upstream release 0.13.0 * Previous patches 0001-0004 are included in the tarball diff --git a/plans/multipath.fmf b/plans/multipath.fmf new file mode 100644 index 0000000..876c77a --- /dev/null +++ b/plans/multipath.fmf @@ -0,0 +1,58 @@ +summary: basic functionality tests + +provision: + hardware: + memory: ">= 2 GB" + +prepare: + how: install + package: + - device-mapper-multipath + - perl + +discover: + how: shell + tests: + - name: medium_error_scsi_debug + path: /tests/medium_error_scsi_debug + test: ./main.sh + duration: 15m + - name: squelch_scsi_id + path: /tests/squelch_scsi_id + test: ./main.sh + duration: 15m + - name: multipathd_oom + path: /tests/multipathd_oom + test: ./main.sh + duration: 15m + - name: user_friendly_names + path: /tests/user_friendly_names + test: ./main.sh + duration: 15m + - name: kpartx_4k_aligned + path: /tests/kpartx_4k_aligned + test: ./main.sh + duration: 15m + - name: bindings + path: /tests/bindings + test: ./main.sh + duration: 15m + - name: restate_module + path: /tests/restate_module + test: ./main.sh + duration: 15m + - name: find_multipaths + path: /tests/find_multipaths + test: ./main.sh + duration: 15m + - name: multipath_conf_syntax + path: /tests/multipath_conf_syntax + test: ./main.sh + duration: 15m + - name: alias_clash + path: /tests/alias_clash + test: ./main.sh + duration: 15m + +execute: + how: tmt diff --git a/tests/provision.fmf b/tests/provision.fmf deleted file mode 100644 index 62a6eba..0000000 --- a/tests/provision.fmf +++ /dev/null @@ -1,5 +0,0 @@ ---- - -standard-inventory-qcow2: - qemu: - m: 2G diff --git a/tests/tests.yml b/tests/tests.yml deleted file mode 100644 index 15f26d2..0000000 --- a/tests/tests.yml +++ /dev/null @@ -1,44 +0,0 @@ ---- -# No tests suitable for atomic environment -# No tests suitable for container environment - -# Tests suitable for classic environment -- hosts: localhost - roles: - - role: standard-test-basic - tags: - - classic - tests: - - medium_error_scsi_debug: - run: ./main.sh - timeout: 15m - - squelch_scsi_id: - run: ./main.sh - timeout: 15m - - multipathd_oom: - run: ./main.sh - timeout: 15m - - user_friendly_names: - run: ./main.sh - timeout: 15m - - kpartx_4k_aligned: - run: ./main.sh - timeout: 15m - - bindings: - run: ./main.sh - timeout: 15m - - restate_module: - run: ./main.sh - timeout: 15m - - find_multipaths: - run: ./main.sh - timeout: 15m - - multipath_conf_syntax: - run: ./main.sh - timeout: 15m - - alias_clash: - run: ./main.sh - timeout: 15m - required_packages: - - device-mapper-multipath - - perl