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 02b2e18..0000000 --- a/0001-Change-the-multipath.conf-manpage-uxsock_timeout-def.patch +++ /dev/null @@ -1,30 +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 - . - . --- -2.17.2 - diff --git a/0124-RH-fixup-udev-rules-for-redhat.patch b/0001-RH-fixup-udev-rules-for-redhat.patch similarity index 97% rename from 0124-RH-fixup-udev-rules-for-redhat.patch rename to 0001-RH-fixup-udev-rules-for-redhat.patch index d5bbd5b..e84f9e0 100644 --- a/0124-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) @@ -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/0002-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 95% rename from 0125-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0002-RH-Remove-the-property-blacklist-exception-builtin.patch index 9c44867..dcb1491 100644 --- a/0125-RH-Remove-the-property-blacklist-exception-builtin.patch +++ b/0002-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/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 2d38590..0000000 --- a/0002-libmultipath-find_mpe-don-t-match-with-empty-WWID.patch +++ /dev/null @@ -1,27 +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) --- -2.17.2 - diff --git a/0126-RH-don-t-start-without-a-config-file.patch b/0003-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 0003-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/0003-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/0003-libmultipath-copy-mpp-hwe-from-pp-hwe.patch b/0003-libmultipath-copy-mpp-hwe-from-pp-hwe.patch deleted file mode 100644 index 63ff6a5..0000000 --- a/0003-libmultipath-copy-mpp-hwe-from-pp-hwe.patch +++ /dev/null @@ -1,260 +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); --- -2.17.2 - diff --git a/0127-RH-Fix-nvme-function-missing-argument.patch b/0004-RH-Fix-nvme-function-missing-argument.patch similarity index 98% rename from 0127-RH-Fix-nvme-function-missing-argument.patch rename to 0004-RH-Fix-nvme-function-missing-argument.patch index b5c63c0..ced7159 100644 --- a/0127-RH-Fix-nvme-function-missing-argument.patch +++ b/0004-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/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 c3a0a18..0000000 --- a/0004-libmultipath-dm_map_present_by_uuid-fix-dm_task_crea.patch +++ /dev/null @@ -1,31 +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); --- -2.17.2 - diff --git a/0128-RH-use-rpm-optflags-if-present.patch b/0005-RH-use-rpm-optflags-if-present.patch similarity index 94% rename from 0128-RH-use-rpm-optflags-if-present.patch rename to 0005-RH-use-rpm-optflags-if-present.patch index f765f47..debec54 100644 --- a/0128-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,12 +49,9 @@ 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 $? - $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< + $(CC) $(CFLAGS) -c -o $@ $< --- -2.17.2 - diff --git a/0005-libdmmp-tests-fix-compilation.patch b/0005-libdmmp-tests-fix-compilation.patch deleted file mode 100644 index d1d9955..0000000 --- a/0005-libdmmp-tests-fix-compilation.patch +++ /dev/null @@ -1,43 +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; --- -2.17.2 - diff --git a/0129-RH-add-mpathconf.patch b/0006-RH-add-mpathconf.patch similarity index 99% rename from 0129-RH-add-mpathconf.patch rename to 0006-RH-add-mpathconf.patch index 346251a..d262f55 100644 --- a/0129-RH-add-mpathconf.patch +++ b/0006-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/0006-libmultipath-prio-constify-some-function-parameters.patch b/0006-libmultipath-prio-constify-some-function-parameters.patch deleted file mode 100644 index 80771ea..0000000 --- a/0006-libmultipath-prio-constify-some-function-parameters.patch +++ /dev/null @@ -1,53 +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 *); --- -2.17.2 - diff --git a/0130-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 0130-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 3f0a9ad..557669b 100644 --- a/0130-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 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/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 90a2f25..0000000 --- a/0007-libmultipath-checkers-prio-allow-non-lazy-.so-loadin.patch +++ /dev/null @@ -1,90 +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; - } - --- -2.17.2 - diff --git a/0131-RH-reset-default-find_mutipaths-value-to-off.patch b/0008-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 0008-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/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 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/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 edc3e66..0000000 --- a/0008-multipath-tools-Makefiles-separate-rules-for-.so-and.patch +++ /dev/null @@ -1,96 +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) --- -2.17.2 - diff --git a/0132-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0009-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 0009-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/0009-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/0009-libmultipath-create-separate-.so-for-unit-tests.patch b/0009-libmultipath-create-separate-.so-for-unit-tests.patch deleted file mode 100644 index 38a01d7..0000000 --- a/0009-libmultipath-create-separate-.so-for-unit-tests.patch +++ /dev/null @@ -1,87 +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)) --- -2.17.2 - 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 new file mode 100644 index 0000000..0ab20c5 --- /dev/null +++ b/0010-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 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, + 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/0010-libmultipath-add-linker-version-script.patch b/0010-libmultipath-add-linker-version-script.patch deleted file mode 100644 index ed6ad7f..0000000 --- a/0010-libmultipath-add-linker-version-script.patch +++ /dev/null @@ -1,303 +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: -+ *; -+}; --- -2.17.2 - diff --git a/0011-libmpathpersist-add-linker-version-script.patch b/0011-libmpathpersist-add-linker-version-script.patch deleted file mode 100644 index 916c4f3..0000000 --- a/0011-libmpathpersist-add-linker-version-script.patch +++ /dev/null @@ -1,81 +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: *; -+}; --- -2.17.2 - diff --git a/0012-libmpathcmd-add-linker-version-script.patch b/0012-libmpathcmd-add-linker-version-script.patch deleted file mode 100644 index 454c3b7..0000000 --- a/0012-libmpathcmd-add-linker-version-script.patch +++ /dev/null @@ -1,74 +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: -+ *; -+}; --- -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 deleted file mode 100644 index a04673d..0000000 --- a/0013-libmpathpersist-initialize-mpp-hwe-in-get_mpvec.patch +++ /dev/null @@ -1,38 +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 ; - } --- -2.17.2 - diff --git a/0014-multipathd-allow-shutdown-during-configure.patch b/0014-multipathd-allow-shutdown-during-configure.patch deleted file mode 100644 index 2cbfecf..0000000 --- a/0014-multipathd-allow-shutdown-during-configure.patch +++ /dev/null @@ -1,140 +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) --- -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 deleted file mode 100644 index c2d1475..0000000 --- a/0015-multipathd-avoid-sending-READY-1-to-systemd-on-early.patch +++ /dev/null @@ -1,67 +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 - } - } - --- -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 deleted file mode 100644 index b38cf2f..0000000 --- a/0016-multipathd-send-STOPPING-1-to-systemd-on-shutdown.patch +++ /dev/null @@ -1,31 +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; - } --- -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 deleted file mode 100644 index 76894d0..0000000 --- a/0017-multipathd-send-RELOADING-1-to-systemd-on-DAEMON_CON.patch +++ /dev/null @@ -1,42 +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 - --- -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 deleted file mode 100644 index 400298e..0000000 --- a/0018-multipathd-use-volatile-qualifier-for-running_state.patch +++ /dev/null @@ -1,31 +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; --- -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 deleted file mode 100644 index 73f99ec..0000000 --- a/0019-multipathd-generalize-and-fix-wait_for_state_change_.patch +++ /dev/null @@ -1,72 +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; - } --- -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 deleted file mode 100644 index a5310f3..0000000 --- a/0020-multipathd-set_config_state-avoid-code-duplication.patch +++ /dev/null @@ -1,55 +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; --- -2.17.2 - 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 cc51513..0000000 --- a/0021-multipathd-cancel-threads-early-during-shutdown.patch +++ /dev/null @@ -1,61 +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); --- -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 deleted file mode 100644 index fe32b1a..0000000 --- a/0022-multipath-tools-don-t-call-dm_lib_release-any-more.patch +++ /dev/null @@ -1,165 +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 */ --- -2.17.2 - 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 b5e96b2..0000000 --- a/0023-libmultipath-devmapper-refactor-libdm-version-determ.patch +++ /dev/null @@ -1,506 +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); - --- -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 deleted file mode 100644 index 026dd7c..0000000 --- a/0024-libmultipath-protect-racy-libdevmapper-calls-with-a-.patch +++ /dev/null @@ -1,437 +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) { --- -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 deleted file mode 100644 index 9470cf4..0000000 --- a/0025-libmultipath-constify-file-argument-in-config-parser.patch +++ /dev/null @@ -1,98 +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); --- -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 deleted file mode 100644 index e3375f0..0000000 --- a/0026-libmultipath-provide-defaults-for-get-put-_multipath.patch +++ /dev/null @@ -1,204 +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; --- -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 deleted file mode 100644 index def8896..0000000 --- a/0027-libmpathpersist-allow-using-libmultipath-get-put-_mu.patch +++ /dev/null @@ -1,156 +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 : --- -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 deleted file mode 100644 index 762daea..0000000 --- a/0028-multipath-use-get_put-_multipath_config-from-libmult.patch +++ /dev/null @@ -1,67 +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); --- -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 deleted file mode 100644 index 6ab3c10..0000000 --- a/0029-mpathpersist-use-get-put-_multipath_config-from-libm.patch +++ /dev/null @@ -1,55 +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; --- -2.17.2 - 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 3bd9de0..0000000 --- a/0030-libmultipath-add-udev-and-logsink-symbols.patch +++ /dev/null @@ -1,168 +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; --- -2.17.2 - diff --git a/0031-multipath-remove-logsink-and-udev.patch b/0031-multipath-remove-logsink-and-udev.patch deleted file mode 100644 index 7ba8272..0000000 --- a/0031-multipath-remove-logsink-and-udev.patch +++ /dev/null @@ -1,48 +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_ --- -2.17.2 - diff --git a/0032-libmpathpersist-call-libmultipath_-init-exit.patch b/0032-libmpathpersist-call-libmultipath_-init-exit.patch deleted file mode 100644 index 9c52f9f..0000000 --- a/0032-libmpathpersist-call-libmultipath_-init-exit.patch +++ /dev/null @@ -1,96 +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. --- -2.17.2 - diff --git a/0033-mpathpersist-remove-logsink-and-udev.patch b/0033-mpathpersist-remove-logsink-and-udev.patch deleted file mode 100644 index 501f32f..0000000 --- a/0033-mpathpersist-remove-logsink-and-udev.patch +++ /dev/null @@ -1,52 +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; - } --- -2.17.2 - diff --git a/0034-multipathd-remove-logsink-and-udev.patch b/0034-multipathd-remove-logsink-and-udev.patch deleted file mode 100644 index 25e929a..0000000 --- a/0034-multipathd-remove-logsink-and-udev.patch +++ /dev/null @@ -1,57 +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 ) { --- -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 deleted file mode 100644 index c8fa5bb..0000000 --- a/0035-multipath-tools-add-Vexata-by-StorCentric-VX-arrays.patch +++ /dev/null @@ -1,40 +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 --- -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 deleted file mode 100644 index 006d74e..0000000 --- a/0036-multipath-tools-Violin-and-Nexsan-were-bought-by-Sto.patch +++ /dev/null @@ -1,45 +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", --- -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 deleted file mode 100644 index 0f67ead..0000000 --- a/0037-libmultipath-fix-memory-leaks-in-coalesce_paths.patch +++ /dev/null @@ -1,117 +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; - } - --- -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 deleted file mode 100644 index d51c502..0000000 --- a/0038-multipath-tools-replace-hidden-tab-by-space-in-hwtab.patch +++ /dev/null @@ -1,31 +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, --- -2.17.2 - 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 6f4fc00..0000000 --- a/0039-multipathd-uxlsnr-avoid-deadlock-on-exit.patch +++ /dev/null @@ -1,105 +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; - --- -2.17.2 - diff --git a/0040-multipathd-Fix-liburcu-memory-leak.patch b/0040-multipathd-Fix-liburcu-memory-leak.patch deleted file mode 100644 index 8f04a66..0000000 --- a/0040-multipathd-Fix-liburcu-memory-leak.patch +++ /dev/null @@ -1,98 +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); --- -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 deleted file mode 100644 index 329876d..0000000 --- a/0041-multipathd-move-handling-of-io_err_stat_attr-into-li.patch +++ /dev/null @@ -1,146 +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 --- -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 deleted file mode 100644 index f65e6eb..0000000 --- a/0042-multipathd-move-vecs-desctruction-into-cleanup-funct.patch +++ /dev/null @@ -1,125 +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(); --- -2.17.2 - diff --git a/0043-multipathd-make-some-globals-static.patch b/0043-multipathd-make-some-globals-static.patch deleted file mode 100644 index 6ae5835..0000000 --- a/0043-multipathd-make-some-globals-static.patch +++ /dev/null @@ -1,45 +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) - { --- -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 deleted file mode 100644 index 6c2251e..0000000 --- a/0044-multipathd-move-threads-destruction-into-separate-fu.patch +++ /dev/null @@ -1,164 +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 --- -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 deleted file mode 100644 index 97125dc..0000000 --- a/0045-multipathd-move-conf-destruction-into-separate-funct.patch +++ /dev/null @@ -1,56 +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 --- -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 deleted file mode 100644 index bbff859..0000000 --- a/0046-multipathd-move-pid-destruction-into-separate-functi.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: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-multipathd-close-pidfile-on-exit.patch b/0047-multipathd-close-pidfile-on-exit.patch deleted file mode 100644 index 6c9c1b1..0000000 --- a/0047-multipathd-close-pidfile-on-exit.patch +++ /dev/null @@ -1,45 +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; --- -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 deleted file mode 100644 index bf3c462..0000000 --- a/0048-multipathd-add-helper-for-systemd-notification-at-ex.patch +++ /dev/null @@ -1,60 +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 --- -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 deleted file mode 100644 index fba8169..0000000 --- a/0049-multipathd-child-call-cleanups-in-failure-case-too.patch +++ /dev/null @@ -1,52 +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 --- -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 deleted file mode 100644 index 279109c..0000000 --- a/0050-multipathd-unwatch_all_dmevents-check-if-waiter-is-i.patch +++ /dev/null @@ -1,28 +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); --- -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 deleted file mode 100644 index 9cf6182..0000000 --- a/0051-multipathd-print-error-message-if-config-can-t-be-lo.patch +++ /dev/null @@ -1,30 +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; --- -2.17.2 - diff --git a/0052-libmultipath-add-libmp_dm_exit.patch b/0052-libmultipath-add-libmp_dm_exit.patch deleted file mode 100644 index db24711..0000000 --- a/0052-libmultipath-add-libmp_dm_exit.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: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/0053-multipathd-fixup-libdm-deinitialization.patch b/0053-multipathd-fixup-libdm-deinitialization.patch deleted file mode 100644 index b57a8cd..0000000 --- a/0053-multipathd-fixup-libdm-deinitialization.patch +++ /dev/null @@ -1,40 +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"); --- -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 deleted file mode 100644 index 004016c..0000000 --- a/0054-libmultipath-log_thread_stop-check-if-logarea-is-ini.patch +++ /dev/null @@ -1,29 +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); --- -2.17.2 - 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 8455a96..0000000 --- a/0055-multipathd-add-cleanup_child-exit-handler.patch +++ /dev/null @@ -1,95 +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); - } - --- -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 deleted file mode 100644 index 106f19a..0000000 --- a/0056-libmultipath-fix-log_thread-startup-and-teardown.patch +++ /dev/null @@ -1,148 +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); --- -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 deleted file mode 100644 index 017034e..0000000 --- a/0057-multipathd-move-cleanup_-prio-checkers-foreign-to-li.patch +++ /dev/null @@ -1,93 +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(); - --- -2.17.2 - 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 444a39d..0000000 --- a/0058-multipath-use-atexit-for-cleanup-handlers.patch +++ /dev/null @@ -1,110 +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 --- -2.17.2 - 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 7494b34..0000000 --- a/0059-mpathpersist-use-atexit-for-cleanup-handlers.patch +++ /dev/null @@ -1,32 +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; - } - --- -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 deleted file mode 100644 index c96f4cb..0000000 --- a/0060-multipath-fix-leak-in-check_path_valid.patch +++ /dev/null @@ -1,95 +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 --- -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 deleted file mode 100644 index 4228be6..0000000 --- a/0061-multipath-tools-mpath-tools.supp-file-with-valgrind-.patch +++ /dev/null @@ -1,62 +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 -+} --- -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 deleted file mode 100644 index 042929d..0000000 --- a/0062-libmultipath-use-libmp_verbosity-to-track-verbosity.patch +++ /dev/null @@ -1,441 +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; - } - --- -2.17.2 - 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 24cf615..0000000 --- a/0063-libmultipath-introduce-symbolic-values-for-logsink.patch +++ /dev/null @@ -1,185 +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) - { --- -2.17.2 - diff --git a/0064-libmultipath-simplify-dlog.patch b/0064-libmultipath-simplify-dlog.patch deleted file mode 100644 index af47833..0000000 --- a/0064-libmultipath-simplify-dlog.patch +++ /dev/null @@ -1,152 +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 --- -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 deleted file mode 100644 index 1fc5a75..0000000 --- a/0065-multipathd-common-code-for-k-and-command-args.patch +++ /dev/null @@ -1,87 +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; --- -2.17.2 - diff --git a/0066-multipathd-sanitize-uxsock_listen.patch b/0066-multipathd-sanitize-uxsock_listen.patch deleted file mode 100644 index d7efc72..0000000 --- a/0066-multipathd-sanitize-uxsock_listen.patch +++ /dev/null @@ -1,157 +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; - --- -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 deleted file mode 100644 index 29f5ce7..0000000 --- a/0067-libmultipath-fix-race-between-log_safe-and-log_threa.patch +++ /dev/null @@ -1,107 +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(); - } --- -2.17.2 - diff --git a/0068-multipath-add-libmpathvalid-library.patch b/0068-multipath-add-libmpathvalid-library.patch deleted file mode 100644 index 24ba4ac..0000000 --- a/0068-multipath-add-libmpathvalid-library.patch +++ /dev/null @@ -1,505 +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; --- -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 deleted file mode 100644 index cd24d4e..0000000 --- a/0069-multipath-tools-tests-and-unit-tests-for-libmpathval.patch +++ /dev/null @@ -1,532 +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; -+} --- -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 deleted file mode 100644 index c052217..0000000 --- a/0070-libmultipath-add-uid-failback-for-dasd-devices.patch +++ /dev/null @@ -1,90 +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, "")))); - } - --- -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 deleted file mode 100644 index 3fa6b93..0000000 --- a/0071-libmultipath-change-log-level-for-null-uid_attribute.patch +++ /dev/null @@ -1,45 +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); - } - } --- -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 deleted file mode 100644 index 8346fa2..0000000 --- a/0072-libmultipath-move-fast_io_fail-defines-to-structs.h.patch +++ /dev/null @@ -1,160 +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; --- -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 deleted file mode 100644 index f5b1d8a..0000000 --- a/0073-libmultipath-add-eh_deadline-multipath.conf-paramete.patch +++ /dev/null @@ -1,338 +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. --- -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 deleted file mode 100644 index c9947f5..0000000 --- a/0074-multipathd-remove-redundant-vector_free-int-configur.patch +++ /dev/null @@ -1,37 +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; - - /* --- -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 deleted file mode 100644 index fe2ea50..0000000 --- a/0075-libmultipath-factor-out-code-to-get-vpd-page-data.patch +++ /dev/null @@ -1,66 +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) --- -2.17.2 - 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 6208fe5..0000000 --- a/0076-libmultipath-limit-reading-0xc9-vpd-page.patch +++ /dev/null @@ -1,91 +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) --- -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 deleted file mode 100644 index ae9385f..0000000 --- a/0077-libmultipath-move-logq_lock-handling-to-log.c.patch +++ /dev/null @@ -1,141 +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) --- -2.17.2 - 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 e27aa64..0000000 --- a/0078-libmultipath-protect-logarea-with-logq_lock.patch +++ /dev/null @@ -1,110 +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 */ --- -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 deleted file mode 100644 index 31fd8b4..0000000 --- a/0079-libmultipath-prevent-DSO-unloading-with-astray-check.patch +++ /dev/null @@ -1,284 +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; --- -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 deleted file mode 100644 index 913c438..0000000 --- a/0080-libmultipath-force-map-reload-if-udev-incomplete.patch +++ /dev/null @@ -1,151 +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) { --- -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 deleted file mode 100644 index 1e67613..0000000 --- a/0081-multipath-tools-avoid-access-to-etc-localtime.patch +++ /dev/null @@ -1,112 +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); --- -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 deleted file mode 100644 index cc3a633..0000000 --- a/0082-multipath-tools-make-sure-plugin-DSOs-use-symbol-ver.patch +++ /dev/null @@ -1,149 +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) --- -2.17.2 - diff --git a/0083-libmultipath.version-add-missing-symbol.patch b/0083-libmultipath.version-add-missing-symbol.patch deleted file mode 100644 index 55e4396..0000000 --- a/0083-libmultipath.version-add-missing-symbol.patch +++ /dev/null @@ -1,30 +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; --- -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 deleted file mode 100644 index 6be89d6..0000000 --- a/0084-multipath-tools-tests-unversioned-.so-for-valgrind-t.patch +++ /dev/null @@ -1,30 +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) --- -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 deleted file mode 100644 index 3a3bbbf..0000000 --- a/0085-multipath-tools-unit-tests-fix-memory-leaks-in-mpath.patch +++ /dev/null @@ -1,53 +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) \ --- -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 deleted file mode 100644 index 3e152fc..0000000 --- a/0086-mpathpersist-Fix-Register-and-Ignore-with-0x00-SARK.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: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-mpathpersist-update-prkeys-file-on-changing-registra.patch b/0087-mpathpersist-update-prkeys-file-on-changing-registra.patch deleted file mode 100644 index 79bee15..0000000 --- a/0087-mpathpersist-update-prkeys-file-on-changing-registra.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: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 deleted file mode 100644 index bbb9f13..0000000 --- a/0088-libmultipath-warn-about-missing-braces-at-end-of-mul.patch +++ /dev/null @@ -1,42 +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); --- -2.17.2 - 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 25aa7ea..0000000 --- a/0089-libmultipath-ignore-multipaths-sections-without-wwid.patch +++ /dev/null @@ -1,37 +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)) --- -2.17.2 - 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 931e81c..0000000 --- a/0090-libmultipath-fix-format-warning-with-clang.patch +++ /dev/null @@ -1,28 +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; --- -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 deleted file mode 100644 index 1f6894d..0000000 --- a/0091-libmultipath-check-for-null-wwid-before-strcmp.patch +++ /dev/null @@ -1,34 +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); --- -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 deleted file mode 100644 index 120c637..0000000 --- a/0092-multipath.conf.5-Improve-checker_timeout-description.patch +++ /dev/null @@ -1,65 +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 --- -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 deleted file mode 100644 index 868fa18..0000000 --- a/0093-multipathd-fix-path-checkint-not-changed-when-path-s.patch +++ /dev/null @@ -1,36 +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) { --- -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 deleted file mode 100644 index e37e4da..0000000 --- a/0094-libmultipath-select_action-skip-is_mpp_known_to_udev.patch +++ /dev/null @@ -1,51 +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); --- -2.17.2 - 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 033525b..0000000 --- a/0095-libmultipath-coalesce_paths-stop-triggering-spurious.patch +++ /dev/null @@ -1,65 +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); --- -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 deleted file mode 100644 index 79912f0..0000000 --- a/0096-Revert-multipathd-uev_trigger-handle-incomplete-ADD-.patch +++ /dev/null @@ -1,61 +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; - } --- -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 deleted file mode 100644 index a19afc4..0000000 --- a/0097-libmultipath-make-find_err_path_by_dev-static.patch +++ /dev/null @@ -1,27 +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; --- -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 deleted file mode 100644 index 4c21465..0000000 --- a/0098-multipathd-avoid-io_err_stat-crash-during-shutdown.patch +++ /dev/null @@ -1,257 +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); - } --- -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 deleted file mode 100644 index 30584f6..0000000 --- a/0099-multipathd-avoid-io_err_stat-ABBA-deadlock.patch +++ /dev/null @@ -1,146 +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) --- -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 deleted file mode 100644 index 89d9f73..0000000 --- a/0100-multipathd-use-get_monotonic_time-in-io_err_stat-cod.patch +++ /dev/null @@ -1,111 +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, --- -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 deleted file mode 100644 index 90fd516..0000000 --- a/0101-multipathd-combine-free_io_err_stat_path-and-destroy.patch +++ /dev/null @@ -1,101 +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); --- -2.17.2 - 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 79ad137..0000000 --- a/0102-multipathd-cleanup-logging-for-marginal-paths.patch +++ /dev/null @@ -1,123 +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) { --- -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 deleted file mode 100644 index 4dd4051..0000000 --- a/0103-libmultipath-fix-NULL-dereference-in-find_path_by_de.patch +++ /dev/null @@ -1,46 +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) --- -2.17.2 - 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 04ff739..0000000 --- a/0104-libmultipath-snprint_devices-avoid-NULL-dereference.patch +++ /dev/null @@ -1,38 +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) --- -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 deleted file mode 100644 index dad9963..0000000 --- a/0105-libmpathpersist-fix-thread-safety-of-default-functio.patch +++ /dev/null @@ -1,274 +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); - --- -2.17.2 - diff --git a/0106-Added-github-action-for-building.patch b/0106-Added-github-action-for-building.patch deleted file mode 100644 index 8a8a7d0..0000000 --- a/0106-Added-github-action-for-building.patch +++ /dev/null @@ -1,37 +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 --- -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 deleted file mode 100644 index 5b25c29..0000000 --- a/0107-github-workflow-use-zram-device-as-test-block-device.patch +++ /dev/null @@ -1,40 +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 --- -2.17.2 - 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 ff565d6..0000000 --- a/0108-github-workflow-use-explicit-Ubuntu-version.patch +++ /dev/null @@ -1,26 +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 --- -2.17.2 - diff --git a/0109-github-workflow-add-valgrind-tests.patch b/0109-github-workflow-add-valgrind-tests.patch deleted file mode 100644 index 5c4e366..0000000 --- a/0109-github-workflow-add-valgrind-tests.patch +++ /dev/null @@ -1,36 +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 --- -2.17.2 - 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 d27f1ca..0000000 --- a/0110-github-workflow-run-apt-get-update.patch +++ /dev/null @@ -1,28 +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 --- -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 deleted file mode 100644 index e95b3f8..0000000 --- a/0111-github-workflow-add-tests-with-gcc-10-and-clang.patch +++ /dev/null @@ -1,90 +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 --- -2.17.2 - 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 49ea563..0000000 --- a/0112-multipathd-Fix-multipathd-stopping-on-shutdown.patch +++ /dev/null @@ -1,38 +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 --- -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 deleted file mode 100644 index 17d53ce..0000000 --- a/0113-libmultipath-use-3rd-digit-as-transport_id-for-expan.patch +++ /dev/null @@ -1,45 +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; - } --- -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 deleted file mode 100644 index 3207d2d..0000000 --- a/0114-libmultipath-sysfs_set_nexus_loss_tmo-support-SAS-ex.patch +++ /dev/null @@ -1,57 +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) { --- -2.17.2 - 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 e231733..0000000 --- a/0115-multipathd-add-code-to-initalize-unwinder.patch +++ /dev/null @@ -1,134 +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(); --- -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 deleted file mode 100644 index b656c08..0000000 --- a/0116-libmultipath-check-if-adopt_path-really-added-curren.patch +++ /dev/null @@ -1,57 +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); --- -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 deleted file mode 100644 index f223728..0000000 --- a/0117-multipathd-ev_add_path-fail-if-add_map_with_path-fai.patch +++ /dev/null @@ -1,31 +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 */ - } - --- -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 deleted file mode 100644 index fe69708..0000000 --- a/0118-libmultipath-check-return-value-of-udev_device_get_d.patch +++ /dev/null @@ -1,31 +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); --- -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 deleted file mode 100644 index cf106c2..0000000 --- a/0119-pathinfo-call-filter_property-after-sysfs_pathinfo.patch +++ /dev/null @@ -1,281 +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); - } --- -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 deleted file mode 100644 index c4c8efc..0000000 --- a/0120-libmultipath-pathinfo-call-filter_property-only-with.patch +++ /dev/null @@ -1,88 +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)) --- -2.17.2 - 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 db6fe52..0000000 --- a/0121-multipath-w-allow-removing-blacklisted-paths.patch +++ /dev/null @@ -1,39 +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; --- -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 deleted file mode 100644 index 6a5fcad..0000000 --- a/0122-libmultipath-fix-use-after-free-in-uev_add_path.patch +++ /dev/null @@ -1,53 +0,0 @@ -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 deleted file mode 100644 index 4db7cfd..0000000 --- a/0123-kpartx-free-loop-device-after-listing-partitions.patch +++ /dev/null @@ -1,61 +0,0 @@ -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/device-mapper-multipath.spec b/device-mapper-multipath.spec index c5ccbcb..e6d6504 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,147 +1,25 @@ Name: device-mapper-multipath -Version: 0.8.5 -Release: 5%{?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-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 +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} @@ -225,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 @@ -339,6 +217,18 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Mon Apr 19 2021 Benjamin Marzinski - 0.8.6-1 +- Update Source to upstream version 0.8.6 + * Previous patches 0001-0123 are included in the commit + * Fixes bz #1951336 +- Rename files + * Previous patches 0124-0132 are now patches 0001-0009 +- Add 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch + * make scsi wwid fallback code result match the default udev wwid + code result (Red Hat specific patch) +- Sync tests with RHEL-8 +- Resolves: bz #1951336 + * Thu Apr 15 2021 Mohan Boddu - 0.8.5-5 - Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937 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